pawn Код:
// ** INCLUDES
#include <a_samp>
#include <YSI\y_ini>
// ** NATIVES
// *** WHIRLPOOL
native WP_Hash(buffer[], len, const str[]);
// ** UN-DEFINES
#undef isnull
// ** DEFINES
// *** FUNCTIONS
#define isnull(%1) ((!(%1[0])) || (((%1[0]) == '\1') && (!(%1[1]))))
// *** DIALOGS
#define DIALOG_REGISTER 0
#define DIALOG_LOGIN 1
// *** DATABASE
#define USER_TAG "player_data"
#define USER_PASSWORD "password"
#define USER_SCORE "score"
#define USER_CASH "cash"
#define USER_KILLS "kills"
#define USER_DEATHS "deaths"
#define USER_ADMIN_LEVEL "admin_level"
// ** ARRAYS AND ENUMERATORS
enum eUserInfo
{
user_password[129],
user_score,
user_cash,
user_kills,
user_deaths,
user_admin_level
}
new aUserInfo[MAX_PLAYERS][eUserInfo];
// ** VARIABLES
// *** PER-PLAYER VARIABLES
// **** PLAYER STATES
new bool:psSignedIn[MAX_PLAYERS] = false;
// ** MAIN
main()
{
print("Loaded \"ini_login_system.amx\".");
}
// ** CALLBACKS
public OnGameModeInit()
{
return 1;
}
public OnGameModeExit()
{
return 1;
}
public OnPlayerConnect(playerid)
{
if(fexist(UserPath(playerid)))
{
INI_ParseFile(UserPath(playerid), "LoadUserData", .bExtra = true, .extra = playerid);
ShowLoginDialog(playerid, "");
}
else
{
ShowRegisterDialog(playerid, "");
}
return 1;
}
public OnPlayerDisconnect(playerid, reason)
{
if(IsPlayerSignedIn(playerid))
{
new INI:file = INI_Open(UserPath(playerid));
INI_SetTag(file, USER_TAG);
INI_WriteInt(file, USER_SCORE, GetPlayerScore(playerid));
INI_WriteInt(file, USER_CASH, GetPlayerMoney(playerid));
INI_WriteInt(file, USER_KILLS, aUserInfo[playerid][user_kills]);
INI_WriteInt(file, USER_DEATHS, aUserInfo[playerid][user_deaths]);
INI_WriteInt(file, USER_ADMIN_LEVEL, aUserInfo[playerid][user_admin_level]);
INI_Close(file);
}
ResetPlayerVariables(playerid);
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, "Enter a password.");
}
else
{
new length = strlen(inputtext);
if(length < 6)
{
ShowRegisterDialog(playerid, "Password is too short.");
}
else if(length > 20)
{
ShowRegisterDialog(playerid, "Password is too long.");
}
else
{
new hash[129];
WP_Hash(hash, sizeof(hash), inputtext);
new INI:file = INI_Open(UserPath(playerid));
INI_SetTag(file, USER_TAG);
INI_WriteString(file, USER_PASSWORD, hash);
INI_WriteInt(file, USER_SCORE, 0);
INI_WriteInt(file, USER_CASH, 0);
INI_WriteInt(file, USER_KILLS, 0);
INI_WriteInt(file, USER_DEATHS, 0);
INI_WriteInt(file, USER_ADMIN_LEVEL, 0);
INI_Close(file);
psSignedIn[playerid] = true;
SendClientMessage(playerid, -1, "You have successfully registered your account.");
}
}
}
}
case DIALOG_LOGIN:
{
if(!response)
{
KickPlayer(playerid);
}
else if(response)
{
if(isnull(inputtext))
{
ShowLoginDialog(playerid, "Enter a password.");
}
else
{
new hash[129];
WP_Hash(hash, sizeof(hash), inputtext);
if(!strcmp(aUserInfo[playerid][user_password], hash, false))
{
INI_ParseFile(UserPath(playerid), "LoadUserData", .bExtra = true, .extra = playerid);
SetPlayerScore(playerid, aUserInfo[playerid][user_score]);
GivePlayerMoney(playerid, aUserInfo[playerid][user_cash]);
psSignedIn[playerid] = true;
SendClientMessage(playerid, -1, "You have successfully logged in to your account.");
}
else
{
ShowLoginDialog(playerid, "Incorrect password.");
}
}
}
}
}
return 1;
}
// ** FUNCTIONS
stock ResetPlayerVariables(playerid)
{
// ** ARRAYS AND ENUMERATORS
aUserInfo[playerid][user_password][0] = EOS;
aUserInfo[playerid][user_score] = 0;
aUserInfo[playerid][user_cash] = 0;
aUserInfo[playerid][user_kills] = 0;
aUserInfo[playerid][user_deaths] = 0;
aUserInfo[playerid][user_admin_level] = 0;
// ** PER-PLAYER VARIABLES
// *** PLAYER STATES
psSignedIn[playerid] = false;
return 1;
}
forward LoadUserData(playerid, name[], value[]);
public LoadUserData(playerid, name[], value[])
{
INI_String(USER_PASSWORD, aUserInfo[playerid][user_password], 129);
INI_Int(USER_SCORE, aUserInfo[playerid][user_score]);
INI_Int(USER_CASH, aUserInfo[playerid][user_cash]);
INI_Int(USER_KILLS, aUserInfo[playerid][user_kills]);
INI_Int(USER_DEATHS, aUserInfo[playerid][user_deaths]);
INI_Int(USER_ADMIN_LEVEL, aUserInfo[playerid][user_admin_level]);
return 1;
}
stock ShowRegisterDialog(playerid, error[])
{
new string[256];
strcat(string, "Welcome. This account is not registered.\n");
strcat(string, "Enter a password below to register an account.");
if(!isnull(error))
{
strcat(string, "\n\n{FF0000}");
strcat(string, error);
}
ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_PASSWORD, "Register", string, "Register", "Close");
return 1;
}
stock ShowLoginDialog(playerid, error[])
{
new string[256];
strcat(string, "Welcome back. This account is already registered.\n");
strcat(string, "Insert your password to log into your account.");
if(!isnull(error))
{
strcat(string, "\n\n{FF0000}");
strcat(string, error);
}
ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_PASSWORD, "Login", string, "Login", "Close");
return 1;
}
stock KickPlayer(playerid)
{
SetTimerEx("KickPlayerAction", 100, false, "i", playerid);
return 1;
}
forward KickPlayerAction(playerid);
public KickPlayerAction(playerid)
{
Kick(playerid);
return 1;
}
stock UserPath(playerid)
{
new string[50], name[MAX_PLAYER_NAME];
GetPlayerName(playerid, name, sizeof(name));
format(string, sizeof(string), "/Users/%s.ini", name);
return string;
}
forward bool:IsPlayerSignedIn(playerid);
public bool:IsPlayerSignedIn(playerid)
{
return psSignedIn[playerid];
}
Please note that the user files save in .../scriptfiles/Users/%s.ini. You also need Whirlpool.