MySQL Система регистрации [Каскадный Запросы (R33 +) + Whirlpool]

Описание: Уроки по скриптингу
Модератор: SJplayer

SJplayer M
Автор темы, Модератор
Модератор
Аватара
SJplayer M
Автор темы, Модератор
Модератор
Сообщения: 196
Зарегистрирован: 25 мая 2013
С нами: 10 лет 10 месяцев

#1 SJplayer » 6 января 2014, 13:31

Автор: newbienoob
Сегодня, я научу вас, как сделать систему регистрации с использованием MySQL. В этом уроке, мы сохраним имя игрока, пароль, IP, уровень администратора, уровень VIP, деньги и положение игрока.

То, что вам нужно

- MySQL плагин - скачать и поместить файлы в директории вашего сервера.
- Whirlpool - Скачать его и поместить файл в директории вашего сервера.
- XAMPP - скачать и установить его в вашем ПК.

Создание новой базы данных:
- Запустить XAMPP-контроль, и вы должны увидеть:
Изображение

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

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

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

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

Начнем скриптинг!

Код: Выделить всё

// Во-первых, конечно, мы должны включить эти файлы
#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    


Код: Выделить всё

// Давайте определим наши настройки 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    


Код: Выделить всё

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


Код: Выделить всё

native WP_Hash(buffer[], len, const str[]); //для хеширования нашего пароля    


Код: Выделить всё

//Теперь давайте создадим 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 выше    


Код: Выделить всё

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


Код: Выделить всё

//Расчетный счет игрока, если они зарегистрированы или нет.
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;
}


Код: Выделить всё

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


Код: Выделить всё

//Теперь давайте ответ на Вход и регистрация диалог
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;
}


Код: Выделить всё

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


Код: Выделить всё

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


  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Уроки»

Кто сейчас на форуме (по активности за 5 минут)

Сейчас этот раздел просматривают: 2 гостя