Русское сообщество по скриптингу

Связка IPB + SERVER

Статьи или фрагменты кода для новичков и уже опытных скриптеров по AMXX.

Модератор: Chuvi

Правила форума
1. Запрещено материться и оскорблять других участников форума.
2. Запрещен флуд, оффтоп, дабл постинг во всех разделах форума, кроме раздела "Болтовня".
3. Запрещено взламывать сайт/форум или наносить любой вред проекту.
4. Запрещено рекламировать другие ресурсы.
5. Запрещено создавать темы без информативного названия. Название темы должно отображать ее смысл.

В данном разделе форума разрешено создавать темы, касающие только обучающему материалу по AMX Mod X.

Связка IPB + SERVER

Сообщение crash94 » 19 дек 2013, 06:36

Привет всем.
Не так давно мне понадобился способ связки IPB форума с сервером для получение информации зарегистрирован ли игрок или нет. Использовать mysql в данном случаи не совсем разумно, ибо требовалось это всё для cso где и так нагрузка жесткая и ответ будет приходит в районе 3-4 секунд, что не очень прикольно.

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

От вас требуется:
IPB Версия от 3.xx
Сервер
Мозг

Принцип работы:
На скрипт будет уходить get-запрос с данными, после чего от него уйдет ответ через rcon протокол.

Плагин:
[pawn]
  1. #include <amxmodx>

  2. #include <amxmisc>

  3. #include <sockets>

  4.  

  5. #define PLUGIN  "IPBAuth"

  6. #define VERSION         "1.0"

  7. #define AUTHOR  "CrAsH"

  8.  

  9. #define HOST            "hard-cs.ru" //Куда уйдет запрос

  10. #define HANDLER  "/check_reg.php" //Скрипт обработчика

  11.  

  12. new iPlayerAuth[33] //Будет хранить авторизовался ли игрок или нет

  13.  

  14. public plugin_init()

  15. {

  16.         register_plugin(PLUGIN, VERSION, AUTHOR)

  17.  

  18.         register_clcmd("say /auth_good", "AuthTest") //Запуск проверки авторизации( Будет верная )

  19.         register_clcmd("say /auth_fail1", "AuthTest1") //Запуск проверки авторизации( Изер не найден )

  20.         register_clcmd("say /auth_fail2", "AuthTest2") //Запуск проверки авторизации( Изер найден, неверный пасс )

  21.  

  22.         register_concmd("forum_auth_resuilt", "CheckReg") //Консольная команда для получение ответа от скрипта

  23. }

  24.  

  25. public AuthTest(id)

  26. {

  27.         if(iPlayerAuth[id])

  28.         {

  29.                 ChatColor(id, "!tВы !yуспешно !gавторизовались !yна !tфоруме")

  30.                 return PLUGIN_HANDLED

  31.         }

  32.  

  33.         GetForumAuth(id, "amx-x", "123456")

  34.         return PLUGIN_HANDLED

  35. }

  36.  

  37. public AuthTest1(id)

  38. {

  39.         GetForumAuth(id, "amx-x123", "123456")

  40.         return PLUGIN_HANDLED

  41. }

  42.  

  43. public AuthTest2(id)

  44. {

  45.         GetForumAuth(id, "amx-x", "12345678")

  46.         return PLUGIN_HANDLED

  47. }

  48.  

  49. public CheckReg()

  50. {

  51.         new szResuilt[128] //Будет хранить всё, что пришло

  52.         read_args(szResuilt, charsmax( szResuilt )) //Формируем всё в 1 строку

  53.  

  54.         new szParseID[32], szParseType[32], szParseForumID[32], szParseForunMessage[32] //Парсим то, что пришло

  55.  

  56.         parse(szResuilt,

  57.                 szParseID, charsmax( szParseID ),

  58.                 szParseType, charsmax( szParseType ),

  59.                 szParseForumID, charsmax( szParseForumID ),

  60.                 szParseForunMessage, charsmax( szParseForunMessage )

  61.         )

  62.  

  63.         new id = str_to_num( szParseID ) //Получаем id игрока, который ввел данные

  64.         new iType = str_to_num( szParseType ) //Получаем число, которое отправили

  65.         new iForumID = str_to_num( szParseForumID ) //Получаем id игрока, который у него на форуме

  66.         new iForumMsg = str_to_num( szParseForunMessage ) //Получаем сколько сообщений у него на форуме

  67.  

  68.         if(!is_user_connected(id)) //Если игрок вдруг вышел, то нахрен это нужно

  69.                 return PLUGIN_CONTINUE

  70.  

  71.         switch( iType ) //Проверяем что пришло

  72.         {

  73.                 case 1: //Пользователь не найден

  74.                 {

  75.                         ChatColor(id, "!tПользователь !gне найден")

  76.                 }

  77.  

  78.                 case 2: //Пользователь найден, но неверный пароль

  79.                 {

  80.                         ChatColor(id, "!tНеверный !gпароль")

  81.                 }

  82.  

  83.                 case 3: //Всё круто =)

  84.                 {

  85.                         iPlayerAuth[id] = true

  86.        

  87.                         ChatColor(id, "!tВы !yуспешно !gавторизовались !yна !tфоруме")

  88.                         ChatColor(id, "!tВаш !yid: !g%d", iForumID)

  89.                         ChatColor(id, "!yУ !tвас !g%d !yсообщений на форуме", iForumMsg)

  90.                 }

  91.         }

  92.         return PLUGIN_CONTINUE

  93. }

  94.  

  95. stock GetForumAuth(id, szName[], szPassword[])

  96. {

  97.         new szText[512] //Массив для записи запроса

  98.         new szIP[32], szRcon[32] //Получаемые данные

  99.  

  100.         get_user_ip(0, szIP, charsmax( szIP ), 0) //IP:PORT

  101.         get_cvar_string("rcon_password", szRcon, charsmax( szRcon )) //Rcon

  102.  

  103.         if(!strlen( szRcon )) //если ркон пустой

  104.         {

  105.                 new iRandom = random_num(10000000, 99999999) //Создаем рандомный Rcon

  106.                 formatex(szRcon, charsmax( szRcon ), "%d", iRandom) //записываем

  107.  

  108.                 set_cvar_string("rcon_password", szRcon)

  109.         }

  110.  

  111.         //Создаем запрос

  112.         formatex(szText, charsmax( szText ), "GET %s?ip=%s&rconpass=%s&id=%d&name=%s&password=%s HTTP/1.1^nHOST:%s^r^n^r^n", HANDLER, szIP, szRcon, id, szName, szPassword, HOST)

  113.  

  114.         new iError //Будет хранить ошибку, если таковые имеются

  115.         new iSocket = socket_open(HOST, 80, SOCKET_TCP, iError) //Открываем соединение с хостом

  116.  

  117.         socket_send(iSocket, szText, charsmax( szText ))  //Отправляем запрос на скрипт

  118.         socket_close(iSocket) //Закрываем соединения

  119. }

  120.  

  121. stock ChatColor(const id, const input[], any:...)

  122. {

  123.         new count = 1, players[32]

  124.         static msg[191]

  125.         vformat(msg, 190, input, 3)

  126.        

  127.         replace_all(msg, 190, "!g", "^4")

  128.         replace_all(msg, 190, "!y", "^1")

  129.         replace_all(msg, 190, "!t", "^3")

  130.        

  131.         if (id) players[0] = id; else get_players(players, count, "ch")

  132.         {

  133.                 for (new i = 0; i < count; i++)

  134.                 {

  135.                         if (is_user_connected(players[i]))

  136.                         {

  137.                                 message_begin(MSG_ONE_UNRELIABLE, get_user_msgid("SayText"), _, players[i]);

  138.                                 write_byte(players[i]);

  139.                                 write_string(msg);

  140.                                 message_end();

  141.                         }

  142.                 }

  143.         }

  144. }
[/pawn]

Обработчик check_reg.php
[pawn]
  1. <?php

  2.         $ip                     = $_GET['ip']; //Получаем IP:Port

  3.         $rcon                   = $_GET['rconpass']; //Получаем Rcon

  4.         $id                     = $_GET['id']; //Получаем id игрока

  5.         $name           = $_GET['name']; //Получаем ник

  6.         $md5Pass        = $_GET['password']; //Получаем пасс

  7.  

  8.         include("rcon_hl_net.inc"); //Подключаем inc для отправки ответа

  9.         $server = new Rcon(); //создаем

  10.         $array = explode(':', $ip); //делим ип и пароль по разделителю

  11.  

  12.         //Собираем данные для запроса

  13.         $server_ip=                     $array[0];

  14.         $server_port=                   $array[1];

  15.         $server_password=       $rcon;

  16.  

  17.         //Подключаем всю лабуду от ipb

  18.         define('IPS_ENFORCE_ACCESS', TRUE);

  19.         define('IPB_THIS_SCRIPT', 'public');

  20.  

  21.         require_once( './initdata.php' );

  22.         require_once( IPS_ROOT_PATH . 'sources/base/ipsRegistry.php' );

  23.         require_once( IPS_ROOT_PATH . 'sources/base/ipsController.php' );

  24.  

  25.         $registry = ipsRegistry::instance();

  26.         $registry->init();

  27.  

  28.         $member = IPSMember::load( $name, 'none', 'username' ); //Получаем массив данных

  29.  

  30.         if(!$member['member_id']) //Если идентификатор форума не найден

  31.         {

  32.                 $server->Connect($server_ip, $server_port, $server_password); //Коннектимся к серверу

  33.  

  34.                 $command = "forum_auth_resuilt ".$id." 1"; //Создаем команду для отправки и передаем число 1, что будет говорить о том, что юзера нет

  35.                 $server->RconCommand($command); //отправляем

  36.                 $server->Disconnect(); //закрываем соединение

  37.  

  38.                 exit; //Заканчиваем

  39.         }

  40.  

  41.         //Форматируем символы пароля

  42.         $md5Pass = str_replace("gigahash", "#", $md5Pass);

  43.         $md5Pass = str_replace("&", "&amp;", $md5Pass);

  44.         $md5Pass = str_replace("\\", "&#092", $md5Pass);

  45.         $md5Pass = str_replace("!", "&#33;", $md5Pass);

  46.         $md5Pass = str_replace("$", "&#036;", $md5Pass);

  47.         $md5Pass = str_replace("\", "&quot;", $md5Pass);

  48.         $md5Pass = str_replace("<", "&lt;", $md5Pass);

  49.         $md5Pass = str_replace(">", "&gt;", $md5Pass);

  50.         $md5Pass = str_replace("'", "&#39;", $md5Pass);

  51.         $md5Pass=md5($md5Pass);

  52.  

  53.         if(IPSMember::authenticateMember( $member['member_id'], $md5Pass ))

  54.         {

  55.                 $server->Connect($server_ip, $server_port, $server_password);  //Коннектимся к серверу

  56.                 $command="forum_auth_resuilt ".$id." 3 ".$member['member_id']." ".$member['posts'].""; //Создаем команду для отправки и передаем число 3, что будет говорить о том, что всё круто

  57.                 $res = $server->RconCommand($command); //отправляем

  58.                 $server->Disconnect(); //закрываем соединение

  59.         }else{

  60.                 $server->Connect($server_ip, $server_port, $server_password);  //Коннектимся к серверу

  61.                 $command="forum_auth_resuilt ".$id." 2"; //Создаем команду для отправки и передаем число 2, что будет говорить о том, что пасс неверный

  62.                 $res = $server->RconCommand($command); //отправляем

  63.                 $server->Disconnect(); //закрываем соединение

  64.         }

  65. ?>
[/pawn]

Способ установки:
1) Компилируем плагин в кодировке utf8 без bom( Для отображение русского текста )
2) Кидаем check_reg.php в корень ipb( Где файлы index.php, initdata.php )
3) Проверяем, включен ли модуль socket в moduels.ini
4) Перезапускаем серв, пробуем

Команды:
say /auth_good //Данные будут верные, авторизация пройдет
say /auth_fail1 //Юзер не найден в базе( Логин не верный )
say /auth_fail2 //Юзер найден, но пароль неверный

Скриншоты:
2013-12-19_00001.jpg

2013-12-19_00002.jpg

2013-12-19_00003.jpg

4.JPG


Вы можете передать любые данные из таблицы members, главное правильно указать ячейки.
Применение плагина может любым. Главное иметь воображение.

Так же прикладываю готовые в файлы, чтобы не было путаниц
IPBAuth.sma

rcon_hl_net.inc

check_reg.php.txt
Аватара пользователя
crash94
 
Сообщения: 683
Зарегистрирован: 25 фев 2010, 16:34
Забанен
Благодарил (а): 80 раз.
Поблагодарили: 317 раз.

Re: Связка IPB + SERVER

Сообщение quckly » 20 дек 2013, 14:45

Pain96, не более 32 запросов в секунду.
Аватара пользователя
quckly
Скриптер
 
