aintaro Posted June 29, 2014 Posted June 29, 2014 (edited) Hello, Today I will be explaining why you should stop use setElementData and how to stop using it. Why should you stop using setElementData? As element data is synced to all clients, it can generate a lot of network traffic and consume server CPU. How to stop using setElementData? Example : Lets say you want to save the total time of a player most people will do it like this : local timePlayed = 0 --declare a variable timePlayed for every player function initPlayer() setElementData(thePlayer, "player_time", timePlayed) --we set the elementData player_time to timePlayed end THATS WRONG! This is how you should do it : local playerData = { --declare playerData for all the players data timePlayed = {} --first dataType = timePlayed } function initPlayer() playerData.timePlayed[thePlayer] = 0 --set timePlayed of "thePlayer" to 0 end playerData.timePlayed[thePlayer] = 0 --set timePlayed of "thePlayer" to 0 this will set timePlayed only to thePlayer userdata PROOF : for i = 1, 10000 do setElementData(thePlayer, "test"..tostring(i), 1000) end execute time : 47 ticks for i = 1, 10000 do setElementData(thePlayer, "test"..tostring(i), 1000,false) end execute time : 40 ticks for i = 1, 10000 do playerData[thePlayer][i] = 1000 end execute time : 1 tick thanks for reading, any questions can be posted under! Edited June 29, 2014 by Guest
Castillo Posted June 29, 2014 Posted June 29, 2014 Do you even know what is setElementData used for? You can disable the synchronization among clients using the fourth argument of the function.
aintaro Posted June 29, 2014 Author Posted June 29, 2014 Do you even know what is setElementData used for?You can disable the synchronization among clients using the fourth argument of the function. lets say you use it, it's still synced with all server
Castillo Posted June 29, 2014 Posted June 29, 2014 Still, your "tutorial" is a bit un-explained, you could explain it a bit more, so these who don't know can understand it. 1
aintaro Posted June 29, 2014 Author Posted June 29, 2014 Still, your "tutorial" is a bit un-explained, you could explain it a bit more, so these who don't know can understand it. I know i'll expand it when I have some free time But it's important to let people know
TheCapn Posted June 30, 2014 Posted June 30, 2014 In fact I use whenever is possible Lua table, but however setElementData and getElementData are useful because you can keep the data among the different resources of your server. If you want to set a data on the "main" resource and use it on the resource concerning the vehicule, it's easy with elementData, and you can't do it with tables.
RottenFlesh Posted July 2, 2014 Posted July 2, 2014 In fact I use whenever is possible Lua table, but however setElementData and getElementData are useful because you can keep the data among the different resources of your server. If you want to set a data on the "main" resource and use it on the resource concerning the vehicule, it's easy with elementData, and you can't do it with tables. Yo can do it with tables, you just have to make an exported function that returns the table with the data. The bad thing is that you would have to do it with each table. But if you are concerned about server performance, you have to consider this system.
AfuSensi Posted July 31, 2014 Posted July 31, 2014 If i understand it correctly, the table PlayerData has subtables of data ( like the key in setElementData ), and in that subtable there is another subtable with all the players in it? So this is server sided. If i understand that correctly, then i have a question. If the player leaves, how do i destroy the subtables that contain information of that player? Like, if thePlayer leaves, it still has the tables timePlayed = { [thePlayer] = 0 } inside of the table.
RottenFlesh Posted July 31, 2014 Posted July 31, 2014 If i understand it correctly, the table PlayerData has subtables of data ( like the key in setElementData ), and in that subtable there is another subtable with all the players in it? So this is server sided. If i understand that correctly, then i have a question. If the player leaves, how do i destroy the subtables that contain information of that player? Like, if thePlayer leaves, it still has the tables timePlayed = { [thePlayer] = 0 } inside of the table. player_data = {} function on_join() player_data[source] = "something you want to save" end addEventHandler('onPlayerJoin', root, on_join) function on_quit() player_data[source] = nil end addEventHandler('onPlayerQuit', root, on_quit) This is how you would delete the data
Booth Posted August 3, 2014 Posted August 3, 2014 Is there a way to make the table available throughout all resources?
Booth Posted August 3, 2014 Posted August 3, 2014 I don't really know how exactly to export a table, could you help me out?
RottenFlesh Posted August 3, 2014 Posted August 3, 2014 table = {} function twerk () return table end then add this to the meta.xml file: <export function="twerk" type="server"/> and when you want to get the table from other resource: table = exports.resourceName:twerk() Easy, right?
Booth Posted August 3, 2014 Posted August 3, 2014 So if the table I have set up is to store all player data whilst the player is actively ingame, is this the right way to structure it? playerData = { SQLID = {}, Username = {}, Password = {} } And will I be able to access these subtables through this exported function?
RottenFlesh Posted August 3, 2014 Posted August 3, 2014 Yeah, but you need to set the player element as the key for the sub-tables. like this: playerData = {} function set_data(player_element, data_key, data_value) -- export this function if type(player_element) == "nil" or type(data_key) == "nil" or type(data_value) == "nil" then return false end if not playerData[player_element] then playerData[player_element] = {} end playerData[player_element][data_key] = data_value return true end function get_data(player_element, data_key) -- export this function if type(player_element) == "nil" or type(data_key) == "nil" then return false end return playerData[player_element] and playerData[player_element][data_key] or false end function delete_data() -- you have to delete the data when the player quits playerData[source] = nil end addEventHandler('onPlayerQuit', root, delete_data) Then, if you export those functions, you can call them from any resource this way: exports.resourceName:set_data(player, "SQLID", 1231231) exports.resourceName:set_data(player, "Username", "Booth") exports.resourceName:set_data(player, "Password", "12345") exports.resourceName:get_data(player, "SQLID") exports.resourceName:get_data(player, "Username") exports.resourceName:get_data(player, "Password") And this is how you would do a basic good-enough data system.
Steph12 Posted August 10, 2014 Posted August 10, 2014 Yeah, but you need to set the player element as the key for the sub-tables. like this: playerData = {} function set_data(player_element, data_key, data_value) -- export this function if type(player_element) == "nil" or type(data_key) == "nil" or type(data_value) == "nil" then return false end if not playerData[player_element] then playerData[player_element] = {} end playerData[player_element][data_key] = data_value return true end function get_data(player_element, data_key) -- export this function if type(player_element) == "nil" or type(data_key) == "nil" then return false end return playerData[player_element] and playerData[player_element][data_key] or false end function delete_data() -- you have to delete the data when the player quits playerData[source] = nil end addEventHandler('onPlayerQuit', root, delete_data) Then, if you export those functions, you can call them from any resource this way: exports.resourceName:set_data(player, "SQLID", 1231231) exports.resourceName:set_data(player, "Username", "Booth") exports.resourceName:set_data(player, "Password", "12345") exports.resourceName:get_data(player, "SQLID") exports.resourceName:get_data(player, "Username") exports.resourceName:get_data(player, "Password") And this is how you would do a basic good-enough data system. How to use this clientside?
Anubhav Posted August 11, 2014 Posted August 11, 2014 playerData = {} function set_data(player_element, data_key, data_value) -- export this function if type(player_element) == "nil" or type(data_key) == "nil" or type(data_value) == "nil" then return false end if not playerData[player_element] then playerData[player_element] = {} end playerData[player_element][data_key] = data_value return true end function get_data(player_element, data_key) -- export this function if type(player_element) == "nil" or type(data_key) == "nil" then return false end return playerData[player_element] and playerData[player_element][data_key] or false end function delete_data() -- you have to delete the data when the player quits playerData[source] = nil end addEventHandler('onClientPlayerQuit', root, delete_data)
RottenFlesh Posted August 11, 2014 Posted August 11, 2014 playerData = {} function set_data(player_element, data_key, data_value) -- export this function if type(player_element) == "nil" or type(data_key) == "nil" or type(data_value) == "nil" then return false end if not playerData[player_element] then playerData[player_element] = {} end playerData[player_element][data_key] = data_value return true end function get_data(player_element, data_key) -- export this function if type(player_element) == "nil" or type(data_key) == "nil" then return false end return playerData[player_element] and playerData[player_element][data_key] or false end function delete_data() -- you have to delete the data when the player quits playerData[source] = nil end addEventHandler('onClientPlayerQuit', root, delete_data) That will not work, as onClientPlayerQuit is only triggered on remote clients. You have to make this system server side, and the use triggerServerEvent and triggerClientEvent to get the data client-side.
Smart. Posted August 21, 2014 Posted August 21, 2014 How to use this clientside? Storing such information on client-side is just a big NONO from me, once I had a player modify a variable client sided which caused a massive money glitch, apparently he made it using cheat engine. Not sure if he was bullshitting, it's been fixed or still working but hey, not a risk I'm willing to take.
Tails Posted September 20, 2014 Posted September 20, 2014 Thanks, good tutorial. So to understand correctly, there is absolutely no use for setElementData or getElementData?
Saml1er Posted September 22, 2014 Posted September 22, 2014 Thanks, good tutorial. So to understand correctly, there is absolutely no use for setElementData or getElementData? Actually there is but depends on you when or how you use it. If you can do it without elemendata then it's really good but if you can't then it's ok to use it but try to use it in only extreme necessary.
Narrator Posted September 25, 2014 Posted September 25, 2014 Ok, thanks for tutorial. But.. Is this method really more useful than elementData? What about hackers? Can they hack client variable? Who use it instead of elementData? Sorry for my mistakes if they're.
Saml1er Posted September 25, 2014 Posted September 25, 2014 Ok, thanks for tutorial. But.. Is this method really more useful than elementData? What about hackers? Can they hack client variable? Who use it instead of elementData? Sorry for my mistakes if they're. I don't know about variables if they can hack it but if a hacker can get access to ftp then yes they can and about element data . It's better to check. https://wiki.multitheftauto.com/wiki/On ... DataChange
Narrator Posted September 25, 2014 Posted September 25, 2014 Saml1er, i know that protection method, but i talking about hack variables with CheatEngine etc. For example if you want create inventory, will you use this method instead of elementData?
Anubhav Posted September 25, 2014 Posted September 25, 2014 I'd prefer you to use this at server side and make a trigger!
Recommended Posts