Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.

Реклама


 

**Как получить V.I.P** (Перейти)
Чтобы заказать рекламу на Pro-Pawn.Ru, обращайтесь в Skype.
Баннерная реклама 100руб/мес, Текстовая 50руб/мес.
Страница 1 из 5 123 ... ПоследняяПоследняя
Показано с 1 по 10 из 50
  1. #1
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    2,956
    Репутация:
    1186 ±

    Создание системы регистрации на примере mxINI

    Я вас категорически приветствую, друзья!



    В данном уроке я постараюсь подробно объяснить вам о том, как создать систему регистрации на примере mxINI и затронуть ещё несколько тем.
    Данный урок создан исключительно для новичков.
    Так же хочу заметить, что все уроки я создаю так, как сам понимаю тему урока.
    Если Вы нашли ошибку в каком-либо моём уроке, прошу оповестить меня об этом и я обязательно исправлю её.




    Система регистрации - это не что иное, как привязка файла/столбца к нику игрока и последующая запись в него данных
    А уже что будут содержать эти переменные и как их назвать - дело только Ваше.


    Вообще сначала нужно определится с тем, на какой системе Вы будете создавать свой мод. Если не углубляться в тонкости, есть два варианта построения регистраций: с использованием баз данных или с использованием файлов.

    Базы данных в SA-MP распространены двух типов: SQLite и MySQL. SQLite является встроенной в сервер SA-MP и не требует никаких сторонних плагинов для работы. MySQL является более лучшим аналогом, поддерживающим многопоточные запросы, но требует подключения стороннего плагина (это не является минусом). Мой урок на тему создания регистрации на MySQL вы можете найти, нажав сюда > •••••
    • C файлами всё гораздо проще: выбора нет. Есть множество инклюдов (mxINI, Dini и .п.) в интернете, но все они работают по одному и тому же принципу - через стандартные функции SA-MP по работе с файлами, и нужны лишь для упрощения работы с этими самыми файлами (они хранят самописанные функции, которые пришлось бы писать самостоятельно, не будь этих инклюдов). В этом уроке, как Вы могли понять из названия, я буду говорить о инклюде mxINI, так как, по моему мнению, он является самым оптимальным в плане удобства и скорости для работы с файлами.


    К слову, какой бы способ реализации регистрации Вы не выбрали, разница будет лишь в функциях, которые Вам потребуется использовать при работе с данными. Логика написания одинакова что для баз данных, что для файлов (есть данные и есть место, куда мы их записываем/выгружаем).

    Перечислять стандартные функции данного инклюда я не буду, ибо это уже прекрасно сделал за меня сам создатель данного инклюда. Прочесть информацию о инклюде можно в теме, которая расположена по этой ссылке. Там же Вы можете найти код самого инклюда. Но, если Вы по какой-то причине не сможете скопировать инклюд, я предоставляю ссылку на скачивание: кликабельная ссылка.



    Любая авторизация работает по следующему типу:
    • Находим файл игрока
      • Записываем данные из строк в выделенные для этого переменные
        • Изменяем значения данных в переменных в ходе игры
          • Во время выхода находим файл игрока и теперь записываем данные из переменных в строки


    Отличие регистрации от авторизации только в первых пунктах. Ведь мы только создаём файл игрока и наоборот записываем данные туда, а не берём их из файла.

    Теперь о самих переменных, в которых мы будем хранить информацию о игроке.
    Вообще принято создавать все переменные для системы регистрации через функцию "enum", но это не обязательно. Для хранения данных подойдут и обычные переменные. Но в enum всё выглядит удобнее и привычнее, поэтому делать будем именно через них.
    Но Вы можете сделать так, как будет Вам удобнее. Код Вы пишете, в первую очередь, для себя. Именно Вам предстоит работать со своим кодом ещё долгое время. А спустя пару месяцев Вы можете забыть предназначение того или иного кода и именно поэтому следует писать код так, как будет понятно и удобно именно Вам. Я это повторю ещё несколько раз в данном уроке.

    О том, что такое enum и с чем его едят, я подробно рассказывать не буду. Попробую описать лишь то, что нам понадобится для создания регистрации. Более подробную информацию о enum вы можете найти в гугле. Достаточно вбить в строку поиска "enum pawn". Приступим к созданию.

    Вот так будет выглядеть сам enum, в который ещё не помещены переменные.
    PHP код:
    enum e_PLAYER_INFO
    {
       
    //Тут помещаются нужные нам переменные
    };
    new 
    p_info[MAX_PLAYERS][e_PLAYER_INFO]; 
     Пояснение:

    PHP код:
    enum p_info 
    Ну тут всё понятно должно быть. На всякий случай объясню.
    enum - сама функция
    p_info - название этой функции. Тут точно так же, как и с переменными. То есть, название enum придумываете только Вы


    PHP код:
    {
       
    //Тут помещаются нужные нам переменные
    }; 
    Между данных скобок помещаются все переменные, которые мы будет использовать в enum для хранения данных игрока (не обязательно тех, которые будут сохранены в аккаунт). Они могут быть любого типа (обычные, float, bool, строки), кроме двумерных и более массивов. Названия этих переменных так же определяете исключительно ВЫ
    Далее все случаи, в которых только Вы решаете как будет выглядеть код, я буду помечать так - (*)


    PHP код:
    new p_info[MAX_PLAYERS][e_PLAYER_INFO]; 
    А это мы создаём переменную (двумерный массив), с помощью которой мы будем работать с данными (запись/изменение - всё через эту переменную). И именно эта переменная задаёт будущую "формулу" кода работы с данными
    p_info - название переменной (*)
    [MAX_PLAYERS] - это уже первый массив, в который мы будем помещать данные. В данном случае это ID игроков на сервере. Но, если Вы создаёте какую-то другую систему, помимо регистрации, тут может быть всё, что душе угодно.
    [e_PLAYER_INFO] - это второй массив, который, в данном случае, является своеобразной ссылкой к enum "e_PLAYER_INFO". То есть, тут мы должны написать название нашего enum, чтобы мод знал откуда брать данные в будущем.


     Пояснение пояснения:
    "Как корабль назовёшь, так на нём и напиши"
    Эта фраза подходит и к этому случаю. Если Вы назовёте переменную
    PHP код:
    new e_PLAYER_INFO[MAX_PLAYERS][p_info]; 
    То в дальнейшем "формула" кода работы с данными будет именно так
    PHP код:
    e_PLAYER_INFO[ид_игрока][имя_переменной
    А если назовёте
    PHP код:
    new VasyaPypkin[MAX_PLAYERS][p_info]; 
    то в дальнейшем Вы должны использовать именно такую "формулу"
    PHP код:
    VasyaPypkin[ид_игрока][имя_переменной


    Так же Вы можете поменять расположение массивов в этой самой переменной (следовательно, и "формулу" Вы тоже поменяете). Например:
    PHP код:
    new p_info[e_PLAYER_INFO][MAX_PLAYERS]; 
    Теперь наша "формула" будет выглядеть следующим образом
    PHP код:
    p_info[имя_переменной][ид_игрока
    Если Вам будет удобнее так - делайте так. Что помещать в эти два массива данных - зависит от ситуации. В какой последовательности помещать - решаете только Вы.


    Теперь приступим к созданию переменных для хранения информации игрока в памяти сервера.
    Сейчас мы создадим массив для хранения ника игрока, переменную, в которой будет хранится пароль, переменную, в которой будут хранится деньги и переменную, которая будет записывать статус авторизации игрока. Ник игрока нам пригодится в дальнейшем, но записывать его в аккаунт не будем (он будет являться названием файла аккаунта). С авторизацией так же, как и с именем, а вот пароль и деньги запишем.

    PHP код:
    enum e_PLAYER_INFO//Даём название нашему enum
    {
        
    p_name[MAX_PLAYER_NAME],//Создаём новый массив для записи имени и ставим запятую
        
    p_password[64],//Создаём новый массив для записи пароля и ставим запятую
        
    p_money,//Создадим новую переменную для записи денег и ставим запятую
        
    boolp_logged//Создадим новую переменную логического типа для записи статистики авторизации
    };
    new 
    p_info[MAX_PLAYERS][e_PLAYER_INFO]; 
     Объяснение
    Enum - своеобразное хранилище с переменными, в которых находятся данные.
    Если привести пример из жизни, то можно провести параллель с банком.
    PHP код:
    enum e_PLAYER_INFO//Название нашего банка
    {
        
    p_name[MAX_PLAYER_NAME],//Банковская ячейка №1
        
    p_password[64],//Банковская ячейка №2
        
    p_money,//Банковская ячейка №3
        
    boolp_logged//Банковская ячейка №4
    };
    new 
    p_info[MAX_PLAYERS][e_PLAYER_INFO];//Набор ключей, который открывает наши ячейки 
    То есть, для открытия ячейки с паролем мы должны "подобрать" ключ к этой ячейке. "Связкой ключей" является переменная "p_info", а самим "ключом" является массив "[e_PLAYER_INFO]". Именно в него мы будем писать название нашего "ключа" (переменной). А "[MAX_PLAYERS]" будет хранить "номер клиента" (то бишь ID игрока) и нужен этот массив только для того, чтобы данные игроков не смешивались.
    Вот как будет выглядеть "подбор ключа" (формула) для извлечения пароля
    PHP код:
    p_info[playerid][p_password
     Пояснение
    p_info - переменная, в которую запишутся данные
    [playerid] - массив, в который запишется ID игрока. ID нам нужен для того, чтобы знать с чьими данными мы работаем
    [p_password] - Наш "ключ" или ссылка на переменную в enum, из которой мы будем извлекать значения

    Вот так будет выглядеть извлечение ника игрока
    PHP код:
    p_info[playerid][p_name
    Вот так деньги
    PHP код:
    p_info[playerid][p_money
    А вот так статистика авторизации (НО: из-за логического типа (bool) данная переменная может использовать только 2 значения - "true/false")
    PHP код:
    p_info[playerid][p_logged


    Теперь у нас выделена память для хранения данных аккаунтов и пора приступать к работе с этими самыми данными. В первую очередь стоит написать код, который будет записывать ник игрока в переменную "p_name". Если подумать, ник игрока остаётся всегда одинаковым во время игры, поэтому зачем постоянно использовать GetPlayerName, когда можно при входе записать имя игрока в переменную и после уже работать с этой переменной. Этим мы и займёмся.
    В паблик OnPlayerConnect нужно поместить следующий код:
    PHP код:
    GetPlayerName(playerid,p_info[playerid][p_name],MAX_PLAYER_NAME); 
     Пояснение
    GetPlayerName - функция, которая узнаёт ник игрока, указанный в окне мультиплеера SA-MP.
    Подробнее о ней Вы можете узнать тут
    playerid - В данной функции хранится ID игрока, который "вызвал" выполнение кода. В данном случае это будет ID игрока, который зашёл на сервер
    p_info[playerid][p_name] - Тут мы "создаём ссылку" на переменную "p_name" в наш enum и записываем туда полученные данные (ник). А именно в массив MAX_PLAYER_NAME.
    MAX_PLAYER_NAME - Длинна ника игрока. Так как мы не знаем какой длинны будет ник у игрока, мы прописываем максимально возможное число символов в нике (24 символа = MAX_PLAYER_NAME)

     Вот так выглядит конечный результат
    PHP код:
    public OnPlayerConnect(playerid)
    {
        
    GetPlayerName(playerid,p_info[playerid][p_name],MAX_PLAYER_NAME);
        return 
    1;


    Но согласитесь, случаев работы с ником игрока бывает довольно много, а писать каждый раз "p_info[playerid][p_name]" довольно неудобно. Поэтому советую вам использовать следующий код:
    PHP код:
    #define pNick(%1)      p_info[%1][p_name] 
     Пояснение:
    Данный код преобразует
    PHP код:
    pNick(ид_игрока); 
    в
    PHP код:
    p_info[ид_игрока][pPlayerName
    То есть, для извлечения ника игрока не нужно будет писать "p_info[playerid][p_name]", а достаточно будет просто написать "pNick(playerid)" и компилятор сам заменит введённый нами код на нужный.


    ид_игрока - любая переменная, хранящая данные о ID игрока. Если нужно узнать ID игрока, который вызвал эту функцию, прописываете "playerid". А бывают случаи, когда нужно узнать ник игрока, которому, например, Вы дали уровень. Обычно для записи ID такого игрока используются переменные "giveplayerid" или "para1" (могут быть и другие. Это уже от скриптера зависит). В этом случае Вы прописываете
    PHP код:
    pNick(giveplayerid
    и всё, больше никаких строк не нужно. Данная функция отобразит ник игрока.
     Как работает система записи ника:
    Мы создали переменную в нашем enum, в которой можно хранить ник. И, если подумать, ник игрока не меняется во время игры на сервере. А значит зачем нам каждый раз узнавать его, когда можно узнать при входе на сервер и всё? Вот именно так мы и поступили. Мы поместили в OnPlayerConnect функцию записи ника в переменную и теперь работаем с полученными данными. Этот способ является своеобразной оптимизацией.
    P.S. Если вы решите создать функцию смены ника игрока прямо в игре (и если игрока не будет кикать с сервера после смены ника), просто перезаписывайте данные. То есть:
    PHP код:
    SetPlayerName(playerid,"Новый_ник");//Меняем ник игроку с ID, который записан в playerid
    GetPlayerName(playerid,p_info[playerid][p_name],MAX_PLAYER_NAME);//Перезаписываем данные о нике игрока 
    Всё. Это единственный случай, когда GetPlayerName используется где-то ещё, кроме паблика OnPlayerConnect. В остальных случаях следует использовать "pNick()" или "p_info[][p_name]"


    Теперь у нас есть переменная, которая хранит ник игрока. Самое время заняться написанием системы создания нового файла для аккаунта игрока. Использовать данную функцию в каких-либо таймерах мы не собираемся. Так что создадим её в виде stock. Подробнее о создании stock Вы можете прочесть в моём предыдущем уроке, поэтому тут заострять на этом внимания я не буду.
    PHP код:
    stock CreateAccount(playeridpassword[])
    {
        new 
    account[37];
        
    format(account,sizeof(account),"users/%s.ini",pNick(playerid));//ОБЯЗАТЕЛЬНО создайте папку "users" в папке "scriptfiles"
        
    if(fexist(account)) return ShowPlayerDialog(playerid,1,DIALOG_STYLE_INPUT"Авторизация""Данный аккаунт зарегистрирован. Введите пароль:""Далее""Выход");
        new 
    iniFile ini_createFile(account);
        if(
    iniFile 0ini_openFile (account);
        {
            
    ini_setString(iniFile,"Пароль",password);//О "ini_setString" и "ini_setInteger" написано в теме, которая описывает инклюд mxINI (выше ссылка)
            
    ini_setInteger(iniFile"Деньги"10000);
            
    ini_closeFile(iniFile);
            
    OnPlayerLogin(playerid);
        }
        return 
    1;

     Пояснение:
    new account[37]; - создаём переменную, которая будет хранить "ссылку" на место, где будет создан файл, и имя файла
    format(account,sizeof(account),"users/%s.ini",pNick(playerid)); - сама строка формирования "ссылки". Данная ссылка должна быть одинакова во всех случаях, где нужно работать с файлом игрока (то есть, какая в создании файла, такая и в загрузке/сохранении файла)
     users/%s.ini
    users - имя папки, в которой будет создан файл. Если файлы расположены в папке - нужно обязательно создать её (в папке scriptfiles)
    / - означает переход в следующий каталог (открытие папки)
    %s - Данный код выведет значение переменной pNick
    .ini - формат файла аккаунтов

    if(fexist(account)) return ShowPlayerDialog(playerid,1,DIALOG_STYLE_INPUT, "Авторизация", "Данный аккаунт зарегистрирован. Введите пароль:", "Далее", "Выход"); - проверка на существование файла игрока. Если файл с таким ником существует - показываем диалог авторизации
    new iniFile = ini_createFile(account); - создаём переменную, которую приравниваем к функции создания игрока (это сделает дальнейший код более читабельным)
    if(iniFile < 0) ini_openFile (account); - Если файл не создан - открываем его
     Почему так? Вот как это объясняет создатель инклюда в теме, на которую я дал ссылку

    Кстати, заметили, что INI ридер/райтер не создает файлы, если они не существуют? Это большой плюс, объясню почему: если нужен специальный формат INI файла, который еще не существует, то достаточно создать в моде строку с этим самым форматом, создать новый файл с помощью fopen и записать в открытый файл эту строку, далее файл закрыть.

    ini_setString(iniFile,"Пароль",password); - изменяем значение строки "Пароль" и записываем в неё введённый игроком пароль
    ini_setInteger(iniFile, "Деньги", 10000); - изменяем значение строки "Деньги" и записываем в неё сумму, которую мы будем выдавать игроку при регистрации
    OnPlayerLogin(playerid); - После создания всех строк, вызываем stock авторизации, который мы создадим чуть позже
    ini_closeFile(iniFile); - Закроем файл игрока


    Теперь займёмся созданием stock, который будет загружать данные игрока из файла в переменные
    PHP код:
    stock OnPlayerLogin(playerid)
    {
        new 
    account[37];
        
    format(account,sizeof(account),"users/%s.ini",pNick(playerid));//ОБЯЗАТЕЛЬНО создайте папку "users" в папке "scriptfiles"
        
    new iniFile ini_openFile(account);
        
    ini_getString(iniFile,"Пароль"p_info[playerid][p_password],64);
        
    ini_getInteger(iniFile"Деньги"p_info[playerid][p_money]);
        
    ini_closeFile(iniFile);
        
    ResetPlayerMoney(playerid);
        
    GivePlayerMoney(playeridp_info[playerid][p_money]);
        
    p_info[playerid][p_logged]=true;
        
    SpawnPlayer(playerid);
        return 
    1;

     Пояснение:
    Первые две строчки имеют точно такое же предназначение, как и в коде создания аккаунта
    new iniFile = ini_openFile(account); - создаём переменную, которую приравниваем к функции открытия файла
    ini_getInteger(iniFile,"Пароль", p_info[playerid][p_password]); - Узнаём данные, которые записаны в строке "Пароль" и записываем их в переменную
    ini_getInteger(iniFile, "Деньги", p_info[playerid][p_money]); - Узнаём данные, которые записаны в строке "Деньги" и записываем их в переменную
    ini_closeFile(iniFile); - закрываем файл
    ResetPlayerMoney(playerid); - Отчищаем значение денег игрока, которые записаны в Hud (который расположен в игре справа сверху)
    GivePlayerMoney(playerid, p_info[playerid][p_money]); - Выдаём деньги игроку. Столько, сколько записано в переменной p_money
    p_info[playerid][p_logged]=true; - Изменяем статистику авторизации игрока на "авторизирован". false - не авторизирован, true - авторизирован
    SpawnPlayer(playerid); - Отправляем игрока на спавн


    Функции создания и загрузки аккаунта у нас уже есть. Теперь приступим к написанию stock сохранения игрока.
    PHP код:
    stock SavePlayer(playerid)
    {
        if(
    p_info[playerid][p_logged]==false) return 1;
        new 
    account[37];
        
    format(account,sizeof(account),"users/%s.ini",pNick(playerid));//ОБЯЗАТЕЛЬНО создайте папку "users" в папке "scriptfiles"
        
    new iniFile ini_openFile(account);
        
    ini_setString(iniFile"Пароль"p_info[playerid][p_password]);
        
    p_info[playerid][p_money] = GetPlayerMoney(playerid);
        
    ini_setInteger(iniFile"Деньги"p_info[playerid][p_money]);
        
    ini_closeFile(iniFile);
        return 
    1;

     Пояснение
    Первые три строки описаны в примере выше
    ini_setString(iniFile, "Пароль", p_info[playerid][p_password]); - Перезаписываем данные, хранящиеся в строке "Пароль", данными из переменной (на случай, если пароль будет изменён)
    ini_setInteger(iniFile, "Деньги", p_info[playerid][p_money]); - Перезаписываем данные, хранящиеся в строке "Деньги", данными из переменной
    ini_closeFile(iniFile); - закрываем файл


    Все нужные функции, через которые мы будем работать с файлами у нас есть. Самое время заняться диалоговыми окнами, через которые будет происходить регистрация/авторизация.
    Находим паблик OnPlayerConnect и после строки GetPlayerName пишем
    PHP код:
    new account[37];
    format(account,sizeof(account),"users/%s.ini",pNick(playerid));
    if(!
    fexist(account))
    {
        
    ShowPlayerDialog(playerid,0,DIALOG_STYLE_INPUT"Регистрация""Данный аккаунт не зарегистрирован на нашем сервере. Для регистрации введите пароль:""Далее""Выход");
    }
    else if(
    fexist(account))
    {
        
    ShowPlayerDialog(playerid,1,DIALOG_STYLE_INPUT"Авторизация""Данный аккаунт зарегистрирован на нашем сервере. Для авторизации введите пароль:""Далее""Выход");

     Пояснение:
    Первые две строчки описаны в примерах выше
    if(!fexist(account)) - Проверяет наличие аккаунта по написанному нами адресу ( в данном случае это "users/%s.ini") и если аккаунта нет - выводим диалог регистрации. В противном случае выводим диалог авторизации
     Вот так это будет выглядеть конечный результат
    PHP код:
    public OnPlayerConnect(playerid)
    {
        
    GetPlayerName(playerid,p_info[playerid][p_name],MAX_PLAYER_NAME);
        new 
    account[37];
        
    format(account,sizeof(account),"users/%s.ini",pNick(playerid));
        if(!
    fexist(account))
        {
            
    ShowPlayerDialog(playerid,0,DIALOG_STYLE_INPUT"Регистрация""Данный аккаунт не зарегистрирован на нашем сервере. Для регистрации введите пароль:""Далее""Выход");
        }
        else
        {
            
    ShowPlayerDialog(playerid,1,DIALOG_STYLE_INPUT"Авторизация""Данный аккаунт зарегистрирован на нашем сервере. Для авторизации введите пароль:""Далее""Выход");
        }
        return 
    1;




    Теперь при входе на сервер нам покажет диалог. Но нам нужно создать действия для этих диалогов. Для этого найдём паблик OnDialogResponse и впишем следующий код:
    PHP код:
    if(dialogid == 0)
    {
        if(!
    response) return Kick(playerid);
        else if(
    response)
        {
            if(!
    strlen(inputtext)) return ShowPlayerDialog(playerid0DIALOG_STYLE_INPUT"{FF0000}Ошибка""Вы не ввели пароль. Без пароля регистрация невозможна!\nВведите ваш пароль:""Далее""Выход");
            new 
    account[37];
            
    format(account,sizeof(account),"users/%s.ini",pNick(playerid));
            if(
    fexist(account)) return ShowPlayerDialog(playerid,1,DIALOG_STYLE_INPUT"Авторизация""Данный аккаунт зарегистрирован на нашем сервере. Для авторизации введите пароль:""Далее""Выход");
            else return 
    CreateAccount(playeridinputtext);
        }   
    }
    else if(
    dialogid == 1)
    {
        if(!
    response) return Kick(playerid);
        else if(
    response)
        {
            if(!
    strlen(inputtext)) return ShowPlayerDialog(playerid1DIALOG_STYLE_INPUT"{FF0000}Ошибка""Для игры на сервере Вы должны авторизироваться!\nВведите ваш пароль:""Далее""Выход");
            new 
    account[37];
            
    format(account,sizeof(account),"users/%s.ini",pNick(playerid));
            if(!
    fexist(account)) return ShowPlayerDialog(playerid,0,DIALOG_STYLE_INPUT"Регистрация""Данный аккаунт не зарегистрирован на нашем сервере. Для регистрации введите пароль:""Далее""Выход");
            else
            {
                new 
    password[64];
                new 
    iniFile ini_openFile(account);
                
    ini_getString(iniFile"Пароль",password);
                
    ini_closeFile(iniFile);
                if(!
    strcmp(inputtextpasswordtrue)) return OnPlayerLogin(playerid);
                else return 
    ShowPlayerDialog(playerid1DIALOG_STYLE_INPUT"{FF0000}Ошибка""Вы ввели неверный пароль! Повторите попытку\nВведите ваш пароль:""Далее""Выход");
            }
        }

     Пояснение:
    if(dialogid == 0) - Если ID диалога, который показан игроку равен 0 - выполняем функции в скобках (с авторизацией так же)
    if(!response) return Kick(playerid); - Если игрок нажал на вторую кнопку ( кнопка "Выход") или нажал на Esc - кикаем игрока (с авторизацией так же)
    else if(response) - Если игрок не нажал на вторую кнопку и нажал на первую кнопку или Enter - выполняем код в скобках (с авторизацией так же)
    if(!strlen(inputtext)) return ShowPlayerDialog(playerid, 0, DIALOG_STYLE_INPUT, "{FF0000}Ошибка", "Вы не ввели пароль. Без пароля регистрация невозможна!\nВведите ваш пароль:", "Далее", "Выход"); - если игрок ничего не ввёл в поле для ввода и нажал на первую кнопку - не дадим зайти и выведем данный диалог (с авторизацией так же)
    new account[37]; - создаём переменную, которая будет хранить "ссылку" на место, где будет создан файл, и имя файла
    format(account,sizeof(account),"users/%s.ini",pNick(playerid)); - сама строка формирования "ссылки". Данная ссылка должна быть одинакова во всех случаях, где нужно работать с файлом игрока (то есть, какая в создании файла, такая и в загрузке/сохранении файла)
     users/%s.ini
    users - имя папки, в которой будет создан файл
    / - означает переход в следующий каталог (открытие папки)
    %s - Данный код выведет значение переменной pNick
    .ini - формат файла аккаунтов

    if(!fexist(account)) return ShowPlayerDialog(playerid,1,DIALOG_STYLE_INPUT, "Авторизация", "Данный аккаунт зарегистрирован на нашем сервере. Для авторизации введите пароль:", "Далее", "Выход"); - если аккаунт уже создан - покажем диалог с авторизацией (в авторизации противоположное действие)
    else return CreateAccount(playerid, inputtext); - если аккаунт не найден - вызовем stock создания аккаунта (в авторизации подобное, только авторизируем игрока, а не создаём аккаунт)
     Вот так это будет выглядеть конечный результат
    PHP код:
    public OnDialogResponse(playeriddialogidresponselistiteminputtext[])
    {
        if(
    dialogid == 0)
        {
            if(!
    response) return Kick(playerid);
            else if(
    response)
            {
                if(!
    strlen(inputtext)) return ShowPlayerDialog(playerid0DIALOG_STYLE_INPUT"{FF0000}Ошибка""Вы не ввели пароль. Без пароля регистрация невозможна!\nВведите ваш пароль:""Далее""Выход");
                new 
    account[37];
                
    format(account,sizeof(account),"users/%s.ini",pNick(playerid));
                if(
    fexist(account)) return ShowPlayerDialog(playerid,1,DIALOG_STYLE_INPUT"Авторизация""Данный аккаунт зарегистрирован на нашем сервере. Для авторизации введите пароль:""Далее""Выход");
                else return 
    CreateAccount(playeridinputtext);
            }
        }
        else if(
    dialogid == 1)
        {
            if(!
    response) return Kick(playerid);
            else if(
    response)
            {
                if(!
    strlen(inputtext)) return ShowPlayerDialog(playerid1DIALOG_STYLE_INPUT"{FF0000}Ошибка""Для игры на сервере Вы должны авторизироваться!\nВведите ваш пароль:""Далее""Выход");
                new 
    account[37];
                
    format(account,sizeof(account),"users/%s.ini",pNick(playerid));
                if(!
    fexist(account)) return ShowPlayerDialog(playerid,0,DIALOG_STYLE_INPUT"Регистрация""Данный аккаунт не зарегистрирован на нашем сервере. Для регистрации введите пароль:""Далее""Выход");
                else
                {
                    new 
    password[64];
                    new 
    iniFile ini_openFile(account);
                    
    ini_getString(iniFile"Пароль",password);
                    
    ini_closeFile(iniFile);
                    if(!
    strcmp(inputtextpasswordtrue)) return OnPlayerLogin(playerid);
                    else return 
    ShowPlayerDialog(playerid1DIALOG_STYLE_INPUT"{FF0000}Ошибка""Вы ввели неверный пароль! Повторите попытку\nВведите ваш пароль:""Далее""Выход");
                }
            }
        }
        return 
    1;



    Мы создавали переменную, хранящую статус авторизации и теперь самое время создать различные проверки на её основе. Вот пара примеров:
     Запрещаем игроку писать в чат, если он не авторизирован
    PHP код:
    public OnPlayerText(playeridtext[])
    {
        if(
    p_info[playerid][p_logged]==false)
        {
            
    SendClientMessage(playerid,0xFF0000FF,"Вы не авторизированы!");
            return 
    0;
        }
        
    //Тут остальной код
        
    return 1;


     Запрещаем игроку использовать команды, если он не авторизирован
    PHP код:
    public OnPlayerCommandText(playeridcmdtext[])
    {
        if(
    p_info[playerid][p_logged]==false) return SendClientMessage(playerid,0xFF0000FF,"Вы не авторизированы!");
        
    //Тут остальной код
        
    return 0;


     Если игрок пытается заспавнится неавторизированным - покажем ему диалоги
    PHP код:
    public OnPlayerSpawn(playerid)
    {
        if(
    p_info[playerid][p_logged]==false)
        {
            new 
    account[37];
            
    format(account,sizeof(account),"users/%s.ini",pNick(playerid));
            if(!
    fexist(account))
            {
                
    ShowPlayerDialog(playerid,0,DIALOG_STYLE_INPUT"Регистрация""Данный аккаунт не зарегистрирован на нашем сервере. Для регистрации введите пароль:""Далее""Выход");
            }
            else if(
    fexist(account))
            {
                
    ShowPlayerDialog(playerid,1,DIALOG_STYLE_INPUT"Авторизация""Данный аккаунт зарегистрирован на нашем сервере. Для авторизации введите пароль:""Далее""Выход");
            }
        }
        
    //Тут остальной код
        
    return 1;



    Теперь создадим stock, который будет обнулять переменные из enum, дабы не было никаких ошибок в работе с данными
    PHP код:
    stock Removee_PLAYER_INFO(playerid)
    {
        
    p_info[playerid][p_logged]=false;//По умолчанию игрок будет не авторизирован
        
    p_info[playerid][p_money]=0;//Обнулим переменную денег
        
    p_info[playerid][p_password]=0;//Обнулим переменную пароля
        //В этот stock можете добавлять любые переменные, значение которых нужно изменять при входе/выходе из игры
        
    return 1;

    И теперь поместим вызов этого stock в паблики OnPlayerConnect и OnPlayerDisconnect. Код вызова будет таким:
    PHP код:
    Removee_PLAYER_INFO(playerid); 
     Вот так это будет выглядеть конечный результат

     OnPlayrConnect
    PHP код:
    public OnPlayerConnect(playerid)
    {
        
    Removee_PLAYER_INFO(playerid);
        
    GetPlayerName(playerid,p_info[playerid][p_name],MAX_PLAYER_NAME);
        new 
    account[37];
        
    format(account,sizeof(account),"users/%s.ini",pNick(playerid));
        if(!
    fexist(account))
        {
            
    ShowPlayerDialog(playerid,0,DIALOG_STYLE_INPUT"Регистрация""Данный аккаунт не зарегистрирован на нашем сервере. Для регистрации введите пароль:""Далее""Выход");
        }
        else if(
    fexist(account))
        {
            
    ShowPlayerDialog(playerid,1,DIALOG_STYLE_INPUT"Авторизация""Данный аккаунт зарегистрирован на нашем сервере. Для авторизации введите пароль:""Далее""Выход");
        }
        
    //Тут остальной код
        
    return 1;


     OnPlayerDisconnect
    PHP код:
    public OnPlayerDisconnect(playerid)
    {
        
    //Тут остальной код
        
    Removee_PLAYER_INFO(playerid);//В самом конце паблика, перед return
        
    return 1;




    И теперь нам осталось сделать сохранение аккаунта при выходе игрока из игры. Делается это очень просто.
    В OnPlayerDisconnect нужно добавить вызов stock с сохранением игрока
    PHP код:
    SavePlayer(playerid); 
     Вот так это будет выглядеть конечный результат
    PHP код:
    public OnPlayerDisconnect(playerid)
    {
        
    SavePlayer(playerid);
        
    //Тут остальной код
        
    Removee_PLAYER_INFO(playerid);
        return 
    1;




    На этом урок окончен. Данный урок позволил вам создать основу, из которой вы уже должны сами создать свой сервер.


    Полезные ссылки:


    Если есть какие-либо вопросы, если что-то непонятно объяснено или есть какие-либо дополнения/исправления для данного урока, прошу написать об этом ниже. Всем постараюсь помочь, все мнения приму к сведению.
    С вами был DeimoS. Спасибо за внимание
    Автор урока - DeimoS
    При копировании данного материала, обязательно указывайте автора и ссылку на данный урок
    Последний раз редактировалось DeimoS; 12.07.2016 в 15:13.

  2. #2
    Аватар для Daniel_Cortez
    new fuck_logic[0] = EOS;

    Статус
    Онлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    1,461
    Репутация:
    2021 ±
    Цитата Сообщение от DeimoS Посмотреть сообщение
    PHP код:
        pName[MAX_PLAYER_NAME],//Создаём новый массив для записи имени и ставим запятую 
    MAX_PLAYER_NAME+1 же.

    MAX_PLAYER_NAME - кол-во символов под ник игрока. Ещё +1 ячейка нужна под завершающий нуль-символ '\0'.
    Индивидуально в PM и Skype по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).
    SA-MP 0.4 is a lie

  3. #3
    Аватар для Salvacore
    Инжунер-погромист

    Статус
    Оффлайн
    Регистрация
    10.05.2013
    Адрес
    Аҧсуа бызшәа
    Сообщений
    2,334
    Репутация:
    418 ±
    Молодец.

  4. #4
    Аватар для Daniel_Cortez
    new fuck_logic[0] = EOS;

    Статус
    Онлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    1,461
    Репутация:
    2021 ±
    Цитата Сообщение от DeimoS Посмотреть сообщение
    Размер ника для игроков не может превышать 20 символов. Так что изначально можно выделать под ник спокойно 20 ячеек, а 4 ячейки дано скриптерам для создания тегов, типа "AFK", что бывает весьма редко. Эти 4 ячейки не обязательны, но Kalcor решил перестраховаться для подобных ситуаций и... В общем, имеем то, что имеем. Давать ещё больше глупо. По крайней мере тут. Если в каком-то случае нужно будет изменить ник и размер его будет больше 24 символов, там уже и ставь нужное значение.

    P.S. Kalcor не дурак и сделал бы 25 символов, если бы этого требовал сам SA-MP. Но как я сказал выше, ник занимает 20 символов и для его хранения нужно максимум 21 ячейка и не более. А 24 сделали для ламеров, коих в сампе много (как это показала тема с взломом ID диалога) и которые не смогут додуматься до этого сами :)
    1. В клиенте макс. длина ника - 20 символов. Но сервер может установить до 24.
    2. То, что сейчас макс. длина ника 20 символов, не значит, что её не увеличат в следующих версиях SA:MP. А если увеличат, тебе придётся переделывать весь мод, т.к. он будет элементарно не готов к апгрейду. Для того и сделаны константы, чтобы пользоваться ими.
    Индивидуально в PM и Skype по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).
    SA-MP 0.4 is a lie

  5. #5
    Аватар для Daniel_Cortez
    new fuck_logic[0] = EOS;

    Статус
    Онлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    1,461
    Репутация:
    2021 ±
    Цитата Сообщение от DeimoS Посмотреть сообщение
    Так а я о чём? Клиент банально не сможет сделать ник, который превысит размер массива. Посмотри где используется pName
    См. пункт 2.
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    2. То, что сейчас макс. длина ника 20 символов, не значит, что её не увеличат в следующих версиях SA:MP. А если увеличат, тебе придётся переделывать весь мод, т.к. он будет элементарно не готов к апгрейду. Для того и сделаны константы, чтобы пользоваться ими.
    Индивидуально в PM и Skype по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).
    SA-MP 0.4 is a lie

  6. #6
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    2,956
    Репутация:
    1186 ±
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    См. пункт 2.
    Охх, ладно. Распишу.
    Переменная pName служит для того, чтоб единожды (при входе) записать ник игрока и после уже работать именно с этой переменной, а не постоянно вызывать GetPlayerName. В эту переменную НЕ надо записывать изменённый ник игрока, если вдруг захочется приписать к нему "AFK" или что-то подобное (если новый ник настоящий - пожалуйста. Но все эти AFK и т.п. - не сюда). В нём хранится лишь истинный ник игрока. Создана переменная с использованием стандартного макроса MAX_PLAYER_NAME, поэтому если и увеличат длину ника, менять ничего не придётся.

    Если хочется установить игроку каким-то образом ник больше 24 символов, дерзай. Создавай новый локальный массив с нужным числом ячеек и пиши в него новый ник (это для случая с тэгом "AFK"). Там выделяй столько ячеек, сколько нужно. А массив pName служит исключительно для хранения настоящего ника игрока и ничего иного. И дабы уж совсем всё ясно было, повторю во второй раз. Так как MAX_PLAYER_NAME подразумевает под собой число, которое равно максимальному числу символов в нике, игрок никак не сможет добиться ситуации, когда массив будет переполнен (исключая ситуации, когда кривые руки скриптера сами дали ему такую возможность. Но тут уже, извините, виноват не я и не SA-MP).

    И я всё равно не понимаю для чего тебе 25 символов под ник. Открою тайну, на самом деле больше 23 символов в ник не ввести. Даже через SetPlayerName. Ник просто не изменит. И именно 24 ячейка служит местом хранения нуль-символа, если длинна ника составит 23 символа. Даже сделав 25 ячеек ты не сможет поставить ник игроку больше 23 символов.
    P.S. Что-то сразу об этом не вспомнил...
    Связаться со мной можно в личных сообщениях этой группы

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

  7. #7
    Аватар для TWIX
    Пользователь

    Статус
    Оффлайн
    Регистрация
    29.10.2013
    Сообщений
    103
    Репутация:
    41 ±
    Классно расписал!
    Уважаю данных Людей:

    1. Osetin(Хороший Администратор)
    2.Daniel_Cortez(Классный скриптер)
    3.Londlem(Офигенный скриптер)
    4.#Carleone(Просто хороший человек)

  8. #8
    Аватар для [ForD]
    Пользователь

    Статус
    Оффлайн
    Регистрация
    14.11.2013
    Адрес
    Свердловская обл.
    Сообщений
    677
    Репутация:
    98 ±
    От души просто!Правда классно,делай побольше уроков дружище!Объяснять ты отлично умеешь.
    PAWN Compiler делает то, что вы приказали ему сделать, а не то, что вы хотели, чтобы он сделал..

    25% времени в программировании уходит на размышления о том, что пользователь может сделать не так.[HR]/Брайан Хьюмс/






  9. #9
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    2,956
    Репутация:
    1186 ±
    Цитата Сообщение от [ForD] Посмотреть сообщение
    От души просто!Правда классно,делай побольше уроков дружище!Объяснять ты отлично умеешь.
    В планах создание Open Source мода-мануала, темы которого будут выглядеть подобным образом. Но пока не могу определиться с тем, на какой системе делать регистрацию.
    Связаться со мной можно в личных сообщениях этой группы

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

  10. #10
    Аватар для Salvacore
    Инжунер-погромист

    Статус
    Оффлайн
    Регистрация
    10.05.2013
    Адрес
    Аҧсуа бызшәа
    Сообщений
    2,334
    Репутация:
    418 ±
    Цитата Сообщение от DeimoS Посмотреть сообщение
    В планах создание Open Source мода-мануала, темы которого будут выглядеть подобным образом. Но пока не могу определиться с тем, на какой системе делать регистрацию.
    Лучше бы MySQL (свежую версию + распиши:O)

 

 
Страница 1 из 5 123 ... ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •