Fundamentos: tu primer recurso en QBCore · Lección 4/5 · 11 min

Tu primer script: un comando que da dinero (bien hecho)

Un /cobrar server-authoritative con QBCore, validación y cooldown, sin agujeros de seguridad.

Vamos a juntar todo en un script real: un comando que paga al jugador con QBCore, pero hecho con cabeza — decidido en el servidor y con un cooldown para que no se abuse.

config.lua (compartido)

lua
Config = {}
Config.Pago = 250            -- cuánto paga
Config.CooldownSegundos = 60 -- cada cuánto se puede usar

config.lua

server.lua (la autoridad)

lua
local QBCore = exports['qb-core']:GetCoreObject()
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
    return QBCore.Functions.Notify(src, 'Aún no puedes cobrar.', 'error')
  end
  ultimoUso[src] = ahora

  local Player = QBCore.Functions.GetPlayer(src)
  if not Player then return end
  Player.Functions.AddMoney('cash', Config.Pago, 'comando-cobrar')

  QBCore.Functions.Notify(src, ('Has cobrado $%s'):format(Config.Pago), 'success')
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. El tercer argumento de AddMoney ('comando-cobrar') es el motivo, que QBCore registra en los logs.

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/3
Rellena los huecos

Completa para obtener el objeto del core y el jugador en el servidor a partir de su source.

1local QBCore = exports['qb-core']:()
2local Player = QBCore.Functions.GetPlayer(source)
Pista

El core de QBCore se importa por export, no por import en el manifest.

Corrige el error

Falta comprobar que el jugador existe antes de darle dinero. Añade el guard justo después de obtenerlo.

Este código tiene un fallo:

1local Player = QBCore.Functions.GetPlayer(source)
2Player.Functions.AddMoney('cash', 250)

Reescríbelo corregido:

Pista

Si GetPlayer devuelve nil, Player.Functions peta. Añade 'if not Player then return end' antes de tocar al jugador.

Test

¿Por qué el AddMoney del comando /cobrar va en el servidor y no en el cliente?

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:

¿Qué tal esta lección?