Fundamentos: tu primer recurso · Lección 4/6 · 11 min
Tu primer script: un comando que da dinero (bien hecho)
Un /cobrar server-authoritative con validación y enfriamiento (cooldown), sin agujeros de seguridad.
Vamos a juntar todo en un script real: un comando que paga al jugador, pero hecho con cabeza — decidido en el servidor y con un cooldown para que no se abuse.
config.lua (compartido)
Config = {}
Config.Pago = 250 -- cuánto paga
Config.CooldownSegundos = 60 -- cada cuánto se puede usarconfig.lua
server.lua (la autoridad)
local ultimoUso = {} -- [src] = timestamp
RegisterCommand('cobrar', function(source)
local src = source
if src == 0 then return end -- 0 = consola, ignorar
local ahora = os.time()
if ultimoUso[src] and (ahora - ultimoUso[src]) < Config.CooldownSegundos then
TriggerClientEvent('chat:addMessage', src, { args = { 'Sistema', 'Aún no puedes cobrar.' } })
return
end
ultimoUso[src] = ahora
-- Aquí darías el dinero con tu framework. Ejemplo con ESX:
-- local xPlayer = ESX.GetPlayerFromId(src)
-- xPlayer.addMoney(Config.Pago)
TriggerClientEvent('chat:addMessage', src, { args = { 'Banco', ('Has cobrado %s€'):format(Config.Pago) } })
end, false)server.lua
Fíjate: la decisión (cuánto, cuándo, a quién) está 100% en el servidor. El cliente no envía cantidades ni nada manipulable. Eso es server-authoritative.
Si pusieras el addMoney en el cliente, cualquiera con un menú trampa se daría dinero infinito. Por eso el dinero SIEMPRE se mueve en el servidor.
Practica lo aprendido
0/3Completa el comando para que ignore a la consola (cuyo source es 0).
RegisterCommand('cobrar', function(source) local src = source if src == then return endend)Pista
La consola del servidor tiene source 0.
¿Para qué sirve el cooldown en el comando /cobrar?
Pista
Piensa en el anti-abuso.
Esta línea da el dinero en el CLIENTE (inseguro). Indica la versión correcta: el dinero se mueve en el servidor con xPlayer.addMoney. Escribe la llamada correcta del servidor que paga Config.Pago.
Este código tiene un fallo:
-- cliente (MAL):SendNUIMessage({ dinero = Config.Pago })Reescríbelo corregido:
Pista
En el servidor: xPlayer.addMoney(Config.Pago).
Reto: prográmalo tú
Amplía el comando para que registre por consola cada cobro con el ID del jugador y la cantidad, y para que el cooldown sea configurable desde Config.
Escríbelo tú en tu editor (VS Code) y pruébalo en tu servidor. Aquí se aprende haciéndolo, no copiando.
Ver pista
Un print(('Jugador %s cobró %s'):format(src, Config.Pago)) justo después de validar el cooldown.
Escribe aquí tu solución:
