I have no idea long I've been working on trying to fix this damn plugin, but for some reason it just wont work properly. I'm sure by now you have at least seen one of my threads regarding the different bugs that have been occurring, and I actually finally thought I had it all fixed, but I was wrong.
This time however, I have managed to figure re-create the bug every time. What is happening is players are getting assigned a different players level from the database. This is an example scenario of what is done to re-create this bug:
Two players in game:
[Lv. 10] Player 1
[Lv. 5] Player 2
This is what is happening:
[Lv. 10] Player 1 Disconnects
[Lv. 5] Player 2 Connects -> Receives [Lv. 10]
[Lv. 5] Player 1 Re-Connects -> Recieves [Lv. 5]
Now I know it has to do with the client indexes being switched, but what I don't understand how since I'm using userid in almost every instance:
Code:
public OnClientAuthorized(client)
{
if(!IsFakeClient(client) && IsValidClient(client, false))
{
ClientDataLoaded[client] = false;
GetPlayerData(client);
decl String:name[MAX_NAME_LENGTH];
GetClientName(client, name, sizeof(name));
PrintToChatAll("Player \x01\x04%s \x01\x07has joined the server!", name);
}
}
Code:
/* Paradise Server Database Functions
**
** Functions To Send & Retrieve Data From The MySQL Database
** -------------------------------------------------------------------------- */
//Connect To Database
CreateDB(&Handle:DbHNDL)
{
SQL_TConnect(SQL_OnConnect, "default");
}
//Connection Callback
public SQL_OnConnect(Handle:owner, Handle:hndl, const String:Error[], any:data)
{
if (hndl == INVALID_HANDLE)
{
//It didn't work, so we log the error
PrintToServer("SQL ERROR: %s", Error);
}
else
{
db = hndl;
PrintToServer("[SQL] Connection Successful!");
SQL_CreateTables();
}
}
//Create Database Tables
SQL_CreateTables()
{
decl String:Query[255];
Format(Query, sizeof(Query), "CREATE TABLE IF NOT EXISTS playerdata (steamid VARCHAR(64), name TEXT, level TINYINT, XP INT);");
SQL_TQuery(db, SQL_OnCreatedTable, Query);
}
//Create Tables Callback
public SQL_OnCreatedTable(Handle:owner, Handle:hndl, const String:Error[], any:data)
{
if (hndl == INVALID_HANDLE)
{
PrintToServer("SQL ERROR: %s", Error);
}
}
//New Player - Add To Database
public CreatePlayer(client)
{
new userid = GetClientUserId(client);
decl String:steamid[32], String:name[(MAX_NAME_LENGTH + 1) * 2], String:Query[255], String:nameBuffer[MAX_NAME_LENGTH];
GetClientName(client, nameBuffer, sizeof(nameBuffer));
SQL_EscapeString(db, nameBuffer, name, sizeof(name));
if(!ClientDataLoaded[client] && GetClientAuthString(client, steamid, sizeof(steamid)))
{
if(IsValidClient(client, false))
{
GetClientAuthString(client, steamid, sizeof(steamid));
Format(Query, sizeof(Query), "INSERT INTO playerdata (steamid, name, level, XP) VALUES ('%s', '%s', '1', '0')", steamid, name);
SQL_TQuery(db, SQL_ErrorCallback, Query, userid);
}
}
GetPlayerData(client);
}
//Existing Player - Update Database
public UpdatePlayer(client)
{
new userid = GetClientUserId(client);
decl String:steamid[32], String:Query[255];
if(ClientDataLoaded[client] && GetClientAuthString(client, steamid, sizeof(steamid)))
{
if(IsValidClient(client, false))
{
GetClientAuthString(client, steamid, sizeof(steamid));
Format(Query, sizeof(Query), "UPDATE playerdata SET level='%i', XP='%i' WHERE (steamid='%s')", Level[client], XP[client], steamid);
SQL_TQuery(db, SQL_ErrorCallback, Query, userid);
}
}
GetPlayerData(client);
}
//General Error Callback
public SQL_ErrorCallback(Handle:owner, Handle:hndl, const String:Error[], any:data)
{
new client = GetClientOfUserId(data);
if(hndl == INVALID_HANDLE)
{
PrintToServer("SQL ERROR: %s", Error);
}
if (client == 0)
{
return;
}
}
//Retrieve Player Data
public GetPlayerData(client)
{
new userid = GetClientUserId(client);
decl String:Query[255], String:steamid[32];
new datacheck = 0;
if(GetClientAuthString(client, steamid, sizeof(steamid)))
{
if(IsValidClient(client, false))
{
GetClientAuthString(client, steamid, sizeof(steamid));
Format(Query, sizeof(Query), "SELECT level, XP FROM playerdata WHERE (steamid='%s')", steamid);
SQL_TQuery(db, SQL_GetPlayerData, Query, userid);
datacheck = 1;
}
}
if (datacheck != 1)
{
PrintToServer("SQL ERROR: Failed to retrieve player data!");
}
}
//Retrieve Player Data Callback
public SQL_GetPlayerData(Handle:owner, Handle:hndl, const String:Error[], any:data)
{
new client = GetClientOfUserId(data);
if(hndl == INVALID_HANDLE)
{
PrintToServer("SQL ERROR: %s", Error);
}
if (client == 0)
{
return;
}
if(!SQL_FetchRow(hndl))
{
CreatePlayer(client);
}
else
{
Level[client] = SQL_FetchInt(hndl, 0);
XP[client] = SQL_FetchInt(hndl, 1);
new L = Level[client];
XP_Needed[client] = ((L * L + L + 3) * 4);
ClientDataLoaded[client] = true;
}
}
I'm so frustrated with this.. I really would love to finally have a stable plugin, so I can move on to developing other things but life is never easy..