So I have the following little plugin which is supposed to save information and retrieve it when necessary, but every time it saves or loads for 2 or more players, it corrupts the data.
Please either help me fix it or give me an example plugin which would have some sort of stocks to create a database, save data to it and load data from it efficiently without corruption or server performance impact and which would work with both sqlite(to save locally inside the hlds) or mysql(to save to a remote database).
PHP Code:
#include <amxmodx>
#include <bitsums>
#include <sqlx>
#include <zombieplaguenightmare>
#pragma reqlib sqlite
#if !defined AMXMODX_NOAUTOLOAD
#pragma loadlib sqlite
#endif
#pragma defclasslib sqlx sqlite
new Handle: g_hTuple, Handle:g_hConnection;
new g_szSqlError[512];
new g_iSqlError;
enum (+= 32)
{
g_iIDTaskUpdateAmmo = 99999,
g_iIDTaskLoadAccount
}
InitializeDatabase() {
SQL_SetAffinity("sqlite");
g_hTuple = SQL_MakeDbTuple("", "", "", "ZPNM_Stats");//127.0.0.1
new Handle: hConnection = UTIL_ConnectToDB();
new Handle: hQuery = SQL_PrepareQuery(hConnection, "CREATE TABLE IF NOT EXISTS Stats (SteamID varchar (36) NOT NULL default '', HumanClass int (32) NOT NULL default -1, ZombieClass int (32) NOT NULL default -1, AmmoPacks int (32) NOT NULL default -1)");
if(!SQL_Execute(hQuery)) {
SQL_QueryError(hQuery, g_szSqlError, charsmax(g_szSqlError));
set_fail_state(g_szSqlError);
}
SQL_FreeHandle(hQuery);
//SQL_FreeHandle(hConnection);
g_hConnection = hConnection;
}
Handle: UTIL_ConnectToDB() {
new Handle: hConnection = SQL_Connect(g_hTuple, g_iSqlError, g_szSqlError, charsmax(g_szSqlError));
if(hConnection == Empty_Handle) {
// We are using SQLite, every connect has to be made! Let's just be strict
set_fail_state(g_szSqlError);
}
return hConnection;
}
//new Handle: g_iSQLTuple, Handle: g_iSQLConnection;
new g_szAuthID[33][36], g_iAmmoPacks[33], g_iBsAuthorized, g_iBsConnected;
public plugin_init()
{
/* new iError, cError[2];
g_iSQLTuple = SQL_MakeDbTuple("127.0.0.1", "", "", "ZPNM_Stats");
g_iSQLConnection = SQL_Connect(g_iSQLTuple, iError, cError, 1);
SQL_SetAffinity( "sqlite" ) // now.test? ye.okay ^^
if( g_iSQLConnection == Empty_Handle) server_print( "ERROR" )
new Handle: iQuery = SQL_PrepareQuery(g_iSQLConnection, "CREATE TABLE IF NOT EXISTS Stats (SteamID varchar (36) NOT NULL default '', HumanClass int (1) NOT NULL default -1, ZombieClass int (1) NOT NULL default -1, AmmoPacks int (3) NOT NULL default -1)");
if ( !SQL_Execute(iQuery) )
pause("ad")
SQL_FreeHandle(iQuery);*/
InitializeDatabase()
//register_clcmd("say /save", "fwClCmdSaySave")
//register_clcmd("say /load", "fwClCmdSayLoad")
}
/*
public fwClCmdSaySave(const iID)
{
SaveAccount(iID)
}
public fwClCmdSayLoad(const iID)
{
LoadAccount(iID + g_iIDTaskLoadAccount)
}*/
public client_authorized(iID)
{
if (!is_user_bot(iID))
get_user_authid(iID, g_szAuthID[iID], charsmax(g_szAuthID[]));
else
{
get_user_name(iID, g_szAuthID[iID], charsmax(g_szAuthID[]))
format(g_szAuthID[iID], charsmax(g_szAuthID[]), "BOT%s", g_szAuthID[iID])
}
bitsum_add(g_iBsAuthorized, iID)
if (bitsum_get(g_iBsConnected, iID))
set_task(1.0, "LoadAccount", iID + g_iIDTaskLoadAccount)
}
public client_putinserver(iID)
{
bitsum_add(g_iBsConnected, iID)
if (bitsum_get(g_iBsAuthorized, iID))
set_task(1.0, "LoadAccount", iID + g_iIDTaskLoadAccount)
}
public client_disconnect(iID)
{
bitsum_del(g_iBsAuthorized, iID)
remove_task(iID + g_iIDTaskUpdateAmmo)
remove_task(iID + g_iIDTaskLoadAccount)
}
public zpnm_user_get_ammo_packs(iID, iAmount, iSource)
{
if (iSource == AMMO_MAIN)
return;
g_iAmmoPacks[iID] = zp_get_user_ammo_packs(iID);
SaveAmmoPacks(iID)
}
public zp_extra_item_selected(iID, iItemID, bIgnoreCost, iCost)
{
if (bIgnoreCost || !iCost)
return;
remove_task(iID + g_iIDTaskUpdateAmmo)
set_task(0.1, "fwTaskUpdateAmmoPacks", iID + g_iIDTaskUpdateAmmo)
}
public fwTaskUpdateAmmoPacks(iID)
{
iID -= g_iIDTaskUpdateAmmo;
g_iAmmoPacks[iID] = zp_get_user_ammo_packs(iID);
SaveAmmoPacks(iID)
}
public zp_round_ended()
{
static iMaxPlayers;
if (!iMaxPlayers)
iMaxPlayers = get_maxplayers();
for (new i = 1; i <= iMaxPlayers; i++)
if (is_user_connected(i))
SaveAccount(i);
}
public LoadAccount(iID)
{
iID -= g_iIDTaskLoadAccount;
static cQuery[256], cData[32];
formatex(cQuery, 255, "SELECT * FROM Stats WHERE SteamID = '%s'", g_szAuthID[iID]);
num_to_str(iID, cData, 31);
SQL_ThreadQuery(/*g_iSQLTuple*/g_hTuple, "_LoadAccount", cQuery, cData, 31);
}
//#include <D7Debug>
SaveAmmoPacks(const iID)
{
//ftD7Log(_, _, "[SaveAmmoPacks] iID: %d. g_iAmmoPacks: %d. g_szAuthID: ^"%s^".", iID, g_iAmmoPacks[iID], g_szAuthID[iID])
new Handle: iQuery = SQL_PrepareQuery(/*g_iSQLConnection*/g_hConnection, "UPDATE Stats SET AmmoPacks = %d WHERE SteamID = '%s'", g_iAmmoPacks[iID], g_szAuthID[iID]);
SQL_Execute(iQuery);
SQL_FreeHandle(iQuery);
}
SaveAccount(iID)
{
//ftD7Log(_, _, "[SaveAccount] iID: %d. g_HumanClass: %d. g_ZombieClass: %d. g_iAmmoPacks: %d. g_szAuthID: ^"%s^".", iID, zpnm_get_user_next_hclass(iID), zp_get_user_next_class(iID), g_iAmmoPacks[iID], g_szAuthID[iID])
new Handle: iQuery = SQL_PrepareQuery(/*g_iSQLConnection*/g_hConnection, "UPDATE Stats SET HumanClass = %d, ZombieClass = %d, AmmoPacks = %d WHERE SteamID = '%s'", zpnm_get_user_next_hclass(iID), zp_get_user_next_class(iID), g_iAmmoPacks[iID], g_szAuthID[iID]);
SQL_Execute(iQuery);
SQL_FreeHandle(iQuery);
}
public _LoadAccount(iFailstate, Handle: iQuery, cError[], iError, cData[], iDatasize, Float: fQueuetime)
{
new iID = str_to_num(cData);
if (SQL_NumResults(iQuery) && SQL_MoreResults(iQuery))
{
//ftD7Log(_, _, "[_LoadAccount] iID: %d. Data found. g_HumanClass: %d. g_ZombieClass: %d. g_iAmmoPacks: %d. g_szAuthID: ^"%s^".", iID, SQL_ReadResult(iQuery, 1), SQL_ReadResult(iQuery, 2), SQL_ReadResult(iQuery, 3), g_szAuthID[iID])
new iTemp = SQL_ReadResult(iQuery, 1);
if (iTemp > -1)
zpnm_set_user_human_class(iID, iTemp)
iTemp = SQL_ReadResult(iQuery, 2);
if (iTemp > -1)
zp_set_user_zombie_class(iID, iTemp)
iTemp = SQL_ReadResult(iQuery, 3);
if (iTemp > -1)
zp_set_user_ammo_packs(iID, iTemp)
}
else
{
//ftD7Log(_, _, "[_LoadAccount] iID: %d. Data not found. Inserting default values. g_HumanClass: -1. g_ZombieClass: -1. g_iAmmoPacks: -1. g_szAuthID: ^"%s^".", iID, g_szAuthID[iID])
new Handle: iQuery = SQL_PrepareQuery(/*g_iSQLConnection*/g_hConnection, "INSERT INTO Stats (SteamID, HumanClass, ZombieClass, AmmoPacks) VALUES ('%s', '-1', '-1', '-1')", g_szAuthID[iID]);
SQL_Execute(iQuery);
SQL_FreeHandle(iQuery);
}
}