BlockIpAddress

Материал из Pro-Pawn Wiki
Перейти к: навигация, поиск
Add.png Данная функция была добавлена в SA-MP 0.3z R2-2 и не работает в более ранних версиях.


Описание:

Блокирует соединения с указанного IP-адреса.

Параметры:

(ip_address[], timems)
ip_address[] IP-адрес, связь с которым требуется заблокировать. Поддерживается использование масок (например, маска "192.128.*.*" заблокирует все адреса, которые начинаются с "192.128").
timems Время блокировки в миллисекундах. Значение 0 означает вечную блокировку (на самом деле не совсем вечную - см. прим.)


Возвращаемое значение:

1, если строка ip_address не пустая, иначе 0.

Info rhombus.png
Примечание
Заблокированные адреса не сохраняются в файл samp.ban, а потому после перезапуска процесса сервера все блокировки, созданные данной функцией, будут аннулированы. Тем не менее, блокировки остаются в силе после перезагрузки/смены мода.
Если во время использования функции под указанным IP-адресом подключен игрок, связь с ним будет прервана.
Функция не блокирует адрес 127.0.0.1. Скорее всего, это сделано чтобы предотвратить непреднамеренную блокировку NPC. Тем не менее, данный адрес можно заблокировать по маске (например, 127.0.0.*).


Bug.png
Баг SA-MP
Функция не проверяет должным образом содержимое строки ip_address и возвращает 0 только если строка пустая. Если передать функции неправильный IP-адрес, она всё равно вернёт 1.
Содержимое массива ip_address не изменяется во время работы функции, однако сам массив объявлен без атрибута const:
native BlockIpAddress(ip_address[], timems);
в то время, как правильный (const-корректный) заголовок функции должен выглядеть так:
native BlockIpAddress(const ip_address[], timems);
Если аргумент-массив объявлен без const, компилятор считает, что функция записывает в него данные, и потому не позволяет передавать в функцию неизменяемые массивы, выдавая ошибку несоответствия типов.
static const address[] = "127.0.0.1";
BlockIpAddress(address, 0); // error 035: argument type mismatch (argument 1)


Пример использования:

new anti_reconnect_ips[MAX_PLAYERS]; // Упакованные IP-адреса игроков.
new anti_reconnect_timestamps[MAX_PLAYERS]; // Время подключения игроков.
new anti_reconnect_max_playerid = -1; // Наибольший ID игрока, подключившегося к серверу.

const ANTI_RECONNECT_INTERVAL = 20; // Время (сек.), через которое разрешается подключаться с одного IP.
const ANTI_RECONNECT_BLOCK_TIME = 60 * 60; // Время (сек.) блокировки IP-адреса при реконнекте.

public OnIncomingConnection(playerid, ip_address[], port)
{
    // Если подключается NPC - пропустим его.
    if (IsPlayerNPC(playerid))
        return;

    new time = gettime();
    // Упакуем строку с адресом в число. Сравнение чисел происходит быстрее, чем сравнение строк, и если
    // на сервере много игроков, время на упаковку в число компенсируется более быстрым поиском адреса.
    new o1, o2, o3, o4;
    sscanf(ip_address, "p<.>iiii", o1, o2, o3, o4);
    new c = (o1 << 24) | (o2 << 16) | (o3 << 8) | o4;

    for (new i = 0; i <= anti_reconnect_max_playerid; ++i)
    {
        // Если под этим IP за последние несколько секунд уже кто-то подключался - блокируем.
        if (c == anti_reconnect_ips[i] && time < anti_reconnect_timestamps[i] + ANTI_RECONNECT_INTERVAL)
        {
            BlockIpAddress(ip_address, ANTI_RECONNECT_BLOCK_TIME * 1000);
            printf("[Anti-Reconnect]: Адрес \"%s\" заблокирован", ip_address);
            break;
        }
    }

    anti_reconnect_ips[playerid] = c;           // Запомним IP-адрес
    anti_reconnect_timestamps[playerid] = time; // и время подключения.
    if (playerid > anti_reconnect_max_playerid)
        anti_reconnect_max_playerid = playerid;
}


См. также: