
BlackHamm3rJack
Members-
Posts
10 -
Joined
-
Last visited
Everything posted by BlackHamm3rJack
-
Function passed as argument becomes nil
BlackHamm3rJack replied to BlackHamm3rJack's topic in Scripting
Yes I thought about that but MTA does not allow to send function objects as data in the event trigger functions... -
I was creating a script that was based on a sort of HTTP client/server model where the client issues a request to the server, the server then elaborates with a particular function and then returns the result (that corresponds to a client-side event) with the elaborated result. So i have created a function that registers the request server-side, by adding an event and an appropriate handler. The function requires an argument that, given the data as a table, it produces another table with the result. The code follows: local nameReq = "[freeroam]:%s:req_%s" local nameRes = "[freeroam]:%s:res_%s" function register_newEvent(name, res, processor) local req = string.format(nameReq, getResourceName(res), name) local res = string.format(nameRes, getResourceName(res), name) if not addEvent(req, true) then return false end if not addEventHandler(req, root, function (data) triggerClientEvent(res, source, processor(data)) end) then return false end return true end As you can see, the function object is called "processor" and when called, if i do the following: outputServerLog(tostring(processor)) it outputs "nil", in fact it gives me an error when i call it in the response event trigger. Another thing i have to specify is that it works resource-local, but when i try to do it from another resource, using the exported functions, the error comes up. The way i call it is the following (server-side): function onResourceStart(res) local exp = exports["req-res"] exp:register_newEvent("getAvailableTranslations", res, function (data) return { database_getAvailableTranslations() } end) exp:register_newEvent("getTranslation", res, function (data) return { database_getTranslation(data.language, data.name) } end) exp:register_newEvent("getLanguageImage", res, function (data) return { database_getLanguageImage(data.language) } end) exp:register_newEvent("getLanguageFullName", res, function (data) return { database_getLanguageFullName(data.language) } end) end addEventHandler("onResourceStart", resourceRoot, onResourceStart) I even tried storing the functions in the script instead of creating them as anonymous functions, but i got the same result. The error i get is: "attempt to call upvale 'processor' (a nil value)". Any solutions? I'm available to give further explanations. Thanks in advance. Update: It looks like that when you call an exported function, if you pass a function object as a parameter, then it will become nil, i hope there are workarounds for this
-
Maybe you misunderstood, if i use getRootElement inside the function, it will trigger the event to every client, but i want the event to be triggered to all the clients that are not logged in.
-
I have this snippet of code: -- Process all the players function language_onResourceStart() for index, player in ipairs(getElementsByType("player")) do -- If the player is not logged in, then show language window if isGuestAccount(getPlayerAccount(player)) then triggerClientEvent(player, "language_showWindow", player) end end end addEventHandler("onResourceStart", root, language_onResourceStart) -- Called when a new player joins function language_onPlayerJoin() -- Check player account if isGuestAccount(getPlayerAccount(source)) then triggerClientEvent(source, "language_showWindow", source) end end addEventHandler("onPlayerJoin", root, language_onPlayerJoin) The problem is: when a player joins, the function language_onPlayerJoin successfully triggers the client event language_showWindow, but when the resource is started, with the function language_onResourceStart the event is instead not triggered (when it should trigger the event for each client). What is happening with this code? I tried to check if the for loop gets executed, and it does. It also finds the correct players, so the local variable player just seems to be correct. I just don't know what's wrong. Any help appreciated, thanks.
-
Ok thx, you method is working
-
I need to create a sort of module in lua, not C++ like a .dll or .so module. The function "require" isn't existing, so how i can do to share functions between the same resource?
-
Messaggi inviati due volte nella chat!
BlackHamm3rJack replied to BlackHamm3rJack's topic in Italian / Italiano
Secondo me non ho capito bene quando, nell'addEventHandler e nel triggerServerEvent devo usare getLocalPlayer() o getRootElement() -
Messaggi inviati due volte nella chat!
BlackHamm3rJack replied to BlackHamm3rJack's topic in Italian / Italiano
Comunque, ho modificato come hai detto tu ma bugga di brutto, tipo ci rimane il pannello di login con quello di registrazione sovrapposto, ecc. Ah il messaggio lo stampa 2 volte ancora. -
Messaggi inviati due volte nella chat!
BlackHamm3rJack replied to BlackHamm3rJack's topic in Italian / Italiano
Hhahhaha mettere le ; lo faccio per abitudine con C, o Pawn, comunque grazie della risposta, ora vedo di provare se va -
Allora, ho fatto uno script do login/registrazione con database SQLite, ma quando mi da la conferma del login/registrazione mi invia due volte lo stesso messaggio! Per esempio quando mi loggo mi dice: -Ti sei loggato con successo -Ti sei loggato con successo Ma dovrebbe inviarmelo solo una volta. Comunque, ecco la descrizione della resource: -Database: Tabella "info": "nome", "password", "seriale", "ip" (lo so la password non è criptata, devo ancora farlo) -Gestore.lua (lato server): -- Controlla che l'account con un determinato nome esista function controllaEsistenzaAccount(nome) -- Codice SQL local db = dbConnect("sqlite", ":mod_libera/utenti.db"); local gQuery = dbQuery(db, "SELECT nome FROM 'info' WHERE nome = '" .. nome .. "';"); local rs, nRighe, msgErr = dbPoll(gQuery, -1); if (nRighe == 0) then triggerClientEvent("rispostaControlloAccount", getRootElement(), 0); else triggerClientEvent("rispostaControlloAccount", getRootElement(), 1); end; end; -- Fa uscire il client function clientEsce(giocatore) kickPlayer(giocatore, "Non puoi giocare senza loggarti/registrarti"); end; -- Logga il client function loggaClient(nome, pass, giocatore) -- Codice SQL local db = dbConnect("sqlite", ":mod_libera/utenti.db"); local gQuery = dbQuery(db, "SELECT password FROM 'info' WHERE nome = '" .. nome .. "';"); local rs, nRighe, msgErr = dbPoll(gQuery, -1); if nRighe > 0 then for rs, riga in pairs (rs) do for colonna, valore in pairs (riga) do if (valore == pass) then -- Login avvenuto con successo spawnPlayer(giocatore, 1965, -1720, 16); fadeCamera(giocatore, true); setCameraTarget(giocatore, giocatore); outputChatBox("Ti sei loggato con successo", giocatore); else -- Password errata outputChatBox("Password errata", giocatore); triggerClientEvent("rispostaControlloAccount", getRootElement(), 1); end; end; end; end; end; -- Registra il client function registraClient(nome, pass, giocatore) -- Codice SQL local db = dbConnect("sqlite", ":mod_libera/utenti.db"); local gQuery = dbQuery(db, "INSERT INTO 'info' VALUES ('" .. nome .. "', '" .. pass .. "', '" .. getPlayerSerial(giocatore) .. "', '" .. getPlayerIP(giocatore) .. "');"); local rs, nRighe, msgErr = dbPoll(gQuery, -1); -- Registrazione avvenuta con successo sempre spawnPlayer(giocatore, 1965, -1720, 16); fadeCamera(giocatore, true); setCameraTarget(giocatore, giocatore); outputChatBox("Ti sei registrato con successo", giocatore); end; -- Nuovi eventi addEvent("controllaAccount", true); addEvent("clientVuoleUscire", true); addEvent("loginClient", true); addEvent("registrazioneClient", true); -- Gestori eventi addEventHandler("controllaAccount", getRootElement(), controllaEsistenzaAccount); addEventHandler("clientVuoleUscire", getRootElement(), clientEsce); addEventHandler("loginClient", getRootElement(), loggaClient); addEventHandler("registrazioneClient", getRootElement(), registraClient); - GUI.lua (lato client): -- Il client ha inviato i dati per il login function clientInviaLogin(bottone, stato) if ((bottone == "left") and (stato == "up")) then local nome = getPlayerName(getLocalPlayer()); local pass = guiGetText(tLPassword); if (pass ~= "") then triggerServerEvent("loginClient", getRootElement(), nome, pass, getLocalPlayer()); guiSetInputEnabled(false); guiSetVisible(fLogin, false); showCursor(false); else outputChatBox("Perfavore, inserisci una password"); end; end; end; -- Il client ha inviato i dati per la registrazione function clientInviaRegistrazione(bottone, stato) if ((bottone == "left") and (stato == "up")) then local nome = getPlayerName(getLocalPlayer()); local pass = guiGetText(tRPassword); if (pass ~= "") then triggerServerEvent("registrazioneClient", getRootElement(), nome, pass, getLocalPlayer()); guiSetInputEnabled(false); guiSetVisible(fRegistrazione, false); showCursor(false); else outputChatBox("Perfavore, inserisci una password"); end; end; end; -- Il client esce dal server function clientInviaUscita() triggerServerEvent("clientVuoleUscire", getRootElement(), getLocalPlayer()); end; -- Crea la finestra per permettere al giocatore di loggarsi e giocare function creaFinestraLogin() -- Centra la finestra a seconda della risoluzione dello schermo del giocatore local alt, lun = 200, 120; local xAlt, yLun = guiGetScreenSize(); local centroX, centroY = (xAlt / 2) - (alt / 2), (yLun / 2) - (lun / 2); -- Crea la finestra fLogin = guiCreateWindow(centroX, centroY, alt, lun, "Perfavore, loggati", false); guiWindowSetMovable(fLogin, false); guiWindowSetSizable(fLogin, false); -- Crea delle labels guiCreateLabel(10, 20, 180, 18, "Inserisci i dati per continuare:", false, fLogin); guiCreateLabel(10, 40, 180, 18, "Password:", false, fLogin); -- Crea il campo di testo e setta alcune impostazioni tLPassword = guiCreateEdit(10, 60, 180, 18, "", false, fLogin); guiEditSetMasked(tLPassword, true); guiEditSetMaxLength(tLPassword, 16); -- Crea il bottone di login e uscita bLogin = guiCreateButton(10, 90, 85, 28, "Login", false, fLogin); bLEsci = guiCreateButton(105, 90, 85, 28, "Esci", false, fLogin); -- Rende la finestra invisibile guiSetVisible(fLogin, false); -- Gestore onClick del bottone esci e login addEventHandler("onClientGUIClick", bLogin, clientInviaLogin, false); addEventHandler("onClientGUIClick", bLEsci, clientInviaUscita, false); end; -- Crea la finestra per registrare il giocatore nuovo function creaFinestraRegistrazione() -- Centra la finestra a seconda della risoluzione dello schermo del giocatore local alt, lun = 200, 120; local xAlt, yLun = guiGetScreenSize(); local centroX, centroY = (xAlt / 2) - (alt / 2), (yLun / 2) - (lun / 2); -- Crea la finestra fRegistrazione = guiCreateWindow(centroX, centroY, alt, lun, "Perfavore, registrati", false); guiWindowSetMovable(fRegistrazione, false); guiWindowSetSizable(fRegistrazione, false); -- Crea delle labels guiCreateLabel(10, 20, 180, 18, "Inserisci i dati per continuare:", false, fRegistrazione); guiCreateLabel(10, 40, 180, 18, "Password:", false, fRegistrazione); -- Crea il campo di testo e setta alcune impostazioni tRPassword = guiCreateEdit(10, 60, 180, 18, "", false, fRegistrazione); guiEditSetMasked(tRPassword, true); guiEditSetMaxLength(fRegistrazione, 16); -- Crea il bottone di registrazione e uscita bRegistrati = guiCreateButton(10, 90, 85, 28, "Registrati", false, fRegistrazione); bREsci = guiCreateButton(105, 90, 85, 28, "Esci", false, fRegistrazione); -- Rende la finestra invisibile guiSetVisible(fRegistrazione, false); -- Gestore onClick del bottone esci e registrati addEventHandler("onClientGUIClick", bRegistrati, clientInviaRegistrazione, false); addEventHandler("onClientGUIClick", bREsci, clientInviaUscita, false); end; function rispostaControllo(esistenza) if (esistenza == 1) then -- Crea una finestra di login creaFinestraLogin(); guiSetVisible(fLogin, true); else -- Crea una finestra di registrazione creaFinestraRegistrazione(); guiSetVisible(fRegistrazione, true); end; -- Abilita l'input dall'utente showCursor(true); guiSetInputEnabled(true); end; -- Nuovi eventi addEvent("rispostaControlloAccount", true); -- Gestore eventi addEventHandler("onClientResourceStart", getRootElement(), function () triggerServerEvent("controllaAccount", getRootElement(), getPlayerName(getLocalPlayer())); end ); addEventHandler("rispostaControlloAccount", getRootElement(), rispostaControllo); Ci sono molti passaggi tra client e server, comunque nel server locale funziona bene, ma quando carico la resource nel mio server hostato, fa quel bug descritto sopra. Grazie per l'aiuto!