Приветствую!
Недавно пришла идея ограничить доступ к авторизации, путем прикрепления к аккуанту списка разрешенных подсетей.
Т.е. каждый игрок может указать до 3-ех подсетей, с которых будет возможна авторизация.
Что такое подсеть? Это часть IP-адреса. Я взял только 2 первых значения.
Например:
Как это работает:
Игрок вводит команду /subnet , появляется диалог:
Игрок нажимает "Далее" появляется новый диалог:
--------------------------------------------
Использовать текущую подсеть - подсеть берется из текущего IP-адреса игрока
Ввод подсетей - При нажатии на этот пункт появляется диалог:
Подсети нужно вводить через запятую, без использования пробелов или сторонних символов.
Собственно, если ввод будет неверный - система напишет об этом
Удалить ограничение - убирает ограничение, теперь все подсети будут иметь доступ к авторизации.
Если игрок попытается подключиться с ип, подсеть которого не имеет доступа, то игрока кикнет:
Ну, вроде я объяснил, как это работает, теперь перейдем непосредственно к коду
Создание системы:
1) Вам необходимо сделать в своем моде сохранение в аккуант игрока строку с ключом;
Если у вас есть система регистрации/авторизации, для вас не будет это проблемой.
От вас требуются начальные знания Pawn.
2) При регистрации этому ключу присвоить значение "none"
3) Перед авторизацией нужно прочесть из файла аккуанта эту строку и добавить перед диалогом:
PHP код:
GetFileMask(playerid, string); // где string - строка, которая содержит данные из файла аккуанта (можете изменить на свое название)
4) В public OnPlayerCommandText(playerid, cmdtext[]) добавляем команду:
PHP код:
if(!strcmp(cmdtext,"/subnet",true))
{
ShowPlayerDialog(playerid, D_SUBNET, DIALOG_STYLE_MSGBOX, " ","{ffcc00}Внимание!!! Неверная установка подсети приведет к тому, что вы не сможете получить доступ к аккуанту!\nЭтот мастер поможет заблокировать доступ к аккуанту с подсетей, которые не будут вами указаны.\nНажмите {ff0000}\"Далее\" {ffcc00}для продолжения.","Далее","Отмена");
return 1;
}
//
5) В public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[]) добавляем:
PHP код:
switch (dialogid)
{
case D_SUBNET:
{
if(!response) return 1;
new string[1024];
format(string,sizeof(string),"{ffcc00}Использовать текущую подсеть[{00ff00}%s{ffcc00}]\n{ffcc00}Ввод подсетей (максимум 3)\n{ffcc00}Удалить ограничение",GetPlayerSubNet(playerid));
ShowPlayerDialog(playerid, D_SUBNET2, DIALOG_STYLE_LIST, "Ограничение по подсети", string, "Ok", "Cancel");
}
case D_SUBNET2:
{
if(!response) return 1;
switch(listitem)
{
case 0,2:
{
if(listitem == 0)
{
//здесь запишите GetPlayerSubNet(playerid) в файл аккуанта игрока
SendClientMessage(playerid,0xFF00FF,"Вы установили доступ к аккуанту только с текущей подсети");
}
else
{
//здесь запишите "none" в файл аккуант игрока
SendClientMessage(playerid,0xFF00FF,"Вы отключили ограничение авторизации по подсети.");
}
}
case 1:
{
ShowPlayerDialog(playerid, D_SUBNET3, DIALOG_STYLE_INPUT, "{7fc7ff}Ввод подсети (подсетей)","{ffcc00}Чтобы разрешить доступ к авторизации с нескольких подсетей, их необходимо перечислить через запятую.\n{ffcc00}Максимальное количество подсетей: 3\n{ff0000}Примеры ввода:\n{ff0000}77.34,15.56 {ffcc00}- разрешает авторизацию с 2-ух подсетей (77.34 и 15.56)\n{ff0000}50.40 {ffcc00}- разрешает авторизацию только с одной подсети","Ок","Отмена");
}
}
}
case D_SUBNET3:
{
if(!CheckMask(playerid,inputtext) || !response) return 1;
new string[256];
format(string,sizeof(string),"Вы установили доступ к аккуанту только с подсетей (подсети) - %s",inputtext);
SendClientMessage(playerid,0xFF00FF,string);
//здесь запишите inputtext в файл аккуанта игрока
}
}
6) Ко всем #define вверху мода добавить:
PHP код:
//ид диалогов, при необходимости - изменить!!!!
#define D_SUBNET 100
#define D_SUBNET2 101
#define D_SUBNET3 102
7) Ну и самое главное - функции)
Вниз мода добавить:
PHP код:
stock GetFileMask(playerid, IP[])
{
if(!strcmp(IP,"none")) return 1;
new cIP[16],CountMask,FileMask[3][8];
cIP = GetPlayerSubNet(playerid);
for(new i, oldpos; i <= strlen(IP); i++)
{
if(IP[i] == 0x2C || IP[i] == EOS)
{
strmid(FileMask[CountMask], IP, oldpos, i);
oldpos = i + 1;
CountMask++;
}
}
for(new i; i != CountMask; i++)
{
if(!strcmp(cIP,FileMask[i])) return 1;
}
SendClientMessage(playerid,0xFF0000,"Для данного аккуанта авторизация доступна только для некоторых подсетей.");
Kick(playerid);
return 1;
}
stock GetPlayerSubNet(playerid)
{
new cIP[16];
GetPlayerIp(playerid, cIP, sizeof(cIP));
for(new i, bool:point; i != strlen(cIP); i++)
{
if(cIP[i] != 0x2E) continue;
if(!point) point = true;
else
{
strmid(cIP, cIP, 0, i);
break;
}
}
return cIP;
}
stock CheckMask(playerid,IP[])
{
new letter[4+1];
if(strlen(IP) > 0x17) return SendClientMessage(playerid,0xFF0000,"Неверный ввод!Пишите подсети через запятую, без использования пробелов! Максимум 3 подсети!"), false;
for(new i, oldpos, bool:point; i <= strlen(IP); i++)
{
if((IP[i] != EOS && IP[i] != 0x2E && IP[i] != 0x2C) && (IP[i] > 0x39 || IP[i] < 0x30)) return SendClientMessage(playerid,0xFF0000,"Неверный ввод! Используйте только \"0-9\",\".\",\",\""), false;
if((IP[i] == 0x2E && !point) || (IP[i] == 0x2C && point) || (IP[i] == EOS && point))
{
strmid(letter, IP, oldpos, i);
oldpos = i + 1;
if(strval(letter) < 0x0 || strval(letter) > 0xFF || strlen(letter) == 0x0 || strlen(letter) > 0x3) return SendClientMessage(playerid,0xFF0000,"Неверный ввод!Маска подсети:0-255.0-255"), false;
if(IP[i] == 0x2E) point = true;
else point = false;
}
else if((IP[i] == 0x2E && point) || (IP[i] == 0x2C && !point) || (IP[i] == EOS && !point)) return SendClientMessage(playerid,0xFF0000,"Неверный ввод!Пишите подсети через запятую, без использования пробелов! Максимум 3 подсети!"), false;
}
return true;
}
Ну, вроде все...
Ничего не поняли выше? Скачайте готовый фс!
Ссылка на фс: http://cruelgame.ru/fs/SubNetProject.rar