iAxel Posted January 9, 2015 Share Posted January 9, 2015 Hello everyone! Please help with the decision I am using a table to change the data Table: Table = { need = { {'Test1', 100}, {'Test2', 100} }, stat = { {'Test3', false}, {'Test4', false} }, item = { {'Test5', 0}, {'Test6', 0} } } When registering: --Version 1 for i, data in ipairs(Table.need) do source:setData(data[1], data[2]) end for i, data in ipairs(Table.stat) do source:setData(data[1], data[2]) end for i, data in ipairs(Table.item) do source:setData(data[1], data[2]) end --Version 2 for _, v in pairs(Table) do for _, v2 in pairs(v) do source:setData(v2[1], v2[2]) end end When loading(MySQL): --Version 1 local needs = fromJSON(data[1]['needs']) local status = fromJSON(data[1]['status']) local items = fromJSON(data[1]['items']) for i, data in ipairs(Table.need) do source:setData(data[1], needs[i]) end for i, data in ipairs(Table.stat) do source:setData(data[1], status[i]) end for i, data in ipairs(Table.item) do source:setData(data[1], items[i]) end --Version 2 not : ( Question - is there any other optimized version? P.S I need an optimized version. Link to comment
Mizudori Posted January 10, 2015 Share Posted January 10, 2015 hmm why no creating normal database and retriev or save data that you need in exact moment? Link to comment
iAxel Posted January 10, 2015 Author Share Posted January 10, 2015 To save, I use mysql Load player date: addEvent('onLogged', true) function onLogged(player) local serial = player:getSerial() local name = player:getName() local query = getDB():query('SELECT * FROM `accounts` WHERE `serial` = "'..serial..'" LIMIT 1') if (query) then local data = query:poll(-1) local pos = fromJSON(data[1]['pos']) local needs, status, items = fromJSON(data[1]['needs']), fromJSON(data[1]['status']), fromJSON(data[1]['items']) player:spawn(pos[1], pos[2], pos[3]) player:setHealth(data[1]['health']) player:fadeCamera(true) player:setCameraTarget() for i, data in ipairs(Table.need) do player:setData(data[1], needs[i]) end for i, data in ipairs(Table.stat) do player:setData(data[1], stats[i]) end for i, data in ipairs(Table.item) do player:setData(data[1], items[i]) end end end addEventHandler('onLogged', root, onLogged) Save player date: function onSave(player) local serial = player:getSerial() local name = player:getName() local health = player:getHealth() local x, y, z = getElementPosition(player) local pos = toJSON({x, y, z}) local needs, status, items = {}, {}, {} for i, data in ipairs(Table.need) do needs[i] = player:getData(data[1]) end for i, data in ipairs(Table.stat) do status[i] = player:getData(data[1]) end for i, data in ipairs(Table.item) do items[i] = player:getData(data[1]) end player:setData('Logged', false) needs, status, items = toJSON(needs), toJSON(status), toJSON(items) getDB():exec('UPDATE `accounts` SET `login` = "'..name..'", `health` = "'..health..'", `pos` = "'..pos..'", `needs` = "'..needs..'", `status` = "'..status..'", `items` = "'..items..'", `lastdate` = NOW() WHERE `serial` = "'..serial..'" LIMIT 1') outputDebugString('Account Name: '..name..' was saved automatically.') end Register player: addEvent('onRegister', true) function onRegister(player) local iRand = math.random(#spawnPos) player:spawn(spawnPos[iRand][1], spawnPos[iRand][2], spawnPos[iRand][3]) player:fadeCamera(true) player:setCameraTarget() for _, data in pairs(Table) do for _, value in pairs(data) do player:setData(value[1], value[2]) end end end addEventHandler('onRegister', root, onRegister) I need an optimized version of the data load Link to comment
iAxel Posted January 10, 2015 Author Share Posted January 10, 2015 Himself solved the problem for k, v in pairs(Table) do for i, data in pairs(v) do if (k == 'need') then player:setData(data[1], needs[i]) elseif (k == 'stat') then player:setData(data[1], status[i]) elseif (k == 'item') then player:setData(data[1], items[i]) end end end The next question is - It's not like will not affect the performance? P.S Answer at least this time ... Link to comment
Moderators IIYAMA Posted January 12, 2015 Moderators Share Posted January 12, 2015 The next question is - It's not like will not affect the performance? Just make sure you don't access the database too much, or your server might crash. Of course you can loop through all the players and store the data when you shut down the server. It will peak your cpu usage, but it must not be constantly like that. Link to comment
iAxel Posted January 12, 2015 Author Share Posted January 12, 2015 Just make sure you don't access the database too much, or your server might crash. Of course you can loop through all the players and store the data when you shut down the server. It will peak your cpu usage, but it must not be constantly like that. Thank you so much, but all the same table used in the loop is not effective? And can a couple of examples of optimization Link to comment
Moderators IIYAMA Posted January 12, 2015 Moderators Share Posted January 12, 2015 Looping through a table which uses custom indexes(something else then numbers) isn't very efficient, but sometimes you have to. I am more worried about the functions(especially database functions) than the loops you are using. When I take a look at your examples, I assume example 2 is more efficient then example 1. Because when you start a loop, the code inside it will be temporary saved in to the ram, which will speed up when the loop executed more then one time. Link to comment
iAxel Posted January 12, 2015 Author Share Posted January 12, 2015 When I take a look at your examples, I assume example 2 is more efficient then example 1. Because when you start a loop, the code inside it will be temporary saved in to the ram, which will speed up when the loop executed more then one time. Variant 1 for i, data in ipairs(Table.need) do source:setData(data[1], data[2]) end for i, data in ipairs(Table.stat) do source:setData(data[1], data[2]) end for i, data in ipairs(Table.item) do source:setData(data[1], data[2]) end Variant 2 for _, v in pairs(Table) do for _, v2 in pairs(v) do source:setData(v2[1], v2[2]) end end 2 variant mean effective than 1? Looping through a table which uses custom indexes(something else then numbers) isn't very efficient, but sometimes you have to. I am more worried about the functions(especially database functions) than the loops you are using. I did not understand, but if you talk about the connection to the database or save data local connect = nil local db = { type = 'mysql', base = 'mta', host = '127.0.0.1', name = 'root', pass = '' } -- function getDB() if (not reconnect) then return connect else Timer(getDB, 150, 1) end end -- addEventHandler('onResourceStart', resourceRoot, function () connect = Connection(db.type, 'dbname='..db.base..';host='..db.host, db.name, db.pass) if (not connect) then outputServerLog('MySQL connection is not established!') else outputServerLog('MySQL connection is established!') end end ) -- addEventHandler('onResourceStop', resourceRoot, function () for i, player in ipairs(getElementsByType('player')) do if (isLogged(player)) then onSave(player) end end for i, vehicle in ipairs(getElementsByType('vehicle')) do if (isVehicle(vehicle)) then onVehSave(vehicle) end end if (isElement(connect)) then connect:destroy() end end ) Save function onSave(player) local serial = player:getSerial() local name = player:getName() local health = player:getHealth() local x, y, z = getElementPosition(player) local pos = toJSON({x, y, z}) local needs, status, items = {}, {}, {} for k, v in pairs(Table) do for i, data in pairs(v) do if (k == 'need') then needs[i] = player:getData(data[1]) elseif (k == 'stat') then status[i] = player:getData(data[1]) elseif (k == 'item') then items[i] = player:getData(data[1]) end end end player:setData('logged', false) needs, status, items = toJSON(needs), toJSON(status), toJSON(items) getDB():exec('UPDATE `accounts` SET `login` = ?, `health` = ?, `pos` = ?, `needs` = ?, `status` = ?, `items` = ?, `lastdate` = NOW() WHERE `serial` = ? LIMIT 1', name, health, pos, needs, status, items, serial) outputServerLog('Account Name: '..name..' was saved automatically.') end If there is an error please correct it, I'm still a noob, I'm just learning) And thank you for the answer, then if not strange ignore or remain silent Link to comment
Moderators IIYAMA Posted January 12, 2015 Moderators Share Posted January 12, 2015 ah your OOP functions are elementdata instead of accountdata. I am not using OOP functions, so I wasn't sure which it was. I am using no OOP functions because I know a lot of mta functions out of my head. function onSave(player) if isElement(player) then local serial = player:getSerial() or "" -- just in case local name = player:getName() or "" -- just in case local health = player:getHealth() or 100 -- just in case local x, y, z = getElementPosition(player) local pos = toJSON({x, y, z}) local needs, status, items = {}, {}, {} for k, v in pairs(Table) do for i, data in pairs(v) do if (k == 'need') then needs[#needs+1] = player:getData(data[1]) -- [#needs+1] < making sure it starts from the first index. elseif (k == 'stat') then status[#status+1] = player:getData(data[1]) elseif (k == 'item') then items[#items+1] = player:getData(data[1]) end end end player:setData('logged', false) needs, status, items = toJSON(needs), toJSON(status), toJSON(items) getDB():exec('UPDATE `accounts` SET `login` = ?, `health` = ?, `pos` = ?, `needs` = ?, `status` = ?, `items` = ?, `lastdate` = NOW() WHERE `serial` = ? LIMIT 1', name, health, pos, needs, status, items, serial) outputServerLog('Account Name: '..name..' was saved automatically.') end end Anyway take a closer look at my notes. Also on what are the accounts based? Name or serial? Because you can never rely on the player his name. Link to comment
iAxel Posted January 12, 2015 Author Share Posted January 12, 2015 ah your OOP functions are elementdata instead of accountdata. I am not using OOP functions, so I wasn't sure which it was.I am using no OOP functions because I know a lot of mta functions out of my head. function onSave(player) if isElement(player) then local serial = player:getSerial() or "" -- just in case local name = player:getName() or "" -- just in case local health = player:getHealth() or 100 -- just in case local x, y, z = getElementPosition(player) local pos = toJSON({x, y, z}) local needs, status, items = {}, {}, {} for k, v in pairs(Table) do for i, data in pairs(v) do if (k == 'need') then needs[#needs+1] = player:getData(data[1]) -- [#needs+1] < making sure it starts from the first index. elseif (k == 'stat') then status[#status+1] = player:getData(data[1]) elseif (k == 'item') then items[#items+1] = player:getData(data[1]) end end end player:setData('logged', false) needs, status, items = toJSON(needs), toJSON(status), toJSON(items) getDB():exec('UPDATE `accounts` SET `login` = ?, `health` = ?, `pos` = ?, `needs` = ?, `status` = ?, `items` = ?, `lastdate` = NOW() WHERE `serial` = ? LIMIT 1', name, health, pos, needs, status, items, serial) outputServerLog('Account Name: '..name..' was saved automatically.') end end Anyway take a closer look at my notes. Also on what are the accounts based? Name or serial? Because you can never rely on the player his name. Thank you very much, I do not use SQLite, I use MySQL for him and not to used setAccountData. Data is saved to check the serial 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