Доступ к архиву

Переход в группу "Пользователь"

300.00 ₽
Одноразовый платёж
Быстрый переход в группу "Пользователи", без надобности написания постов и ожидания.

Покупка дает возможность:
Быть полноправным участником форума
Нормальное копирование кода
Создавать темы
Скачивать файлы
Доступ к архиву Pawno-Info

Создание системы регистрации с Диалогом

Статус
В этой теме нельзя размещать новые ответы.

sasa50

Умник
Итак, для этого грязного мы будем использовать:
1. Denwer - через эту программу мы будем запускать и администрировать SQL сервер.
Скачать!
2. MySQL Plugin R6-2 - плагин для работы с базой данных.
Это кинуть в папку Plugins
Это кинуть в папку с сервером + в server.cfg добавить строку plugins mysql sscanf
Это кинуть в папку Pawno\Includes
3. Sscanf Plugin - плагин, при помощи которого нам будет удобней и быстрей извлекать данные из результата при выборке из таблицы.
Скачать!

Начнём.
> Устанавливаем Denwer, запускаем сервер (на рабочем столе будет ярлык "Start Denwer").
> Заходим в браузер и в адресной строке вводим "localhost" (без кавычек).
> Спускаемся ниже и переходим по ссылке:
> Итак, вы видите 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...).

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

>> Сверху мода, где вы подключаете все инкдюлы добавляем эти строки:
PHP:
#include <a_mysql> // SQL функции.
#include <sscanf2> // Извлечение данных.
>> Чуть ниже задефайним парметры БД:
#define SQL_HOST "localhost" // IP адресс БД.
#define SQL_USER "root" // Login БД.
#define SQL_DB "pawno" // Название БД.
#define SQL_PASS "" // Пароль БД.[/code]
Дефайны для ID'ов диалогов и цвета сообщений.
PHP:
#define DIALOG_LOGIN         1
#define DIALOG_REGISTER     2
#define DIALOG_WRONGPAS     3
#define COLOR_LIGHTRED         0xFF6347AA
>> Создадим массив для хранения данных аккаунта.
PHP:
enum Variables {
     aID,
     aName[MAX_PLAYER_NAME],
     aPassword[64],
     bool: aLogged,
     aWrongPassword,
};
new playerVariable[100][Variables]; // 100 - моё кол-во слотов для игроков на сервере.
Создадим сток для подключения и отключения к БД.
PHP:
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;
}
Тут у нас стоки для регистрации и логина.
PHP:
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;
}
Создадим сток для очистки массивов при коннекте/дисконнекте.
PHP:
stock RemovePlayerVariables(playerid) {
     playerVariable[playerid][aWrongPassword] = 0;
     playerVariable[playerid][aID] = 0;
     playerVariable[playerid][aLogged] = false;
     return 1;
}
Наши диалоги:
PHP:
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://s24.ucoz.net/sm/23/smile.gif" border="0" align="absmiddle" alt="smile" />
         }
         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;
} [
Отключаем возможность писать в чат неавторизованному.
PHP:
public OnPlayerText(playerid, text[])
{
     if(playerVariable[playerid][aLogged] == false) return 0;
     return 1;
}
наш OnPlayerConnect
PHP:
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;
}
Всё ставьте + если помог
 
Статус
В этой теме нельзя размещать новые ответы.
Сверху Снизу