Client and server in depth · Lesson 1/4 · 10 min
Secure events: don't trust the client
Any player can trigger your network events with whatever data they want. Learn to validate them so they don't take over your server.
A RegisterNetEvent is an open door: any player can trigger it from their client with whatever arguments they please. If you don't validate, you're handing out cheats.
The typical mistake (vulnerable)
-- ❌ BAD: trusts the amount sent by the client
RegisterNetEvent('tienda:server:vender')
AddEventHandler('tienda:server:vender', function(cantidad, precio)
local xPlayer = ESX.GetPlayerFromId(source)
xPlayer.addMoney(cantidad * precio) -- the client sends amount AND price = infinite money
end)Vulnerable
Here a cheater sends cantidad=99999 and precio=99999 and gets rich. The price and the logic must NEVER come from the client.
The secure version
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) validate types and ranges
cantidad = tonumber(cantidad)
if not cantidad or cantidad < 1 or cantidad > 100 then return end
-- 2) the PRICE is decided by the server, not the client
local precio = Config.Precios[itemName]
if not precio then return end
-- 3) check that the player ACTUALLY has what they claim to sell
local item = xPlayer.getInventoryItem(itemName)
if not item or item.count < cantidad then return end
xPlayer.removeInventoryItem(itemName, cantidad)
xPlayer.addMoney(precio * cantidad)
end)Full validation
- Validate the type and range of every argument (tonumber, limits).
- Prices, rewards and logic come from Config or the DB on the server, never from the client.
- Check that the player has/can do what they ask (item, money, job, distance).
Practice what you learned
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].
Challenge: code it yourself
Take an event that gives an item to the player and harden it: validate the amount (1-10) and that the item exists in a list of Config-allowed items.
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
tonumber + range check + Config.ItemsPermitidos[item] before addInventoryItem.
Escribe aquí tu solución:
