Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Страница 1 из 2 1 2 ПоследняяПоследняя
Показано с 1 по 10 из 14
  1. #1
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±

    О командных процессорах

    Всем привет.

    Как вы могли догадаться по названию темы, в ней будут обсуждаться командные процессоры.
    Но я не собираюсь советовать вам тот или иной командный движок - вместо этого я приведу несколько фактов и оставлю возможность выбора вам.
    Итак, начнём.


    Одной из основных проблем в обработке команд является линейная зависимость времени отклика от названия команды или её расположения в коде.
    Что представляет из себя эта зависимость:
    • Без командного процессора производятся лишние вызовы strcmp, чтобы найти нужную команду.
      Пример:
      PHP код:
      public OnPlayerCommandText(playeridcmdtext[])
      {
          if (
      == strcmp(cmdtext"/command1"))
          {
              return 
      SendClientMessage(playerid, -1"Вызвана 1-я команда.");
          }
          if (
      == strcmp(cmdtext"/command2"))
          {
              return 
      SendClientMessage(playerid, -1"Вызвана 2-я команда.");
          }
          if (
      == strcmp(cmdtext"/command3"))
          {
              return 
      SendClientMessage(playerid, -1"Вызвана 3-я команда.");
          }
          return 
      SendClientMessage(playerid, -1"Ошибка: Неизвестная команда.");

      Самое малое время отклика будет у команды "/command1", т.к. она реализована в OnPlayerCommandText самой первой и при её вызове будет совершён всего 1 вызов функции strcmp.
      В то же время, команда "/command3" находится в самом невыгодном положении, т.к. при её вызове строка в cmdtext будет сравниваться сначала с "/command1" и "/command2", и только потом с "/command3", т.е. произойдут 2 лишних вызова strcmp.
      В итоге чем больше команд находится перед вызванной командой, тем больше будет "холостых" срабатываний strcmp и тем больше времени уйдёт на поиск. Это и есть линейная зависимость времени отклика команды от её расположения в OPCT.

    • Во многих командных движках наподобие ZCMD тоже есть линейная зависимость, но только от названия команды.
      Команды в них реализуются в виде public-функций. В скомпилированном скрипте (*.amx) названия таких функций сохраняются в таблице экспортируемых функций, чтобы их можно было найти и вызвать извне (т.е. со стороны сервера, а не только из кода на Pawn).
      Пример:
      PHP код:
      CMD:abc(playeridparams[])
      {
          return 
      SendClientMessage(playerid, -1"abc");
      }
      CMD:def(playeridparams[])
      {
          return 
      SendClientMessage(playerid, -1"def");
      }
      CMD:ghi(playeridparams[])
      {
          return 
      SendClientMessage(playerid, -1"ghi");
      }
      CMD:jkl(playeridparams[])
      {
          return 
      SendClientMessage(playerid, -1"jkl");

      При раскрытии макроса "CMD:" к названию public-функции добавляется префикс "cmd_". Например, для "CMD:abc" функция будет называться "cmd_abc".
      Без префикса командный процессор мог бы вызвать любую public-функцию. Например, любой игрок мог бы ввести "/OnGameModeInit", инициировать "перезагрузку" сервера - загрузку домов, бизнесов и всего прочего, без сохранения того, что было у игроков до перезагрузки.
      Записи в таблице экспортируемых функций будут располагаться в алфавитном порядке:
      Код:
      abc
      def
      ghi
      jkl
      Чтобы вызвать функцию на Pawn по её имени, нужно сначала найти её ID, т.е. её порядковый номер в таблице функций.
      Эта задача осуществляется с помощью amx_FindNative, если для обработки команд используется плагин, или funcidx на стороне Pawn (она сама вызывает amx_FindNative).
      Функция amx_FindNative производит линейный поиск по таблице экспортируемых функций, поочерёдно сравнивая указанное имя с каждым именем в таблице, пока не найдёт совпадение.
      При таком поиске название abc попадётся самым первым, а для jkl будут совершены 3 лишних сравнения с предыдущими именами в таблице.
      Как результат, время отклика при такой схеме зависит от названия самой команды.

    В теории наличие линейной зависимости во времени отклика открывает для злоумышленников вектор атаки: флудить вызовом команды, которая либо самая последняя по алфавиту (например, что-нибудь на букву Z), либо реализована самой последней в OnPlayerCommandText (это можно узнать из слитых исходников или исходников паблик-мода, на котором основан мод сервера).
    Если на сервере достаточно много команд и атакующий удачно подобрал команду для флуда, он сможет спровоцировать максимальное использование ресурсов и, возможно, отключение сервера хостером, чтобы не влиять на работу других серверов, находящихся на той же машине.

    В DC_CMD для обработки команд используется хеш-таблица.
    Во время запуска сервера плагин просматривает таблицу public-функций и для тех функций, названия которых начинаются с "cmd_", вычисляет из названия хеш-сумму, находит ID функции и полученные пары "хеш-ID" сохраняет в хеш-таблице.
    При вводе команды от названия вычисляется хеш и по нему в таблице находится ID соответствующей public-функции. При такой схеме отсутствует линейная зависимость от названия функции, т.к. время поиска по хеш-таблице примерно равно для каждого элемента.

    По такому же принципу работает плагин Pawn.CMD и движок y_commands.
    Значительным недостатком y_commands является то, что он использует несколько других инклудов из YSI, состоящих из грязных хаков на основе багов Pawn 3.0, не говоря уже о реализации хеш-таблицы в YSI: вместо динамической аллокации памяти под её элементы используется очень большой массив, который всё время занимает место в памяти сервера. И хотя память не является особой проблемой, используемые в YSI практики только поощряют расточительство и использование багов вместо того, чтобы сделать адекватную реализацию через плагин.
    Про минусы Pawn.CMD можно прочесть здесь. Также есть информация, что под Linux этот плагин приводит к падению сервера с JIT, но эта информация пока что не подтверждена (буду очень благодарен, если кто-нибудь найдёт время, чтобы её подтвердить/опровергнуть).
    Среди преимуществ Pawn.CMD и y_commands можно отметить поддержку отдельных реализаций команд для справки об аргументах команды и для разных групп игроков, но без этого синтаксического сахара можно легко обойтись, больше никаких проблем они не решают.


    Как я уже сказал ранее, я не буду навязывать вам выбор. Это было бы неэтично с моей стороны, т.к. я, как разработчик DC_CMD, могу быть заинтересованным лицом (хоть я уже и несколькько лет практически не притрагивался к исходникам плагина).
    Моей задачей в этой статье было всего лишь привести факты, т.к. я не видел, чтобы о них хоть где-то упоминали ранее.

    Выбирайте с умом. Или без. Всё в ваших руках.


    Статью подготовил: Daniel_Cortez

    Специально для Pro-Pawn.ru
    Копирование данной статьи на других ресурсах без разрешения автора запрещено!
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  2. 9 пользователя(ей) сказали cпасибо:
    Blood (30.01.2017) Geebrox (29.01.2017) Igoreshka (31.01.2017) iWors (30.01.2017) Osetin (29.01.2017) Seviel (29.01.2017) vovandolg (29.01.2017) [ForD] (29.01.2017) _lizard (29.01.2017)
  3. #2
    Аватар для Nexius_Tailer
    Пользователь

    Статус
    Оффлайн
    Регистрация
    04.01.2015
    Адрес
    Гомель, Беларусь
    Сообщений
    547
    Репутация:
    158 ±
    Интересно.
    Хотя всё-же стоит учитывать, что перебор названий пабликов в любом случае будет быстрее, чем многократный вызов strcmp из pawn скрипта.
    Юзать y_cmd единственной из YSI, при этом ещё и не используя ни одной из её фич, действительно было-бы малоразумно, так что такой вариант мало кому подходит.

    И если говорить про обходимость без синтаксического сахара, то в этом плане вполне и сам zcmd/izcmd - вообще почти ничего лишнего)
    Последний раз редактировалось Nexius_Tailer; 29.01.2017 в 20:56.
    Не хотите постоянно проверять обновления моих скриптов?
    Подключите его последним, после всех остальных
    Nexius's Update Checker

  4. #3
    Аватар для VVWVV
    ?

    Статус
    Оффлайн
    Регистрация
    09.07.2015
    Сообщений
    731
    Репутация:
    353 ±
    Цитата Сообщение от Nexius_Tailer Посмотреть сообщение
    Интересно.
    Хотя всё-же стоит учитывать, что перебор названий пабликов в любом случае будет быстрее, чем многократный вызов strcmp из pawn скрипта.
    Юзать y_cmd единственной из YSI, при этом ещё и не используя ни одной из её фич, действительно было-бы малоразумно, так что такой вариант мало кому подходит.

    И если говорить про обходимость без синтаксического сахара, то в этом плане вполне и сам zcmd/izcmd - вообще почти ничего лишнего)
    Вместо библиотеки Y_Less'а можно использовать библиотеку SmartCMD, которая мало чем отличается от y_commands. Более того, она должна быть быстрее y_commands.

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

    Статус
    Оффлайн
    Регистрация
    04.01.2015
    Адрес
    Гомель, Беларусь
    Сообщений
    547
    Репутация:
    158 ±
    Цитата Сообщение от VVWVV Посмотреть сообщение
    Вместо библиотеки Y_Less'а можно использовать библиотеку SmartCMD, которая мало чем отличается от y_commands. Более того, она должна быть быстрее y_commands.
    Ну да, в последнее время их много развелось (Smart-CMD, SickAttack's Command Processor и ещё там какие-то). А кто-то когда-то говорил, что эра гонок cmd-процессоров закончилась :P
    Надо будет как-нибудь каждый из них изучить получше
    Не хотите постоянно проверять обновления моих скриптов?
    Подключите его последним, после всех остальных
    Nexius's Update Checker

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

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от Nexius_Tailer Посмотреть сообщение
    Интересно.
    Хотя всё-же стоит учитывать, что перебор названий пабликов в любом случае будет быстрее, чем многократный вызов strcmp из pawn скрипта.
    Да, я этого и не отрицал, но зависимость времени отклика от названия всё ещё остаётся.

    Цитата Сообщение от Nexius_Tailer Посмотреть сообщение
    И если говорить про обходимость без синтаксического сахара, то в этом плане вполне и сам zcmd/izcmd - вообще почти ничего лишнего)
    ... или писать все команды в OnPlayerCommandText - тогда даже никаких инклудов подключать не придётся!

    Я не просто так упомянул в том предложении о решении других проблем. Если сами по себе движки y_commands, Pawn.CMD и DC_CMD устраняют линейную зависимость времени отклика от того или иного признака, избавляя от возможного вектора атаки, то синтаксический сахар... это просто сахар.

    Цитата Сообщение от VVWVV Посмотреть сообщение
    Вместо библиотеки Y_Less'а можно использовать библиотеку SmartCMD, которая мало чем отличается от y_commands. Более того, она должна быть быстрее y_commands.
    В ней, как и в ZCMD (и вообще во всех остальных, поиск функций в которых производится не по хеш-таблице), время отклика зависит от названия команды. Да и при нормальных условиях на сервере разница в производительности вряд ли будет заметна.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

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

    Статус
    Оффлайн
    Регистрация
    04.01.2015
    Адрес
    Гомель, Беларусь
    Сообщений
    547
    Репутация:
    158 ±
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    ... или писать все команды в OnPlayerCommandText - тогда даже никаких инклудов подключать не придётся!
    Ну так там при большом количестве команд разница в скорости будет уже гораздо заметнее.

    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    Я не просто так упомянул в том предложении о решении других проблем. Если сами по себе движки y_commands, Pawn.CMD и DC_CMD устраняют линейную зависимость времени отклика от того или иного признака, избавляя от возможного вектора атаки, то синтаксический сахар... это просто сахар.
    От возможного вектора атаки обычно избавляет анти-флуд. А синтаксический сахар кому-то также предоставляет и более удобный скриптинг, если тот в нём нуждается. Это обычно отдельная категория людей, которые и скоростью ради этого жертвовать не против были, хотя с появлением pawn.cmd, получается, для них это вообще идеальный вариант.

    - - - Добавлено - - -

    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    Да и при нормальных условиях на сервере разница в производительности вряд ли будет заметна.
    В принципе это и говорит о том, что проблем как таковых и нет. С нормальным кодом внутри команды будут нормально работать и на zcmd
    Последний раз редактировалось Nexius_Tailer; 29.01.2017 в 21:25.
    Не хотите постоянно проверять обновления моих скриптов?
    Подключите его последним, после всех остальных
    Nexius's Update Checker

  8. #7
    Аватар для ziggi
    Проверенный

    Статус
    Оффлайн
    Регистрация
    14.05.2015
    Сообщений
    1,181
    Репутация:
    790 ±
    Цитата Сообщение от Nexius_Tailer Посмотреть сообщение
    Этот особо повеселил: https://github.com/Kevin-Reinke/Comm...r.inc#L58-L516

  9. #8
    Аватар для Redsan
    Пользователь

    Статус
    Оффлайн
    Регистрация
    07.06.2016
    Адрес
    Minsk, Belarus
    Сообщений
    78
    Репутация:
    15 ±
    Цитата Сообщение от ziggi Посмотреть сообщение
    Этот особо повеселил: https://github.com/Kevin-Reinke/Comm...r.inc#L58-L516
    Лучший

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

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от Nexius_Tailer Посмотреть сообщение
    Ну так там при большом количестве команд разница в скорости будет уже гораздо заметнее.
    Странно, я думал, это будет очевидно из моего ответа. Видимо, нет -_-


    Цитата Сообщение от Nexius_Tailer Посмотреть сообщение
    От возможного вектора атаки обычно избавляет анти-флуд.
    Атака может выполняться не одним игроком. И даже если она не вызовет полного отказа, повышение нагрузки может отразиться на геймплее.


    Цитата Сообщение от Nexius_Tailer Посмотреть сообщение
    А синтаксический сахар кому-то также предоставляет и более удобный скриптинг, если тот в нём нуждается. Это обычно отдельная категория людей, которые и скоростью ради этого жертвовать не против были, хотя с появлением pawn.cmd, получается, для них это вообще идеальный вариант.
    Не спорю, хоть в сообществе такой сахар пока что не сильно популярен (по крайней мере, в русскоязычной части). В принципе, в плане производительности "гоняться" здесь уже давно незачем. Пожалуй, именно поэтому я так давно не работал над новыми версиями DC_CMD. При последних тенденциях есть лишь смысл работать над удобством.


    Цитата Сообщение от Nexius_Tailer Посмотреть сообщение
    В принципе это и говорит о том, что проблем как таковых и нет. С нормальным кодом внутри команды будут нормально работать и на zcmd
    Под "нормальными условиями" имелось в виду отсутствие атак флудом.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

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

    Статус
    Оффлайн
    Регистрация
    04.01.2015
    Адрес
    Гомель, Беларусь
    Сообщений
    547
    Репутация:
    158 ±
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    Странно, я думал, это будет очевидно из моего ответа. Видимо, нет -_-
    Действительно, видимо кому-то не очевидно. Тогда стоит посмотреть на любые тесты скорости cmd-процессоров, где участвует strcmp. И сразу станет видно, что если между zcmd-подобными разница, пусть даже в разы, то с strcmp с каждым из них в десятки раз, что наверное о чём-то, да должно говорить.

    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    Атака может выполняться не одним игроком. И даже если она не вызовет полного отказа, повышение нагрузки может отразиться на геймплее.
    В принципе оно так, но если с другой стороны, флудить можно чем угодно, где есть перебор: пикапами, чекпоинтами, диалогами и прочим. Если у злоумышленников цель будет зафлудить сервер, и они будут иметь при этом достаточные ресурсы - они это сделают.
    Не хотите постоянно проверять обновления моих скриптов?
    Подключите его последним, после всех остальных
    Nexius's Update Checker

 

 
Страница 1 из 2 1 2 ПоследняяПоследняя

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

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

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

Ваши права

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