Wikipedia MTA

triggerServerEvent y triggerClientEvent en MTA:SA: cómo comunicar cliente y servidor

En MTA:SA el código se ejecuta en dos "lados" separados: servidor y cliente. Cada jugador conectado tiene su propio cliente, mientras que el servidor es único y controla la lógica compartida. Para que ambos lados se comuniquen, MTA usa un sistema de eventos personalizados disparados con triggerServerEvent y triggerClientEvent.

¿Por qué no basta con una sola pieza de código?

Ciertas cosas solo pueden (o deben) hacerse en un lado específico:

  • El cliente controla la interfaz, el input del jugador (teclas, clics) y todo lo visual (dx, GUI, cámara).
  • El servidor controla lo que debe ser confiable y compartido entre todos: dinero, inventario, permisos, resultado de acciones importantes.
Si dejas que el cliente decida por sí solo cosas como "cuánto dinero gano al vender un objeto", cualquier jugador con un cliente modificado podría alterar ese valor. Por eso las decisiones importantes siempre deben validarse en el servidor.

Evento personalizado: primero se declara

Antes de poder disparar un evento propio, hay que declararlo con addEvent:

-- Este código debe ejecutarse tanto en cliente como en servidor
addEvent("onVenderObjeto", true) -- true = permite que se dispare de forma remota

Del cliente al servidor: triggerServerEvent

Ejemplo: el jugador hace clic en un botón de "vender" en su interfaz, y el cliente le pide al servidor que procese la venta.

-- CLIENTE
triggerServerEvent("onVenderObjeto", localPlayer, "espada_oxidada")
-- SERVIDOR
addEventHandler("onVenderObjeto", root, function(itemName)
    local precio = 50 -- el precio se calcula/valida en el servidor, nunca se confía en el cliente
    local dineroActual = getElementData(source, "dinero") or 0
    setElementData(source, "dinero", dineroActual + precio)
    outputChatBox("Vendiste " .. itemName .. " por $" .. precio, source, 0, 255, 0)
end)

Del servidor al cliente: triggerClientEvent

Ejemplo: el servidor confirma la venta y le indica al cliente que reproduzca un sonido o muestre una animación.

-- SERVIDOR
triggerClientEvent(source, "onVentaConfirmada", source, 50)
-- CLIENTE
addEvent("onVentaConfirmada", true)
addEventHandler("onVentaConfirmada", localPlayer, function(precio)
    outputChatBox("¡Venta confirmada por $" .. precio .. "!")
end)

Regla de oro

El cliente pide, el servidor decide. Cualquier cosa que afecte dinero, progreso, permisos o resultados de juego debe calcularse y validarse en el servidor, incluso si eso significa duplicar una pequeña parte de la lógica en ambos lados. Confiar ciegamente en datos que llegan desde el cliente es una de las causas más comunes de trampas y exploits en servidores de MTA:SA.
Aporte por:
Nicolas ECM
Udemy

Curso Programación en LUA para MTA

Aprende a programar desde 0 hasta avanzado con ejercicios prácticos

🔥 Ver Curso en Udemy