Hi,
ich habe das Login/Register Script von maddinat0r zu seinem Plugin von github übenommen und meinen Bedürfnissen angepasst. Eine Zeit lang hat alles funktioniert, nun schaltet sich der Server beim Connecten aber direkt ab.
Code
hook OnPlayerConnect(playerid)
{
//Disable class selection
TogglePlayerSpectating(playerid, true);
//MySQL Race Check
MysqlRaceCheck[playerid]++;
//Reset pInfo and load player's name into it
static const empty_player[PlayerInfo];
pInfo[playerid] = empty_player;
GetPlayerName(playerid, pInfo[playerid][Name], MAX_PLAYER_NAME);
//Select the player's entry in the database (search for the name)
new
query[128];
mysql_format(handle, query, sizeof(query), "SELECT * FROM `accounts` WHERE `Name` = '%e' LIMIT 1", pInfo[playerid][Name]);
mysql_tquery(handle, query, "OnAccountLoaded", "dd", playerid, MysqlRaceCheck[playerid]);
return 1;
}
Alles anzeigen
Code
forward OnAccountLoaded(playerid, race_check);
public OnAccountLoaded(playerid, race_check)
{
/*
Player A connects -> SELECT query is fired -> query takes very long with many database entries
While the query from player A is still processing, player A disconnects with playerid 0.
Now, while the query from the disconnected player A is still processing, player B connects
and is assigned the playerid 0. Then the query finishes and the player retrieves the data from
the previously disconnected player A.
Counter measure: Race Check
We create a connection count for each playerid and increase it everytime the according playerid
connects or disconnects. We also pass the current value of the connection count to the
OnAccountLoaded callback. Then we check if the current connection count is the same as the one
we passed to the callback. If yes, the data belongs to the correct player. If no, it's the wrong
data and we just safely kick the wrong player.
*/
if(race_check != MysqlRaceCheck[playerid])
{
SendClientMessage(playerid, -1, "An error has occurred. Please rejoin. || Ein Fehler ist aufgetreten. Bitte verbinde dich erneut.");
return Kick(playerid);
}
if(cache_num_rows() > 0) //If the player is registered, show login dialog
{
//Store the password, the security question and the security answer for the login
cache_get_value(0, "Password", pInfo[playerid][Password], 129);
cache_get_value_int(0, "Language", pInfo[playerid][Language]);
cache_get_value_int(0, "SecurityQuestion", pInfo[playerid][SecurityQuestion]);
cache_get_value(0, "SecurityAnswer", pInfo[playerid][SecurityAnswer], 129);
//Saves the active cache in the memory and returns a cache-ID to access it for later use
pInfo[playerid][Cache_ID] = cache_save();
//Direct the player to the login menu
ShowLanguageDialog(playerid, D_PRE_LOGIN, DIALOG_STYLE_LIST, "Login Menu", "Login Menü", "Login\nForgot password\nChange password", "Einloggen\nPasswort vergessen\nPasswort ändern", "OK", "OK", "Leave", "Verlassen");
//From this moment, the player has 30 seconds to insert the correct password to login
pInfo[playerid][LoginTimer] = SetTimerEx("TimerLoginTimeout", SECONDS_TO_LOGIN, false, "d", playerid);
}
else //If the player is not registered, show language dialog
{
ShowPlayerDialog(playerid, D_LANGUAGE, DIALOG_STYLE_LIST, "Language|Sprache", "[ENG] English\n[GER] Deutsch", "OK", "X");
}
return 1;
}
Alles anzeigen
Code
[20:56:37] [INFO] changed log level from 'warning, error' to 'debug, info, warning, error'
[20:56:37] [DEBUG] mysql_init_options()
[20:56:37] [INFO] Options instance with id '1' successfully created.
[20:56:37] [DEBUG] mysql_init_options: return value: '1'
[20:56:37] [DEBUG] mysql_set_option(1, 0)
[20:56:37] [DEBUG] mysql_set_option: return value: '1'
[20:56:37] [DEBUG] mysql_connect("localhost", "many", "*****", "many", 1)
[20:56:37] [DEBUG] CHandleManager::Create(this=0x911fd58, host='localhost', user='many', pass='****', db='many', options=0x906ddf0)
[20:56:37] [INFO] Creating new connection handle...
[20:56:37] [DEBUG] CConnection::CConnection(this=0x911fef8, host='localhost', user='many', passw='****', db='many', options=0x906ddf0)
[20:56:37] [DEBUG] CConnection::CConnection - new connection = 0x9120058
[20:56:37] [DEBUG] CConnection::CConnection(this=0xf5062008, host='localhost', user='many', passw='****', db='many', options=0x906ddf0)
[20:56:37] [DEBUG] CConnection::CConnection - new connection = 0x91385c8
[20:56:37] [DEBUG] CThreadedConnection::CThreadedConnection(this=0xf5062008, connection=0xf5062008)
[20:56:37] [DEBUG] CConnectionPool::CConnectionPool(size=2, this=0x9006fb0)
[20:56:37] [DEBUG] CConnection::CConnection(this=0xf47e0008, host='localhost', user='many', passw='****', db='many', options=0x906ddf0)
[20:56:37] [DEBUG] CThreadedConnection::WorkerFunc(this=0xf5062008, connection=0xf5062008)
[20:56:37] [DEBUG] CConnection::CConnection - new connection = 0x913ebc0
[20:56:37] [DEBUG] CThreadedConnection::CThreadedConnection(this=0xf47e0008, connection=0xf47e0008)
[20:56:37] [DEBUG] CConnection::CConnection(this=0xf475f008, host='localhost', user='many', passw='****', db='many', options=0x906ddf0)
[20:56:37] [DEBUG] CThreadedConnection::WorkerFunc(this=0xf47e0008, connection=0xf47e0008)
[20:56:37] [DEBUG] CConnection::CConnection - new connection = 0x9145258
[20:56:37] [DEBUG] CThreadedConnection::CThreadedConnection(this=0xf475f008, connection=0xf475f008)
[20:56:37] [INFO] Connection handle with id '1' successfully created.
[20:56:37] [DEBUG] CHandleManager::Create - new handle = 0x8f7a7f8
[20:56:37] [DEBUG] mysql_connect: return value: '1'
[20:56:37] [DEBUG] CThreadedConnection::WorkerFunc(this=0xf475f008, connection=0xf475f008)
[20:56:37] [DEBUG] mysql_errno(1)
[20:56:37] [DEBUG] CHandle::GetErrorId(this=0x8f7a7f8)
[20:56:37] [DEBUG] CConnection::GetError(this=0x911fef8, connection=0x9120058)
[20:56:37] [DEBUG] CHandle::GetErrorId - return value: true, error id: '0', error msg: ''
[20:56:37] [DEBUG] mysql_errno: return value: '0'
[17:34:57] [DEBUG] mysql_format(1, 0xF5304D1C, 128, "SELECT * FROM `accounts` WHERE `Name` = '%e' LIMIT 1")
[17:34:57] [DEBUG] CHandle::EscapeString(this=0x8f7a7f8, src='[AMB]Manyula')
[17:34:57] [DEBUG] CConnection::EscapeString(src='[AMB]Manyula', this=0x911fef8, connection=0x9120058)
[17:34:57] [DEBUG] CHandle::EscapeString - return value: true, escaped string: '[AMB]Manyula'
[17:34:57] [DEBUG] mysql_format: return value: '62'
[17:34:57] [DEBUG] mysql_tquery(1, "SELECT * FROM `accounts` WHERE `Name` = '[AMB]Manyula' LIMIT 1", "OnAccountLoaded", "dd")
[17:34:57] [DEBUG] CCallback::Create(amx=0x90e2750, name='OnAccountLoaded', format='dd', params=0xf5304d00, param_offset=5)
[17:34:57] [DEBUG] CCallback::Create - callback index for 'OnAccountLoaded': 5
[17:34:57] [DEBUG] processing specifier 'd' with parameter index 0
[17:34:57] [DEBUG] retrieved and pushed value '0'
[17:34:57] [DEBUG] processing specifier 'd' with parameter index 1
[17:34:57] [DEBUG] retrieved and pushed value '1'
[17:34:57] [INFO] Callback 'OnAccountLoaded' set up for delayed execution.
[17:34:57] [DEBUG] created delayed callback with 2 parameters
[17:34:57] [DEBUG] CHandle::Execute(this=0x8f7a7f8, type=1, query=0x9164ff4)
[17:34:57] [DEBUG] CHandle::Execute - return value: true
[17:34:57] [DEBUG] CConnection::Execute(query=0x9164ff4, this=0xf5062008, connection=0x91385c8)
[17:34:57] [DEBUG] mysql_tquery: return value: '1'
[17:34:57] [DEBUG] CQuery::Execute(this=0x9164ff4, connection=0x91385c8)
[17:34:57] [INFO] query "SELECT * FROM `accounts` WHERE `Name` = '[AMB]Manyula' LIMIT 1" successfully executed within 0.807 milliseconds
[17:34:57] [DEBUG] CResultSet::Create(connection=0x91385c8, query_str='SELECT * FROM `accounts` WHERE `Name` = '[AMB]Manyula' LIMIT 1')
[17:34:57] [DEBUG] created new resultset '0xf4600668'
[17:34:57] [DEBUG] fetched MySQL result '0xf4606aa0'
[17:34:57] [DEBUG] allocated 0 bytes for PAWN result
Alles anzeigen
Ich hab bereits versucht das Plugin nochmal neu runterzuladen, hat aber nichts gebracht. Der Code bricht ab, nachdem in OnPlayerConnect der tquery abgesendet wird. Das dürfte dann die Stelle sein, wo im MySQL Log "allocated 0 bytes for PAWN result" steht.