Skip to content

krs_helper ​

Ponte entre os scripts e o framework do servidor. Os scripts chamam as exports do krs_helper, e ele resolve no framework detectado. Sem framework, ele sobe no modo none, com identidade pela license e grupos por ACE.

Precisa de: oxmysql, ox_lib

Instalação ​

cfg
set mysql_connection_string "mysql://usuario:senha@localhost/nome_do_banco?charset=utf8mb4"
setr ox:locale "pt-br"

ensure oxmysql
ensure ox_lib

# o seu framework, só um:
ensure krs
# ensure qb-core
# ensure qb-inventory
# ensure vrp

ensure krs_helper
# os scripts vêm depois

Sem framework, apague a linha dele. As tabelas krs_helper_data, krs_helper_gems e krs_helper_schema são criadas sozinhas, quando o framework precisa delas. Veja a ordem no server.cfg.

Frameworks suportados ​

FrameworkValor do convarResourceCharIdTipo
krskrskrsid do personagemnúmero
QBCoreqbcoreqb-core e qb-inventorycitizenidtexto
Creativecreativevrp, com a marca do Creative no manifestoPassportnúmero
vRPvrpvrp, sem essa marcauser_idnúmero
Sem frameworknonenenhumlicense, sem o prefixo license:texto

A detecção segue Config.Detection: krs, qbcore, creative, vrp. Se nada for encontrado, entra o modo none, com aviso no console. O framework precisa estar iniciado antes do krs_helper.

Para forçar um framework:

cfg
setr krs_helper_framework "qbcore"

Use setr: o cliente também lê esse convar. Valor inválido gera aviso no console e cai na detecção automática.

O que muda entre eles ​

RecursokrsCreativeQBCorevRPSem framework
Dinheiro em mãositem dollaritem dollarmoney.cashdinheiro do vRPnão tem
Cartão do bancorealsem cartão: PayCard usa o bancosem cartão: PayCard usa o bancosem cartão: PayCard usa o banconão tem
Em serviçorealrealjob.onduty. Gang e ACE contam como em serviçonão existe: OnDuty é igual a HasGroupter a ACE
Grupo de quem está offlinesimdo frameworknãonãonão
Item usávelsimnãosimnãonão
Gemasdo frameworkdo frameworkkrs_helper_gemskrs_helper_gemskrs_helper_gems
Status e efeitossimnãonãonãonão

Como virar Admin ​

krs ​

Com o admin ligado, rode no console do servidor:

setgroup 1 Admin 1

O primeiro número é o passaporte, e o último é o cargo. O passaporte é o id do personagem na tabela characters. Em jogo, a tecla F7 mostra o de quem está por perto.

Creative ​

Dê o grupo Admin pelo próprio framework.

QBCore ​

No server.cfg:

cfg
add_principal identifier.license:SUA_LICENSE group.admin
add_ace group.admin admin allow

O grupo Admin aceita qualquer nome de Config.Groups.Admin: god, admin ou mod. Para usar outro nome: add_ace group.admin god allow.

vRP ​

Dê um dos grupos god, admin ou mod. Uma permissão do vRP com esse nome também vale. A posição na lista define o cargo: god é 1, admin é 2 e mod é 3.

Sem framework ​

cfg
add_principal identifier.license:SUA_LICENSE group.admin
add_ace group.admin group.Admin allow

Outros grupos seguem a mesma regra: add_ace group.admin group.Policia allow. Quem tem a ACE conta como cargo 1.

Onde achar a license ​

  1. Abra o txAdmin, aba Players.
  2. Clique no jogador.
  3. Abra IDs e encontre a linha que começa com license:.
  4. Copie só o que vem depois de license:.

Modo sem framework ​

Entra quando nada é detectado ou com setr krs_helper_framework "none". Nenhuma export dá erro.

FuncionaComo
CharId, License, Source, PlayersO CharId é a license
NameNome do FiveM, com o jogador online
ExistsOnline, ou a license já entrou alguma vez
HasGroup, HasGroupDirect, OnDuty, OnDutyListACE group.<Grupo>. Quem tem é cargo 1
GroupHasMembersSó conta quem está online
Gemas e comandos de gemasTabela krs_helper_gems, por license
DataGet, DataSet, DataDelete, PlayerData, SetPlayerDataTabela krs_helper_data
Notify, Progress, Requestox_lib. Config.Notify.none traduz as cores
Callbacks, Cooldown, Lock, Config, Schema, CheckVersion, LogIgual aos outros modos

Não funcionam, e devolvem 0, false ou vazio, com um aviso no console por função: dinheiro, itens, SetGroup, RemoveGroup, veículos, AddStatus, SetEffect e RegisterUsable. ItemName devolve o próprio nome.

Webhook ​

Para mandar o Log também ao Discord:

cfg
set krs_helper_webhook "https://discord.com/api/webhooks/..."
  • Use set, não setr. A URL fica só no servidor.
  • O valor precisa começar com https://. Sem isso, o envio fica desligado.
  • O convar é lido quando o krs_helper inicia. Depois de mudar, reinicie o resource.
  • Cada mensagem sai sem menções e é cortada em 1900 caracteres.
  • Config.LogWebhookRate limita os envios por segundo. O excesso fica só no console.

No krs, o Log também passa pelos logs do framework.

Comandos ​

ComandoO que faz
/darGemas <passaporte> <quantidade>Dá gemas
/tirarGemas <passaporte> <quantidade>Tira gemas até zerar
/gemas [passaporte]Mostra o saldo. Sem passaporte, mostra o seu

O passaporte é o CharId: citizenid no QBCore e license sem framework. O saldo é da conta, e todos os personagens dela dividem.

Permissão ​

Os comandos de gemas funcionam no console. Em jogo, valem a ACE krs_helper.gems em qualquer framework e a regra de Config.Gems.Admin:

FrameworkRegra padrão
krs, CreativeGrupo Admin, cargo 1
QBCorePermissão admin
vRPQualquer nome de Config.Groups.Admin
Sem frameworkACE group.Admin

Configuração ​

Tudo fica em config.lua, que também vai para o cliente. Não coloque segredo nele.

OpçãoPadrãoO que muda
Detectionkrs, qbcore, creative, vrpOrdem de detecção
GroupsAdmin, Policia, Paramedico, MecanicoGrupo dos scripts para nomes do QBCore e do vRP, do cargo mais alto para o mais baixo
ItemsvazioItem dos scripts para item do framework. Ex.: { water = "agua" }
NoAce"group."Prefixo da ACE no modo sem framework
Cash"dollar"Nome do item de dinheiro em mãos
Callback.Timeout10000Tempo até o callback devolver nil, em ms
Callback.Limit10Chamadas por segundo, por jogador e por nome
RequestTimeout60000Espera da confirmação do jogador, em ms
Notify.Time5000Duração dos avisos, em ms
Notify.qbcore, Notify.vrp, Notify.nonever arquivoCor dos scripts para tipo de aviso
Notify.TitleInTexttrueNo QBCore, junta título e texto
UseOxLibtrueUsa o ox_lib no cliente para barra de progresso e confirmação
Gems.Enabledtruefalse desliga as gemas próprias de QBCore, vRP e modo none
Gems.Max1000000Maior quantidade aceita numa operação
Gems.CommandsdarGemas, tirarGemas, gemasNome dos comandos. "" desliga
Gems.Ace"krs_helper.gems"ACE que libera os comandos
Gems.Adminver PermissãoRegra por framework
Updates.EnabledtrueAviso de versão nova no console
Updates.GitHubAPI de releases do GitHubURL consultada no aviso
LogWebhookRate2Mensagens por segundo para o webhook

Em Config.Groups, grupo fora da lista usa o próprio nome. No krs e no Creative, os nomes já são os mesmos dos scripts. Para ligar um grupo novo no QBCore ou no vRP:

lua
Config.Groups = {
	Admin = { "god","admin","mod" },
	Policia = { "police" },
	Petshop = { "petshop" }
}
ConvarTipoO que faz
krs_helper_frameworksetrForça o framework
krs_helper_webhooksetURL do webhook do Log
ox:localesetrIdioma: pt-br, en, es, fr, zh-cn, hi, ar ou bn

Os adapters ficam em server/adapters/ e podem ser editados para um framework próprio.

Para programadores ​

Chame as exports direto, sem incluir arquivo do krs_helper.

lua
local CharId = exports.krs_helper:CharId(source)
if CharId and exports.krs_helper:HasGroup(CharId,"Admin",2) then
	exports.krs_helper:AddBank(CharId,500)
end

Exports de servidor ​

Quem espera resposta do cliente, como Request e AwaitClient, precisa rodar em thread.

AssuntoExports
JogadorCharId(source), Source(charId), Players(), Name(charId, mode?), License(source), Exists(charId)
DinheiroBank(charId), AddBank(charId, valor, notify?), RemoveBank(charId, valor), PayBank(charId, valor, notify?), Pay(charId, valor, notify?), PayCard(charId, valor, notify?), HasCard(charId)
GemasGems(charId), AddGems(charId, qtd, motivo?), PayGems(charId, qtd, motivo?), SetGems(charId, qtd), LicenseGems(licença)
ItensItemCount(charId, item), HasItem(charId, item, qtd?), GiveItem(charId, item, qtd, notify?), GiveItemRaw(charId, item, qtd, notify?), TakeItem(charId, item, qtd, notify?, slot?), UseCharge(charId, itemCompleto, item, slot?), CanCarry(charId, item, qtd), Weight(charId), MaxWeight(charId), ItemName(item), ItemExists(item), RegisterUsable(item, fn)
GruposHasGroup(charId, grupo, nivel?), HasGroupDirect(charId, grupo, nivel?), OnDuty(charId, grupo, nivel?), OnDutyList(grupo, nivel?), GroupHasMembers(grupo), SetGroup(charId, grupo, nivel?), RemoveGroup(charId, grupo)
StatusAddStatus(charId, status, qtd), SetEffect(charId, efeito, minutos)
VeículosVehicleOwned(charId, modelo), VehicleOwner(placa), NewPlate()
DadosDataGet(chave, save?), DataSet(chave, valor, save?), DataDelete(chave, ignore?), PlayerData(charId, chave), SetPlayerData(charId, chave, valor)
AvisosRequest(source, titulo, texto), Log(canal, mensagem)
CallbacksRegisterCallback(nome, handler, limite?), AwaitClient(source, nome, ...), AwaitClientFor(timeout, source, nome, ...)
AjudantesCooldown(chave, segundos), ClearCooldown(chave), Lock(chave), Unlock(chave)
AtualizaçãoConfig(resource, padroes, config, migracoes?), Schema(resource, passos), CheckVersion(resource), Framework()

Regras que valem para todos:

  • Nível 1 é o cargo mais alto. nivel pede aquele cargo ou acima. "Policia-2" é o grupo Policia, nível 2.
  • GroupHasMembers devolve nil em erro do framework ou do banco. Trate nil diferente de false.
  • Exists aceita inteiro a partir de 1 ou texto de até 64 caracteres, com letras, números, _ e -. Fora disso, ou em erro, devolve false.
  • HasItem deve ser usado só como booleano.
  • Gemas aceitam inteiro positivo até Config.Gems.Max. SetGems aceita 0.
  • DataGet devolve uma cópia. Depois de mudar, chame DataSet(chave, tabela, true).
  • No QBCore e no modo none, DataSet sem save só grava quando o krs_helper para. Se o servidor cair, o dado se perde.
  • Cooldown devolve 0 quando libera e já marca. As chaves de Cooldown e Lock são separadas por resource e somem quando ele para.

Exports de cliente ​

ExportO que faz
Framework()Nome do framework
CharId()CharId do jogador. Fora do krs, pergunta ao servidor
HasGroup(grupo, nivel?), OnDuty(grupo, nivel?)Grupo do jogador. Fora do krs, pergunta ao servidor
RegisterCallback(nome, handler)Registra um callback no cliente
Await(nome, ...), AwaitFor(timeout, nome, ...)Chama um callback do servidor
Cuffed(), Blocked()Jogador algemado ou bloqueado
AnimClear(modo?), AnimPlay(upper, sequencia, loop), AnimProp(dict, anim, prop, flag, mao, altura, pos1, pos2, pos3, pos4, pos5)Animações
ObjectPlace(modelo, rotacao?, align?, distancia?, chao?, inicio?)Posiciona um objeto. Só o krs tem o posicionador visual
CreateObject(modelo), DeleteObject(objeto)Cria e apaga objeto em rede
VehicleModels()Lista de veículos. Lista grande: chame uma vez
ItemName(item)Nome do item. Fora do krs, pergunta ao servidor
SetState(chave, valor)State bag do jogador. Só para estado visual: o servidor não deve confiar nele

Exports que perguntam ao servidor não devem rodar por frame.

Eventos ​

lua
-- servidor, sem retorno
TriggerEvent("krs_helper:Notify",source,titulo,texto,cor,tempo)
TriggerEvent("krs_helper:Progress",source,texto,tempo)

-- cliente, sem retorno
TriggerEvent("krs_helper:Notify",titulo,texto,cor,tempo)
TriggerEvent("krs_helper:Progress",texto,tempo)

Cores: verde, amarelo e vermelho.

Eventos locais do cliente: krs_helper:CharLoaded(charId) e krs_helper:CharUnloaded(charId). Qualquer código do cliente pode dispará-los, então use só para tela.

Callbacks ​

O protocolo é o mesmo em todos os frameworks: tempo limite de 10 s devolvendo nil, limite por segundo no servidor e nil em erro no handler. Quem passa do limite dispara krs:callback:flood.

lua
-- servidor
exports.krs_helper:RegisterCallback("loja:Comprar",function(source,Item)
	return true
end,2)

-- cliente
local Ok = exports.krs_helper:Await("loja:Comprar","water")

Item usável ​

lua
exports.krs_helper:RegisterUsable("cigarro",function(source,slot,qtd,itemCompleto)
	-- o script tira o item, se quiser
end)

Funciona no krs e no QBCore. No Creative, no vRP e sem framework, devolve false com um aviso. O gancho para Creative e vRP está comentado no fim do adapter de cada um e precisa de um ajuste no inventário do servidor.

Config, banco e versão ​

Chame uma vez, no start do script.

lua
Config = exports.krs_helper:Config(GetCurrentResourceName(),Defaults,Config,{
	["1.2.0"] = { rename = { ["OldName"] = "NewName" } }
})

exports.krs_helper:Schema(GetCurrentResourceName(),{
	[1] = "CREATE TABLE IF NOT EXISTS shop_sales (Id INT AUTO_INCREMENT PRIMARY KEY, CharId VARCHAR(50), Price INT)"
})

exports.krs_helper:CheckVersion(GetCurrentResourceName())
  • Config: chave que falta usa o padrão. Chave desconhecida é ignorada, com aviso. Tipo errado usa o padrão, com aviso. Lista do dono substitui a lista inteira. Tabela com _open = true nos padrões aceita chaves novas.
  • Schema: aplica só os passos pendentes, em ordem, e grava a versão em krs_helper_schema. Passo que falha é tentado de novo no próximo start.
  • CheckVersion: lê version e repository ou update_url do manifesto e imprime uma linha se houver versão maior. Nunca baixa nem roda código.

Problemas comuns ​

Mensagem no consoleO que fazer
nenhum framework encontrado (krs, qb-core ou vrp): modo sem frameworkColoque o ensure do framework antes do krs_helper, ou mantenha o modo none se for o caso
krs_helper_framework=... inválidoUse krs, qbcore, creative, vrp ou none
item usável não disponível neste frameworkVeja Item usável
banco indisponível: a tabela krs_helper_data não foi criadaConfira o oxmysql e reinicie o krs_helper
chave de dados inválidaA chave precisa ser texto de 1 a 150 caracteres
falha ao aplicar a versão ... do bancoCorrija o erro de SQL. O passo roda de novo no próximo start