AlliedModders Donor
|
10-20-2008
, 16:54
Re: Is OnClientDisconnect called when map ends?
|
#7
|
Oh, You probably DON'T want a threaded query going on when the map changes. Bad things happen. I have code that performs threaded saves, but it switches to non-threaded saves when the map is changing.
Here is the code I use. g_MaspChanging is a bool I set when events that indicate the map is being changed h
Code:
public OnPluginStart()
{
RegConsoleCmd("changelevel",ChangelevelCommand);
}
public Action:ChangelevelCommand(client,args)
{
g_MapChanging = true;
return Plugin_Continue;
}
public OnMapStart()
{
g_MapChanging = false;
}
bool:SavePlayerData(client, Handle:playerHandle, bool:disconnected)
{
if (DatabaseAvailable())
{
decl String:steamid[64];
if (GetClientAuthString(client,steamid,sizeof(steamid)))
{
// Don't use threaded saves when the map is changing!
// or the map is about to end
new timeleft = 0;
new bool:threaded;
if (g_MapChanging)
threaded = false;
else if (GetMapTimeLeft(timeleft))
threaded = (timeleft > 60);
else
threaded = true;
new player_ident = GetDatabaseIdent(playerHandle);
if (player_ident > 0)
{
new Handle:raceHandle = GetRaceHandle(GetRace(playerHandle));
new race_ident = GetRaceIdent(raceHandle);
new Settings:bits = GetClientSettingsBits(client);
new overall_level = GetOverallLevel(playerHandle);
new crystals = GetCrystals(playerHandle);
new vespene = GetVespene(playerHandle);
if (threaded)
{
// When threading, copy the data first so it can't
// get freed while we are using it!
new Handle:playerData;
if (disconnected)
playerData = playerHandle;
else
playerData = ClonePlayer(playerHandle);
new Handle:dataPack = CreateDataPack();
WritePackCell(dataPack, client);
WritePackCell(dataPack, _:playerData);
WritePackCell(dataPack, player_ident);
ResetPack(dataPack);
decl String:SQLString[512];
Format(SQLString,sizeof(SQLString),
"UPDATE sc_players SET race_ident=%d, crystals=%d, vespene=%d, overall_level=%d, settings=%d, last_update=current_timestamp WHERE player_ident = %d",
race_ident, crystals, vespene, overall_level, bits, player_ident);
SQL_TQuery(g_DbHandle, SQL_UpdatePlayer, SQLString, dataPack);
if (playerData != playerHandle)
{
// Assume save will work and mark playerHandle data saved.
new raceId = GetRace(playerHandle);
new upgradeCount = GetUpgradeCount(raceHandle);
for(new upgrade=0;upgrade<upgradeCount;upgrade++)
{
new upgradeLevel = GetUpgradeLevel(playerHandle,raceId,upgrade);
SetSavedUpgradeLevel(playerHandle,raceId,upgrade,upgradeLevel);
}
SetDatabaseSaved(playerHandle,1);
}
return false;
}
else
{
decl String:error[256];
error[0] = '\0';
// Process this query in the main thread
SQL_LockDatabase(g_DbHandle);
new Handle:dbUpdatePlayerStmtHandle = SQL_PrepareQuery(g_DbHandle, "UPDATE sc_players SET race_ident=?, crystals=?, vespene=?, overall_level=?, settings=?, last_update=current_timestamp WHERE player_ident = ?", error, sizeof(error));
if (dbUpdatePlayerStmtHandle == INVALID_HANDLE)
{
LogError("Unable to prepare Player Update: %s", error);
SQL_UnlockDatabase(g_DbHandle);
CloseDatabase();
return true;
}
SQL_BindParamInt(dbUpdatePlayerStmtHandle, 0, race_ident);
SQL_BindParamInt(dbUpdatePlayerStmtHandle, 1, crystals);
SQL_BindParamInt(dbUpdatePlayerStmtHandle, 2, vespene);
SQL_BindParamInt(dbUpdatePlayerStmtHandle, 3, overall_level);
SQL_BindParamInt(dbUpdatePlayerStmtHandle, 4, _:bits);
SQL_BindParamInt(dbUpdatePlayerStmtHandle, 5, player_ident);
if (SQL_Execute(dbUpdatePlayerStmtHandle))
{
CloseHandle(dbUpdatePlayerStmtHandle);
if (SavePlayerRaceData(client, playerHandle, player_ident))
SetDatabaseSaved(playerHandle,1);
}
else
{
SetDatabaseIdent(playerHandle,-1);
SQL_GetError(dbUpdatePlayerStmtHandle, error, sizeof(error));
CloseHandle(dbUpdatePlayerStmtHandle);
LogError("Unable to update %N's player record, client=%d, handle=%x, ident=%d: %s",
client, client, playerHandle, player_ident, error);
}
SQL_UnlockDatabase(g_DbHandle);
}
}
else
return InsertPlayerData(client, playerHandle, disconnected, steamid, threaded);
}
else
LogError("Unable to obtain steamid when saving %N", client);
}
return true;
}
|
|