Перейти к содержанию
Авторизация  
#Dmitriy

Создание Системы Регистрации (Mysql )

Рекомендуемые сообщения

#Dmitriy

В этом уроке я вам для примера расскажу, как сделать регистрацию в new.pwn моде и в процессе этого я Вам расскажу, что тут к чему, позже вы сможете использовать полученные знания для других целей, например для разных домов, системы банов, всякой фигни для ГФ мода и так дальше.

 

Итак, для этого грязного мы будем использовать:

1. Denwer - через эту программу мы будем запускать и администрировать SQL сервер.

Скачать

2. MySQL Plugin R6-2 - плагин для работы с базой данных.

Это кинуть в папку Plugins

Это кинуть в папку с сервером + в server.cfg добавить строку plugins mysql sscanf

Это кинуть в папку PawnoIncludes

3. Sscanf Plugin - плагин, при помощи которого нам будет удобней и быстрей извлекать данные из результата при выборке из таблицы.

Скачать!

 

Начнём.

> Устанавливаем Denwer, запускаем сервер (на рабочем столе будет ярлык "Start Denwer").

> Заходим в браузер и в адресной строке вводим "localhost" (без кавычек).

> Спускаемся ниже и переходим по ссылке: http://localhost/Too...admin/index.php

> Итак, вы видите phpmyadmin, сейчас мы можем управлять базой данных.

> Создаём таблицу:

>> Там примерно в центре есть "Create new database".

>>> Я назвал свою БД "pawno", кодировку выбрал "cp1251_bin".

Изображение

>>> БД создана

Изображение

>>>> Теперь нам нужно создать таблицу для аккаунтов.

Изображение

Name - Название таблицы, Number of Fields - количество полей.

Мы используем 3 поля,

1 - ID аккаунта, чтобы можно было его распознать в таблице, можно, конечно использовать ник, но с ИД удобней;

2 - Ник игрока, думаю тут всё ясно.

3 - Пароль игрока.

>>>> Таблица создана, сейчас мы настроим наши поля.

Изображение

Нажимаем Save.

Все нужное я выделил красным, теперь расскажу, что за что отвечает.

Field - название поля;

Type - тип данных, есть integer, string (VARCHAR, TEXT), float, DATE, DATETIME, TIME и т.д., в общем как в павно, тут я использую VARCHAR для стринга, и INT для ID.

Length/Values - сколько "ячеек" мы выделяем для поля, для ника 24 (MAX_PLAYER_NAME), для пароля - 64.

Collation - кодировка.

AUTO_INCREMENT - генерирует значения для ID игрока в порядке возрастания (1, 2, 3...).

 

>>>> Так будет выглядеть пустая, без аккаунтов таблица:

Изображение

> Базу данных и таблицу мы подготовили, теперь перейдем к моду.

 

>> Сверху мода, где вы подключаете все инкдюлы добавляем эти строки:

#include <a_mysql> // SQL функции.
#include <sscanf2> // Извлечение данных.

>> Чуть ниже задефайним парметры БД:

#define SQL_HOST	 "localhost" // IP адресс БД.
#define SQL_USER	 "root" // Login БД.
#define SQL_DB		 "pawno" // Название БД.		
#define SQL_PASS	 "" // Пароль БД.
>> Дефайны для ID'ов диалогов и цвета сообщений.

#define DIALOG_LOGIN		 1
#define DIALOG_REGISTER		 2
#define DIALOG_WRONGPAS	 3
#define COLOR_LIGHTRED		 0xFF6347AA
#define COLOR_YELLOW		 0xFFFF00AA

>> Создадим массив для хранения данных аккаунта.

enum Variables {
	 aID,
	 aName[MAX_PLAYER_NAME],
	 aPassword[64],
	 bool: aLogged,
	 aWrongPassword,
};
new playerVariable[100][Variables]; // 100 - моё кол-во слотов для игроков на сервере.

>> Создадим сток для подключения и отключения к БД.

