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.