Proyecto final: una tienda 24/7 con QBCore · Lección 3/4 · 11 min
El servidor: compra validada
El corazón de la tienda: un callback (o evento) que comprueba el precio desde Config, cobra y entrega.
Aquí está lo importante: el servidor recibe SOLO el nombre del item, busca su precio en Config, comprueba que el jugador tiene dinero, cobra y entrega. Con anti-spam para evitar abusos.
-- server.lua
local QBCore = exports['qb-core']:GetCoreObject()
local ultimo = {}
local function precioDe(itemName)
for _, p in ipairs(Config.Productos) do
if p.item == itemName then return p.precio end
end
return nil
end
RegisterNetEvent('tienda:server:comprar', function(itemName)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if not Player then return end
-- anti-spam
local ahora = GetGameTimer()
if ultimo[src] and (ahora - ultimo[src]) < 500 then return end
ultimo[src] = ahora
-- precio desde el SERVIDOR
local precio = precioDe(itemName)
if not precio then return end -- item no está en el catálogo
-- cobra (RemoveMoney valida saldo y devuelve true/false)
if Player.Functions.RemoveMoney('cash', precio, 'tienda-247') then
Player.Functions.AddItem(itemName, 1)
TriggerClientEvent('inventory:client:ItemBox', src, QBCore.Shared.Items[itemName], 'add')
QBCore.Functions.Notify(src, 'Comprado', 'success')
else
QBCore.Functions.Notify(src, 'No tienes suficiente efectivo', 'error')
end
end)server.lua
Cuenta los blindajes: jugador existe, anti-spam, el item está en Config (precio válido), y RemoveMoney comprueba el saldo antes de entregar. Sin uno de esos checks, un tramposo se lleva items gratis.
Practica lo aprendido
0/3Ordena el evento de compra del servidor: obtener jugador, anti-spam, precio desde Config, cobrar y entregar.
Coloca las líneas en el orden correcto con las flechas.
local Player = QBCore.Functions.GetPlayer(src) local precio = precioDe(itemName) Player.Functions.AddItem(itemName, 1)end)RegisterNetEvent('tienda:server:comprar', function(itemName) if Player.Functions.RemoveMoney('cash', precio, 'tienda-247') then if not Player then return end end local src = source if not precio then return endPista
source primero, guard del jugador, precio de Config, y solo entregas si RemoveMoney devuelve true.
Completa el guard que comprueba que el jugador existe antes de tocar su dinero.
local Player = QBCore.Functions.GetPlayer(src)if not then return endPista
GetPlayer puede devolver nil si el jugador no está cargado; córtalo ahí.
Este evento entrega el item sin comprobar que existe en QBCore.Shared.Items, así que un item mal escrito en Config rompe el inventario. Añade esa validación antes de cobrar.
Este código tiene un fallo:
local precio = precioDe(itemName)if not precio then return endif Player.Functions.RemoveMoney('cash', precio, 'tienda-247') then Player.Functions.AddItem(itemName, 1)endReescríbelo corregido:
Pista
Comprueba QBCore.Shared.Items[itemName] justo después de validar el precio y antes de RemoveMoney.
Reto: prográmalo tú
Añade un límite: que no se pueda comprar si el item no existe en QBCore.Shared.Items (item mal escrito en Config).
Escríbelo tú en tu editor (VS Code) y pruébalo en tu servidor. Aquí se aprende haciéndolo, no copiando.
Ver pista
if not QBCore.Shared.Items[itemName] then return end antes de RemoveMoney.
Escribe aquí tu solución:
