Cliente y servidor a fondo · Lección 1/4 · 10 min
Eventos seguros: no te fíes del cliente
Cualquier jugador puede disparar tus eventos de red con los datos que quiera. Aprende a validarlos para que no te roben el servidor.
Un RegisterNetEvent es una puerta abierta: cualquier jugador puede dispararlo desde su cliente con los argumentos que le dé la gana. Si no validas, le estás regalando trampas.
El error típico (vulnerable)
-- ❌ MAL: confía en la cantidad que manda el cliente
RegisterNetEvent('tienda:server:vender')
AddEventHandler('tienda:server:vender', function(cantidad, precio)
local xPlayer = ESX.GetPlayerFromId(source)
xPlayer.addMoney(cantidad * precio) -- el cliente manda cantidad Y precio = dinero infinito
end)Vulnerable
Aquí un tramposo manda cantidad=99999 y precio=99999 y se forra. El precio y la lógica NUNCA deben venir del cliente.
La versión segura
RegisterNetEvent('tienda:server:vender')
AddEventHandler('tienda:server:vender', function(itemName, cantidad)
local src = source
local xPlayer = ESX.GetPlayerFromId(src)
if not xPlayer then return end
-- 1) valida tipos y rangos
cantidad = tonumber(cantidad)
if not cantidad or cantidad < 1 or cantidad > 100 then return end
-- 2) el PRECIO lo decide el servidor, no el cliente
local precio = Config.Precios[itemName]
if not precio then return end
-- 3) comprueba que el jugador TIENE lo que dice vender
local item = xPlayer.getInventoryItem(itemName)
if not item or item.count < cantidad then return end
xPlayer.removeInventoryItem(itemName, cantidad)
xPlayer.addMoney(precio * cantidad)
end)Validación completa
- Valida tipo y rango de cada argumento (tonumber, límites).
- Precios, recompensas y lógica salen de Config o BD en el servidor, nunca del cliente.
- Comprueba que el jugador tiene/puede hacer lo que pide (item, dinero, trabajo, distancia).
Practica lo aprendido
0/3Un evento de servidor hace: xPlayer.addMoney(cantidad * precio), donde cantidad y precio llegan como argumentos del cliente. ¿Por qué es un agujero?
Pista
¿Quién controla los valores que llegan en los argumentos?
Completa la validación segura: convierte la cantidad a número, comprueba el rango y saca el precio del servidor.
cantidad = (cantidad)if not cantidad or cantidad < 1 or cantidad > 100 then return endlocal precio = [itemName]if not precio then return endPista
Primero valida el tipo numérico; el precio sale de tu tabla de Config.
Blinda este evento vulnerable: el precio NO puede venir del cliente, debe salir de Config, y valida la cantidad con tonumber.
Este código tiene un fallo:
RegisterNetEvent('tienda:server:vender')AddEventHandler('tienda:server:vender', function(cantidad, precio) local xPlayer = ESX.GetPlayerFromId(source) xPlayer.addMoney(cantidad * precio)end)Reescríbelo corregido:
Pista
Quita 'precio' de los argumentos y léelo de Config.Precios[itemName].
Reto: prográmalo tú
Coge un evento que dé un item al jugador y blíndalo: que valide la cantidad (1-10) y que el item exista en una lista de Config permitidos.
Escríbelo tú en tu editor (VS Code) y pruébalo en tu servidor. Aquí se aprende haciéndolo, no copiando.
Ver pista
tonumber + comprobar rango + Config.ItemsPermitidos[item] antes de addInventoryItem.
Escribe aquí tu solución:
