Введение.
В этой статье я постараюсь объяснить как можно дать бан(блокировку какую-либо) по кукам через МОТД окно клиента. На STEAM клиенте может не работать! Для примера возьмём пермаментный бан. Для тестирования нам понадобится web-сервер с поддержкой PHP и MYSQL.
Как будет работать блокировка? При бане открываем игроку MOTD окно, вместо обычной странички показываем ему свою с баном. При последующем подключение, будет идти проверка так же через MOTD окно(со своим скриптом), если кука отсутствует(нету бана) значит всё хорошо, если есть значит игрок забанен и кикаем его. Ну и так, думаю начнём.
Сначала обычное подключение библиотек:
[pawn]
- #include <amxmodx>
- #include <sqlx>
Теперь нужно хукнуть MOTD окно:
[pawn]
- public plugin_init () {
- // Регистрируем нужное событие
- register_message (get_user_msgid ("MOTD"),"start_motd")
- }
Создадим булевую, с помощью неё будем отсеивать все хукнутые MOTD окна(нам нужен только первый)
[pawn]
- static bool: g_bMotdStatus[33]
Создаём подключения к Mysql серверу:
[pawn]
- static Handle: g_hSql
- static Handle: g_hSqlConnect
Подключаемся к Mysql:
[pawn]
- public plugin_init () {
- // Через секунду подключаемся
- set_task (1.0,"mysql_integration")
- }
Здесь само подключение :
[pawn]
- public mysql_integration () {
- // Переменные под возможные ошибки
- new sError[64];
- new iError;
- // Подключаемя к mysql
- g_hSql = SQL_MakeDbTuple("localhost","root","","database");
- g_hSqlConnect = SQL_Connect(g_hSql,iError,sError,127);
- // Если неудача - выводим сообщение об ошибке
- if (g_hSqlConnect == Empty_Handle) server_print ("Error #%d (%s)",iError,sError);
- // Иначе информируем об успешном подключении
- else server_print ("Successfully connected to database");
- }
Во время подключения игрока, обнуляем переменную:
[pawn]
- public client_connect (id) {
- // Обнуляем переменную статуса показа мотд
- g_bMotdStatus[id] = false;
- }
Теперь показ MOTD окна игроку. Инфа о клиенте будет отсылаться на web-сервер, отсылаются его userid методом get:
[pawn]
- public start_motd(const iMsg, const iMsgDest, const iEnt) {
- // Если начальное мотд-окно уже поазывалось - выходим из подпрограммы
- if (g_bMotdStatus[iEnt] == true) return PLUGIN_CONTINUE;
- // Формируем url к скрипту
- new sBuffer[256];
- format (sBuffer,255,"http://localhost/check.php?id=%d",sBuffer,get_user_userid (iEnt));
- // Показываем игроку мотд
- show_motd (iEnt,sBuffer,"Counter-Strike server");
- g_bMotdStatus[iEnt] = true;
- // Блокируем стандартное окно
- return PLUGIN_HANDLED;
- }
С этим вроде всё, но еще вернёмся!
Теперь web-сервер.
Файл check.php - его задача проверить игрока на куку отвечающую за бан и внести в mysql таблицу индекс кука.
Но так как у нас идеализированный пример мы поступим проще - в таблице будет только одно поле и оно будет называться userid, в это поле попадет индекс игрока в случае наличии куки.
Подключаемся к БД:
[pawn]
- <?php
- // Подключаемся к mysql (хост, пользователь, пароль)
- $connect = mysql_connect ("localhost","root","");
- // В случае неудачи выводим на экран ошибки
- if (!$connect) die ('Error: '.mysql_error());
- // Подключаемся к базе данных (название бд, указатель на подключение)
- $database = mysql_select_db ("database",$connect);
- // В случае неудачи выводим на экран ошибки
- if (!$database) die ('Error: '.mysql_error());
- ?>
Если же кука есть, то вносим индекс в таблицу:
[pawn]
- <?php
- if (strlen ($_COOKIE['ban_info'])) {
- // Формируем запрос к бд
- $buffer =
- "INSERT INTO table (userid)
- VALUES (".$_GET['id'].")";
- // Вносим новый индекс в мускуль-таблицу
- $query = mysql_query ($buffer);
- }
- ?>
Опять к серверной части. Через три секунды после показа MOTD окна запускаем проверку на индекс в БД:
[pawn]
- set_task (3.0,"check_user_ban_info",iEnt)
Запрос к Mysql:
[pawn]
- public check_user_ban_info (id) {
- // Переменная под возможные ошибки
- new sError[64];
- // Подготавливаем запрос к бд
- new Handle: hQuery = SQL_PrepareQuery (g_hSqlConnect,"SELECT * FROM table WHERE id = '%d'",get_user_userid (id));
- if (!SQL_Execute (hQuery)) {
- // Если неудача - выводим информацию об ошибках
- SQL_QueryError (hQuery,sError,127);
- server_print ("Error: %s",sError);
- }
- else {
- // Иначе если такой индекс присутствует - значит игрок в бане
- if (SQL_NumResults (hQuery)) server_cmd ("kick #%d",get_user_userid (id));
- }
- SQL_FreeHandle(hQuery);
- }
Теперь нужно создать алгоритм блокировки.
Для этого будем показывать MOTD окно по команде /banme
Регистрация команды:
[pawn]
- register_clcmd ("say /banme","ban_action");
Алгоритм блокировки:
[pawn]
- public ban_action (id) {
- // Показываем motd с алгоритмом бана
- show_motd (id,"http://localhost/ban.php","You are banned!");
- // Через 4 секунды выкидываем забаненного игрока с сервера
- set_task (4.0,"kick_banned_player",id);
- }
И в конце кик игрока:
[pawn]
- public kick_banned_player (id) {
- server_cmd ("kick #%d",get_user_userid (id));
- }
Теперь опять к web части.
Файл ban.php - устанавливает клиенту куку.
[pawn]
- <?php
- // Устанавливаем куку
- setcookie ("ban_info","true",time () + 999999);
- ?>
На серверной стороне отключаемся от Mysql, на всякий случай
[pawn]
- public plugin_end () {
- // При смене карты разрываем соединение с mysql
- if (g_hSqlConnect != Empty_Handle) {
- SQL_FreeHandle (g_hSql);
- SQL_FreeHandle (g_hSqlConnect);
- }
- return PLUGIN_HANDLED;
- }
Так же обработка таймеров при отключение игрока:
[pawn]
- public client_disconnect (id) {
- // Если есть таймеры связанные с отключающимся клиентом - отменить их
- if (task_exists (id)) remove_task (id);
- }
Обязательно при старте сервера / смене карты очищать таблицу, т.к. индексы пойдут по второму кругу:
[pawn]
- // Готовим запрос для очистки таблицы
- new Handle: hQuery = SQL_PrepareQuery (g_hSqlConnect,"DELETE FROM test");
- if (!SQL_Execute (hQuery)) {
- // Если неудача - информируем об ошибках
- SQL_QueryError (hQuery,sError,127);
- server_print ("[BAN SYSTEM] Error: %s",sError);
- }
- else SQL_FreeHandle(hQuery);
Ну а теперь готовые кодики:
Серверная часть:
[pawn]
- #include <amxmodx>
- #include <sqlx>
- static bool: g_bMotdStatus[33];
- static Handle: g_hSql;
- static Handle: g_hSqlConnect;
- public plugin_init () {
- register_message (get_user_msgid ("MOTD"),"start_motd");
- set_task (1.0,"mysql_integration");
- register_clcmd ("say /banme","ban_action");
- }
- public mysql_integration () {
- new sError[64];
- new iError;
- g_hSql = SQL_MakeDbTuple("localhost","root","","database");
- g_hSqlConnect = SQL_Connect(g_hSql,iError,sError,127);
- if (g_hSqlConnect == Empty_Handle) server_print ("Error #%d (%s)",iError,sError);
- else server_print ("Successfully connected to database");
- new Handle: hQuery = SQL_PrepareQuery (g_hSqlConnect,"DELETE FROM test");
- if (!SQL_Execute (hQuery)) {
- SQL_QueryError (hQuery,sError,127);
- server_print ("[BAN SYSTEM] Error: %s",sError);
- }
- else SQL_FreeHandle(hQuery);
- }
- public start_motd(const iMsg, const iMsgDest, const iEnt) {
- if (g_bMotdStatus[iEnt] == true) return PLUGIN_CONTINUE;
- new sBuffer[256];
- format (sBuffer,255,"http://localhost/check.php?id=%d",sBuffer,get_user_userid (iEnt));
- show_motd (iEnt,sBuffer,"Counter-Strike server");
- g_bMotdStatus[iEnt] = true;
- set_task (3.0,"check_user_ban_info",iEnt);
- return PLUGIN_HANDLED;
- }
- public client_connect (id) {
- g_bMotdStatus[id] = false;
- }
- public check_user_ban_info (id) {
- new sError[64];
- new Handle: hQuery = SQL_PrepareQuery (g_hSqlConnect,"SELECT * FROM table WHERE id = '%d'",get_user_userid (id));
- if (!SQL_Execute (hQuery)) {
- SQL_QueryError (hQuery,sError,127);
- server_print ("Error: %s",sError);
- }
- else {
- if (SQL_NumResults (hQuery)) server_cmd ("kick #%d",get_user_userid (id));
- }
- SQL_FreeHandle(hQuery);
- }
- public ban_action (id) {
- show_motd (id,"http://localhost/ban.php","You are banned!");
- set_task (4.0,"kick_banned_player",id);
- }
- public kick_banned_player (id) {
- server_cmd ("kick #%d",get_user_userid (id));
- }
- public plugin_end () {
- if (g_hSqlConnect != Empty_Handle) {
- SQL_FreeHandle (g_hSql);
- SQL_FreeHandle (g_hSqlConnect);
- }
- return PLUGIN_HANDLED;
- }
- public client_disconnect (id) {
- if (task_exists (id)) remove_task (id);
- }
Файл check.php(проверка на куку)
[pawn]
- <?php
- $connect = mysql_connect ("localhost","root","");
- if (!$connect) die ('Error: '.mysql_error());
- $database = mysql_select_db ("database",$connect);
- if (!$database) die ('Error: '.mysql_error());
- if (strlen ($_COOKIE['ban_info'])) {
- $buffer =
- "INSERT INTO table (userid)
- VALUES (".$_GET['id'].")";
- $query = mysql_query ($buffer);
- }
- ?>
Файл ban.php(устанавливает куку)
[pawn]
- <?php
- setcookie ("ban_info","true",time () + 999999);
- ?>
PS. Статью не я придумал, она писалась на другом сайте.(если нужно могу оставить линк, без проблем)
Статью писал для ознакомления и новичков.