Jump to content

[Help] Use mysql instead Get & Set accountdata


SinaAmp

Recommended Posts

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
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)

 

 

 

  • Thanks 1
Link to comment

@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
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):

676649160_Schermafbeelding2022-02-07om19_04_15.png.d0f41e82a6696070acef6b5216c742be.png

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.

 

 

 

 

  • Like 1
Link to comment

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
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
  • Moderators
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
  • Moderators
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

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
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
  • Moderators
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

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...