SinaAmp Posted February 6, 2022 Author Share Posted February 6, 2022 Thank you @IIYAMA I get element data from client side which is static for setting up timer Isn't that cause of the problem? Link to comment
Moderators IIYAMA Posted February 6, 2022 Moderators Share Posted February 6, 2022 2 hours ago, SinaAmp said: I get element data from client side which is static for setting up timer Isn't that cause of the problem? Probably, can you show me that clientside part just to be sure? Link to comment
SinaAmp Posted February 6, 2022 Author Share Posted February 6, 2022 here: Spoiler function checkHunger() local Hunger = tonumber(getElementData(localPlayer, "Hunger")) if Hunger and Hunger >= 0 then setElementData(localPlayer, "Hunger", Hunger - 1) end if Hunger <= 20 then outputChatBox("You need to feed as fast as possible.", 255, 0, 0) playSoundFrontEnd(40) end if Hunger == 0 then if not isPedDead(localPlayer) then local hp = getElementHealth(localPlayer) setElementHealth(localPlayer, hp - 30) end end end setTimer(checkHunger, 60000, 0) function onClientPlayerSpawn() setElementData(source, "Hunger", 100) end addEventHandler("onClientPlayerSpawn", root, onClientPlayerSpawn) function checkThirst() local Thirst = tonumber(getElementData(localPlayer, "Thirst")) if Thirst and Thirst >= 0 then setElementData(localPlayer, "Thirst", Thirst - 1) end if Thirst <= 20 then outputChatBox("You need to drink something as fast as possible.", 255, 0, 0) playSoundFrontEnd(40) end if Thirst == 0 then if not isPedDead(localPlayer) then local hp = getElementHealth(localPlayer) setElementHealth(localPlayer, hp - 30) end end end setTimer(checkThirst, 60000, 0) function onClientPlayerSpawn() setElementData(source, "Thirst", 100) end addEventHandler("onClientPlayerSpawn", root, onClientPlayerSpawn) Link to comment
Moderators IIYAMA Posted February 6, 2022 Moderators Share Posted February 6, 2022 2 hours ago, SinaAmp said: setTimer(checkThirst, 60000, 0) This update rate is fine, unless you have about/more than ~40 players in your server. Fix for that: Client (set Thirst with sync disabled) Thirst = Thirst - 1 setElementData(localPlayer, "Thirst", Thirst, false) + https://wiki.multitheftauto.com/wiki/TriggerServerEvent (https://wiki.multitheftauto.com/wiki/TriggerLatentServerEvent) + Server (set Thirst with sync disabled) setElementData(client, "Thirst", Thirst, false) 1 Link to comment
SinaAmp Posted February 7, 2022 Author Share Posted February 7, 2022 @IIYAMA sorry for late response i think my way of creating hunger and thirst system with get/setelementdata is complatly wrong and that cause of performance issues in future may i use only triggerevents and a variable to process 1 Link to comment
SinaAmp Posted February 7, 2022 Author Share Posted February 7, 2022 @IIYAMA i tryed to do this method can you please review my code i commented near the lines i had problem [ -- this ] server: function AccDatacallback(AccData, player, account, AccName) local result = dbPoll( AccData, 0 ) if(result) then if(#result > 0) then for _,row in ipairs(result) do local Hunger = row["Hunger"] local Thirst = row["Thirst"] break end end end end function afterlogin (_,Acc) local AccName = getAccountName(Acc) dbQuery(AccDatacallback,{source, account, AccName},db,"SELECT Hunger,Thirst FROM stats WHERE Account=?", AccName) end addEventHandler ("onPlayerLogin",root, afterlogin) -- function to send hunger and thirst to client for process function sendhsdata (_, Acc, Hunger ,Thirst) -- ***this*** local AccName = getAccountName(Acc) local hsdata = dbPoll(dbQuery(db,"SELECT Hunger,Thirst FROM stats WHERE Account=?", AccName), -1) local Hunger = hsdata["Hunger"] -- ***this*** local Thirst = hsdata["Thirst"] -- ***this*** end addEvent( "onSendData", true ) -- ***this*** addEventHandler( "onSendData", root, sendhsdata) -- ***this*** -- Data saving function function saveAccountData (player) local playerAccount = getPlayerAccount(player) if(playerAccount) then if(isGuestAccount(playerAccount)) then return end end local AccName = getAccountName(playerAccount) local Hungers = triggerClientEvent(player, "onSendPData", playersource, PHunger) -- ***this*** local Thirsts = triggerClientEvent(player, "onSendPData", playersource, PThirst) -- ***this*** dbExec(db,"UPDATE stats SET Hunger=?, Thirst=? WHERE Account=?",Hungers, Thirsts, AccName) end addEventHandler ( 'onPlayerQuit', root, function ( ) saveAccountData(source) end ) client: function checkHunger(PHunger) local Hunger = triggerServerEvent("onSendData", resourceRoot, Hunger) -- ***this*** if Hunger and Hunger >= 0 then PHunger = Hunger - 1 -- ***this*** end if Hunger <= 20 then outputChatBox("You need to feed as fast as possible.", 255, 0, 0) playSoundFrontEnd(40) end if Hunger == 0 then if not isPedDead(localPlayer) then local hp = getElementHealth(localPlayer) setElementHealth(localPlayer, hp - 30) end end end setTimer(checkHunger, 60000, 0) addEvent( "onSendPHData", true ) -- ***this*** addEventHandler( "onSendPHData", localPlayer, checkHunger ) -- ***this*** function onClientPlayerSpawn() setElementData(source, "Hunger", 100) end addEventHandler("onClientPlayerSpawn", root, onClientPlayerSpawn) function checkThirst(PThirst) -- ***this*** local Thirst = triggerServerEvent("onSendData", resourceRoot, Thirst) -- ***this*** if Thirst and Thirst >= 0 then PThirst = Thirst - 1 -- ***this*** end if Thirst <= 20 then outputChatBox("You need to drink something as fast as possible.", 255, 0, 0) playSoundFrontEnd(40) end if Thirst == 0 then if not isPedDead(localPlayer) then local hp = getElementHealth(localPlayer) setElementHealth(localPlayer, hp - 30) end end end setTimer(checkThirst, 60000, 0) addEvent( "onSendPTData", true ) -- ***this*** addEventHandler( "onSendPTData", localPlayer, checkThirst ) -- ***this*** function onClientPlayerSpawn() setElementData(source, "Thirst", 100) end addEventHandler("onClientPlayerSpawn", root, onClientPlayerSpawn) Link to comment
Moderators IIYAMA Posted February 7, 2022 Moderators Share Posted February 7, 2022 35 minutes ago, SinaAmp said: local Thirst = triggerServerEvent("onSendData", resourceRoot, Thirst) -- ***this*** triggerServerEvent is unable to receive data. If you take a look at the syntax of that function, you will see that it only returns a boolean(true/false): https://wiki.multitheftauto.com/wiki/TriggerServerEvent You can make it possible using this library, but that wouldn't create a solid system. The server should be in charge of the hunger and Thirst values. What you want is the following: Server A timer (or multiple timers) This one gets the Hunger and Thirst Updates the Hunger and Thirst (-1) according to your needs. Sets the health or kills the player. triggerClientEvent (or elementdata with https://wiki.multitheftauto.com/wiki/AddElementDataSubscriber + setElementData [syncMode is "subscribe"]) Client Just updates the UI to show the player his hunger and thirst values. 1 Link to comment
SinaAmp Posted February 7, 2022 Author Share Posted February 7, 2022 thank you @IIYAMA 1 Link to comment
SinaAmp Posted February 7, 2022 Author Share Posted February 7, 2022 sorry @IIYAMA i can't understand why should i use triggerClientEvent in server side when i use your library and calc hunger and thirst in server side i dont know how to get my processed hunger and thirst from server side please look at this: server: Spoiler function AccDatacallback(AccData, player, account, AccName) local result = dbPoll( AccData, 0 ) if(result) then if(#result > 0) then for _,row in ipairs(result) do Hunger = row["Hunger"] Thirst = row["Thirst"] break end end end end function afterlogin (_,Acc) local AccName = getAccountName(Acc) dbQuery(AccDatacallback,{source, account, AccName},db,"SELECT Hunger,Thirst FROM stats WHERE Account=?", AccName) end addEventHandler ("onPlayerLogin",root, afterlogin) -- calc hunger and thirst function checkHunger(player, PHunger) if Hunger and Hunger >= 0 then PHunger = Hunger - 1 end if PHunger <= 20 then outputChatBox("You need to feed as fast as possible.", 255, 0, 0) end if PHunger == 0 then if not isPedDead(Player) then local hp = getElementHealth(Player) setElementHealth(Player, hp - 30) end end end setTimer(checkHunger, 30000, 0) function checkThirst(player, PThirst) if Thirst and Thirst >= 0 then PThirst = Thirst - 1 end if PThirst <= 20 then outputChatBox("You need to drink something as fast as possible.", 255, 0, 0) playSoundFrontEnd(40) end if PThirst == 0 then if not isPedDead(Player) then local hp = getElementHealth(Player) setElementHealth(Player, hp - 30) end end end setTimer(checkThirst, 30000, 0) -- Data saving function function saveAccountData (player) local playerAccount = getPlayerAccount(player) if(playerAccount) then if(isGuestAccount(playerAccount)) then return end end local AccName = getAccountName(playerAccount) local Hungers = PHunger local Thirsts = PThirst dbExec(db,"UPDATE stats SET Hunger=?, Thirst=? WHERE Account=?",Hungers, Thirsts, AccName) end addEventHandler ( 'onPlayerQuit', root, function ( ) saveAccountData(source) end ) client: Spoiler callserver ("checkHunger","PHunger") Link to comment
Moderators IIYAMA Posted February 7, 2022 Moderators Share Posted February 7, 2022 28 minutes ago, SinaAmp said: when i use your library First of all, you do not need to use my library. Only if you are going to make use of callbacks. 29 minutes ago, SinaAmp said: i dont know how to get my processed hunger and thirst from server side You do not get the hunger, you send it using triggerClientEvent. for _,row in ipairs(result) do Hunger = row["Hunger"] Thirst = row["Thirst"] break end local row = result[1] Hunger = row["Hunger"] Thirst = row["Thirst"] 32 minutes ago, SinaAmp said: function checkHunger(player, PHunger) if Hunger and Hunger >= 0 then PHunger = Hunger - 1 end if PHunger <= 20 then outputChatBox("You need to feed as fast as possible.", 255, 0, 0) end if PHunger == 0 then if not isPedDead(Player) then local hp = getElementHealth(Player) setElementHealth(Player, hp - 30) end end end setTimer(checkHunger, 30000, 0) You should get here the current hunger values from the database. https://wiki.multitheftauto.com/wiki/DbPrepareString Finish the code yourself. local players = getElementsByType("player") local queryString = dbPrepareString( db, "SELECT Hunger,Thirst FROM stats WHERE Account IN ( " -- loop with player account names queryString = queryString .. dbPrepareString( db, "?, ", AccName) -- loop end queryString = queryString .. " )" local handle = dbQuery( db, queryString ) -- Receive data here and combine the correct database data with the player. Link to comment
SinaAmp Posted February 7, 2022 Author Share Posted February 7, 2022 why i need to get hunger and thirst in 'checkhunger' function when i got them from 'afterlogin' function? Link to comment
Moderators IIYAMA Posted February 8, 2022 Moderators Share Posted February 8, 2022 10 hours ago, SinaAmp said: why i need to get hunger and thirst in 'checkhunger' function when i got them from 'afterlogin' function? Because you didn't save it there. You have not written a (memory) cache for your database. Link to comment
SinaAmp Posted February 8, 2022 Author Share Posted February 8, 2022 i got this error repeatly Database result uncollected after 5 minutes. [Query: SELECT Hunger,Thirst FROM stats WHERE Account IN ( NULL, )] Link to comment
Moderators IIYAMA Posted February 8, 2022 Moderators Share Posted February 8, 2022 48 minutes ago, SinaAmp said: i got this error repeatly Database result uncollected after 5 minutes. [Query: SELECT Hunger,Thirst FROM stats WHERE Account IN ( NULL, )] That happens when you fire a query (with a callback) and restart/stop the resource directly after that. Link to comment
SinaAmp Posted February 8, 2022 Author Share Posted February 8, 2022 edited server side: Spoiler -- calc hunger and thirst function checkHunger(playersource,PHunger) local players = getElementsByType("player") local queryString = dbPrepareString( db, "SELECT Hunger,Thirst FROM stats WHERE Account IN ( ") queryString = queryString .. dbPrepareString( db, "?, ", AccName) queryString = queryString .. " )" local handle = dbQuery( db, queryString ) setTimer(function() if Hunger and Hunger >= 0 then local row = handle[1] Hunger = row["Hunger"] PHunger = Hunger - 1 outputDebugString(PHunger) end if PHunger <= 20 then outputChatBox("You need to feed as fast as possible.", 255, 0, 0) end if PHunger == 0 then if not isPedDead(Player) then local hp = getElementHealth(Player) setElementHealth(Player, hp - 30) end end end,30000,0) end triggerClientEvent("onGetData", root,PHunger) but i got this error: server triggered client side event but event is not added Link to comment
Moderators IIYAMA Posted February 8, 2022 Moderators Share Posted February 8, 2022 20 minutes ago, SinaAmp said: server triggered client side event but event is not added 20 minutes ago, SinaAmp said: triggerClientEvent("onGetData", root,PHunger) You are sending a message to all clients/players directly when the server is executing the script. The clients/players haven't loaded their scripts yet, to receive the message. Link to comment
SinaAmp Posted February 8, 2022 Author Share Posted February 8, 2022 what i will do now to solve this problem? Link to comment
Moderators IIYAMA Posted February 8, 2022 Moderators Share Posted February 8, 2022 14 minutes ago, SinaAmp said: what i will do now to solve this problem? Doing it at the right moment. For example on the event "onPlayerResourceStart" and sending it only to this player. https://wiki.multitheftauto.com/wiki/OnPlayerResourceStart Read the wiki of that event carefully, since there is info in it that most people forget to read... 1 Link to comment
SinaAmp Posted February 8, 2022 Author Share Posted February 8, 2022 (edited) sorry i wasted your time @IIYAMAthank you for help addEventHandler("onPlayerResourceStart", root, function(hungerandthirst) if loadedResource == resource then triggerClientEvent(source, "onGetData", resourceRoot,PHunger) end end) @Burak5312 bro can you complete this part? Edited February 8, 2022 by SinaAmp 1 Link to comment
Moderators IIYAMA Posted February 8, 2022 Moderators Share Posted February 8, 2022 32 minutes ago, SinaAmp said: sorry i wasted your time @IIYAMAthank you for help No worries. BTW, you can only send the hunger value when you know which account this player has logged in to. There is a chance that the player hasn't logged in yet when the resource has been loaded. On closer inspection it might be better to try it on onPlayerLogin and using a login panel to delay the user-interaction. addEventHandler ("onPlayerLogin",root, afterlogin) Link to comment
SinaAmp Posted February 8, 2022 Author Share Posted February 8, 2022 im little bit confused to be honest this is out of my lua abilitys i need somone to complete this so i can learn the way Link to comment
SinaAmp Posted February 9, 2022 Author Share Posted February 9, 2022 How i can get the player account name in custom event? everything i try i got nil errors Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now