Сообщения: 403
Зарегистрирован: 20 ноя 2009, 10:03
Благодарил (а): 41 раз.
Поблагодарили: 243 раз.
Опыт программирования: Около 6 месяцев
Языки программирования: Counter-Strike 1.6

Re: Связка IPB + SERVER

Сообщение crash94 » 20 дек 2013, 15:12

BaHeK писал(а):
Pain96 писал(а):
quckly писал(а):А не проще и быстрее выполнить sql запрос?


Здесь речь скорее не про "проще", "не проще". Представь сколько будет запросов, как думаешь серверу будет все равно?

Для каждой команды 1 mysql запрос.

register_concmd("forum_auth_resuilt", "CheckReg") //Консольная команда для получение ответа от скрипта

Зачем, когда есть socket_recv?

А ты вообще работал с это функцией?В ответ тебе придет нечто такого

[pawn]
  1. HTTP/1.1 200 OK

  2. Date: 20 Dec 2013 15:00:22 GMT

  3. Server: Apache/2.2.22 PHP/5.2.3

  4. X-Powered-By: PHP/5.2.3

  5. Expires: Thu, 19 Nov 1981 08:52:00 GMT

  6. Cache-Control: no-store, no-ca

  7. ml xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru" lang="ru">

  8. и тут ответ.
[/pawn]

Ты этот мусор как чистить собираешься?

Добавлено спустя 2 минуты 49 секунд:
quckly писал(а):Pain96, не более 32 запросов в секунду.

Никто не ставил под сомнения использования mysql, но в моей ситуации это было невозможно и я решил сделать способ куда практичнее. К тому не будем забывать, что некоторые хосты блочат частные запросы к базе, что вообще не гуд.
Аватара пользователя
crash94
 
Сообщения: 683
Зарегистрирован: 25 фев 2010, 16:34
Забанен
Благодарил (а): 80 раз.
Поблагодарили: 317 раз.

Re: Связка IPB + SERVER

Сообщение BaHeK » 20 дек 2013, 16:53

crash94 писал(а):
BaHeK писал(а):
Pain96 писал(а):
quckly писал(а):А не проще и быстрее выполнить sql запрос?


Здесь речь скорее не про "проще", "не проще". Представь сколько будет запросов, как думаешь серверу будет все равно?

Для каждой команды 1 mysql запрос.

register_concmd("forum_auth_resuilt", "CheckReg") //Консольная команда для получение ответа от скрипта

Зачем, когда есть socket_recv?

А ты вообще работал с это функцией?В ответ тебе придет нечто такого

[pawn]
  1. HTTP/1.1 200 OK

  2. Date: 20 Dec 2013 15:00:22 GMT

  3. Server: Apache/2.2.22 PHP/5.2.3

  4. X-Powered-By: PHP/5.2.3

  5. Expires: Thu, 19 Nov 1981 08:52:00 GMT

  6. Cache-Control: no-store, no-ca

  7. ml xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru" lang="ru">

  8. и тут ответ.
[/pawn]

Ты этот мусор как чистить собираешься?

Ответ в json передать и получить текст после первой скобки "{" так сложно?

Ну или разделить заголовок и содержимое каким-нибудь, символом, который не встречается в заголовке, куча вариантов

[spoiler]Я VS VolksWagen POLO, МКАД
Психанул или моя русская рулетка
http://cs618330.vk.me/v618330946/8c16/hEeTVyYjCZw.jpg - Ой как плохо поступил[/spoiler]
Аватара пользователя
BaHeK
Скриптер
 
Сообщения: 544
Зарегистрирован: 26 авг 2011, 19:32
Откуда: Москва
Благодарил (а): 403 раз.
Поблагодарили: 261 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6

Re: Связка IPB + SERVER

Сообщение crash94 » 20 дек 2013, 17:15

с таким же успехом можно в mysql юзать - куда проще.
Аватара пользователя
crash94
 
Сообщения: 683
Зарегистрирован: 25 фев 2010, 16:34
Забанен
Благодарил (а): 80 раз.
Поблагодарили: 317 раз.

Re: Связка IPB + SERVER

Сообщение BaHeK » 20 дек 2013, 17:34

crash94 писал(а):с таким же успехом можно в mysql юзать - куда проще.

Проще и быстрее получится

