Hey guys, I having problem in understanding y_ini.. It's just going over my head. I mean what is ParseFile and stuff. Actually what do you expect from a 14 kid.. Well So, I wanna Ask that Should I keep on trying to understand y_ini or switch to my_sql? What will be better? Please Reply with your adive/suggestion.
I find working with databases much easier than files. Easier to backup, easier to administrate, more realistic if you want to ever create a control panel, etc. You should do due diligence to learn SQL before trying to actually use it. SQL is its own language and should be treated as such.
It means that it will load a player's file.
pawn Код:
// [ DEVELOPMENT GAMEMODE ]
// INCLUDES:
#include <a_samp>
#include <YSI\y_ini>
// NATIVES:
// WHIRLPOOL:
native WP_Hash(buffer[], len, const str[]);
// UNDEFINES:
#undef isnull
// DEFINES:
// FUNCTIONS:
#define function%0(%1) forward%0(%1); public%0(%1)
#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_VIP_LEVEL "vip_level"
#define USER_ADMIN_LEVEL "admin_level"
// ARRAYS AND ENUMERATORS:
enum eUserInfo
{
user_password[129],
user_score,
user_cash,
user_kills,
user_deaths,
user_vip_level,
user_admin_level
}
new aUserInfo[MAX_PLAYERS][eUserInfo];
// VARIABLES:
// STATES:
new bool:sSignedIn[MAX_PLAYERS] = false;
// MAIN:
main()
{
print("Development Mode: 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_VIP_LEVEL, aUserInfo[playerid][user_vip_level]);
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) return KickPlayer(playerid);
if(response)
{
if(isnull(inputtext)) return ShowRegisterDialog(playerid, "Enter a password.");
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_VIP_LEVEL, 0);
INI_WriteInt(file, USER_ADMIN_LEVEL, 0);
INI_Close(file);
sSignedIn[playerid] = true;
SendClientMessage(playerid, -1, "You have successfully registered an account.");
}
}
case DIALOG_LOGIN:
{
if(!response) return KickPlayer(playerid);
if(response)
{
if(isnull(inputtext)) return ShowLoginDialog(playerid, "Enter a password.");
new hash[129];
WP_Hash(hash, sizeof(hash), inputtext);
if(strcmp(aUserInfo[playerid][user_password], hash, false) == 0)
{
INI_ParseFile(UserPath(playerid), "LoadUserData", .bExtra = true, .extra = playerid);
SetPlayerScore(playerid, aUserInfo[playerid][user_score]);
GivePlayerMoney(playerid, aUserInfo[playerid][user_cash]);
sSignedIn[playerid] = true;
SendClientMessage(playerid, -1, "You have successfully logged into your account.");
}
else return ShowLoginDialog(playerid, "Incorrect password.");
}
}
}
return 1;
}
// FUNCTIONS:
stock ResetPlayerVariables(playerid)
{
// ARRAYS AND ENUMERATORS:
aUserInfo[playerid][user_password] = EOS;
aUserInfo[playerid][user_score] = 0;
aUserInfo[playerid][user_cash] = 0;
aUserInfo[playerid][user_kills] = 0;
aUserInfo[playerid][user_deaths] = 0;
aUserInfo[playerid][user_vip_level] = 0;
aUserInfo[playerid][user_admin_level] = 0;
// PER-PLAYER VARIABLES:
// STATES:
sSignedIn[playerid] = false;
}
function 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_VIP_LEVEL, aUserInfo[playerid][user_vip_level]);
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)) format(string, sizeof(string), "%s\n\n{FF0000}%s", string, error);
return ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_INPUT, "Register", string, "Register", "Quit");
}
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)) format(string, sizeof(string), "%s\n\n{FF0000}%s", string, error);
return ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_INPUT, "Login", string, "Login", "Quit");
}
stock KickPlayer(playerid) return SetTimerEx("KickPlayerEx", 100, false, "i", playerid);
function KickPlayerEx(playerid) return Kick(playerid);
stock UserPath(playerid)
{
new string[128], name[MAX_PLAYER_NAME];
GetPlayerName(playerid, name, sizeof(name));
format(string, sizeof(string), "/Users/%s.ini", name);
return string;
}
stock IsPlayerSignedIn(playerid) return sSignedIn[playerid];
If you cannot understand INI files (how they work, etc), then there is absolutely no reason to switch over to MySQL. SQL is a also a programming language, you will no longer be coding in one programming language, but in two.
SickAttack, does that mean that I can use call LoadUserData function in ParseFile without doing things like LoadUser%s etc...?