Fundamentals: your first resource · Lesson 4/6 · 11 min

Your first script: a command that gives money (done right)

A server-authoritative /cobrar with validation and cooldown, no security holes.

Let's put it all together in a real script: a command that pays the player, but done smartly — decided on the server and with a cooldown so it can't be abused.

config.lua (shared)

lua
Config = {}
Config.Pago = 250          -- how much it pays
Config.CooldownSegundos = 60 -- how often it can be used

config.lua

server.lua (the authority)

lua
local ultimoUso = {} -- [src] = timestamp

RegisterCommand('cobrar', function(source)
  local src = source
  if src == 0 then return end -- 0 = console, ignore

  local ahora = os.time()
  if ultimoUso[src] and (ahora - ultimoUso[src]) < Config.CooldownSegundos then
    TriggerClientEvent('chat:addMessage', src, { args = { 'Sistema', 'You cannot collect yet.' } })
    return
  end
  ultimoUso[src] = ahora

  -- Here you'd grant the money with your framework. Example with ESX:
  -- local xPlayer = ESX.GetPlayerFromId(src)
  -- xPlayer.addMoney(Config.Pago)

  TriggerClientEvent('chat:addMessage', src, { args = { 'Banco', ('You collected %s€'):format(Config.Pago) } })
end, false)

server.lua

Notice: the decision (how much, when, to whom) is 100% on the server. The client doesn't send amounts or anything tamperable. That's server-authoritative.

If you put addMoney on the client, anyone with a cheat menu would give themselves infinite money. That's why money is ALWAYS moved on the server.

Challenge: code it yourself

Extend the command so it logs every payout to the console with the player's ID and the amount, and so the cooldown is configurable from Config.

Write it yourself in your editor (VS Code) and test it on your server. You learn here by doing it, not by copying.

See hint

A print(('Player %s collected %s'):format(src, Config.Pago)) right after validating the cooldown.

Escribe aquí tu solución:

How was this lesson?