[Release] Player total online time counter - FILE or SQL SAVE

Today i will release a update to solve this, sorry for that

1 Like

While I think this script has a good purpose, I think people should be aware of the potential weight of this script on their server. For each player connected, there will be at least 4 MySQL updates every second. That means on a full server, you’re looking at 128 updates a second for a single script, not including any other mods.

1 Like

yes that is true!
Today i am going to solve that problem, dont worry

2 Likes

Good work on the script, quick feedback:

	MySQL.Async.fetchAll('SELECT * FROM tempo WHERE identifier=@id', {['@id'] = identifier}, function(gotInfo)
		if gotInfo[1] ~= nil then
			if gotInfo[1].identifier == GetPlayerIdentifiers(_source)[1] then
		        TriggerClientEvent("sendDados", _source, gotInfo[1].Segundos, gotInfo[1].Minutos, gotInfo[1].Horas, gotInfo[1].Dias)
		    end
        end

That identifier check is not needed as you’re already searching after it.

  • Updating the database every second is not optimal at all, especally when you havea full server. I’d save the time to a variable and update the database every minute or two.
  • The trigger names are not following the de facto, your trigger names should always start with your resource name, something like this myscript:doStuff
  • Since the rest of your code is in English, why isn’t the database created in the same language?
1 Like

Thanks for the feedback.
1- I am aware of that and yes my solution is that, but yesterday i dont got the time to do it.
2- This is a mandatory or only optional rule? :thinking:
3- I understand but I think this does not change any performance or quality in the script, because in reality nothing needs to be changed in the database, only if it is a matter of reading when they want to know the time of some player of the server. But I did not write the database in Portuguese for evil, I just wanted to leave something of my native language, but since this is a problem for some I will change.

1 Like

UPDATED V2

I made an update on both versions, what was changed in each of them will be explained below:

File Version

  • Added some comments to the script for better understanding.

  • The trigger names are now starting with the resource name. :grin: @Hawaii_Beach

  • Best way to get the player time, now is stored in tables.

Download: onlinetime_file_V2.rar (2.9 KB) | onlinetime_file_V2.zip (3.6 KB)

SQL Version

  • Added some comments to the script for better understanding.

  • The trigger names are now starting with the resource name. :grin: @Hawaii_Beach

  • Best way to get the player time, nwow is stored in tables.

  • The time saving way was changed, instead of saving every second, which exceeded the connection limit of mysql, time is saved when player disconects and every 30 seconds by default, which can be changed in the file " config.lua ".
    WARNING: Do not write a very low value to save the data as it can exceed the connection limit of MYSql!

  • The mysql columns and the mysql table are now in English instead of Portuguese. Those who use the first version and want to update it will have to change the names of the tables and columns according to the new ones! :smiley: @Hawaii_Beach

Download: onlinetime_sql_V2.rar (3.3 KB) | onlinetime_sql_V2.zip (3.9 KB)

Detailed Suport:

My Discord

Thanks:

For reporting: @Skrubby
For opinions: @SaltyGrandpa @Hawaii_Beach

3 Likes

Nice update man. I think that’s a vast improvement for the MySQL version.

2 Likes

Nice update, thanks.
Small problem with the SQL version thought.

Example:
Player has game on steam, enters the server ->> identifier by steam:xxxxxx gets saved in the database.
Same player joins the next day without launching steam ->> identifier by license:xxxxx gets saved in the database.
So the same player will now have 2 rows in the database with 2 different values.
Is there a workaround for this without forcing the server to only accept steam players ?

I guess servers that use some kind of account id could use that to save data instead of an identifier?

Ok i understand your problem, you have two solutions:

  1. Accept only player with steam to join your server.

  2. Or doing the save in the license every time, so if the plyer join with or without steam, the time saves only with the license:

RegisterServerEvent("onlinetime_sql:time")
AddEventHandler("onlinetime_sql:time", function()
	local _source = source
	local identifier = GetPlayerIdentifiers(_source)[1]
	local identifier2 = GetPlayerIdentifiers(_source)[2]
	if GetPlayerIdentifiers(_source)[3] == nil then -- NO STEAM
	    MySQL.Async.fetchAll('SELECT * FROM times WHERE identifier=@id', {['@id'] = identifier}, function(gotInfo)
		    if gotInfo[1] ~= nil then
		        TriggerClientEvent("onlinetime_sql:sendDados", _source, gotInfo[1].Seconds, gotInfo[1].Minutes, gotInfo[1].Hours, gotInfo[1].Days)
		    else
			    local news = 0
			    local newm = 0
		        local newh = 0
		        local newd = 0
			    MySQL.Async.execute("INSERT INTO times (identifier, Seconds, Minutes, Hours, Days) VALUES (@Identifier,@Seconds,@Minutes,@Hours,@Days)", {['@identifier'] = identifier, ['@Seconds'] = news, ['@Minutes'] = newm, ['@Hours'] = newh, ['@Days'] = newd})
			    TriggerClientEvent("onlinetime_sql:sendDados", _source, news, newm, newh, newd)
			end
		end)
	else -- WITH STEAM
	    MySQL.Async.fetchAll('SELECT * FROM times WHERE identifier=@id', {['@id'] = identifier2}, function(gotInfo)
		    if gotInfo[1] ~= nil then
		        TriggerClientEvent("onlinetime_sql:sendDados", _source, gotInfo[1].Seconds, gotInfo[1].Minutes, gotInfo[1].Hours, gotInfo[1].Days)
		    else
			    local news = 0
			    local newm = 0
		        local newh = 0
		        local newd = 0
			    MySQL.Async.execute("INSERT INTO times (identifier, Seconds, Minutes, Hours, Days) VALUES (@Identifier,@Seconds,@Minutes,@Hours,@Days)", {['@identifier'] = identifier2, ['@Seconds'] = news, ['@Minutes'] = newm, ['@Hours'] = newh, ['@Days'] = newd})
			    TriggerClientEvent("onlinetime_sql:sendDados", _source, news, newm, newh, newd)
			end
		end)
	end
end)

EDIT: Maybe today i will update the SQL and file version to do this already, only saving the time in the license.

1 Like

Thanks for the fast reply, I’ve just tried this code, in both cases only license:xxxxx identifier gets saved in the database which is good but when playing with steam ON, time doesn’t get saved.

So i’ve changed this part too:

-- SAVING THE TIME IN THE DB
RegisterServerEvent("onlinetime_sql:savetimedb")
AddEventHandler("onlinetime_sql:savetimedb", function(s, m, h, d)
	local _source = source
	local identifier = GetPlayerIdentifiers(_source)[1]	
	local identifier2 = GetPlayerIdentifiers(_source)[2]
	    if GetPlayerIdentifiers(_source)[3] == nil then -- NO STEAM
    MySQL.Async.execute("UPDATE times SET Seconds=@SECONDS WHERE identifier=@identifier", {["@SECONDS"] = s, ['@identifier'] = identifier})
	MySQL.Async.execute("UPDATE times SET Minutes=@MINUTES WHERE identifier=@identifier", {["@MINUTES"] = m, ['@identifier'] = identifier})
    MySQL.Async.execute("UPDATE times SET Hours=@HOURS WHERE identifier=@identifier", {["@HOURS"] = h, ['@identifier'] = identifier})
	MySQL.Async.execute("UPDATE times SET Days=@DAYS WHERE identifier=@identifier", {["@DAYS"] = d, ['@identifier'] = identifier}) 
       else
	MySQL.Async.execute("UPDATE times SET Seconds=@SECONDS WHERE identifier=@identifier", {["@SECONDS"] = s, ['@identifier'] = identifier2})
	MySQL.Async.execute("UPDATE times SET Minutes=@MINUTES WHERE identifier=@identifier", {["@MINUTES"] = m, ['@identifier'] = identifier2})
    MySQL.Async.execute("UPDATE times SET Hours=@HOURS WHERE identifier=@identifier", {["@HOURS"] = h, ['@identifier'] = identifier2})
	MySQL.Async.execute("UPDATE times SET Days=@DAYS WHERE identifier=@identifier", {["@DAYS"] = d, ['@identifier'] = identifier2}) 
	end
end)

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

-- SAVING THE TIME WHEN PLAYER DISCONNECT
AddEventHandler('playerDropped', function() 
    local _source = source
	local identifier = GetPlayerIdentifiers(_source)[1]	
    local identifier2 = GetPlayerIdentifiers(_source)[2]
	    if GetPlayerIdentifiers(_source)[3] == nil then -- NO STEAM
	MySQL.Async.execute("UPDATE times SET Seconds=@SECONDS WHERE identifier=@identifier", {["@SECONDS"] = se[source].total, ['@identifier'] = identifier})
	MySQL.Async.execute("UPDATE times SET Minutes=@MINUTES WHERE identifier=@identifier", {["@MINUTES"] = mi[source].total, ['@identifier'] = identifier})
    MySQL.Async.execute("UPDATE times SET Hours=@HOURS WHERE identifier=@identifier", {["@HOURS"] = hr[source].total, ['@identifier'] = identifier})
	MySQL.Async.execute("UPDATE times SET Days=@DAYS WHERE identifier=@identifier", {["@DAYS"] = di[source].total, ['@identifier'] = identifier})   
          else
	MySQL.Async.execute("UPDATE times SET Seconds=@SECONDS WHERE identifier=@identifier", {["@SECONDS"] = se[source].total, ['@identifier'] = identifier2})
	MySQL.Async.execute("UPDATE times SET Minutes=@MINUTES WHERE identifier=@identifier", {["@MINUTES"] = mi[source].total, ['@identifier'] = identifier2})
    MySQL.Async.execute("UPDATE times SET Hours=@HOURS WHERE identifier=@identifier", {["@HOURS"] = hr[source].total, ['@identifier'] = identifier2})
	MySQL.Async.execute("UPDATE times SET Days=@DAYS WHERE identifier=@identifier", {["@DAYS"] = di[source].total, ['@identifier'] = identifier2}) 
	end
end)
1 Like

is it me or does the sql version have a massive impact on server usage?

yes, use the SQL Version 2 with a high value in the “savetime” in the config.lua

@Cheleber

What does this error means and how to fix it, pls? Use the SQL-Version:
Error running system event handling function for resource onlinetime_sql_V2: citizen:/scripting
/lua/scheduler.lua:41: Failed to execute thread: server.lua:74: attempt to index a nil value (field ‘?’)
stack traceback:
server.lua:74: in upvalue ‘handler’
citizen:/scripting/lua/scheduler.lua:175: in function citizen:/scripting/lua/scheduler.lua:174
stack traceback:
[C]: in function ‘error’
citizen:/scripting/lua/scheduler.lua:41: in field ‘CreateThreadNow’
citizen:/scripting/lua/scheduler.lua:174: in function citizen:/scripting/lua/scheduler.lua:138
Sending heartbeat to live-internal.fivem.net:30110
Error running system event handling function for resource onlinetime_sql_V2: citizen:/scripting/lua/scheduler.lua:41: Failed to execute thread: server.lua:74: attempt to index a nil value (field ‘?’)
stack traceback:
server.lua:74: in upvalue ‘handler’
citizen:/scripting/lua/scheduler.lua:175: in function citizen:/scripting/lua/scheduler.lua:174
stack traceback:
[C]: in function ‘error’
citizen:/scripting/lua/scheduler.lua:41: in field ‘CreateThreadNow’
citizen:/scripting/lua/scheduler.lua:174: in function citizen:/scripting/lua/scheduler.lua:138
Sending heartbeat to live-internal.fivem.net:30110

1 Like

You have an issue in the server.lua on line 74.

Yeah sure I do not see the forest for the trees…

if err then
error('Failed to resume thread: ’ … debug.traceback(resumableThread.coroutine, err))
end
its the newes version, whats wrong here? O_o

Have you edited any of the files?

No i didn’t do that… search me a wulf and find no help… it runs but i ve the error:

Error running system event handling function for resource onlinetime_sql_V2: citizen:/scripting/lua/scheduler.lua:41: Failed to execute thread: server.lua:74: attempt to index a nil value (field ‘?’)
stack traceback:
server.lua:74: in upvalue ‘handler’
citizen:/scripting/lua/scheduler.lua:175: in function citizen:/scripting/lua/scheduler.lua:174
stack traceback:
[C]: in function ‘error’
citizen:/scripting/lua/scheduler.lua:41: in field ‘CreateThreadNow’
citizen:/scripting/lua/scheduler.lua:174: in function citizen:/scripting/lua/scheduler.lua:138

Maybe @Cheleber no what the error means and how i can fix it?

Server.lua line 74 is where the issue is…

@FAXES here the part of the scheduler.lua and line 74 is marked https://hastebin.com/umunilucoc.lua can you see an error, pls?

You solved your problem @NebelRebell?