pawn Код:
// ** INCLUDES
#include <a_samp>
// ** NATIVES
// *** WHIRLPOOL
native WP_Hash(buffer[], len, const str[]);
// ** DEFINES
// *** FUNCTIONS
#define isnull(%1) ((!(%1[0])) || (((%1[0]) == '\1') && (!(%1[1]))))
#define strcat_format(%0,%1,%2) format(%0[strlen(%0)], %1 - strlen(%0), %2)
// *** DIALOGS
#define DIALOG_REGISTER 0
#define DIALOG_CONFIRM_REGISTER 1
#define DIALOG_LOGIN 2
// *** DATABASE
// **** USER DATABASE
// ***** GENERAL
#define TABLE_USERS "USERS"
// ***** PATHS
#define USER_DATABASE_PATH "database.db"
// ***** FIELDS
#define USER_NAME "name"
#define USER_PASSWORD "password"
#define USER_IP_ADDRESS "ip_address"
#define USER_SCORE "score"
#define USER_CASH "cash"
#define USER_ADMIN_LEVEL "admin_level"
// ** COLORS
// *** GENERAL
#define COLOR_WHITE 0xFFFFFFFF
#define COL_WHITE "{FFFFFF}"
#define COLOR_RED 0xFF0000FF
#define COL_RED "{FF0000}"
// *** CUSTOM
#define COLOR_ACCOUNT 0x37E9A0FF
#define COL_ACCOUNT "{37E9A0}"
// ** ARRAYS AND ENUMERATORS
enum eUserInfo
{
user_score,
user_cash,
user_admin_level
}
new aUserInfo[MAX_PLAYERS][eUserInfo];
// ** VARIABLES
// *** GLOBAL VARIABLES
// **** DATABASE
new DB:database;
// *** PER-PLAYER VARIABLES
// **** GENERAL
new pPasswordHash[MAX_PLAYERS][129],
pLoggingAttempts[MAX_PLAYERS];
// **** PLAYER STATES
new bool:sSignedIn[MAX_PLAYERS] = false;
// ** HOOKS
stock Hook_SetPlayerScore(playerid, score)
{
aUserInfo[playerid][user_score] = score;
return SetPlayerScore(playerid, score);
}
#if defined _ALS_SetPlayerScore
#undef SetPlayerScore
#else
#define _ALS_SetPlayerScore
#endif
#define SetPlayerScore Hook_SetPlayerScore
// ** MAIN
main()
{
print("Loaded \"scripts.amx\".");
}
// ** CALLBACKS
public OnGameModeInit()
{
LoadDatabase();
return 1;
}
public OnGameModeExit()
{
db_close(database);
return 1;
}
public OnPlayerConnect(playerid)
{
new query[300], DBResult:result;
TogglePlayerSpectating(playerid, true);
strcat_format(query, sizeof(query), "SELECT `%s`", USER_NAME);
strcat_format(query, sizeof(query), " FROM `%s`", TABLE_USERS);
strcat_format(query, sizeof(query), " WHERE `%s` = '%q' COLLATE NOCASE LIMIT 1", USER_NAME, PlayerName(playerid));
result = db_query(database, query);
if(db_num_rows(result))
{
ShowLoginDialog(playerid);
}
else
{
ShowRegisterDialog(playerid);
}
db_free_result(result);
return 1;
}
public OnPlayerDisconnect(playerid, reason)
{
if(IsPlayerSignedIn(playerid))
{
new query[400];
strcat_format(query, sizeof(query), "UPDATE `%s` SET ", TABLE_USERS);
strcat_format(query, sizeof(query), "%s = '%d',", USER_SCORE, aUserInfo[playerid][user_score]);
strcat_format(query, sizeof(query), "%s = '%d',", USER_CASH, aUserInfo[playerid][user_cash]);
strcat_format(query, sizeof(query), "%s = '%d'", USER_ADMIN_LEVEL, aUserInfo[playerid][user_admin_level]);
strcat_format(query, sizeof(query), " WHERE `%s` = '%q' COLLATE NOCASE", USER_NAME, PlayerName(playerid));
db_query(database, query);
}
return 1;
}
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
switch(dialogid)
{
case DIALOG_REGISTER:
{
if(!response)
{
KickPlayer(playerid);
}
else if(response)
{
if(isnull(inputtext))
{
ShowRegisterDialog(playerid);
}
else if(strlen(inputtext) < 3)
{
SendClientMessage(playerid, COLOR_RED, "Your password is too short, please try again.");
ShowRegisterDialog(playerid);
}
else if(strlen(inputtext) > 20)
{
SendClientMessage(playerid, COLOR_RED, "Your password is too long, please try again.");
ShowRegisterDialog(playerid);
}
else
{
WP_Hash(pPasswordHash[playerid], 129, inputtext);
ShowConfirmPasswordDialog(playerid);
}
}
}
case DIALOG_CONFIRM_REGISTER:
{
if(!response)
{
ShowRegisterDialog(playerid);
}
else if(response)
{
new hash[129];
WP_Hash(hash, sizeof(hash), inputtext);
if(isnull(inputtext))
{
ShowConfirmPasswordDialog(playerid);
}
else if(!strcmp(pPasswordHash[playerid], hash, true))
{
new query[500];
strcat_format(query, sizeof(query), "INSERT INTO `%s` (", TABLE_USERS);
strcat_format(query, sizeof(query), "`%s`,", USER_NAME);
strcat_format(query, sizeof(query), "`%s`,", USER_PASSWORD);
strcat_format(query, sizeof(query), "`%s`,", USER_IP_ADDRESS);
strcat_format(query, sizeof(query), "`%s`,", USER_SCORE);
strcat_format(query, sizeof(query), "`%s`,", USER_CASH);
strcat_format(query, sizeof(query), "`%s`", USER_ADMIN_LEVEL);
strcat(query, ") VALUES (");
strcat_format(query, sizeof(query), "'%q',", PlayerName(playerid)); // USER_NAME
strcat_format(query, sizeof(query), "'%q',", hash); // USER_PASSWORD
strcat_format(query, sizeof(query), "'%q',", GetPlayerIP(playerid)); // USER_IP_ADDRESS
strcat(query, "'0',"); // USER_SCORE
strcat(query, "'0',"); // USER_CASH
strcat(query, "'0')"); // USER_ADMIN_LEVEL
db_query(database, query);
sSignedIn[playerid] = true;
TogglePlayerSpectating(playerid, false);
SendClientMessage(playerid, COLOR_ACCOUNT, "You have successfully registered your account.");
}
else
{
SendClientMessage(playerid, COLOR_RED, "That's not the same password as the first one.");
ShowConfirmPasswordDialog(playerid);
}
}
}
case DIALOG_LOGIN:
{
if(!response)
{
KickPlayer(playerid);
}
else if(response)
{
if(isnull(inputtext))
{
ShowLoginDialog(playerid);
}
else
{
new query_1[500], DBResult:result, hash[129];
WP_Hash(hash, sizeof(hash), inputtext);
strcat_format(query_1, sizeof(query_1), "SELECT `%s`,", USER_IP_ADDRESS);
strcat_format(query_1, sizeof(query_1), "`%s`,", USER_SCORE);
strcat_format(query_1, sizeof(query_1), "`%s`,", USER_CASH);
strcat_format(query_1, sizeof(query_1), "`%s`", USER_ADMIN_LEVEL);
strcat_format(query_1, sizeof(query_1), " FROM `%s`", TABLE_USERS);
strcat_format(query_1, sizeof(query_1), " WHERE `%s` = '%q'", USER_NAME, PlayerName(playerid));
strcat_format(query_1, sizeof(query_1), " AND `%s` = '%q' COLLATE NOCASE LIMIT 1", USER_PASSWORD, hash);
result = db_query(database, query_1);
if(db_num_rows(result))
{
new field[128], temp;
db_get_field_assoc(result, USER_IP_ADDRESS, field, sizeof(field));
if(strcmp(GetPlayerIP(playerid), field, true))
{
new query_2[128];
strcat_format(query_2, sizeof(query_2), "UPDATE `%s` SET ", TABLE_USERS);
strcat_format(query_2, sizeof(query_2), "`%s` = '%q'", USER_IP_ADDRESS, GetPlayerIP(playerid));
strcat_format(query_2, sizeof(query_2), " WHERE `%s` = '%q' COLLATE NOCASE", USER_NAME, PlayerName(playerid));
db_query(database, query_2);
}
temp = db_get_field_assoc_int(result, USER_SCORE);
SetPlayerScore(playerid, temp);
temp = db_get_field_assoc_int(result, USER_CASH);
SetPlayerMoney(playerid, temp);
aUserInfo[playerid][user_admin_level] = db_get_field_assoc_int(result, USER_ADMIN_LEVEL);
db_free_result(result);
sSignedIn[playerid] = true;
TogglePlayerSpectating(playerid, false);
SendClientMessage(playerid, COLOR_ACCOUNT, "You have successfully logged in to your account.");
}
else
{
new string[144];
db_free_result(result);
pLoggingAttempts[playerid] ++;
format(string, sizeof(string), "That password is incorrect. Attempts left: %d.", (3 - pLoggingAttempts[playerid]));
SendClientMessage(playerid, COLOR_RED, string);
if(pLoggingAttempts[playerid] == 3)
{
KickPlayer(playerid);
}
else
{
ShowLoginDialog(playerid);
}
}
}
}
}
}
return 1;
}
// ** FUNCTIONS
// *** LOAD COMPONENTS
stock LoadDatabase()
{
new query[400];
database = db_open(USER_DATABASE_PATH);
strcat_format(query, sizeof(query), "CREATE TABLE IF NOT EXISTS `%s` (", TABLE_USERS);
strcat_format(query, sizeof(query), "`%s` TEXT,", USER_NAME);
strcat_format(query, sizeof(query), "`%s` TEXT,", USER_PASSWORD);
strcat_format(query, sizeof(query), "`%s` TEXT,", USER_IP_ADDRESS);
strcat_format(query, sizeof(query), "`%s` INTEGER,", USER_SCORE);
strcat_format(query, sizeof(query), "`%s` INTEGER,", USER_CASH);
strcat_format(query, sizeof(query), "`%s` INTEGER)", USER_ADMIN_LEVEL);
db_query(database, query);
return 1;
}
// *** GENERAL
stock GetPlayerIP(playerid)
{
new ip[16];
GetPlayerIp(playerid, ip, sizeof(ip));
return ip;
}
stock ShowRegisterDialog(playerid)
{
new string[256];
strcat_format(string, sizeof(string), "{FFFFFF}Welcome, %s!\n\n", PlayerName(playerid));
strcat(string, "You must register to play here.");
return ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_PASSWORD, "Register", string, "Next", "Close");
}
stock ShowConfirmPasswordDialog(playerid)
{
new string[256];
strcat_format(string, sizeof(string), "{FFFFFF}Welcome, %s!\n\n", PlayerName(playerid));
strcat(string, "You must confirm your registration to play here.");
return ShowPlayerDialog(playerid, DIALOG_CONFIRM_REGISTER, DIALOG_STYLE_PASSWORD, "Confirm Registration", string, "Register", "Back");
}
stock ShowLoginDialog(playerid)
{
new string[256];
strcat_format(string, sizeof(string), "{FFFFFF}Welcome back, %s!\n\n", PlayerName(playerid));
strcat(string, "You must log in to play here.");
return ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_PASSWORD, "Log In", string, "Log In", "Close");
}
stock PlayerName(playerid)
{
new name[MAX_PLAYER_NAME];
GetPlayerName(playerid, name, MAX_PLAYER_NAME);
return name;
}
stock SetPlayerMoney(playerid, cash)
{
aUserInfo[playerid][user_cash] = cash;
ResetPlayerMoney(playerid);
return GivePlayerMoney(playerid, cash);
}
stock KickPlayer(playerid)
{
return SetTimerEx("KickPlayerEx", 100, false, "i", playerid);
}
forward KickPlayerEx(playerid);
public KickPlayerEx(playerid)
{
return Kick(playerid);
}
forward bool:IsPlayerSignedIn(playerid);
public bool:IsPlayerSignedIn(playerid)
{
return sSignedIn[playerid];
}