[spoiler]Я VS VolksWagen POLO, МКАД
Психанул или моя русская рулетка
http://cs618330.vk.me/v618330946/8c16/hEeTVyYjCZw.jpg - Ой как плохо поступил[/spoiler]
Аватара пользователя
BaHeK
Скриптер
 
Сообщения: 544
Зарегистрирован: 26 авг 2011, 19:32
Откуда: Москва
Благодарил (а): 403 раз.
Поблагодарили: 261 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6

Re: Связка IPB + SERVER

Сообщение crash94 » 21 дек 2013, 09:25

когда у тебя cso будет занимать целое ядро ты задумаешься стоит ли юзать mysql =)
Аватара пользователя
crash94
 
Сообщения: 683
Зарегистрирован: 25 фев 2010, 16:34
Забанен
Благодарил (а): 80 раз.
Поблагодарили: 317 раз.

Re: Связка IPB + SERVER

Сообщение BaHeK » 21 дек 2013, 15:10

crash94 писал(а):когда у тебя cso будет занимать целое ядро ты задумаешься стоит ли юзать mysql =)

Разве php скрипт не юзает mysql?
А теперь представь, что обработается быстрее
1) - запрос в mysql
- ответ из mysql
- обработка ответа
2) - отправка сокета на php скрипт
- запрос в mysql
- ответ из mysql
- отправка rcon команды на сервер
- обработка ответа

[spoiler]Я VS VolksWagen POLO, МКАД
Психанул или моя русская рулетка
http://cs618330.vk.me/v618330946/8c16/hEeTVyYjCZw.jpg - Ой как плохо поступил[/spoiler]
Аватара пользователя
BaHeK
Скриптер
 
Сообщения: 544
Зарегистрирован: 26 авг 2011, 19:32
Откуда: Москва
Благодарил (а): 403 раз.
Поблагодарили: 261 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6

Re: Связка IPB + SERVER

Сообщение crash94 » 21 дек 2013, 16:08

BaHeK писал(а):
crash94 писал(а):когда у тебя cso будет занимать целое ядро ты задумаешься стоит ли юзать mysql =)

Разве php скрипт не юзает mysql?
А теперь представь, что обработается быстрее
1) - запрос в mysql
- ответ из mysql
- обработка ответа
2) - отправка сокета на php скрипт
- запрос в mysql
- ответ из mysql
- отправка rcon команды на сервер
- обработка ответа


Кажется ты до конца не понимаешь всю специфику приведения данного примера. Он был создан с 1 и 1 только целью - не грузить сервак частыми запросами со стороны mysql. Я лишь поделился мысли и не прошу выдать мне оскар.
Аватара пользователя
crash94
 
Сообщения: 683
Зарегистрирован: 25 фев 2010, 16:34
Забанен
Благодарил (а): 80 раз.
Поблагодарили: 317 раз.

Re: Связка IPB + SERVER

Сообщение 9iky6 » 22 дек 2013, 00:30

crash94, пили дальше тутор по сокетам! :thumbs_up
BaHeK, так надежнее будет! Через sql запрос через раз доходит :( к сожалению. Хотя и на много удобнее и проще
Аватара пользователя
9iky6
 
Сообщения: 2174
Зарегистрирован: 30 янв 2012, 19:07
Откуда: Россия
Благодарил (а): 375 раз.
Поблагодарили: 707 раз.

Re: Связка IPB + SERVER

Сообщение BaHeK » 22 дек 2013, 01:14

crash94 писал(а):Он был создан с 1 и 1 только целью - не грузить сервак частыми запросами со стороны mysql.

Все запросы асинхронные сделать и тогда все ок будет. А вообще на вкус и цвет товарища нет, кому как удобней, тот так и сделает.
9iky6 писал(а):BaHeK, так надежнее будет! Через sql запрос через раз доходит :( к сожалению. Хотя и на много удобнее и проще

Бред, все нормально доходит.

[spoiler]Я VS VolksWagen POLO, МКАД
Психанул или моя русская рулетка
http://cs618330.vk.me/v618330946/8c16/hEeTVyYjCZw.jpg - Ой как плохо поступил[/spoiler]
Аватара пользователя
BaHeK
Скриптер
 
Сообщения: 544
Зарегистрирован: 26 авг 2011, 19:32
Откуда: Москва
Благодарил (а): 403 раз.
Поблагодарили: 261 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6

Пред.След.

Вернуться в Статьи / фрагменты кода

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 8

cron