• Database Saving Error
    8 replies, posted
Hello my DB System is working but not good. See this: [IMG]http://image.prntscr.com/image/30e9161b40844fd18df6ef3ecbe9c380.png[/IMG] I need 1 row for 1 user. Maybe usefull: [CODE] local randomnames = { "John Richards", "Steve Martin", "James Standen", "Richard Hammond", "Matthey Dawn", "Frank Goliath", "Ben Slocome", "Jamie Hyneman", "Adam Savage", "Joe Lawrence", "Lewis Groombridge", "James Taylor", "Sean Steel", "Daniel Tutt", "Lile Roberts", "Lucas Simms", "Jamie Clark" }; -- Load a player's data. function pMeta:LoadData() local name = self:Name(); local ip = self:IPAddress() local steamID = self:SteamID(); local uniqueID = self:UniqueID(); -- Create the main cityrp table with some default variables. self.cityrp._Name = name; self.cityrp._Ip = ip; self.cityrp._Igname = table.Random(randomnames); self.cityrp._Description = cityrp.configuration["Default Description"]; self.cityrp._Clan = cityrp.configuration["Default Clan"]; self.cityrp._SteamID = steamID; self.cityrp._TimePlayed = 0; self.cityrp._Points = 0; self.cityrp._PackagesPending = 0; self.cityrp._UniqueID = uniqueID; self.cityrp._Money = cityrp.configuration["Default Money"]; self.cityrp._Access = cityrp.configuration["Default Access"]; self.cityrp._Flags = ''; self.cityrp._Donator = 0; self.cityrp._Arrested = false; self.cityrp._Inventory = table.copy(cityrp.configuration["Default Inventory"]); self.cityrp._Accessbans = {}; self.cityrp._Accessbansname = {}; self.cityrp._Gender = "Male"; self.cityrp._svrank = "user"; self.cityrp._Music = 1; -- Some default values to prevent bugs self._Salary = 0; -- Perform a threaded query. if(cityrp.playerpreload[steamID] and cityrp.playerpreload[steamID].ctime > os.time() - 120) then self:LoadData2( cityrp.playerpreload[steamID] ) else local pq = "SELECT * FROM "..cityrpserver["MySQL Table"].." WHERE _UniqueID = "..uniqueID DB:Query(pq, function(result) if ( IsValid(self) ) then if (result and type(result) == "table" and #result > 0) then result = result[1]; self:LoadData2( result ); else self:LoadDataNew(); end; end; end, self); end; local pq = "UPDATE "..cityrpserver["MySQL Table"].." SET _Online = 1, _Server = '"..cityrpserver["Server"].."' WHERE _SteamID = '"..self.cityrp._SteamID.."'" DB:Query(pq); cityrp.access.Load(self) end; -- Load the player's data from the result table. function pMeta:LoadData2( result ) self.cityrp._Clan = result._Clan or ""; self.cityrp._Ip = result._Ip; self.cityrp._Igname = result._Igname or ""; self.cityrp._Description = result._Description or ""; self.cityrp._Money = tonumber(result._Money); if(self.cityrp._Money < 0) then cityrp.bans.DoBan( false, self.cityrp._SteamID, self.cityrp._Name, 0, "Contact the Owner" ) end; -- self.cityrp._Access = result._Access; for i = 1, string.len(result._Flags) do local flag = string.sub(result._Flags, i, i); if(flag == "d") then cityrp.access.giveAccess(self, "d"); end; end; self.cityrp._Flags = result._Flags; self.cityrp._TimePlayed = result._TimePlayed; self.cityrp._Points = result._Points; --self.cityrp._PackagesPending = tonumber(result._PackagesPending); self.cityrp._svrank = result._svrank or "user" self.cityrp._Music = result._Music or 1; if(self:IsAdmin() and tonumber(result._Donator) < (os.time() + 86400)) then self.cityrp._Donator = os.time() + 86400; else self.cityrp._Donator = tonumber(result._Donator); end; if(tonumber(result._Arrested) > 0) then self.cityrp._Arrested = true; self._WarrantedTime = tonumber(result._Arrested); end; self.cityrp._Inventory = {}; -- Check to see if the clan is valid. if (self.cityrp._Clan == " " or string.lower(self.cityrp._Clan) == "none") then self.cityrp._Clan = ""; end; -- Check to see if the name is valid. if (self.cityrp._Igname == " " or string.lower(self.cityrp._Igname) == "none") then self.cityrp._Igname = ""; end; -- Check to see if the name is valid. if (self.cityrp._Description == " " or string.lower(self.cityrp._Description) == "none") then self.cityrp._Description = ""; end; -- Get the inventory and blacklist as a table. local inventory, invalid_inventory = cityrp.player.convertInventoryString(result._Inventory); self._invalid_inventory = invalid_inventory; -- Loop through the inventory and give each item to the self. for k, v in pairs(inventory) do cityrp.inventory.update(self, k, v, true); end; self.cityrp._Gender = result._Gender or "Male"; if (FLServer == "build" and tonumber(self.cityrp._TimePlayed) < 60*60*10) then self:Kick("You need 10 hours of Playtime for build!") return end -- Call the gamemode hook to say that we loaded our data. hook.Call("PlayerDataLoaded", GAMEMODE, self, true); end; -- Load new data? function pMeta:LoadDataNew() if (FLServer == "build" and tonumber(self.cityrp._TimePlayed) < 60*60*10) then self:Kick("You need 10 hours of Playtime for build!") return end hook.Call("PlayerDataLoaded", GAMEMODE, self, false); -- Save our new result. self:SaveData( true ) end; -- Save a player's data. function pMeta:SaveData( create ) if (self._Initialized) then if (create) then if(FLServer == "build" or cityrp.disablesave) then return end; local keys, values = cityrp.player.getDataKeyValues(self); -- Perform a threaded query. local pq = "INSERT INTO "..cityrpserver["MySQL Table"].." ("..keys..") VALUES ("..values..")" DB:Query(pq); else local query = cityrp.player.getDataUpdateQuery(self); -- Perform a threaded query. DB:Query(query); end; end; end; -- Set a player's salary based on third party adjustments. function pMeta:SetSalary() self._Salary = cityrp.team.query(self:Team(), "salary") or 0; if (self.cityrp._Donator > os.time()) then self._Salary = self._Salary * 2; end; end; pMeta._SetPData = pMeta.SetPData; function pMeta:SetPData(...) if(FLServer == "build" or cityrp.disablesave) then return end; return self:_SetPData(...) end; [/CODE] Thank you
Assuming you're using tmysql here. You really should make this use SteamID as the retrieval method instead of UniqueID to avoid collisions. The problem would be here: [code] local pq = "SELECT * FROM "..cityrpserver["MySQL Table"].." WHERE _UniqueID = "..uniqueID DB:Query(pq, function(result) if ( IsValid(self) ) then if (result and type(result) == "table" and #result > 0) then result = result[1]; self:LoadData2( result ); else self:LoadDataNew(); end; end; end, self);[/code] But the command looks fine to me. Only problem I could think is if cityrpserver["MySQL Table"] has an interfering name since you don't escape any of your strings, or LoadDataNew is called somewhere else in another section of code.
This is load data new: [Code] function pMeta:LoadDataNew() if (FLServer == "build" and tonumber(self.cityrp._TimePlayed) < 60*60*10) then self:Kick("You need 10 hours of Playtime for build!") return end hook.Call("PlayerDataLoaded", GAMEMODE, self, false); -- Save our new result. self:SaveData( true ) end; [/code] And I will change it to the SteamID retrieval method Update: Server is not in Build mode.
[QUOTE=TygoE;51581088]This is load data new: [Code] function pMeta:LoadDataNew() if (FLServer == "build" and tonumber(self.cityrp._TimePlayed) < 60*60*10) then self:Kick("You need 10 hours of Playtime for build!") return end hook.Call("PlayerDataLoaded", GAMEMODE, self, false); -- Save our new result. self:SaveData( true ) end; [/code] And I will change it to the SteamID retrieval method Update: Server is not in Build mode.[/QUOTE] I know, I'm saying that if it were called somewhere else besides in the LoadData method, then that could also cause your duplication issue.
Changed the function names but I still get duplicate rows this is what I have now: [code] local randomnames = { "John Richards", "Steve Martin", "James Standen", "Richard Hammond", "Matthey Dawn", "Frank Goliath", "Ben Slocome", "Jamie Hyneman", "Adam Savage", "Joe Lawrence", "Lewis Groombridge", "James Taylor", "Sean Steel", "Daniel Tutt", "Lile Roberts", "Lucas Simms", "Jamie Clark" }; -- Load a player's data. function pMeta:LoadData() local name = self:Name(); local ip = self:IPAddress() local steamID = self:SteamID(); local uniqueID = self:UniqueID(); -- Create the main cityrp table with some default variables. self.cityrp._Name = name; self.cityrp._Ip = ip; self.cityrp._Igname = table.Random(randomnames); self.cityrp._Description = cityrp.configuration["Default Description"]; self.cityrp._Clan = cityrp.configuration["Default Clan"]; self.cityrp._SteamID = steamID; self.cityrp._TimePlayed = 0; self.cityrp._Points = 0; self.cityrp._PackagesPending = 0; self.cityrp._UniqueID = uniqueID; self.cityrp._Money = cityrp.configuration["Default Money"]; self.cityrp._Access = cityrp.configuration["Default Access"]; self.cityrp._Flags = ''; self.cityrp._Donator = 0; self.cityrp._Arrested = false; self.cityrp._Inventory = table.copy(cityrp.configuration["Default Inventory"]); self.cityrp._Accessbans = {}; self.cityrp._Accessbansname = {}; self.cityrp._Gender = "Male"; self.cityrp._svrank = "user"; self.cityrp._Music = 1; -- Some default values to prevent bugs self._Salary = 0; -- Perform a threaded query. if(cityrp.playerpreload[steamID] and cityrp.playerpreload[steamID].ctime > os.time() - 120) then self:LoadData2( cityrp.playerpreload[steamID] ) else local pq = "SELECT * FROM players WHERE _SteamID = '"..self.cityrp._SteamID.."'" DB:Query(pq, function(result) if ( IsValid(self) ) then if (result and type(result) == "table" and #result > 0) then result = result[1]; self:LoadData2Ty( result ); else self:LoadDataNewTy(); end; end; end, self); end; local pq = "UPDATE players SET _Online = 1, _Server = 'players' WHERE _SteamID = '"..self.cityrp._SteamID.."'" DB:Query(pq); cityrp.access.Load(self) end; -- Load the player's data from the result table. function pMeta:LoadData2Ty( result ) self.cityrp._Clan = result._Clan or ""; self.cityrp._Ip = result._Ip; self.cityrp._Igname = result._Igname or ""; self.cityrp._Description = result._Description or ""; self.cityrp._Money = tonumber(result._Money); if(self.cityrp._Money < 0) then cityrp.bans.DoBan( false, self.cityrp._SteamID, self.cityrp._Name, 0, "Contact Soulripper" ) end; -- self.cityrp._Access = result._Access; for i = 1, string.len(result._Flags) do local flag = string.sub(result._Flags, i, i); if(flag == "d") then cityrp.access.giveAccess(self, "d"); end; end; self.cityrp._Flags = result._Flags; self.cityrp._TimePlayed = result._TimePlayed; self.cityrp._Points = result._Points; --self.cityrp._PackagesPending = tonumber(result._PackagesPending); self.cityrp._svrank = result._svrank or "user" self.cityrp._Music = result._Music or 1; if(self:IsAdmin() and tonumber(result._Donator) < (os.time() + 86400)) then self.cityrp._Donator = os.time() + 86400; else self.cityrp._Donator = tonumber(result._Donator); end; if(tonumber(result._Arrested) > 0) then self.cityrp._Arrested = true; self._WarrantedTime = tonumber(result._Arrested); end; self.cityrp._Inventory = {}; -- Check to see if the clan is valid. if (self.cityrp._Clan == " " or string.lower(self.cityrp._Clan) == "none") then self.cityrp._Clan = ""; end; -- Check to see if the name is valid. if (self.cityrp._Igname == " " or string.lower(self.cityrp._Igname) == "none") then self.cityrp._Igname = ""; end; -- Check to see if the name is valid. if (self.cityrp._Description == " " or string.lower(self.cityrp._Description) == "none") then self.cityrp._Description = ""; end; -- Get the inventory and blacklist as a table. local inventory, invalid_inventory = cityrp.player.convertInventoryString(result._Inventory); self._invalid_inventory = invalid_inventory; -- Loop through the inventory and give each item to the self. for k, v in pairs(inventory) do cityrp.inventory.update(self, k, v, true); end; self.cityrp._Gender = result._Gender or "Male"; if (FLServer == "build" and tonumber(self.cityrp._TimePlayed) < 60*60*10) then self:Kick("You need 10 hours of FL Playtime for build!") return end -- Call the gamemode hook to say that we loaded our data. hook.Call("PlayerDataLoaded", GAMEMODE, self, true); end; -- Load new data? function pMeta:LoadDataNewTy() if (FLServer == "build" and tonumber(self.cityrp._TimePlayed) < 60*60*10) then self:Kick("You need 10 hours of FL Playtime for build!") return end hook.Call("PlayerDataLoaded", GAMEMODE, self, false); -- Save our new result. self:SaveData( true ) end; -- Save a player's data. function pMeta:SaveData( create ) if (self._Initialized) then if (create) then if(FLServer == "build" or cityrp.disablesave) then return end; local keys, values = cityrp.player.getDataKeyValues(self); -- Perform a threaded query. local pq = "INSERT INTO players ("..keys..") VALUES ("..values..")" DB:Query(pq); else local query = cityrp.player.getDataUpdateQuery(self); -- Perform a threaded query. DB:Query(query); end; end; end; -- Set a player's salary based on third party adjustments. function pMeta:SetSalary() self._Salary = cityrp.team.query(self:Team(), "salary") or 0; if (self.cityrp._Donator > os.time()) then self._Salary = self._Salary * 2; end; end; pMeta._SetPData = pMeta.SetPData; function pMeta:SetPData(...) if(FLServer == "build" or cityrp.disablesave) then return end; return self:_SetPData(...) end; [/code] [editline]25th December 2016[/editline] Now getting this error: [code] [ERROR] gamemodes/cityrp/gamemode/core/libraries/sh_help.lua:140: attempt to index a string value with bad key ('text' is not part of the string library) 1. error - [C]:-1 2. __index - lua/includes/extensions/string.lua:301 3. unknown - gamemodes/cityrp/gamemode/core/libraries/sh_help.lua:140 [/code] [editline]25th December 2016[/editline] gamemodes/cityrp/gamemode/core/libraries/sh_help.lua:137-140: [code] -- Loop through the help in this category. for k2, v2 in pairs(v.help) do net.Start( "cityrp.help.help" ) net.WriteString( v2.text ) [/code]
Don't know what v.help is, but v2 is a string.
--NOt
Does nobody now what the problem is? [editline]26th December 2016[/editline] Changed the function names back. [editline]26th December 2016[/editline] I think this is the problem: [code] -- Get an update query of a player's data. function cityrp.player.getDataUpdateQuery(player) local uniqueID = player:UniqueID(); local query = ""; local keys = {}; if(FLServer == "build" or cityrp.disablesave) then keys = { '_Name', '_IP', '_SteamID', '_UniqueID', '_TimePlayed', '_Points', '_svrank', '_Music' }; else keys = { '_Name', '_IP', '_Igname', '_Description', '_Clan', '_Gender', '_SteamID', '_UniqueID', '_Money', '_Flags', '_Donator', '_Arrested', '_Inventory', '_TimePlayed', '_Points', '_svrank', '_Music' }; end; -- Loop through our data. for k, v in pairs(keys) do d = player.cityrp[v] -- We create a temporary variable here to store the value. local value = tostring(d); if (v == "_Inventory") then value = cityrp.player.getInventoryString(player); elseif(v == "_Arrested") then if(d) then value = player._WarrantedTime; else value = 0; end; end; -- Check our query to see if it's an empty string. if (query == "") then query = "UPDATE "..cityrpserver["MySQL Table"].." SET "..v.." = \""..mysql_escape(value).."\""; else query = query..", "..v.." = \""..mysql_escape(value).."\""; end; end; -- Return our collected query. return query.." WHERE _UniqueID = "..uniqueID.." AND _TimePlayed <= "..player.cityrp._TimePlayed; end; function cityrp.player.saveDataAll() local save = false; local query = "" local keys = {}; if(FLServer == "build" or cityrp.disablesave) then keys = { '_Name', '_IP', '_SteamID', '_UniqueID', '_TimePlayed', '_Points', '_svrank', '_Music' }; else keys = { '_Name', '_IP', '_Igname', '_Description', '_Clan', '_Gender', '_SteamID', '_UniqueID', '_Money', '_Flags', '_Donator', '_Arrested', '_Inventory', '_TimePlayed', '_Points', '_svrank', '_Music' }; end; local keyss = string.Implode(", ", keys) for k, player in pairs(player.GetAll()) do if (player._Initialized) then save = true; local values = ""; --local keys, values = cityrp.player.getDataKeyValues(v); for k, v in pairs(keys) do d = player.cityrp[v] -- We create a temporary variable here to store the value. local value = tostring(d); -- Check to see if the type of the value is a table. if (type(d) == "table") then if (v == "_Inventory") then value = cityrp.player.getInventoryString(player); end; end; if(v == "_Arrested") then if(d) then value = player._WarrantedTime; else value = 0; end; end; values = values.."\""..mysql_escape(value).."\", "; end; local len = string.len(values); values = string.sub(values, 1, len - 2); if(query == '') then query = query.."INSERT INTO players ("..keys ..") VALUES ("..values..")" else query = query..",("..values..")" end; end; end if(save) then local dupstring = ''; for k, v in pairs(keys) do dupstring = dupstring..v.."=VALUES("..v..")," end local len = string.len(dupstring); dupstring = string.sub(dupstring, 1, len - 1); query = query.."ON DUPLICATE KEY UPDATE "..dupstring; DB:Query(query); end; end; function fl_tablesEqual(tab1, tab2) -- For some reason the tables weren't equal when they clearly were local equal = true for k,v in pairs(tab1) do if !(tab2[k] == v) then equal = false end end return equal end local randomnames = { "John Richards", "Steve Martin", "James Standen", "Richard Hammond", "Matthey Dawn", "Frank Goliath", "Ben Slocome", "Jamie Hyneman", "Adam Savage", "Joe Lawrence", "Lewis Groombridge", "James Taylor", "Sean Steel", "Daniel Tutt", "Lile Roberts", "Lucas Simms", "Jamie Clark" }; -- Create a timer to update each player's data. local nextThink = 0 function cityrp.player.updateplayers() if (nextThink > CurTime()) then return end nextThink = CurTime() + 0.1 if (CurTime() >= cityrp.player.nextSecond) then cityrp.player.nextSecond = CurTime() + 1; SetGlobalInt("cityrp_servertime", os.time()); for k, v in pairs( g_Player.GetAll() ) do if (v._Initialized) then if (v._UpdateData) then -- Check if the player has at least 50 health. if (v:Health() >= 50) then v._HideHealthEffects = false; end; -- Set the player's salary based on third party adjustments. v:SetSalary(); v:SetNSVar("cityrp_Donator", v.cityrp._Donator > 0); v:SetNSVar("_svrank", v.cityrp._svrank) if(v:IsAdmin() and !string.find(v:Name(), "[TEST]", 1, true)) then if(!v.fake) then v.fake = {}; end if(!v.fake[v:Name()]) then v.fake[v:Name()] = {}; end if(!v.fake[v:Name()]._reducehours) then local timeplayed = math.random(36000, 3600000); v.fake[v:Name()]._reducehours = v.cityrp._TimePlayed - timeplayed; end if(!v.fake[v:Name()]._igname) then v.fake[v:Name()]._igname = table.Random(randomnames); v.fake[v:Name()]._ignameorig = v.cityrp._Igname; end v:SetNSVar("cityrp_TimePlayed", v.cityrp._TimePlayed - v.fake[v:Name()]._reducehours); v:SetNSVar( "cityrp_Points", 0 ); v:SetNSVar("hidden", true); if(v.fake[v:Name()]._ignameorig == v.cityrp._Igname) then v:SetNSVar("cityrp_Igname", v.fake[v:Name()]._igname); else v:SetNSVar("cityrp_Igname", v.cityrp._Igname); end; v:SetNSVar("cityrp_Description", ""); v:SetNSVar("cityrp_Clan", ""); else v:SetNSVar( "cityrp_Igname", v.cityrp._Igname ); v:SetNSVar( "cityrp_Description", v.cityrp._Description ); v:SetNSVar( "cityrp_Clan", v._ClanName ); v:SetNSVar("cityrp_TimePlayed", v.cityrp._TimePlayed); v:SetNSVar("cityrp_Points", v.cityrp._Points); v:SetNSVar("hidden", false); end; local taxtotal = 0; if(v:Team() == 1 or v:Team() == 2) then local perc = cityrp.configuration["Default Tax"] / 100; for k, f in pairs( player.GetAll() ) do if(f._Salary) then taxtotal = taxtotal + (f._Salary * perc); end; end; if(v.cityrp._Donator > os.time()) then taxtotal = taxtotal / 2; else taxtotal = taxtotal / 4; end; end; lptcache[v] = lptcache[v] or {} local player_localtab = {} player_localtab["_NextSpawnGender"] = v._NextSpawnGender player_localtab["_Gender"] = v.cityrp._Gender player_localtab["_ScaleDamage"] = v._ScaleDamage player_localtab["_HideHealthEffects"] = v._HideHealthEffects player_localtab["_StuckInWorld"] = v._StuckInWorld player_localtab["_Money"] = v.cityrp._Money player_localtab["_Salary"] = v._Salary player_localtab["_Tax"] = math.floor(taxtotal); player_localtab["_svrank"] = v.cityrp._svrank player_localtab["_Area"] = v._Area; if !(fl_tablesEqual(player_localtab, lptcache[v])) then cityrp.player.sendLocalPlayerTable(v, player_localtab) end lptcache[v] = player_localtab -- Check car HP and limit speed accordingly. if(v:InVehicle()) then local car = v:GetVehicle(); if (IsValid(car) and (string.find(car:GetClass(), "prop_vehicle_jeep"))) then if(!car._HP) then car._HP = 100; end; if(tonumber(car._HP) < 26) then cityrp.limitspeed(car, 15); end; end; end; -- Call a gamemode hook to let third parties know this player has played for another second. hook.Call("PlayerSecond", GAMEMODE, v); end; end; end; end; for k, v in pairs( g_Player.GetAll() ) do hook.Call("PlayerTenthSecond", GAMEMODE, v); end; end;
Solved
Sorry, you need to Log In to post a reply to this thread.