Pular para o conteúdo

O seu primeiro recurso BS19

Este guia constrói um pequeno recurso do zero: um comando /checkin que dá a um sobrevivente uma garrafa de água, no máximo uma vez por hora. Demora cerca de 15 minutos. Precisa de um servidor BS19 a correr, acesso aos ficheiros e à consola do txAdmin, e um editor de texto (o VS Code funciona bem).

Quando funcionar, Escrever um recurso sobre o bs_core mostra os passos seguintes: código de cliente, callbacks e as armadilhas a evitar.

Na pasta resources do servidor, crie uma pasta chamada [local] (os parênteses retos contam: fazem dela uma categoria, não um recurso) e dentro dela uma pasta chamada bs_checkin. Guarde os seus recursos em [local] para que as atualizações do framework nunca os substituam.

resources/[local]/bs_checkin/
├── fxmanifest.lua
├── config.lua
└── server.lua

O nome da pasta é o nome do recurso. Comece-o por bs_ para não chocar com outro script.

Todo o recurso FiveM precisa deste ficheiro. Diz ao servidor que ficheiros carregar e de que lado.

fx_version 'cerulean'
game 'gta5'
lua54 'yes'
name 'bs_checkin'
description 'My first BS19 resource'
shared_scripts {
'@bs_core/shared/sh_bridge.lua', -- gives you BSB (commands, callbacks)
'config.lua',
}
server_scripts { 'server.lua' }
dependencies { 'bs_core', 'bs_inventory' }

A linha @bs_core/shared/sh_bridge.lua carrega a ponte do BS19 no seu recurso. Sem ela, BSB não existe e o ficheiro do servidor falha.

Coloque numa só tabela todos os valores que um dono de servidor possa querer mudar, para que ninguém tenha de mexer no seu código.

Checkin = {
item = 'water_bottle', -- any item name from bs_inventory's item list
amount = 1,
cooldown = 3600, -- seconds between two check-ins (1 hour)
}
local lastCheckin = {} -- [charId] = os.time() of the last check-in
local function notify(src, kind, message)
TriggerClientEvent('bs:ui:notify', src, { type = kind, message = message })
end
BSB.RegisterCommand('checkin', nil, 'Daily survivor check-in', {}, function(src)
if src == 0 then return print('Run /checkin in game, not in the console.') end
local p = exports.bs_core:GetPlayerSummary(src)
if not p then return notify(src, 'error', 'Pick a character first.') end
local now = os.time()
local last = lastCheckin[p.charId]
if last and now - last < Checkin.cooldown then
local minutes = math.ceil((Checkin.cooldown - (now - last)) / 60)
return notify(src, 'error', ('Come back in %d min.'):format(minutes))
end
local ok, reason = exports.bs_inventory:GiveItem(src, Checkin.item, Checkin.amount)
if not ok then return notify(src, 'error', 'No room: ' .. tostring(reason)) end
lastCheckin[p.charId] = now
notify(src, 'success', ('Welcome back, %s. Here is some water.'):format(p.firstName))
end)

O que faz, linha a linha:

  • BSB.RegisterCommand cria o comando de chat. O nil significa que todos o podem usar; coloque uma ACE como 'bs.admin' para o limitar à staff.
  • GetPlayerSummary devolve nil enquanto o jogador ainda está no ecrã de personagens, por isso verifique isso primeiro.
  • A espera é guardada por personagem (charId), não por jogador, por isso um segundo personagem tem o seu próprio check-in. Reinicia quando o recurso reinicia, o que chega para um primeiro recurso.
  • Os itens passam sempre por exports.bs_inventory:GiveItem. Devolve false e um motivo quando o inventário está cheio. Nunca escreva diretamente na base de dados.

Adicione esta linha ao fim do server.cfg, depois dos recursos do BS19:

ensure bs_checkin

Depois, na consola em direto do txAdmin (não é preciso reiniciar o servidor):

refresh
ensure bs_checkin

refresh faz o servidor ver a pasta nova. A consola deve mostrar Started resource bs_checkin. Quando editar um ficheiro mais tarde, basta ensure bs_checkin para o recarregar.

  1. Entre no servidor e escolha um personagem.
  2. Carregue em T, escreva /checkin e carregue em Enter. Recebe uma notificação verde e uma garrafa de água no inventário (I).
  3. Escreva /checkin outra vez. Recebe uma mensagem vermelha “Come back in 60 min.”.
O que vêPorquêSolução
Couldn't find resource bs_checkinO servidor não viu a pasta ou o nome é diferenteExecute refresh e confirme que a pasta se chama exatamente bs_checkin
attempt to index a nil value (global 'BSB')Falta a linha da ponteVerifique a linha @bs_core/shared/sh_bridge.lua no fxmanifest.lua
No such export GetPlayerSummaryO bs_core ainda não arrancouMantenha ensure bs_checkin abaixo dos recursos do BS19 no server.cfg
/checkin não faz nada, sem erroAinda está no ecrã de personagens ou o comando nunca foi registadoEscolha um personagem e procure uma linha vermelha [bs_checkin] na consola
“No room: …”O inventário está cheio ou pesado demaisLargue algo e tente de novo

Qualquer erro vermelho na consola também indica o ficheiro e a linha. Corrija, execute ensure bs_checkin de novo e volte a tentar.

  • Mude item para bandage no config.lua e execute ensure bs_checkin. Sem mexer no código.
  • Dê também algum dinheiro: exports.bs_core:AddMoney(src, 'cash', 25, 'checkin').
  • Dê XP: exports.bs_core:AddXP(src, 10, 'checkin').
  • Veja as chamadas disponíveis em Visão geral de exports e eventos.