PDA

Просмотр полной версии : [Урок] Система регистрации Mysql



Nurick
10.07.2014, 13:49
Здраствуйте! сегодня наткнулся на официальном сайте www.sa-mp.com на урок по системе регистрации Mysql.
Как так тут нету подобных уроков решил перевести и выложить данную статью тут(Так как у меня с английским не очень, поэтому я воспользовался переводчиком. И поэтому могу быть несостыковки в тексте)

Автор данной статьи: newbienoob

Что нам понадобиться:
1. Mysql plugin (http://forum.sa-mp.com/showthread.php?t=56564)
2. Whirlpool (http://forum.sa-mp.com/showthread.php?t=65290)

Ко всем include добавим:

#include <a_samp> //без этого мы не сможем использовать все samp функции/обратные вызовы
#include <a_mysql> //без этого мы не сможем использовать все функции mysql
Ко всем define добавим:

#define host "localhost" //это будет ваш хост mysql. По умолчанию для xampp-localhost
#define user "root" //это будет имя пользователя mysql. По умолчанию для xampp-это корень
#define db "server" //название базы данных. Помните, мы создали базу данных, которая называется сервером перед.
#define pass "" //это Ваш пароль mysql. В xampp, пароль не ставил. Так что оставьте его пустым.


#define dregister 6287 //диалог регистрации
#define dlogin 6288 // диалог авторизации
К глобальным переменным:

static mysql, //эта переменная будет использоваться для управления в базе
Name[MAX_PLAYERS][24], //мы будем использовать эту переменную для хранения имени игрока.
IP[MAX_PLAYERS][16] //мы будем использовать эту переменную для хранения игрока ip.
;

native WP_Hash(buffer[], len, const str[]);

enum PDATA
{
ID, //Будет использоваться в дальнейшем для хранения игрока ID из базы данных, поэтому мы можем использовать его в любом месте позже
Password[129],//Мы будем загружать игрока пароль в это varible из базы данных
Admin, //Мы будем загружать игрока на уровне администратора из базы данных в этой переменной, чтобы мы могли использовать его в любом месте позже.
VIP, //Мы будем загружать уровня VIP игрока из базы данных в этой переменной, чтобы мы могли использовать его в любом месте позже.
Money, //Мы будем загружать деньги игрока из базы данных в этой переменной, чтобы мы могли использовать его в любом месте позже.
Float:posX, //Мы будем загружать игрока X позиция из базы данных в этой переменной, чтобы мы могли использовать его в любом месте позже.
Float:posY, //Мы будем загружать игрока Y позиции из базы данных в этой переменной, чтобы мы могли использовать его в любом месте позже.
Float:posZ //Мы будем загружать игрока Z позиции из базы данных в этой переменной, чтобы мы могли использовать его в любом месте позже.

}

new pInfo[MAX_PLAYERS][PDATA]; //Переменная, которая хранит перечислитель выше
В public OnGameModeInit():

mysql_log(LOG_ERROR | LOG_WARNING | LOG_DEBUG); //Давайте включим отладку, так мы можем выявить проблемы(если есть)
mysql = mysql_connect(host, user, db, pass); //Эта функция будет подключение сервера к базе данных. Помните, мы определили наш хост, имя пользователя базы данных и пароль. Это время, чтобы использовать его здесь.
if(mysql_errno(mysql) != 0) print("Не удалось подключиться к базе данных!"); //Об этом скажет, если соединение с базой данных успешно или нет. Если это не так, проверьте хост, имя пользователя базы данных и пароль. Убедитесь, что все они правы
В public OnPlayerConnect(playerid):

new query[128]; //Мы используем эту переменную в формате запрос
GetPlayerName(playerid, Name[playerid], 24); //Получение имени игрока
GetPlayerIp(playerid, IP[playerid], 16); //Получение IP игрока
mysql_format(mysql, query, sizeof(query),"SELECT `Password`, `ID` FROM `players` WHERE `Username` = '%e' LIMIT 1", Name[playerid]);
// - Мы используем mysql_format вместо формате, потому что мы можем использовать %e спецификатор. %e спецификатор экранирует строку, чтобы мы могли избежать sql-инъекции, которая означает, что мы не должны использовать mysql_real_escape_string
// - Форматирование наш запрос; SELECT `Password`, `ID` FROM `players` WHERE `Username`='%e' означает, что мы выбирает пароль и ID-это столбец в таблице, который имеет имя игрока в столбец " имя пользователя.
// - LIMIT 1; нам нужно только 1 результат будет показано
mysql_tquery(mysql, query, "OnAccountCheck", "i", playerid);
//позволяет выполнить форматированный запрос и при исполнении сделано, обратного вызова OnAccountCheck будет называться
//Вы можете назвать обратного вызова как вам нравится
В конце скрипта создадим public:

forward OnAccountCheck(playerid);
public OnAccountCheck(playerid)
{
new rows, fields; //переменная, которая будет использоваться для извлечения строк и полей в базе данных.
cache_get_data(rows, fields, mysql);//Let's get строк и полей из базы данных.
if(rows) //если есть строка
{//затем
cache_get_field_content(0, "PASS", pInfo[playerid][Password], mysql, 129);
//мы будем загружать игрока пароль в pInfo[playerid][Password], используемый в регистрации
pInfo[playerid][ID] = cache_get_field_content_int(0, "ID"); //теперь давайте загрузки ID игрока в pInfo[playerid][ID], чтобы мы могли использовать его позже
printf("%s", pInfo[playerid][Password]); //Дополнительно: только для отладки. Если он не показывал свой пароль, то должно быть что-то неправильно при получении пароля игрока
ShowPlayerDialog(playerid, dlogin, DIALOG_STYLE_INPUT, "авторизация", "Для того чтобы начать игру, необходимо авторизоваться", "Вход", "Выйти"); //И так как мы обнаружили, в результате из базы данных, что означает, происходит расчет; мы показываем диалог входа
}
else //если мы не нашли каких-либо строк из базы данных, что означает, никакие учетные записи не были найдены
{
ShowPlayerDialog(playerid, dregister, DIALOG_STYLE_INPUT, "регистрация", "Для того, чтобы начать игру, Вам необходимо зарегистрироваться.", "регистрация", "Выйти");
//Так мы покажем им диалоговое окно register
}
return 1;
}

forward OnAccountLoad(playerid);
forward OnAccountRegister(playerid);
public OnAccountLoad(playerid)
{
pInfo[playerid][Admin] = cache_get_field_content_int(0, "Admin"); //мы получаем поле 4 ряда 0. И так как это целое число, мы используем cache_get_row_int
pInfo[playerid][VIP] = cache_get_field_content_int(0, "VIP"); //Выше
pInfo[playerid][Money] = cache_get_field_content_int(0, "Money");//Выше
pInfo[playerid][posX] = cache_get_field_content_float(0, "PosX");//С позиции игрока-это float, мы используем cache_get_field_content_float
pInfo[playerid][posY] = cache_get_field_content_float(0, "PosY");//Выше
pInfo[playerid][posZ] = cache_get_field_content_float(0, "PosZ");//Выше

GivePlayerMoney(playerid, pInfo[playerid][Money]);//Установим свои деньги
SendClientMessage(playerid, -1, "Успешный вход!"); //скажите им, что они успешно вошли в
return 1;
}

public OnAccountRegister(playerid)
{
pInfo[playerid][ID] = cache_insert_id(); //загружает ID игрока в переменную, после того, как они зарегистрированы.
printf("New account registered. ID: %d", pInfo[playerid][ID]); //просто для отладки.
return 1;
}
В public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[]):

switch(dialogid)
{
case dlogin: //диалоговое окно входа в систему
{
if(!response) return Kick(playerid); //если нажали выйти, мы будем кикать их
new hpass[129]; //для хэширования паролей
new query[100]; // для форматирования нашего запроса
WP_Hash(hpass, 129, inputtext); //хеширования inputtext
if(!strcmp(hpass, pInfo[playerid][Password])) //помните, мы загрузили пароля игрока, в эту переменную, pInfo[playerid][Password] ранее. Теперь давайте используем ее, чтобы сравнить хэш пароля с паролем, который мы загружаем
{//если хэшированный пароль совпадает с загруженным пароль от базы данных
mysql_format(mysql, query, sizeof(query), "SELECT * FROM `players` WHERE `Username` = '%e' LIMIT 1", Name[playerid]);
//давайте формате запрос
//Выбираем все строки в таблице, которая имеет свое имя и ограничьте результат 1
mysql_tquery(mysql, query, "OnAccountLoad", "i", playerid);
//позволяет выполнить форматированный запрос и при исполнении сделано, обратного вызова OnAccountLoad будет называться
//Вы можете назвать обратного вызова как вам нравится
}
else //если хэшированный пароль не совпадает с загруженным пароль(pInfo[playerid][Password])
{
//мы говорим им, что они вставили неправильный пароль
ShowPlayerDialog(playerid, dlogin, DIALOG_STYLE_INPUT, "авторизация", "Чтобы начать игру необходимо вести пароль", "Вход", "Выйти");
}
}
case dregister: //диалоговое окно регистрации
{
if(!response) return Kick(playerid); //если нажали выйти, мы будем кикать их
if(strlen(inputtext) < 6) return ShowPlayerDialog(playerid, dregister, DIALOG_STYLE_INPUT, "регистрация", "Для того, чтобы играть, Вам необходимо зарегистрироваться.\nваш пароль должен быть не менее 6 символов!", "регистрация", "Выйти");
//strlen проверяет длину строки. так что если игрок вводит свой пароль, который ниже, чем 6, и мы говорим им; пароль должен содержать не менее 6 символов!
new query[300];
WP_Hash(pInfo[playerid][Password], 129, inputtext); //хеширования inputtext
mysql_format(mysql, query, sizeof(query), "INSERT INTO `players` (`Username`, `Password`, `IP`, `Admin`, `VIP`, `Money`, `PosX` ,`PosY`, `PosZ`) VALUES ('%e', '%s', '%s', 0, 0, 0, 0.0, 0.0, 0.0)", Name[playerid], pInfo[playerid][Password], IP[playerid]);
//Теперь создадим новую строку и вставить игрока информация в нем
mysql_tquery(mysql, query, "OnAccountRegister", "i", playerid);
//выполним запрос
}
}
В public OnPlayerDisconnect(playerid, reason):

new query[128], Float:pos[3]; //query[128] для форматирования наш запрос и Float:pos[3] Для получения и сохранения позиции игрока
GetPlayerPos(playerid, pos[0], pos[1], pos[2]); //Let's get позиции игрока, когда они покидают сервер
mysql_format(mysql, query, sizeof(query), "UPDATE `players` SET `Admin`=%d, `VIP`=%d, `Money`=%d, `posX`=%f, `posY`=%f, `posZ`=%f WHERE `ID`=%d",\
pInfo[playerid][Admin], pInfo[playerid][VIP], pInfo[playerid][Money], pos[0], pos[1], pos[2], pInfo[playerid][ID]);
//Обновляем таблицу ("игроков"), получив игрока на уровне администратора, vip-уровень, деньги, и должности, и сохранять их в базу данных
mysql_tquery(mysql, query, "", "");
//выполним запрос.
В public OnPlayerSpawn(playerid):

SetPlayerPos(playerid, pInfo[playerid][posX], pInfo[playerid][posY], pInfo[playerid][posZ]);
//Установка позиции игрока к последней сохраненной позиции.
Оригинал: Просмотреть (http://forum.sa-mp.com/showthread.php?t=485633)

L0ndl3m
10.07.2014, 14:09
SetPlayerPos(playerid, pInfo[playerid][posX], pInfo[playerid][posZ], pInfo[playerid][posZ]);

Nurick
10.07.2014, 14:17
SetPlayerPos(playerid, pInfo[playerid][posX], pInfo[playerid][posZ], pInfo[playerid][posZ]);
Исправил