#include forward OnPlayerLogin(playerid); forward OnPlayerRegister(playerid); forward Account_Create(playerid); forward Account_Validate(playerid, bool:success); static AccountName[MAX_PLAYERS][MAX_PLAYER_NAME]; static AccountIP[MAX_PLAYERS][MAX_PLAYER_IP]; static AccountGPCI[MAX_PLAYERS][MAX_PLAYER_GPCI]; static AccountSQLID[MAX_PLAYERS]; static AccountPassword[MAX_PLAYERS][BCRYPT_HASH_LENGTH]; static PasswordAttempts[MAX_PLAYERS]; static bool:LoggedIn[MAX_PLAYERS]; hook OnPlayerConnect(playerid) { GetPlayerName(playerid, AccountName[playerid], MAX_PLAYER_NAME); GetPlayerIp(playerid, AccountIP[playerid], MAX_PLAYER_IP); gpci(playerid, AccountGPCI[playerid], MAX_PLAYER_GPCI); AccountSQLID[playerid] = 0; AccountPassword[playerid][0] = EOS; PasswordAttempts[playerid] = 0; LoggedIn[playerid] = false; Ban_CheckUser(playerid); } hook OnPlayerPassedBanCheck(playerid) { inline const OnAccountCheck() { if(cache_num_rows()) { cache_get_value_name_int(0, "id", AccountSQLID[playerid]); cache_get_value_name(0, "password", AccountPassword[playerid]); Account_PromptLogin(playerid); } else Account_PromptRegister(playerid); } MySQL_TQueryInline(MySQL_GetHandle(), using inline OnAccountCheck, "SELECT id, password FROM accounts WHERE name = '%e'", AccountName[playerid]); } Account_PromptLogin(playerid) { inline const _response(response, listitem, string:inputtext[]) { #pragma unused listitem if(!response) return Kick(playerid); bcrypt_verify(playerid, "Account_Validate", inputtext, AccountPassword[playerid]); } Dialog_ShowCallback(playerid, using inline _response, DIALOG_STYLE_PASSWORD, "GTA Stories", "{FFFFFF}This account is {33AA33}registered.\n{FFFFFF}Please enter your password below in order to authenticate:", "Login", "Quit"); return 1; } Account_PromptRegister(playerid) { inline _response(response, listitem, string:inputtext[]) { #pragma unused listitem if(!response) return Kick(playerid); if(!(3 <= strlen(inputtext) <= 20)) { SendErrorMessage(playerid, "Password length must be between 3 and 20 characters."); return Account_PromptRegister(playerid); } if(IsNumeric(inputtext)) { SendErrorMessage(playerid, "The password must contain letters."); return Account_PromptRegister(playerid); } bcrypt_hash(playerid, "Account_Create", inputtext, BCRYPT_COST, "i", playerid); } Dialog_ShowCallback(playerid, using inline _response, DIALOG_STYLE_PASSWORD, "GTA Stories", "{FFFFFF}Your name is currently not registered!\nPlease enter a safe and secure password below to register with your master account:", "Register", "Quit"); return 1; } public Account_Validate(playerid, bool:success) { if(!success) { PasswordAttempts[playerid]++; if(PasswordAttempts[playerid] >= 3) { SendErrorMessage(playerid, "You have been kicked from the server because you mistyped the password three times."); return Kick(playerid); } SendErrorMessage(playerid, "The password you entered is incorrect, please try again."); return Account_PromptLogin(playerid); } CallRemoteFunction("OnPlayerLogin", "i", playerid); return 1; } public Account_Create(playerid) { new hash[BCRYPT_HASH_LENGTH]; bcrypt_get_hash(hash, sizeof(hash)); inline const OnRegister() { AccountSQLID[playerid] = cache_insert_id(); AccountPassword[playerid] = hash; CallRemoteFunction("OnPlayerRegister", "i", playerid); } MySQL_TQueryInline(MySQL_GetHandle(), using inline OnRegister, "INSERT INTO accounts (name, password, ip, gpci) VALUES ('%e', '%e', '%e', '%e')", AccountName[playerid], hash, AccountIP[playerid], AccountGPCI[playerid]); } public OnPlayerLogin(playerid) { LoggedIn[playerid] = true; new query[134]; mysql_format(MySQL_GetHandle(), query, sizeof(query), "UPDATE accounts SET ip = '%e', last_login = CURRENT_TIMESTAMP() WHERE id = %d", AccountIP[playerid], AccountSQLID[playerid]); mysql_tquery(MySQL_GetHandle(), query); } public OnPlayerRegister(playerid) { LoggedIn[playerid] = true; } stock Account_GetSQLID(playerid) { return AccountSQLID[playerid]; } stock Account_GetPassword(playerid) { return AccountPassword[playerid]; } stock Account_SetPassword(playerid, const hash[]) { format(AccountPassword[playerid], BCRYPT_HASH_LENGTH, hash); } stock Account_GetName(playerid) { return AccountName[playerid]; } stock Account_SetName(playerid, const name[]) { format(AccountName[playerid], MAX_PLAYER_NAME, name); } stock Account_GetIP(playerid) { return AccountIP[playerid]; } stock Account_SetIP(playerid, const ip[]) { format(AccountIP[playerid], MAX_PLAYER_IP, ip); } stock Account_GetGPCI(playerid) { return AccountGPCI[playerid]; } stock Account_SetGPCI(playerid, const gpci[]) { format(AccountGPCI[playerid], MAX_PLAYER_GPCI, gpci); } stock bool:IsAccountLoggedIn(playerid) { if(LoggedIn[playerid]) { return true; } return false; } stock Account_SetLoggedIn(playerid, bool:status) { LoggedIn[playerid] = status; }