Yo Maddinat0r,
Could you check out this code real quick and let me know if I have done it correctly? I don't want to cause any account issues with it
I have this PrepareAccount function that (by following AndreT's tutorial), sets up the ORM system and loads the data from the SELECT query into my player enum.
When a player connects to the server, I call the SendToLobbyScreen function.
pawn Код:
public OnPlayerConnect(playerid) {
//Some checks..
SendToLobbyScreen(playerid);
}
Inside the SendToLobbyScreen function, I call the PrepareAccount function like so:
pawn Код:
stock SendToLobbyScreen(playerid) {
print("SendToLobbyScreen");
ShowLobbyScreen(playerid); //Show them the lobby screen (custom camera and textdraws).
PrepareAccount(playerid); //Call the PrepareAccount function.
return 1;
}
Okay, so from there, they can click Login or Register as the PrepareAccount function does all the 'account exists' checking and all.
The main question behind all this is when someone logs in, I simply just spawn them but when a player registers, I want them to be 'logged out of their newly registered account' and sent back to the lobby where they have to log in again.
It works perfectly so far it seems but I may have missed something that will bite me down the line and I was hoping to avoid that by asking you if it looks all good from your perspective.
Please see the commented line labelled //QUESTION HERE.
pawn Код:
stock PrepareAccount(playerid) { //Readies the players enum to be filled in with data that comes from the SELECT query.
print("PrepareAccount");
//Get the name of the player.
GetPlayerName(playerid, AccountInfo[playerid][pName], MPN + 1);
new ORM:ormid;
//QUESTION HERE
if(!AccountInfo[playerid][ORM_ID]) { //Is this going to work as intended?
//This is called when the player only has to log in.
printf("Creating new ORM:ID for %s.", AccountInfo[playerid][pName]);
ormid = AccountInfo[playerid][ORM_ID] = orm_create("accounts");
} else {
ormid = AccountInfo[playerid][ORM_ID];
//This is called when a player registers and is then asked to log back in. Instead of creating a new ORM instance for the already connected player, i simply just use the existing ORM instance.
printf("Using existing ORM:ID for %s.", AccountInfo[playerid][pName]);
}
orm_addvar_int(ormid, AccountInfo[playerid][pID], "pID");
orm_addvar_string(ormid, AccountInfo[playerid][pName], MPN+1, "pName");
orm_addvar_string(ormid, AccountInfo[playerid][pPassword], 129, "pPassword");
orm_addvar_string(ormid, AccountInfo[playerid][pRegisteredIP], 16, "pRegisteredIP");
orm_addvar_string(ormid, AccountInfo[playerid][pLastIP], 16, "pLastIP");
orm_addvar_string(ormid, AccountInfo[playerid][pRecoveryQuestion], 80, "pRecoveryQuestion");
orm_addvar_string(ormid, AccountInfo[playerid][pRecoveryAnswer], 80, "pRecoveryAnswer");
orm_addvar_int(ormid, AccountInfo[playerid][pRegisterDate], "pRegisterDate");
orm_addvar_int(ormid, AccountInfo[playerid][pRegistered], "pRegistered");
//---------------------------------------------------------------------------
orm_addvar_int(ormid, AccountInfo[playerid][pAdminLevel], "pAdminLevel");
orm_addvar_string(ormid, AccountInfo[playerid][pAdminPassword], 129, "pAdminPassword");
orm_addvar_int(ormid, AccountInfo[playerid][pAdminActions], "pAdminActions");
//---------------------------------------------------------------------------
orm_addvar_float(ormid, AccountInfo[playerid][pLastXPos], "pLastXPos");
orm_addvar_float(ormid, AccountInfo[playerid][pLastYPos], "pLastYPos");
orm_addvar_float(ormid, AccountInfo[playerid][pLastZPos], "pLastZPos");
orm_addvar_float(ormid, AccountInfo[playerid][pLastAPos], "pLastAPos");
orm_addvar_int(ormid, AccountInfo[playerid][pInterior], "pInterior");
orm_addvar_int(ormid, AccountInfo[playerid][pVirtualWorld], "pVirtualWorld");
//---------------------------------------------------------------------------
orm_addvar_int(ormid, AccountInfo[playerid][pPlayerState], "pPlayerState");
orm_setkey(ormid, "pName"); //Set the 'SELECT' query's WHERE id to the "Name" field.
orm_select(ormid, "OnAccountDataLoad", "d", playerid); //Send the SELECT query and go to the OnPlayerDataLoad callback when it's done.
}
public OnAccountDataLoad(playerid) { //This callback is called after the SELECT query finishes.
new
ip[16];
GetPlayerIp(playerid, ip, 16); //Get the players IP Address.
AccountInfo[playerid][pLastIP] = ip; //Assign the ip address to the account enum, we do this here as you can't use GetPlayerIp under OnPlayerDisconnect and we need to wait until all the MySQL data has been retrieved and applied.
CheckIPBans(playerid); //Check the players IP Address for any currently banned accounts as he may be ban evading. Possibly issue: same IP address players.
//printf("OnPlayerDataLoad");
switch(orm_errno(AccountInfo[playerid][ORM_ID])) {
case ERROR_OK: { //If the account EXISTS.
CheckAccountBans(playerid); //Check the players Account for bans. May need to make it so you are checked when you try to log in.
}
case ERROR_NO_DATA: { //If the account does NOT EXIST.
//Not sure if this is needed yet.
SCM(playerid, COLOR_LOBBY, "Hello! Welcome to "#SERVER_NAME"! Please click the Register button to get started!");
}
}
orm_setkey(AccountInfo[playerid][ORM_ID], "pID"); // Set a new key to use WHERE `pID` = ... in future queries!
return 1;
}
Or should I insert and then update the table for newly registered users, destroy the ORM instance and then resend him to the PrepareAccount function to retrieve a new ORM id?
Thanks a lot for any feedback. (If this is very unclear or anything, please let me know and I will PM you a better overview
)
(It does seem to work perfectly (testing) and in my eyes the logic is perfect behind it but i could just be simply missing one tiny thing and it gets messed up.)
Also, great work on this plugin. It really is amazing.
EDIT: Tested it some more and there doesn't seem to be any issues.