#include <a_samp> // 0.3.7 Include
#include <a_mysql>// MySQL R41-2
#define MySQL_Host ""
#define MySQL_User ""
#define MySQL_Password ""
#define MySQL_Database ""
new MySQL:MHandle;
enum
{
Register,
Login
};
enum Player
{
Name[MAX_PLAYERS_NAME],
Admin,
Deaths,
Kills
};
new PlayerInfo[MAX_PLAYERS][Player]
native WP_Hash(buffer[], len, const str[]);
CREATE TABLE IF NOT EXISTS `accounts` (`Name` VARCHAR(24), `IP` VARCHAR(16), `Password` VARCHAR(129), `Admin` INT(2), `Deaths` INT(6), `Kills` INT(6))
public OnGameModeInit()
{
// Connecting to mysql server using MHandle
MHandle = mysql_connect(MySQL_Host, MySQL_User, MySQL_Password, MySQL_Database);
if(mysql_errno() != 0) // checks if the server failed to connected or not
{
print("[MYSQL]: Failed to connect with using Following Informations: ");
printf(" Host: %s | User: %s | Password: ****** | Database: %s", MySQL_Host, MySQL_User, MySQL_Database);
}
else
{
printf("[MYSQL]: Connection Success to database: %s !", MySQL_Database);
mysql_query(MHandle, "CREATE TABLE IF NOT EXISTS `accounts` (`Name` VARCHAR(24), `IP` VARCHAR(16), `Password` VARCHAR(129), `Admin` INT(2), `Deaths` INT(6), `Kills` INT(6))"); // creating tables once server got connected to mysql server
}
return 1;
}
forward OnPlayerAccountCheck(playerid);
public OnPlayerAccountCheck(playerid)
{
new rows;
cache_get_row_count(rows); // Server count how many rows find in the mysql server
if(rows) // if he find any row then the player registered
{
cache_get_value_name(0, "Password", PlayerInfo[playerid][Password]); // here we get the password of the player account for compare it later with the entred password on the dialog
ShowPlayerDialog(playerid, Login, DIALOG_STYLE_PASSWORD, "Login", "Welcome Back !\nWe miss you here !\nPlease fill you password here to get stats back!", "Login", "Cancel");
}
else // else he is not
{
ShowPlayerDialog(playerid, Register, DIALOG_STYLE_PASSWORD, "Register", "Welcome to our server! \nthis account not register at the database \nPlease fill a password to register your account", "Register", "Cancel");
}
return 1;
}
public OnPlayerConnect(playerid)
{
new query[50];
GetPlayerName(playerid, PlayerInfo[player][Name], sizeof(PlayerInfo[player][Name])); // gets player name on connect
mysql_format(MHandle, query, sizeof(query), "SELECT * FROM `accounts` WHERE `Name` = '%e'", PlayerInfo[player][Name]);
mysql_tquery(MHandle, query, "OnPlayerAccountCheck", "i", playerid); // in this step the server checks if player registered or not using the callback up ^^
return 1;
}
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
switch(dialogid)
{
case Login:
{
new loginattemp, buf[129];
if(!response) Kick(playerid);
if(isnull(PlayerInfo[playerid][Password])) // checks if password correctly loaded else check below :)
{
SendClientMessage(playerid, -1,"[MYSQL]: Sorry, we have some problems on database right now, Come back later !");
Kick(playerid);
print("[MYSQL]: Password Value 'PlayerInfo[playerid][Password]' not correctly loaded! please check OnPlayerAccountCheck callback");
print("[SA-MP Server]: Server shutdown..");
SendRconCommand("exit");
return 1;
}
WP_Hash(buf, sizeof(buf), inputtext);
if(!strcmp(buf, PlayerInfo[playerid][Password], true)) // comparing the passwords (database & entrerd)
{
new query[70], Cache:GetCache;
mysql_format(MHandle, query, sizeof(query), "SELECT * FROM `accounts` WHERE `Name` = '%e' LIMIT 1", PlayerInfo[player][Name]);
GetCache = mysql_query(MHandle, query);
// Importing data after beigning sure he is the right user
new rows;
cache_get_row_count(rows);
if(rows == 1)
{
cache_get_value_name_int(0, "Admin", PlayerInfo[playerid][Admin]);
cache_get_value_name_int(0, "Deaths", PlayerInfo[playerid][Deaths]);
cache_get_value_name_int(0, "Kills", PlayerInfo[playerid][Kills]);
}
SendClientMessage(playerid, -1, "You have successfully logged in.");
cache_delete(GetCache);
}
else // if he entred an wrrong password
{
if(loginattemp == 3) return Kick(playerid); // if he entred the same wrrong password 3 times he got kicked
SendClientMessage(playerid, -1, "You have specified an incorrect password!");
ShowPlayerDialog(playerid, Login, DIALOG_STYLE_PASSWORD, "Login", "Welcome Back !\nWe miss you here !\nPlease fill you password here to get stats back!", "Login", "Cancel");
loginattemp++; // adding +1 for every attemp
}
}
case Register:
{
if(!response) return Kick(playerid);
if(strlen(inputtext) < 5)
{
SendClientMessage(playerid, -1, "Your password must at least contain more than 4 characters.");
return ShowPlayerDialog(playerid, Register, DIALOG_STYLE_PASSWORD, "Register", "Welcome to our server! \nthis account not register at the database \nPlease fill a password to register your account", "Register", "Cancel");
}
new
query[287],
playerip[16],
buf[129]
;
WP_Hash(buf, sizeof(buf), inputtext); // hashing password using Whirlpool engine
GetPlayerIp(playerid, playerip, sizeof(playerip));
mysql_format(MHandle, query, sizeof(query), "INSERT INTO `accounts` (`Name`, `Password`, `IP`, `Admin`,`Deaths`, `Kills`) VALUES ('%e', '%e', '%e', 0, 0, 0)", PlayerInfo[player][Name], buf, playerip);
mysql_query(MHandle, query); // here inserting the player account in the database as a registered player
}
}
return 0;
}
public OnPlayerDeath(playerid, killerid, reason)
{
PlayerInfo[killerid][Kills]++; // increasing Kills value for killer
PlayerInfo[playerid][Deaths]++; // increasing Deaths value for the victim
return 1;
}
UPDATE `accounts` SET `Kills` = '', `Deaths` = '', `Admin` = '', WHERE `name` = ''
public OnPlayerDisconnect(playerid, reason)
{
new querylist[120];
mysql_format(MHandle, querylist, sizeof(querylist),
"UPDATE `accounts` SET `Kills` = %d, `Deaths` = %d, `Admin` = %d WHERE `name` = '%e'"
, PlayerInfo[playerid][Kills], PlayerInfo[playerid][Deaths], PlayerInfo[playerid][Admin], PlayerInfo[player][Name]);
mysql_query(MHandle, querylist);
return 1;
}
CMD:[nameofcommand](playerid, params[])
{
// check if the player is admin
if(PlayerInfo[playerid][Admin] == 0) return SendClientMessage(playerid, -1, "you are not admin");
// codes here ...
return 1; // if you return 0 the command will not created.
}
as i noticed the most of tutorials are outdated and some onces are bugged! so In this tutorial i will show you a simple and fast way to create a simple register system using The lastest version of MySQL by BlueG/maddinat0r (R41-2)
|
4 - Adding the whirlpool hashing engine
PHP код:
|
mysql_format(MHandle, query, sizeof(query), "SELECT * FROM `accounts` WHERE `Name` = '%s' LIMIT 1", pname);
mysql_format(MHandle, query, sizeof(query), "SELECT * FROM `accounts` WHERE `Name` = '%e' LIMIT 1", pname);
4. Use mysql_format instead of format while calling a query, Also don't forget to escape the text (like player name).
|
also doesn't matter the synatax always keep work with it or without it
|
Stop being a dumbass.
What? It does matter. https://sampwiki.blast.hk/wiki/MySQL#mysql_format -- You seem like you can't handle the criticisms, Don't bother releasing stuff then. |
I would still just say good job yup there were some corrections to be made which you already did......
But I would say to oMa37 atleast he made the tutorial which I really haven't seen yet with a update....Why didn't you made that? Why you didn't get idea on this topic earlier? |
Well were you there watching him when he was making tutorial and you guessed that it took 5 minutes?
Anyways lol I don't want to spam the thread....So let's keep it going.. |
I would still just say good job yup there were some corrections to be made which you already did......
But I would say to oMa37 atleast he made the tutorial which I really haven't seen yet with a update....Why didn't you made that? Why you didn't get idea on this topic earlier? |
Why would I make this when there is a better version? I would say it's the best version, This one.
|
@oMa37 stop it! it's just a file without any explaintion, i can do that just check my scripts at http://github.com/saplayground
|
public OnPlayerConnect(playerid) { new query[50], pname[MAX_PLAYERS_NAME]; GetPlayerName(playerid, pname, sizeof(pname)); // gets player name on connect mysql_format(MHandle, query, sizeof(query), "SELECT * FROM `accounts` WHERE `Name` = '%e'", pname); mysql_tquery(MHandle, query, "OnPlayerAccountCheck", "i", playerid); // in this step the server checks if player registered or not using the callback up ^^ return 1; }
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[]) { switch(dialogid) { case Login: { static loginattemp, buf[129], pname[MAX_PLAYERS_NAME]; GetPlayerName(playerid, pname, sizeof(pname)); if(!response) Kick(playerid); if(isnull(PlayerInfo[playerid][Password])) // checks if password correctly loaded else check below :) { SendClientMessage(playerid, -1,"[MYSQL]: Sorry, we have some problems on database right now, Come back later !"); Kick(playerid); print("[MYSQL]: Password Value 'PlayerInfo[playerid][Password]' not correctly loaded! please check OnPlayerAccountCheck callback"); print("[SA-MP Server]: Server shutdown.."); SendRconCommand("exit"); return 1; } WP_Hash(buf, sizeof(buf), inputtext); if(!strcmp(buf, PlayerInfo[playerid][Password], true)) // comparing the passwords (database & entrerd) { new query[70], Cache:GetCache; mysql_format(MHandle, query, sizeof(query), "SELECT * FROM `accounts` WHERE `Name` = '%e' LIMIT 1", pname); GetCache = mysql_query(MHandle, query); // Importing data after beigning sure he is the right user new rows; cache_get_row_count(rows); if(rows == 1) { cache_get_value_name_int(0, "Admin", PlayerInfo[playerid][Admin]); cache_get_value_name_int(0, "Deaths", PlayerInfo[playerid][Deaths]); cache_get_value_name_int(0, "Kills", PlayerInfo[playerid][Kills]); } SendClientMessage(playerid, -1, "You have successfully logged in."); cache_delete(GetCache); } else // if he entred an wrrong password { if(loginattemp == 3) return Kick(playerid); // if he entred the same wrrong password 3 times he got kicked SendClientMessage(playerid, -1, "You have specified an incorrect password!"); ShowPlayerDialog(playerid, Login, DIALOG_STYLE_PASSWORD, "Login", "Welcome Back !\nWe miss you here !\nPlease fill you password here to get stats back!", "Login", "Cancel"); loginattemp++; // adding +1 for every attemp } } case Register: { if(!response) return Kick(playerid); if(strlen(inputtext) < 5) { SendClientMessage(playerid, -1, "Your password must at least contain more than 4 characters."); return ShowPlayerDialog(playerid, Register, DIALOG_STYLE_PASSWORD, "Register", "Welcome to our server! \nthis account not register at the database \nPlease fill a password to register your account", "Register", "Cancel"); } new query[287], playername[MAX_PLAYER_NAME], playerip[16], buf[129] ; WP_Hash(buf, sizeof(buf), inputtext); // hashing password using Whirlpool engine GetPlayerName(playerid, playername, sizeof(playername)); GetPlayerIp(playerid, playerip, sizeof(playerip)); mysql_format(MHandle, query, sizeof(query), "INSERT INTO `accounts` (`Name`, `Password`, `IP`, `Admin`,`Deaths`, `Kills`) VALUES ('%e', '%e', '%e', 0, 0, 0)", playername, buf, playerip); mysql_query(MHandle, query); // here inserting the player account in the database as a registered player } } return 0; }
static loginattemp
array_name[size char];
did this tutorial work ? Yes.
did it's take so much cpu ? No. so it's fine to use . |
Okay Mr Pro scripter i will tell you what exactly is optmisation is.It is not actually reducing no of lines in a script.It how you hacks with compiler and machine.Also overdoing an optmisation is also bad programming do the optmisation where ever necessary and never should it compromise it with readability.
|
^^ another bad habit a good programmer cares about data structure rather than code. Instead creating an overhead to this function every time its better to have per player array to hold name on connection and not to mention your database arrangement it also need to normalized.
|
That's not the point. A tutorial should teach the best method. People reading a tutorial assume that what you've written is the best method to achieve the desired result. I'm sure all that you've written here will work, but as long as you don't understand the concept of keys in SQL you shouldn't write an SQL related tutorial.
|