stock ConnectMySQL() { // В OnGameModeInIt вставьте ConnectMySQL();
mysql_connect(SQL_HOST, SQL_USER, SQL_DB, SQL_PASS); // Тут мы используем все данные, которые мы дефайнили.
switch(mysql_ping()) { // Проверка на то, что мы подключены к БД.
			 case 1: print("MySQL connection: alive."); // Если подключена БД.
			 case -1: print("MySQL connection: dead."); // Если не подключена БД.
	 }
	 return 1;
}[/background][/size][/font][/color]
[color=#1C2837][font=tahoma, arial, verdana, sans-serif][size=3][background=rgb(251, 253, 254)]stock DisconnectMySQL() { // Вставьте DisconnectMySQL(); в OnGameModeExit, отключаемся от БД.
	 mysql_close();
	 print("MySQL connection closed.");
}[/background][/size][/font][/color]
[color=#1C2837][font=tahoma, arial, verdana, sans-serif][size=3][background=rgb(251, 253, 254)]stock CheckMySQLConnection() { // Этот сток мы будем использовать для проверки, подключена ли БД перед её использованием.
	 if(mysql_ping() == -1) mysql_reconnect();
	 return 1;
}

>> Тут у нас стоки для регистрации и логина.

stock CreateAccount(playerid, password[]) {
	 new
		 query[128], // Для запроса.
			 sqlname[MAX_PLAYER_NAME],
		 sqlpassword[32];
	 mysql_real_escape_string(playerVariable[playerid][aName], sqlname); // Защитит от sql inject
	 mysql_real_escape_string(password, sqlpassword); // Защитит от sql inject
	 format(query, sizeof(query), "INSERT INTO `Accounts` (`Nickname`, `Password`) VALUE ('%s', '%s')", sqlname, sqlpassword); // Добавляем в таблицу запись.
	 // INSERT - добавление записи в таблицу, 1. () - поля. 2. VALUE - значения этих полей.
	 mysql_query(query); // Отправляем запрос.
GetAccountID(playerid); // Узнаём ИД аккаунта, будет использоваться для сохранения и прочих операций.
strmid(playerVariable[playerid][aPassword], password, 0, 64, 255); // Внедряем в массив аккаунта введенный игроком пароль.
	 playerVariable[playerid][aLogged] = true; // Мы авторизованы.
	 return 1;
}
stock LoadAccount(playerid, password[]) {
	 new
			 query[128],
			 sqlpass[32],
			 result[5+24+64],
			 dialog[128];
	 mysql_real_escape_string(password, sqlpass); // Защита от SQL Inject, шифрует кодировку.
	 format(query, sizeof(query), "SELECT * FROM `Accounts` WHERE `Password` = '%s' AND `ID` = '%i'", sqlpass, playerVariable[playerid][aID]);
	 // SELECT * - выбрать, FROM - с таблицы, WHERE - где, пароль равен введенному паролю и ID равен иду ника человека.
	 mysql_query(query); // Отправляем запрос.
	 mysql_store_result(); // Смотрим записи, которые мы выбрали запросом выше.
	 if(mysql_num_rows() == 1) { // Если выбрало только 1 аккаунт с таким паролем и ИД - успех, пароль введен верно, загружаем данные в массив.
	 mysql_fetch_row_format(result, "|"); // split, данные в результате записываются типо "1|Snoowker|parol"
	 sscanf(result, "p<|>is[24]s[32]", // i - ид (int), s[размер] - string, ник и пароль.
					 playerVariable[playerid][aID],
					 playerVariable[playerid][aName],
					 playerVariable[playerid][aPassword]);
			 playerVariable[playerid][aLogged] = true;
			 mysql_free_result(); // Очищаем память.
			 return 1;
	 }
	 else { // Мы ввели неверный пароль.
		 if(playerVariable[playerid][aWrongPassword] == 4) {
					 SendClientMessage(playerid, COLOR_LIGHTRED, "Вы 3 раза ввели неверный пароль и были отключены от сервера.");
					 Kick(playerid);
					 return 1;
			 }
			 format(dialog, sizeof(dialog),
					 "Вы ввели неверный пароль.n
					 У Вас осталось %i/3 попыток ввода.", 3 - playerVariable[playerid][aWrongPassword]);
			 ShowPlayerDialog(playerid, DIALOG_WRONGPAS, DIALOG_STYLE_MSGBOX, "Ошибка.", dialog, "Повтор", "Отмена");
	 }
	 return 1;
}
stock GetAccountID(playerid) {
	 new
			 query[128];
	 format(query, sizeof(query),"SELECT `ID` FROM `Accounts` WHERE `Nickname` = '%s'", playerVariable[playerid][aName]);
	 // Выбираем ID, с таблицы Accounts, где Ник равен нику игрока.
	 mysql_query(query); // Отправляем запрос.
	 mysql_store_result(); // Видим
	 if(mysql_num_rows() == 1) { // Если у нас в результате выбрало 1 запись, т.е. аккаунт игрока.
			 playerVariable[playerid][aID] = mysql_fetch_int(); // ИД игрока равен номеру записи.
			 mysql_free_result(); // Очищаем память.
			 return playerVariable[playerid][aID]; // Возвращаем ИД игрока.
	 }
	 return 0;
}[/background][/size][/font][/color]
[color=#1C2837][font=tahoma, arial, verdana, sans-serif][size=3][background=rgb(251, 253, 254)]stock SaveAccount(playerid) { // Сохранение аккаунта.
	 if(playerVariable[playerid][aLogged] == true) { // Проверка, если аккаунт авторизован.
		 CheckMySQLConnection(); // Проверяем, подключена ли БД.
			 new
					 query[186],
					 sqlname[MAX_PLAYER_NAME],
					 sqlpass[64];
			 mysql_real_escape_string(playerVariable[playerid][aName], sqlname);
			 mysql_real_escape_string(playerVariable[playerid][aPassword], sqlpass);
			 format(query, sizeof(query), "UPDATE `Accounts` SET `Nickname` = '%s', `Password` = '%s' WHERE `ID` = '%i'", sqlname, sqlpass, playerVariable[playerid][aID]);
			 mysql_query(query); // Отправляем запрос
	 }
	 return 1;
}

Создадим сток для очистки массивов при коннекте/дисконнекте.

stock RemovePlayerVariables(playerid) {
	 playerVariable[playerid][aWrongPassword] = 0;
	 playerVariable[playerid][aID] = 0;
	 playerVariable[playerid][aLogged] = false;
	 return 1;
}

Наши диалоги:

public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[]) {
	 switch(dialogid) {
			 case DIALOG_LOGIN: { // Диалог авторизации.
				 if(!response) { // Если нажал "Отмена".
							 SendClientMessage(playerid, COLOR_YELLOW, "* Введите /q(uit), чтобы выйти из игры.");
							 Kick(playerid);
							 return 1;
					 }
				 if(!strlen(inputtext)) { // Если поле ввода пустое.
					 new dialog[134+MAX_PLAYER_NAME];
						 format(dialog, sizeof(dialog),
									 "Добро пожаловать на Сервер!n
									 Этот аккаунт зарегистрирован.nn
									 Логин: %sn
									 Введите пароль:",
									 playerVariable[playerid][aName]);
							 ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_INPUT, "Авторизация.", dialog, "Войти", "Отмена");
							 return 1;
					 }
					 LoadAccount(playerid, inputtext); // Пробуем его авторизовать.
			 }
			 case DIALOG_REGISTER: { // Диалог регистрации.
				 if(!response) { // Если нажал "Отмена".
							 SendClientMessage(playerid, COLOR_YELLOW, "* Введите /q(uit), чтобы выйти из игры.");
							 Kick(playerid);
							 return 1;
					 }
					 if(!strlen(inputtext) || strlen(inputtext) < 6 || strlen(inputtext) > 64) { // Если пустое поле ввода или пароль имеет меньше 6 или больше 64 символов
							 new dialog[380+24+10];
							 format(dialog, sizeof(dialog),
									 "Добро пожаловать на Сервер!n
								 Этот аккаунт не зарегистрирован.nn
								 Логин: %sn
									 Введите пароль и нажмите "Далее".nn
									 Примечания:n
							 - Пароль чувствительный к регистру.n
								 - Длина пароля от 6 до 32 символов.n
								 - В пароле можно использовать символы на кириллице и латинице.n", playerVariable[playerid][aName]);
							 ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_INPUT, "Регистрация.", dialog, "Далее", "Отмена");
							 return 1;
					 }
					 CreateAccount(playerid, inputtext); // Создаём аккаунт.
					 playerVariable[playerid][aLogged] = true; // Авторизуем игрока.
			 }
			 case DIALOG_WRONGPAS: { // Если неверный пароль.
					 if(response) {
							 new dialog[134+MAX_PLAYER_NAME];
							 format(dialog, sizeof(dialog),
									 "Добро пожаловать на Сервер!n
									 Этот аккаунт зарегистрирован.nn
									 Логин: %sn
									 Введите пароль:",
									 playerVariable[playerid][aName]);
							 ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_INPUT, "Авторизация.", dialog, "Войти", "Отмена");
							 return 1;
					 }
					 else { // Если нажал "Отмена".
							 Kick(playerid);
							 return 1;
					 }
			 }
	 }
	 return 1;
}

