- Автор темы
- #1
Здравствуйте посетители портала pawno-help.ru
Решил написать для вас урок по написанию регистрации на модулях с использованием:
Пока мы не перешли к написанию кода модулей, настроим полностью наш исходник.
Переходим в public OnGameModeInit и пишем там:
Теперь немножко теории:
И так продолжаем, переходим в public OnGameModeExit и там пишем:
Данная функция закрывает соединение при выключении сервера
Теперь переходим к public OnPlayerRequestClass и напишем туда следующий код:
И снова чуть чуть теории
Теперь переходим в public OnPlayerConnect и пишем
Так как нам нужно обнулить данные игрока, мы используем данный сток(он будет дальше в модулях)
Переходим в public OnPlayerDisconnect и пишем
Немножко теории
Переходим в public OnPlayerSpawn и пишем
И снова немного теории
Теперь создаёт репозиторий sourse, а в нём создаём файл header.pwn, который и будет подгружать наши модули, и пишем туда следующий код
И снова теория
Идём дальше, создаём 4 репозитория, в репозитории sourse: array, function, stock, dialog
В репозитории stock создадим файл regex.pwn
Немного теории
Теперь переходим к репозиторию stock и создаём там accounts.pwn и пишем
Ну а теперь опишу что за что отвечает
Переходим в репозиторий function и создаём файл accounts.pwn и пишем
Немного теории
Теперь идём в репозиторий dialog и cоздаём в нём файл и репозиторий, файл называет dialog.pwn, репозиторий называем accounts, в dialog.pwn пишем код
ну а теперь переходим в репозиторий dialog->accounts и создаём там файл reg.pwn и пишем
Осталось совсем чуть чуть, переходим в репозиторий stock и добавим accounts.pwn и пишем
Осталось создать только базу, создаём таблицу members и делаем следующие параметры
По итогу все готово.
Автор: Gazmerin
Спасибо за внимание
Решил написать для вас урок по написанию регистрации на модулях с использованием:
- MySQL R41-4
- mdialog
- foreach
- PawnRegex
PHP:
#include <a_samp>
#include <a_mysql>
#include <Pawn.Regex>
#include <foreach>
#include <mdialog>
#include "../sourse/header.pwn"
Переходим в public OnGameModeInit и пишем там:
PHP:
public OnGameModeInit()
{
dbHandle = mysql_connect(mysql_host, mysql_user, mysql_pass, mysql_base);
if(mysql_errno(dbHandle) != 0) printf("Error connect database. Code: %d", mysql_errno(dbHandle));
else print("Success connect database");
SetGameModeText(NAME_SERVER"|"VERS_SERVER);
AddPlayerClass(0, 1958.3783, 1343.1572, 15.3746, 269.1425, 0, 0, 0, 0, 0, 0);
return 1;
}
PHP:
dbHandle - Наша переменная, через которую мы будем передавать данные в базу данных
mysql_host - Наш макрос, для подключение к базе данных, отвечает за хост к которому мы подключаемся
mysql_user - Наш макрос, для подключение к базе данных, отвечает за пользователя базы данных
mysql_pass - Наш макрос, для подключение к базе данных, отвечает за пароль от базы данных
mysql_base - Наш макрос, для подключение к базе данных, отвечает за нашу базу данных (название базы данных)
if(mysql_errno(dbHandle) != 0) - В случае если подключение не проходит, то пишет ошибку
SetGameModeText - Функция даёт название нашему моду, отображается в клиенте во вкладке mode
AddPlayerClass - Очень важная функция, если её не будет то при онлайне 2+ будет очень не приятный баг
PHP:
public OnGameModeExit()
{
mysql_close(dbHandle);
return 1;
}
Теперь переходим к public OnPlayerRequestClass и напишем туда следующий код:
PHP:
public OnPlayerRequestClass(playerid, classid)
{
if(Iter_Contains(player_logged, playerid))
{
SetSpawnInfo(playerid, 0, 0, 1958.3783, 1343.1572, 15.3746, 269.1425, 0, 0, 0, 0, 0, 0);
SpawnPlayer(playerid);
}
else
{
SetTimerEx("OnPlayerJoin", 35, false, "d", playerid);
}
return 1;
}
PHP:
Iter_Contains - Функция из библиотеки foreach, в данном случае проверяет игрок с playerid авторизирован или нет
SetSpawnInfo - Задаёт координаты спавна, в данном случае решает баг
SpawnPlayer - Отправляет игрока на public OnPlayerSpawn
SetTimerEx - Таймер как и SetTimer, но имеет аргумент
OnPlayerJoin - Наш паблик, где будет проверяться есть ли аккаунт в базе данных либо нет
35 - Задержка в миллисекундах
false - он же 0, отвечает за повтор паблика, 0 - запрет на повтор, 1 - разрешение на повтор
PHP:
public OnPlayerConnect(playerid)
{
clear_player(playerid);
return 1;
}
Переходим в public OnPlayerDisconnect и пишем
PHP:
public OnPlayerDisconnect(playerid, reason)
{
if(Iter_Contains(player_logged, playerid))
{
Iter_Remove(player_logged, playerid);
}
return 1;
}
PHP:
Iter_Remove - Удаляет наш аккаунт из итератора player_logged
PHP:
public OnPlayerSpawn(playerid)
{
if(!Iter_Contains(player_logged, playerid)) return true;
SetPlayerColor(playerid, 0xFFFFFFFF);
SetPlayerSkin(playerid, PlayerInfo[playerid][pSkin]);
TogglePlayerSpectating(playerid, 0);
SetPlayerPos(playerid, 1757.4146,-1896.6600,13.5611);
SetPlayerFacingAngle(playerid, 270.0);
return 1;
}
PHP:
SetPlayerColor - Устанавливаем игроку клист
SetPlayerSkin - Устанавливаем игроку скин
TooglePlayerSpectating - 0 выходим из слежки | 1 - входим в слежку
SetPlayerPos - телепортируем игрока по коордам X, Y, Z
SetPlayerFacingAngle - Устанавливаем игроку поворот
PHP:
// ===================== [ DEFINE ] ===================== //
#undef MAX_PLAYERS
#define MAX_PLAYERS (10)
#define function%0(%1) forward%0(%1);public%0(%1)
#define COLOR_SERVER_EX "{BE2D2D}"
#define COLOR_SERVER 0xBE2D2DFF
#define NAME_SERVER "Tutorial RP"
#define VERS_SERVER "0.1"
#define BONUS_LEVEL 1
#define BONUS_MONEY 350
#define mysql_host "localhost"
#define mysql_user "root"
#define mysql_pass ""
#define mysql_base "servers"
#define GetName(%0) PlayerInfo[%0][pNickname]
// ===================== [ VARIABLE ] ===================== //
new MySQL:dbHandle, player_string[MAX_PLAYERS][512];
new skin_rega[2][9] = {{78,79,95,128,132,133,134,135},// Мужской
{31,38,39,54,77,129,130,131,151}};// Женский
#include "../sourse/stock/regex.pwn"
#include "../sourse/array/accounts.pwn"
#include "../sourse/function/accounts.pwn"
#include "../sourse/stock/accounts.pwn"
#include "../sourse/dialog/dialog.pwn"
PHP:
#undef - Убирает макрос
#define - Задаёт макрос
function - Макрос public + forward
COLOR_SERVER_EX - Макрос основного цвета для использование в format для убоства
COLOR_SERVER - Макрос основного цвета для использование в SendClientMessage для убоства
NAME_SERVER - Макрос названия сервера
VERS_SERVER - Макрос версии игрового мода
BONUS_LEVEL - Макрос бонуса уровня, выдающийся во время регистрации
BONUS_MONEY - Макрос бонуса денег, выдающийся во время регистрации
Про mysql_host, mysql_user, mysql_pass, mysql_base говорить не буду, выше описал
new - Объявление переменной
MySQL:dbHandle - Объявление переменной для работы с базой данных
player_string[MAX_PLAYERS][512] - Объявление переменной для работы с format
skin_rega - Переменная, которая нам при регистрации будет давать рандомный скин в зависимости от пола
В репозитории stock создадим файл regex.pwn
PHP:
stock IsValidNickname(const nickname[])
{
static Regex:regex;
if(!regex) regex = Regex_New("[A-Z][a-z]+_[A-Z][a-z]+");
return Regex_Check(nickname, regex);
}
stock IsValidEmail(const email[])
{
static Regex:regex;
if(!regex) regex = Regex_New("^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$");
return Regex_Check(email, regex);
}
stock IsValidPass(const password[])
{
static Regex:regex;
if(!regex) regex = Regex_New("^[a-zA-Z0-9]");
return Regex_Check(password, regex);
}
PHP:
IsValidNickname - Проверяет на символы никнейм игрока, если имеются запрещенные символы, то не даёт даже войти
IsValidEmail - Проверяет на символы электронную почту, если в ней имеются запрещенные символы и не соблюдаются обязательные условие, такие как @ и . то не даёт дальше регистрироватся
IsValidPass - Проверяет на символы пароль, чтобы в нём не было символов и кириллицы
PHP:
enum players{
pID,
pNickname[MAX_PLAYER_NAME],
pPassword[64],
pEmail[64],
pFriend,
pLearned,
pRassa,
pSex,
pSkin,
pMoney,
pLevel,
pExp,
}
new PlayerInfo[MAX_PLAYERS][players];
// Итераторы
new Iterator:player_logged<MAX_PLAYERS>;
PHP:
pID - id в базе данных
pNickname - никнейм
MAX_PLAYER_NAME - макрос, на 24 ячейки
pPassword - пароль
pEmail - электронная почта
pFriend - id в базе нашёго друга
pLearned - откуда узнали о сервере
pRassa - расса
pSex - пол
pSkin - скин(как будем выглядеть)
pMoney - деньги
pLevel - уровень
pExp - опыт
new Iterator:player_logged<MAX_PLAYERS>; - создаём итератор
PHP:
function OnPlayerJoin(playerid)
{
TogglePlayerSpectating(playerid, 1);
player_string[playerid][0] = 0;
GetPlayerName(playerid, PlayerInfo[playerid][pNickname], MAX_PLAYER_NAME);
mysql_format(dbHandle, player_string[playerid], 105, "SELECT `id`,`password` FROM `members` WHERE `nickname` = '%e' LIMIT 1", PlayerInfo[playerid][pNickname]);
new Cache: result = mysql_query(dbHandle, player_string[playerid]), rows = cache_num_rows();
if(rows) {}
else Dialog_Show(playerid, Dialog:register_1);
cache_delete(result);
return true;
}
function PlayerKick(playerid) return Kick(playerid);
PHP:
GetPlayerName - Получение никнейма игрока
mysql_format - форматируем запрос
mysql_query - отправляем запрос в базу
new Cache:result - создаем временный кеш
cache_delete - удаляем кеш
PHP:
#include "../sourse/dialog/accounts/reg.pwn"
PHP:
// ============ [ Пароль ] ============ //
DialogCreate:register_1(playerid)
{
player_string[playerid][0] = 0;
format(player_string[playerid], 180, "{FFFFFF}Добро пожаловать на"COLOR_SERVER_EX NAME_SERVER"\n{FFFFFF}Ваш логин: %s [{FF0000}свободен{FFFFFF}]\n\nДля продолжение регистрации введите пароль",PlayerInfo[playerid][pNickname]);
return Dialog_Open(playerid, Dialog:register_1, DIALOG_STYLE_INPUT, !"{FFFFFF}Регистрация "COLOR_SERVER_EX"[1/5]", player_string[playerid], !"Далее", !"Отмена");
}
DialogResponse:register_1(playerid, response, listitem, inputtext[])
{
if(!response) return SendClientMessage(playerid, COLOR_SERVER, !"Вы отказались от регистрации");
if(!strlen(inputtext) || strlen(inputtext) < 6 || strlen(inputtext) > 24 || IsValidPass(inputtext))
{
if(!strlen(inputtext)) SendClientMessage(playerid, COLOR_SERVER, !"[Ошибка]{FFFFFF} Вы нечего не ввели!");
else if(strlen(inputtext) < 6) SendClientMessage(playerid, COLOR_SERVER, !"[Ошибка]{FFFFFF} Пароль не может содержать менее 6-и символов!");
else if(strlen(inputtext) > 24) SendClientMessage(playerid, COLOR_SERVER, !"[Ошибка]{FFFFFF} Пароль не может содержать более 24-ех символов!");
else if(IsValidPass(inputtext)) SendClientMessage(playerid, COLOR_SERVER, !"[Ошибка]{FFFFFF} Пароль не может содержать запретные символы!");
return Dialog_Show(playerid, Dialog:register_1);
}
strmid(PlayerInfo[playerid][pPassword], inputtext, 0, strlen(inputtext), 24);
return Dialog_Show(playerid, Dialog:register_2);
}
DialogCreate:register_2(playerid) return Dialog_Open(playerid, Dialog:register_2, DIALOG_STYLE_INPUT, !"{FFFFFF}Регистрация "COLOR_SERVER_EX"[2/5]", !"{FFFFFF}Введите свою электронную почту\nВ случае утеря пароля\nвы сможете его восстановить", !"Далее", !"Назад");
DialogResponse:register_2(playerid, response, listitem, inputtext[])
{
if(!response) return Dialog_Show(playerid, Dialog:register_2);
if(!strlen(inputtext) || strlen(inputtext) < 6 || strlen(inputtext) > 64 || !IsValidEmail(inputtext))
{
if(!strlen(inputtext)) SendClientMessage(playerid, COLOR_SERVER, !"[Ошибка]{FFFFFF} Вы нечего не ввели!");
else if(strlen(inputtext) < 6) SendClientMessage(playerid, COLOR_SERVER, !"[Ошибка]{FFFFFF} Электронная почта не может содержать менее 6-и символов!");
else if(strlen(inputtext) > 64) SendClientMessage(playerid, COLOR_SERVER, !"[Ошибка]{FFFFFF} Электронная почта не может содержать более 24-ех символов!");
else if(!IsValidEmail(inputtext)) SendClientMessage(playerid, COLOR_SERVER, !"[Ошибка]{FFFFFF} Электронная почта не может содержать запретные символы!");
return Dialog_Show(playerid, Dialog:register_2);
}
strmid(PlayerInfo[playerid][pEmail],inputtext,0,strlen(inputtext),64);
return Dialog_Show(playerid, Dialog:register_3);
}
DialogCreate:register_3(playerid) return Dialog_Open(playerid, Dialog:register_3, DIALOG_STYLE_LIST, !"{FFFFFF}Регистрация "COLOR_SERVER_EX"[3/5]", !"{BBBBBB}Откуда вы о нас узнали?\n"COLOR_SERVER_EX"-{FFFFFF} Вкладка 'Hosted'\n"COLOR_SERVER_EX"-{FFFFFF} От друзей\n"COLOR_SERVER_EX"-{FFFFFF} На порталах/форумах\n"COLOR_SERVER_EX"-{FFFFFF} В поисковике\n"COLOR_SERVER_EX"-{FFFFFF} Другое", !"Далее", !"Назад");
DialogResponse:register_3(playerid, response, listitem, inputtext[])
{
if(!response) return Dialog_Show(playerid, Dialog:register_2);
if(!listitem) return Dialog_Show(playerid, Dialog:register_3);
PlayerInfo[playerid][pLearned] = listitem;
return Dialog_Show(playerid, Dialog:register_4);
}
DialogCreate:register_4(playerid)
{
switch(PlayerInfo[playerid][pLearned])
{
case 2: Dialog_Open(playerid, Dialog:register_4, DIALOG_STYLE_INPUT, !"{FFFFFF}Регистрация "COLOR_SERVER_EX"[3/5]", !"{FFFFFF}Вы указали что узнали об сервере "COLOR_SERVER_EX"'От друзей'\n{FFFFFF}Укажите ник приглосившего вас друга\n\nПри достижении вами "COLOR_SERVER_EX"4 уровня{ffffff} вы оба получите "COLOR_SERVER_EX"200.000$", !"Далее", !"Назад");
default: Dialog_Show(playerid, Dialog:register_5);
}
return true;
}
DialogResponse:register_4(playerid, response, listitem, inputtext[])
{
if(!response) return Dialog_Show(playerid, Dialog:register_3),PlayerInfo[playerid][pFriend] = 0;
if(!strlen(inputtext) || strlen(inputtext) < 6 || strlen(inputtext) > 24 || !IsValidNickname(inputtext))
{
if(!strlen(inputtext)) SendClientMessage(playerid, COLOR_SERVER, !"[Ошибка]{FFFFFF} Вы нечего не ввели!");
else if(strlen(inputtext) < 6) SendClientMessage(playerid, COLOR_SERVER, !"[Ошибка]{FFFFFF} Nickname друга не может содержать менее 6-и символов!");
else if(strlen(inputtext) > 64) SendClientMessage(playerid, COLOR_SERVER, !"[Ошибка]{FFFFFF} Nickname друга не может содержать более 24-ех символов!");
else if(!IsValidEmail(inputtext)) SendClientMessage(playerid, COLOR_SERVER, !"[Ошибка]{FFFFFF} Nickname друга не может содержать запретные символы!");
return Dialog_Show(playerid, Dialog:register_4);
}
player_string[playerid][0] = 0;
mysql_format(dbHandle, player_string[playerid], 80, "SELECT `id` FROM `members` WHERE `nickname` = '%e'", inputtext);
new Cache: result = mysql_query(dbHandle, player_string[playerid]), rows = cache_num_rows();
if(rows)
{
cache_get_value_name_int(0, "id", PlayerInfo[playerid][pFriend]);
Dialog_Show(playerid, Dialog:register_5);
}
else
{
SendClientMessage(playerid, 0xff0000ff, !"[Ошибка]{FFFFFF} Данный ник не найден в базе данных!");
Dialog_Show(playerid, Dialog:register_4);
}
cache_delete(result);
return true;
}
DialogCreate:register_5(playerid) return Dialog_Open(playerid, Dialog:register_5, DIALOG_STYLE_LIST, !"{FFFFFF}Регистрация "COLOR_SERVER_EX"[4/5]", !"{BBBBBB}Укажите рассу персонажа\n"COLOR_SERVER_EX"-{FFFFFF} Европеойдная\n"COLOR_SERVER_EX"-{FFFFFF} Монголоидная\n"COLOR_SERVER_EX"-{FFFFFF} Азиатская", !"Далее", !"Назад");
DialogResponse:register_5(playerid, response, listitem, inputtext[])
{
if(!response) return Dialog_Show(playerid, Dialog:register_3);
if(!listitem) return Dialog_Show(playerid, Dialog:register_5);
PlayerInfo[playerid][pRassa] = listitem;
return Dialog_Show(playerid, Dialog:register_6);
}
DialogCreate:register_6(playerid) return Dialog_Open(playerid, Dialog:register_6, DIALOG_STYLE_LIST, !"{FFFFFF}Регистрация "COLOR_SERVER_EX"[5/5]", !"{BBBBBB}Выберите пол персонажа\n"COLOR_SERVER_EX"-{FFFFFF} Мужской\n"COLOR_SERVER_EX"-{FFFFFF} Женский", !"Далее", !"Назад");
DialogResponse:register_6(playerid, response, listitem, inputtext[])
{
if(!response) return Dialog_Show(playerid, Dialog:register_5);
if(!listitem) return Dialog_Show(playerid, Dialog:register_6);
PlayerInfo[playerid][pSex] = listitem;
PlayerInfo[playerid][pSkin] = skin_rega[PlayerInfo[playerid][pSex]-1][random(9)];
create_accounts(playerid);
return true;
}
PHP:
stock create_accounts(playerid)
{
player_string[playerid][0] = 0;
PlayerInfo[playerid][pMoney] = BONUS_MONEY;
PlayerInfo[playerid][pLevel] = BONUS_LEVEL;
mysql_format(dbHandle, player_string[playerid], 350, "INSERT INTO `members` (`nickname`,`password`,`email`,`friend`,`rassa`,`learned`,`sex`,`skin`,`money`,`level`) VALUES ('%s','%s','%s',%i,%i,%i,%i,%i,%i,%i)", PlayerInfo[playerid][pNickname], PlayerInfo[playerid][pPassword], PlayerInfo[playerid][pEmail], PlayerInfo[playerid][pFriend], PlayerInfo[playerid][pRassa], PlayerInfo[playerid][pLearned], PlayerInfo[playerid][pSex], PlayerInfo[playerid][pSkin], PlayerInfo[playerid][pMoney], PlayerInfo[playerid][pLevel]);
mysql_query(dbHandle, player_string[playerid]);
Iter_Add(player_logged, playerid);
GivePlayerMoney(playerid, PlayerInfo[playerid][pMoney]);
SetPlayerScore(playerid, PlayerInfo[playerid][pLevel]);
SpawnPlayer(playerid);
return true;
}
stock clear_player(playerid)
{
PlayerInfo[playerid][pID] = -1;
strdel(PlayerInfo[playerid][pPassword],0,64);
strdel(PlayerInfo[playerid][pEmail],0,64);
PlayerInfo[playerid][pLearned] = PlayerInfo[playerid][pFriend] = PlayerInfo[playerid][pSex] = PlayerInfo[playerid][pSkin] = PlayerInfo[playerid][pMoney] = PlayerInfo[playerid][pLevel] = PlayerInfo[playerid][pExp] = 0;
return true;
}
stock KickEx(playerid) return SetTimerEx("PlayerKick", 45, false, "d", playerid);
По итогу все готово.
Автор: Gazmerin
Спасибо за внимание
Последнее редактирование: