Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Показано с 1 по 7 из 7
  1. #1
    Аватар для Nexius_Tailer
    Пользователь

    Статус
    Оффлайн
    Регистрация
    04.01.2015
    Адрес
    Гомель, Беларусь
    Сообщений
    547
    Репутация:
    158 ±

    Определение типа скрипта (FS/GM) используя state

    Всем привет :)

    Предисловие:
    Недавно нашёл тему обсуждений "как лучше структурировать античит", откуда выяснил, что лучшим способом для меня было бы реализовать в инклуде, которую можно было-бы подключать как к фильтрскрипту, так и к гейммоду. Но стояла небольшая проблема: как написал Y_less, не всегда можно наверняка знать, задефайнит ли пользователь в своём фильтрскрипте "FILTERSCRIPT" (из чего и можно было узнать, что это FS), или нет.
    Тем не менее, мне нужен был способ, который не будет задействовать ни два разных файла, ни предоставленный выше не очень надёжный вариант.
    Упомянутый выше Y_less предложил такой метод:

    PHP код:
    new bool:AC_FILTERSCRIPT false;

    public 
    OnFilterScriptInit()
    {
        
    AC_FILTERSCRIPT true;
        
    AC_OnScriptInit();
    }

    public 
    OnGameModeInit()
    {
        if (!
    AC_FILTERSCRIPTAC_OnScriptInit();

    Но проанализировав его я понял, что вызывать каллбэки, типо OnPlayerUpdate придётся и в FS и в моде, тем самым каждый раз в каждом каллбэке будет идти проверка условия "фильтрскрипт ли это или нет" (с данным же способом эти проверки также будут, но неявными, т.е. самому их делать каждый раз не придётся).

    В итоге на основе его идеи и кода, я сделал свой вариант с использованием state, что проверено мной на работоспособность в данный момент.

    Итак, идея кода выглядит следующим образом:

    PHP код:
    public OnFilterScriptInit()
    {
        
    state ScriptType:FilterScript;
        return 
    1;
    }

    //Все последующие паблики

    public OnGameModeInit() <ScriptType:FilterScript//Если фильтрскрипт
    {
        print(
    "Это FilterScript!");
        return 
    1;
    }

    public 
    OnGameModeInit() <> //В остальных случаях (гейммод)
    {
        print(
    "Это GameMode!");
        return 
    1;

    Ок, написав такой скрипт, его можно загрузить как FS, либо как GM, при этом в зависимости от вашего выбора, при включении сервера нам напишет одно из двух сообщений (и соответственно выполнится только одно из двух OnGameModeInit). Ну а т.к. это всего лишь пример, то на практике работать это будет со всеми пабликами.

    Как же нам всё это адаптировать к инклуде, чтобы при включении мода/FS, нам соответственно это определяло?
    Просто! :D Для этого мы будем использовать основу кода выше + Hook Method 7, а именно:

    PHP код:
    public OnFilterScriptInit()
    {
        
    state ScriptType:FilterScript;
        
    //Hook Method 7
        #if defined MyLib_OnFilterScriptInit
            
    return MyLib_OnFilterScriptInit();
        
    #else
            
    return 1;
        
    #endif
    }

    //Hook Method 7
    #if defined _ALS_OnFilterScriptInit
        #undef OnFilterScriptInit
    #else
        #define _ALS_OnFilterScriptInit
    #endif
    #define OnFilterScriptInit MyLib_OnFilterScriptInit
    #if defined MyLib_OnFilterScriptInit
        
    forward MyLib_OnFilterScriptInit();
    #endif

    public OnGameModeInit() <ScriptType:FilterScript>
    {
        print(
    "[Inc] Это FilterScript!");
        
    //Hook Method 7
        #if defined MyLib_OnGameModeInit
            
    return MyLib_OnGameModeInit();
        
    #else
            
    return 1;
        
    #endif
    }

    public 
    OnGameModeInit() <>
    {
        print(
    "[Inc] Это GameMode!");
        
    //Hook Method 7
        #if defined MyLib_OnGameModeInit
            
    return MyLib_OnGameModeInit();
        
    #else
            
    return 1;
        
    #endif
    }

    //Hook Method 7
    #if defined _ALS_OnGameModeInit
        #undef OnGameModeInit
    #else
        #define _ALS_OnGameModeInit
    #endif
    #define OnGameModeInit MyLib_OnGameModeInit
    #if defined MyLib_OnGameModeInit
        
    forward MyLib_OnGameModeInit();
    #endif 
    При этом вызов конечного паблика будет таким-же, как будто он был вызван сразу.
    Заметьте, важно учитывать то, что будучи вызванным при разных состояниях, OnGameModeInit это один паблик, поэтому код

    PHP код:
    #if defined _ALS_OnGameModeInit
        #undef OnGameModeInit
    #else
        #define _ALS_OnGameModeInit
    #endif
    #define OnGameModeInit MyLib_OnGameModeInit
    #if defined MyLib_OnGameModeInit
        
    forward MyLib_OnGameModeInit();
    #endif 
    Мы используем только один раз, и в конце.
    Опять-же, как и с OnGameModeInit можно работать и с любыми другими каллбэками.

    В дополнение: стоит указывать свой тег для любой подмены (хука, перехвата) во избежание каких-либо совпадений между ними. Тег "MyLib_" является примером.


    Если вы хотите вызвать паблик только для одного случая - эти макросы будут полезны (спасибо Y_less'у):

    PHP код:
    #define fspublic%0(%1) public%0(%1) <> {} public%0(%1) <ScriptType:FilterScript>
    #define gmpublic%0(%1) public%0(%1) <ScriptType:FilterScript> {} public%0(%1) <> 
    Then you just have:

    PHP код:
    fspublic OnPlayerUpdate()
    {

    Итог:
    Данный метод будет в любом случае полезен, т.к. определяется тип скрипта прямо во время его выполнения.

    P.S. Хорошо, но чтобы увидеть все на практике, вы можете скачать готовый скрипт с инклудом (ссылка на .pwn + ссылка на .inc).
    Можно скомпилировать, а затем загрузить основной скрипт и как GM, и как FS - в любом случае, когда запустится сервер, в консоли будет написан ваш выбор, а когда вы подключаетесь к серверу - в чате :)

    Если есть предложения, буду рад их услышать.
    Спасибо.
    Последний раз редактировалось Nexius_Tailer; 22.06.2023 в 01:26.
    Не хотите постоянно проверять обновления моих скриптов?
    Подключите его последним, после всех остальных
    Nexius's Update Checker

  2. #2
    Аватар для Пельмень
    Пользователь

    Статус
    Оффлайн
    Регистрация
    05.12.2013
    Сообщений
    188
    Репутация:
    116 ±
    И всё же для создания античита лучше использовать разработку того самого (уже 10 раз упомянутого) Y_Less под названием y_master

  3. #3
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от Пельмень Посмотреть сообщение
    И всё же для создания античита лучше использовать разработку того самого (уже 10 раз упомянутого) Y_Less под названием y_master
    Очень развёрнутый и аргументированный ответ (нет).
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  4. #4
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Ок, пока что я переместил тему в раздел "Добавить урок", т.к. ещё нужно уточнить несколько фактов - например, вот этот:
    Но проанализировав его я понял, что вызывать каллбэки, типо OnPlayerUpdate придётся и в FS и в моде, тем самым каждый раз в каждом каллбэке будет идти проверка условия "фильтрскрипт ли это или нет".
    Эта проверка и в варианте со state тоже будет. Отличие лишь в том, что для проверки состояния автоматона перед телом функции (т.е. непосредственно перед инструкцией PROC, которая обычно означает начало функции) создаётся конструкция switch, которая перебирает все состояния автоматона, встречающиеся в скрипте.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  5. #5
    Аватар для Nexius_Tailer
    Пользователь

    Статус
    Оффлайн
    Регистрация
    04.01.2015
    Адрес
    Гомель, Беларусь
    Сообщений
    547
    Репутация:
    158 ±
    По крайней мере это условие не нужно делать самому скриптеру, что как минимум удобнее (особенно если ещё и использовать макросы в конце).
    Не хотите постоянно проверять обновления моих скриптов?
    Подключите его последним, после всех остальных
    Nexius's Update Checker

  6. #6
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от Nexius_Tailer Посмотреть сообщение
    По крайней мере это условие не нужно делать самому скриптеру, что как минимум удобнее (особенно если ещё и использовать макросы в конце).
    В любом случае было бы не лишним упомянуть об этом в статье. А заодно и поменять MyLib на какой-нибудь свой префикс, чтобы код перехватов заранее был готов к использованию.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  7. #7
    Аватар для Nexius_Tailer
    Пользователь

    Статус
    Оффлайн
    Регистрация
    04.01.2015
    Адрес
    Гомель, Беларусь
    Сообщений
    547
    Репутация:
    158 ±
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    В любом случае было бы не лишним упомянуть об этом в статье. А заодно и поменять MyLib на какой-нибудь свой префикс, чтобы код перехватов заранее был готов к использованию.
    Первое уточнил. Второе, думаю, пусть будет как есть, т.к. это пример.
    Не хотите постоянно проверять обновления моих скриптов?
    Подключите его последним, после всех остальных
    Nexius's Update Checker

 

 

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •