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
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 depoisSem 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
| Framework | Valor do convar | Resource | CharId | Tipo |
|---|---|---|---|---|
| krs | krs | krs | id do personagem | número |
| QBCore | qbcore | qb-core e qb-inventory | citizenid | texto |
| Creative | creative | vrp, com a marca do Creative no manifesto | Passport | número |
| vRP | vrp | vrp, sem essa marca | user_id | número |
| Sem framework | none | nenhum | license, 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:
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
| Recurso | krs | Creative | QBCore | vRP | Sem framework |
|---|---|---|---|---|---|
| Dinheiro em mãos | item dollar | item dollar | money.cash | dinheiro do vRP | não tem |
| Cartão do banco | real | sem cartão: PayCard usa o banco | sem cartão: PayCard usa o banco | sem cartão: PayCard usa o banco | não tem |
| Em serviço | real | real | job.onduty. Gang e ACE contam como em serviço | não existe: OnDuty é igual a HasGroup | ter a ACE |
| Grupo de quem está offline | sim | do framework | não | não | não |
| Item usável | sim | não | sim | não | não |
| Gemas | do framework | do framework | krs_helper_gems | krs_helper_gems | krs_helper_gems |
| Status e efeitos | sim | não | não | não | não |
Como virar Admin
krs
Com o admin ligado, rode no console do servidor:
setgroup 1 Admin 1O 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:
add_principal identifier.license:SUA_LICENSE group.admin
add_ace group.admin admin allowO 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
add_principal identifier.license:SUA_LICENSE group.admin
add_ace group.admin group.Admin allowOutros grupos seguem a mesma regra: add_ace group.admin group.Policia allow. Quem tem a ACE conta como cargo 1.
Onde achar a license
- Abra o txAdmin, aba Players.
- Clique no jogador.
- Abra IDs e encontre a linha que começa com
license:. - 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.
| Funciona | Como |
|---|---|
CharId, License, Source, Players | O CharId é a license |
Name | Nome do FiveM, com o jogador online |
Exists | Online, ou a license já entrou alguma vez |
HasGroup, HasGroupDirect, OnDuty, OnDutyList | ACE group.<Grupo>. Quem tem é cargo 1 |
GroupHasMembers | Só conta quem está online |
| Gemas e comandos de gemas | Tabela krs_helper_gems, por license |
DataGet, DataSet, DataDelete, PlayerData, SetPlayerData | Tabela krs_helper_data |
Notify, Progress, Request | ox_lib. Config.Notify.none traduz as cores |
Callbacks, Cooldown, Lock, Config, Schema, CheckVersion, Log | Igual 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:
set krs_helper_webhook "https://discord.com/api/webhooks/..."- Use
set, nãosetr. 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_helperinicia. Depois de mudar, reinicie o resource. - Cada mensagem sai sem menções e é cortada em 1900 caracteres.
Config.LogWebhookRatelimita os envios por segundo. O excesso fica só no console.
No krs, o Log também passa pelos logs do framework.
Comandos
| Comando | O 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:
| Framework | Regra padrão |
|---|---|
| krs, Creative | Grupo Admin, cargo 1 |
| QBCore | Permissão admin |
| vRP | Qualquer nome de Config.Groups.Admin |
| Sem framework | ACE group.Admin |
Configuração
Tudo fica em config.lua, que também vai para o cliente. Não coloque segredo nele.
| Opção | Padrão | O que muda |
|---|---|---|
Detection | krs, qbcore, creative, vrp | Ordem de detecção |
Groups | Admin, Policia, Paramedico, Mecanico | Grupo dos scripts para nomes do QBCore e do vRP, do cargo mais alto para o mais baixo |
Items | vazio | Item 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.Timeout | 10000 | Tempo até o callback devolver nil, em ms |
Callback.Limit | 10 | Chamadas por segundo, por jogador e por nome |
RequestTimeout | 60000 | Espera da confirmação do jogador, em ms |
Notify.Time | 5000 | Duração dos avisos, em ms |
Notify.qbcore, Notify.vrp, Notify.none | ver arquivo | Cor dos scripts para tipo de aviso |
Notify.TitleInText | true | No QBCore, junta título e texto |
UseOxLib | true | Usa o ox_lib no cliente para barra de progresso e confirmação |
Gems.Enabled | true | false desliga as gemas próprias de QBCore, vRP e modo none |
Gems.Max | 1000000 | Maior quantidade aceita numa operação |
Gems.Commands | darGemas, tirarGemas, gemas | Nome dos comandos. "" desliga |
Gems.Ace | "krs_helper.gems" | ACE que libera os comandos |
Gems.Admin | ver Permissão | Regra por framework |
Updates.Enabled | true | Aviso de versão nova no console |
Updates.GitHub | API de releases do GitHub | URL consultada no aviso |
LogWebhookRate | 2 | Mensagens 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:
Config.Groups = {
Admin = { "god","admin","mod" },
Policia = { "police" },
Petshop = { "petshop" }
}| Convar | Tipo | O que faz |
|---|---|---|
krs_helper_framework | setr | Força o framework |
krs_helper_webhook | set | URL do webhook do Log |
ox:locale | setr | Idioma: 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.
local CharId = exports.krs_helper:CharId(source)
if CharId and exports.krs_helper:HasGroup(CharId,"Admin",2) then
exports.krs_helper:AddBank(CharId,500)
endExports de servidor
Quem espera resposta do cliente, como Request e AwaitClient, precisa rodar em thread.
| Assunto | Exports |
|---|---|
| Jogador | CharId(source), Source(charId), Players(), Name(charId, mode?), License(source), Exists(charId) |
| Dinheiro | Bank(charId), AddBank(charId, valor, notify?), RemoveBank(charId, valor), PayBank(charId, valor, notify?), Pay(charId, valor, notify?), PayCard(charId, valor, notify?), HasCard(charId) |
| Gemas | Gems(charId), AddGems(charId, qtd, motivo?), PayGems(charId, qtd, motivo?), SetGems(charId, qtd), LicenseGems(licença) |
| Itens | ItemCount(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) |
| Grupos | HasGroup(charId, grupo, nivel?), HasGroupDirect(charId, grupo, nivel?), OnDuty(charId, grupo, nivel?), OnDutyList(grupo, nivel?), GroupHasMembers(grupo), SetGroup(charId, grupo, nivel?), RemoveGroup(charId, grupo) |
| Status | AddStatus(charId, status, qtd), SetEffect(charId, efeito, minutos) |
| Veículos | VehicleOwned(charId, modelo), VehicleOwner(placa), NewPlate() |
| Dados | DataGet(chave, save?), DataSet(chave, valor, save?), DataDelete(chave, ignore?), PlayerData(charId, chave), SetPlayerData(charId, chave, valor) |
| Avisos | Request(source, titulo, texto), Log(canal, mensagem) |
| Callbacks | RegisterCallback(nome, handler, limite?), AwaitClient(source, nome, ...), AwaitClientFor(timeout, source, nome, ...) |
| Ajudantes | Cooldown(chave, segundos), ClearCooldown(chave), Lock(chave), Unlock(chave) |
| Atualização | Config(resource, padroes, config, migracoes?), Schema(resource, passos), CheckVersion(resource), Framework() |
Regras que valem para todos:
- Nível 1 é o cargo mais alto.
nivelpede aquele cargo ou acima."Policia-2"é o grupoPolicia, nível 2. GroupHasMembersdevolvenilem erro do framework ou do banco. Tratenildiferente defalse.Existsaceita inteiro a partir de 1 ou texto de até 64 caracteres, com letras, números,_e-. Fora disso, ou em erro, devolvefalse.HasItemdeve ser usado só como booleano.- Gemas aceitam inteiro positivo até
Config.Gems.Max.SetGemsaceita 0. DataGetdevolve uma cópia. Depois de mudar, chameDataSet(chave, tabela, true).- No QBCore e no modo
none,DataSetsemsavesó grava quando okrs_helperpara. Se o servidor cair, o dado se perde. Cooldowndevolve0quando libera e já marca. As chaves deCooldowneLocksão separadas por resource e somem quando ele para.
Exports de cliente
| Export | O 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
-- 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.
-- 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
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.
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 = truenos padrões aceita chaves novas.Schema: aplica só os passos pendentes, em ordem, e grava a versão emkrs_helper_schema. Passo que falha é tentado de novo no próximo start.CheckVersion: lêversionerepositoryouupdate_urldo manifesto e imprime uma linha se houver versão maior. Nunca baixa nem roda código.
Problemas comuns
| Mensagem no console | O que fazer |
|---|---|
nenhum framework encontrado (krs, qb-core ou vrp): modo sem framework | Coloque o ensure do framework antes do krs_helper, ou mantenha o modo none se for o caso |
krs_helper_framework=... inválido | Use krs, qbcore, creative, vrp ou none |
item usável não disponível neste framework | Veja Item usável |
banco indisponível: a tabela krs_helper_data não foi criada | Confira o oxmysql e reinicie o krs_helper |
chave de dados inválida | A chave precisa ser texto de 1 a 150 caracteres |
falha ao aplicar a versão ... do banco | Corrija o erro de SQL. O passo roda de novo no próximo start |