>> Отключаем возможность писать в чат неавторизованному.

public OnPlayerText(playerid, text[])
{
	 if(playerVariable[playerid][aLogged] == false) return 0;
	 return 1;
}

>> Наш OnPlayerConnect.

public OnPlayerConnect(playerid)
{
	 RemovePlayerVariables(playerid);
//------------------------------------------------------------------------------
	 GetPlayerName(playerid, playerVariable[playerid][aName], MAX_PLAYER_NAME);
//------------------------------------------------------------------------------
	 if(GetAccountID(playerid)) { // Аккаунт зарегистрирован
			 new dialog[128+MAX_PLAYER_NAME];
			 format(dialog, sizeof(dialog),
					 "Добро пожаловать на Сервер!n
					 Этот аккаунт зарегистрирован.nn
					 Логин: %sn
					 Введите пароль:",
					 playerVariable[playerid][aName]);
			 ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_INPUT, "Авторизация.", dialog, "Войти", "Отмена");
	 }
	 else { // Аккаунт не зарегистрирован (return 0, в функции GetAccountID, т.е. не нашло записи с аккаунтом).
			 new dialog[344+MAX_PLAYER_NAME];
			 format(dialog, sizeof(dialog),
					 "Добро пожаловать на Сервер!n
				 Этот аккаунт не зарегистрирован.nn
				 Логин: %sn
					 Введите пароль и нажмите "Далее".nn
					 Примечания:n
					 - Пароль чувствительный к регистру.n
				 - Длина пароля от 6 до 32 символов.n
				 - В пароле можно использовать символы на кириллице и латинице.n", playerVariable[playerid][aName]);
			 ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_INPUT, "Регистрация.", dialog, "Далее", "Отмена");
	 }
	 return 1;
}

Готово, у нас есть система регистрации.

Вот так выглядит таблица с аккаунтами:

Изображение

 

Автор урока: snoowker

Изменено пользователем Amfy
  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Amfy

Написал настоящего автора!

А Вам Karpov14 выдал второе предупреждение за присвоение авторских прав себе! Повториться в третий раз - пропишу билет в баню.

  • Like 2

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация  

  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу

×

Важная информация

Мы разместили cookie-файлы на ваше устройство, чтобы помочь сделать этот сайт лучше. Вы можете изменить свои настройки cookie-файлов, или продолжить без изменения настроек.