Сегодня, я научу вас, как сделать систему регистрации с использованием MySQL. В этом уроке, мы сохраним имя игрока, пароль, IP, уровень администратора, уровень VIP, деньги и положение игрока.
То, что вам нужно
- MySQL плагин - скачать и поместить файлы в директории вашего сервера.
- Whirlpool - Скачать его и поместить файл в директории вашего сервера.
- XAMPP - скачать и установить его в вашем ПК.
Создание новой базы данных:
- Запустить XAMPP-контроль, и вы должны увидеть:

- Нажмите кнопку Пуск на Apache и MySQL. Если у вас открыт скайп, закройте его.

- Выберите Администратор в MySQL для управления / создания базы данных.

- Нажмите на базах данных, чтобы создать новую базу данных.

- Назовите вашу базу данных сервера и нажмите кнопку Создать (В этом уроке будет использовать "server", как наша база)

Начнем скриптинг!
Code: Select all
// Во-первых, конечно, мы должны включить эти файлы
#include <a_samp> //Without this, we won't be able to use all samp functions/callbacks
#include <a_mysql> //Without this, we won't be able to use all mysql functions
Code: Select all
// Давайте определим наши настройки MySQL
#define host "localhost" //This will be your mysql host. Default for xampp is localhost
#define user "root" //This will be your mysql username. Default for xampp is root
#define db "server" //This is your database name. Remember we have created a database called server before.
#define pass "" //This is your mysql password. In xampp, the password didn't set. So leave it empty
Code: Select all
//Глобальные переменные. Мы будем использовать их позже
static
mysql, //Эта переменная будет использоваться для управления в нашей базе данных
Name[MAX_PLAYERS][24 char], //Мы будем использовать эту переменную для хранения имя игрока.
IP[MAX_PLAYERS][16 char] //Мы будем использовать эту переменную для хранения ip игрока.
;
Code: Select all
native WP_Hash(buffer[], len, const str[]); //для хеширования нашего пароля
Code: Select all
//Теперь давайте создадим enum, который содержит информацию игрока
enum PDATA //Мы называем наш enum как PDATA (которая выступает за PlayerDATA). Вы можете назвать его как хотите.
{
ID, //Будет использоваться позже для хранения ID игрока из базы данных, чтобы мы могли использовать его позже, в любом месте
Password[129], //Мы будем загружать пароль игрока в эту varible из базы данных.
Admin, //Мы будем загружать уровень администратора игрока из базы данных в эту переменную, чтобы мы могли использовать его позже в любом месте.
VIP, //Мы будем загружать VIP уровень игрока из базы данных в эту переменную, чтобы мы могли использовать его позже, в любом месте.
Money, //Мы будем загружать деньги игрока из базы данных в эту переменную, чтобы мы могли использовать его позже, в любом месте.
Float:posX, //Мы будем загружать X позицию игрока из базы данных в эту переменную, чтобы мы могли использовать его позже, в любом месте.
Float:posY, //Мы будем загружать Y позицию игрока из базы данных в эту переменную, чтобы мы могли использовать его позже, в любом месте.
Float:posZ //Мы будем загружать Z позицию игрока из базы данных в эту переменную, чтобы мы могли использовать его позже, в любом месте.
}
new pInfo[MAX_PLAYERS][PDATA]; //Переменная, которая хранит enum выше
Code: Select all
public OnGameModeInit()
{
mysql_debug(1); //Давайте включим отладку, чтобы мы могли обнаружить проблему (если есть)
mysql = mysql_connect(host, user, db, pass); //Эта функция будет подключить сервер к базе данных. Помните, что мы определили наш хост, имя пользователя базы данных и пароль. Пора использовать его здесь.
if(mysql_errno(mysql) != 0) print("Не удалось подключиться к базе данных!"); //Это покажет, если подключение к базе данных является успешным или нет. Если это не так, проверьте ваш хост, имя пользователя базы данных и пароль. Убедитесь, что все они верны.
//Если всё хорошо, пришло время, чтобы создать таблицу для вашей базы данных.
mysql_tquery(mysql, "CREATE TABLE IF NOT EXISTS `players`(\
`ID` int(10) NOT NULL AUTO_INCREMENT, \
`Username` varchar(24) NOT NULL, \
`Password` varchar(129) NOT NULL, \
`IP` varchar(16) NOT NULL, \
`Admin` int(10) NOT NULL, \
`VIP` int(10) NOT NULL, \
`Money` int(10) NOT NULL, \
`posX` float NOT NULL, \
`posY` float NOT NULL, \
`posZ` float NOT NULL, \
PRIMARY KEY (`ID`))", "", "");
/*Мы будем использовать mysql_tquery для выполнения запроса
Мы создаем таблицу с именем `players`.
`ID` int(10) NOT NULL AUTO_INCREMENT, = Мы создаем столбец внутри таблицы под названием ID и она должна быть внутр с ID является целым числом . NOT NULL означает, что столбец не должен быть пустым (например, не вставляя значение в него ) . AUTO_INCREMENT , он автоматически генерирует новый идентификатор регистров каждый игрок (1,2,3,4 ... и так далее )
`Username` varchar(24) NOT NULL, = Мы создаем столбец внутри таблицы под названием Имя пользователя . Он будет использоваться для хранения имени игрока в нем и так имя игрока является строкой, мы должны использовать varchar
`Password` varchar(129) NOT NULL, = То же самое
`IP` varchar(16) NOT NULL, = То же самое
`Admin` int(10) NOT NULL, = То же самое
`VIP` int(10) NOT NULL, = То же самое
`Money` int(10) NOT NULL, = То же самое
`posX` float NOT NULL, = POSX является X позиция игрока. Так должно быть float
`posY` float NOT NULL, = То же самое
`posZ` float NOT NULL, = То же самое
"", ""); = Выходим это 2 параметров ( обратный вызов [] и формат [] ) пустые , потому что мы только понадобится , если мы используем ВЫБОР
*/
return 1;
}
Code: Select all
//Расчетный счет игрока, если они зарегистрированы или нет.
public OnPlayerConnect(playerid)
{
new query[128]; //Мы используем эту переменную для форматирования нашего запроса
GetPlayerName(playerid, Name[playerid], 24); //Получение имя игрока
GetPlayerIp(playerid, IP[playerid], 16); //Получение IP
mysql_format(mysql, query, sizeof(query),"SELECT * FROM `players` WHERE `Username` = '%e' LIMIT 1", Name[playerid]);
// - Мы используем mysql_format вместо формате, потому что мы можем использовать% E спецификатор. % е спецификатор убегает строку, чтобы мы могли избежать SQL-инъекция, которая означает, что мы не должны использовать mysql_real_escape_string
// - Форматирование наш запрос; SELECT * FROM `игроки` WHERE `Имя пользователя` = '% е' означает, что мы выбора всех строк в таблице под названием `игроки`, который имеет свое имя в Логин колонке
// - LIMIT 1, нам нужно 1 результат только в данном периоде
mysql_tquery (MySQL, запрос, "OnAccountCheck", "я", PlayerID);
// позволяет выполнять форматированный запрос и когда выполнение будет сделано, обратного вызова OnAccountCheck будет называться
// Вы можете назвать обратный вызов, как вам нравится
return 1;
}
Code: Select all
//OnAccountCheck обычай обратного вызова, который означает, что он должен быть направлен.
forward OnAccountCheck(playerid);
//Теперь, как только запрос был обработан;
public OnAccountCheck(playerid)
{
new rows, fields; //переменная, которая будет использоваться для получения строк и поля в базе данных.
cache_get_data(rows, fields, mysql);//давайте строки и поля из базы данных.
if(rows) //если есть строка
{//затем
cache_get_row(0, 2, pInfo[playerid][Password], mysql, 129);
//мы будем загружать свои пароли в pInfo[playerid][Password] для использования в регистрации
//0 ряд, 2 поля. Если вам интересно, почему строка 0, помните, мы использовали лимит 1 в то время как текущий счет игрока. LIMIT ограничение результатов и требовалось доказать. Так как мы использовали лимит 1, это было бы как
// ---> row> ID | Username | Password | IP | Admin | .... and so on
// ^ ^ ^
// fields 0 1 2
//So we're getting row 0, field 2 which is password
pInfo[playerid][ID] = cache_get_row_int(0, 0); //Теперь давайте загрузим ID игрока в pInfo [PlayerID] [ID], чтобы мы могли использовать его позже
printf("%s", pInfo[playerid][Password]); //OPTIONAL: Просто для отладки. Если он не показал свой пароль, то должно быть что-то не так при получении пароль игрока
ShowPlayerDialog(playerid, 1, DIALOG_STYLE_INPUT, "Login", "In order to play, you need to login", "Login", "Quit"); //А так как мы нашли результат из базы данных, что означает, есть счет, и покажем, диалог входа
}
else //если мы не нашли ни одной строки из базы данных, это значит, не было найдено счета
{
ShowPlayerDialog(playerid, 2, DIALOG_STYLE_INPUT, "Register", "In order to play, you need to register.", "Register", "Quit");
//Так мы показываем диалоговое регистрации
}
return 1;
}
Code: Select all
//Теперь давайте ответ на Вход и регистрация диалог
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
new query[300];
switch(dialogid)
{
case 1: //login dialog
{
if(!response) Kick(playerid); //если они нажали Quit, мы будем кикать их
new hpass[129]; //для хэширования паролей
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]);
//давайте отформатируем наш запрос
//в очередной раз, мы выбираем все строки в таблице, которая имеет свое имя и ограничить результат
mysql_tquery(mysql, query, "OnAccountLoad", "i", playerid);
//позволяет выполнять форматированный запрос и когда выполнение будет сделано, обратного вызова OnAccountLoad будет называться
//Вы можете назвать обратный вызов, как вам нравится
}
else //если хэш пароля не совпадает с загруженным паролем(pInfo[playerid][Password])
{
//мы говорим им, что они указали неправильный пароль
ShowPlayerDialog(playerid, 1, DIALOG_STYLE_INPUT, "Login", "In order to play, you need to login\nWrong password!", "Login", "Quit");
}
}
case 2: //диалог регистрации
{
if(!response) return Kick(playerid); //если они нажали Quit, мы будем кикать их
if(strlen(inputtext) < 6) return ShowPlayerDialog(playerid, 2, DIALOG_STYLE_INPUT, "Register", "In order to play, you need to register.\nYour password must be at least 6 characters long!", "Register", "Quit");
//STRLEN проверяет длину строки. так что если игрок типа их пароль, что ниже, чем 6, мы говорим им, Ваш пароль должен содержать не менее 6 символов!
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, "", "");
//давайте выполним запрос
}
}
return 1;
}
Code: Select all
forward OnAccountLoad(playerid);
//давайте загрузим информацию игрока
public OnAccountLoad(playerid)
{
// ---> row> ID | Username | Password | IP | Admin | VIP | Money | posX | posY | posZ
// ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
// fields 0 1 2 3 4 5 6 7 8 9
pInfo[playerid][Admin] = cache_get_row_int(0, 4); //ы получаем поле 4 из строки 0. И так как это целое число, мы используем cache_get_row_int
pInfo[playerid][VIP] = cache_get_row_int(0, 5); //выше
pInfo[playerid][Money] = cache_get_row_int(0, 6);//выше
pInfo[playerid][posX] = cache_get_row_float(0, 7);//выше. С позиции игрока является float, мы используем cache_get_row_float
pInfo[playerid][posY] = cache_get_row_float(0, 8);//выше
pInfo[playerid][posZ] = cache_get_row_float(0, 9);//выше
GivePlayerMoney(playerid, pInfo[playerid][Money]);//Давайте установим свои деньги
//Для позиции игрока, установите его, как только они spawn(OnPlayerSpawn)
SendClientMessage(playerid, -1, "Successful logged in"); //сказать им, что они успешно вошли в систему
return 1;
}
Code: Select all
public OnPlayerDisconnect(playerid, reason)
{
new query[128], Float:pos[3]; //query[128] является для форматирования наш запрос и Float: POS [3] для получения и сохранения позиции игрока
GetPlayerPos(playerid, pos[0], pos[1], pos[2]); //давайте позицию игрока, когда они покидают свой сервер
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]);
//Мы обновляем таблицу (`players`), получив уровень игрока администратора, уровень VIP, деньги, и позиции и сохранять их в базе данных
mysql_tquery(mysql, query, "", "");
//let's execute the query.
return 1;
}