Форум Pawn-Wiki.Ru - Воплоти мечту в реальность!: Создание системы регистрации - Форум Pawn-Wiki.Ru - Воплоти мечту в реальность!

Перейти к содержимому

  • (17 Страниц) +
  • 1
  • 2
  • 3
  • Последняя »
  • Вы не можете создать новую тему
  • Вы не можете ответить в тему

[ Урок ]
Создание системы регистрации MySQL
Оценка: ****- 6 Голосов

#1
Пользователь офлайн   Romzes 

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

Итак, для этого грязного мы будем использовать:
  • Denwer - через эту программу мы будем запускать и администрировать SQL сервер.
    Скачать!
  • MySQL Plugin R6-2 - плагин для работы с базой данных.
    plugin-R6_2-win32_vs9.rar [497,24К]
  • 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;
}

stock DisconnectMySQL() { // Вставьте DisconnectMySQL(); в OnGameModeExit, отключаемся от БД.
	mysql_close();
	print("MySQL connection closed.");
}

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;
}

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\
					Этот аккаунт зарегистрирован.\n\n\
					Логин: %s\n\
					Введите пароль:",
		 			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\
				    Этот аккаунт не зарегистрирован.\n\n\
				    Логин: %s\n\
					Введите пароль и нажмите \"Далее\".\n\n\
			  		Примечания:\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; // Авторизуем игрока. <img src='http://pawn-wiki.ru/public/style_emoticons/<#EMO_DIR#>/smile.gif'
 class='bbc_emoticon' alt=':)' />
		}
		case DIALOG_WRONGPAS: { // Если неверный пароль.
			if(response) {
				new dialog[134+MAX_PLAYER_NAME];
				format(dialog, sizeof(dialog),
					"Добро пожаловать на Сервер!\n\
					Этот аккаунт зарегистрирован.\n\n\
					Логин: %s\n\
					Введите пароль:",
					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\
			Этот аккаунт зарегистрирован.\n\n\
			Логин: %s\n\
			Введите пароль:",
 			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\
		    Этот аккаунт не зарегистрирован.\n\n\
		    Логин: %s\n\
			Введите пароль и нажмите \"Далее\".\n\n\
	  		Примечания:\n\
			- Пароль чувствительный к регистру.\n\
		    - Длина пароля от 6 до 32 символов.\n\
		    - В пароле можно использовать символы на кириллице и латинице.\n", playerVariable[playerid][aName]);
		ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_INPUT, "Регистрация.", dialog, "Далее", "Отмена");
	}
	return 1;
}

Готово, у нас есть система регистрации.
Вот так выглядит таблица с аккаунтами:
Изображение

Автор урока: Snoowker.

Сообщение отредактировал Romzes: 13 Июнь 2017 - 03:54
Причина редактирования: Перезалил ссылку на плагин

11

#2
Пользователь офлайн   cr1me 

  • Прохожий
  • Вставить ник
  • Раскрыть информацию
Здравствуйте! Сразу предупреждаю, в Pawn работаю не так давно. Написал всё по вашему уроку, но вот при компиляции выдаёт множество ошибок...

D:\Games\GTA Criminal Russia\RolePlay\gamemodes\Rega.pwn(75) : error 017: undefined symbol "RemovePlayerVariables"
D:\Games\GTA Criminal Russia\RolePlay\gamemodes\Rega.pwn(76) : warning 217: loose indentation
D:\Games\GTA Criminal Russia\RolePlay\gamemodes\Rega.pwn(76) : error 017: undefined symbol "playerVariable"
D:\Games\GTA Criminal Russia\RolePlay\gamemodes\Rega.pwn(76) : warning 215: expression has no effect
D:\Games\GTA Criminal Russia\RolePlay\gamemodes\Rega.pwn(76) : error 001: expected token: ";", but found "]"
D:\Games\GTA Criminal Russia\RolePlay\gamemodes\Rega.pwn(76) : error 029: invalid expression, assumed zero
D:\Games\GTA Criminal Russia\RolePlay\gamemodes\Rega.pwn(76) : fatal error 107: too many error messages on one line



А вот то, что у меня получилось мод...
Помогите пожалуйста!
0

#3
Пользователь офлайн   n0rze 

  • Новичок
  • Вставить ник
  • Раскрыть информацию
Скачать|кликабельно

таблицу сам создаш.

Сообщение отредактировал n0rze: 26 Май 2012 - 07:28

1

#4
Пользователь офлайн   KoTe 

  • Местный
  • Вставить ник
  • Раскрыть информацию
импортируйте базу и кинте ему + не тестил
0

#5
Пользователь офлайн   Snoowker 

  • Прохожий
  • Вставить ник
  • Раскрыть информацию

Просмотр сообщенияn0rze (26 Май 2012 - 07:28) писал:

Скачать|кликабельно

таблицу сам создаш.



Просмотр сообщенияKoTe (26 Май 2012 - 13:06) писал:

импортируйте базу и кинте ему + не тестил

Нахрена просить готовое? На то урок и написан, чтобы постепенно вставляли код и обучались хоть как-то. Если копирование идёт в виде «скопирую, вставлю и подгоню» — знаний никогда не будет и всегда будешь ныть на форумах с ошибками и писать быдлокод в РЛС-подобных модах.
0

#6
Пользователь офлайн   VitaliyPRO 

  • Новичок
  • Вставить ник
  • Раскрыть информацию
Ураааа! Получилось, спасибо автору...
Были ошибки, но немножко усердия, и вуаля! ;) ;) ;)

#7
Пользователь офлайн   Pacman 

  • Пользователь
  • Вставить ник
  • Раскрыть информацию
У меня не сохраняются данные о акке что делать?*
0

#8
Пользователь офлайн   VitaliyPRO 

  • Новичок
  • Вставить ник
  • Раскрыть информацию

Просмотр сообщенияPacman (04 Август 2012 - 11:31) писал:

У меня не сохраняются данные о акке что делать?*

Saveall

#9
Пользователь офлайн   GranD 

  • Прохожий
  • Вставить ник
  • Раскрыть информацию
C:\Documents and Settings\Bulla\Рабочий стол\ПАВНО\gamemodes\gf.pwn(3) : fatal error 100: cannot read from file: "a_mysql"

Compilation aborted.Pawn compiler 3.2.3664	 	 	Copyright (c) 1997-2006, ITB CompuPhase


1 Error.


Помогите, в чём дело?
Инклуд стоит!

Сообщение отредактировал GranD: 07 Сентябрь 2012 - 06:14

0

#10
Пользователь офлайн   Rock & Roll 

  • Эксперт
  • Вставить ник
  • Раскрыть информацию

Просмотр сообщенияGranD (07 Сентябрь 2012 - 06:13) писал:

C:\Documents and Settings\Bulla\Рабочий стол\ПАВНО\gamemodes\gf.pwn(3) : fatal error 100: cannot read from file: "a_mysql"

Compilation aborted.Pawn compiler 3.2.3664          	Copyright (c) 1997-2006, ITB CompuPhase


1 Error.


Помогите, в чём дело?
Инклуд стоит!


Открывай павно, в котором есть мускул. А только потом мод.
0

Поделиться темой:


  • (17 Страниц) +
  • 1
  • 2
  • 3
  • Последняя »
  • Вы не можете создать новую тему
  • Вы не можете ответить в тему

1 человек читают эту тему
0 пользователей, 1 гостей, 0 скрытых пользователей