В теме 1 сообщение

Cawfee
Великий Гуру

1. Введение. Суть перехватов.

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

 

Что такое перехваты? Зачастую возникает ситуация, когда нам необходимо как-то изменить действия, происходящие в функции. Но редактирование уже имеющейся функции (как правило, это стандартные функции) не есть лучший вариант. Почему? Если мы хотим внести какие-то дополнительные действия в нужную нам функцию, придется открывать файл, в котором содержится данная функция, ее редактировать. А если выйдет новая версия файла a_samp? Все наши действия придется повторить сначала, теперь уже в новом файле.

 

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

перехваченная_функция_1 -> перехваченная_функция_2 -> перехваченная функция_3 -> основная_функция_которую_перехватывали

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

 

Для перехвата функций нам потребуются некоторые директивы (#define, #if defined, #endif), а также сами функции, которые мы внедряем в перехваты.

 

2. Построение перехватов.

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

 

У нас есть функция A. Мы хотим, чтобы в ней происходил вывод текста "Hello world" в логи сервера. Как говорили ранее, внедрять этот текст в код функции A мы не будем (потому, что если выйдет обновление версии файла, в котором содержится эта функция, мы утратим свои корректировки в данной функции). Значит, нам нужно сделать так, чтобы это изменение могли внести без изменения кода файла.

 

Рассмотрим следующий вариант:

#define InterceptFunctionA()\
	printf("Hello world");A();

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

 

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

 

В общем и целом метод перехватов, которому мы сейчас обучаемся, выглядит следующим образом:

<перехватчик 1>
	<выполняем действия перехватчика 1>
  	<вызываем следующий перехватчик>
<конец перехватчика>

<перехватчик 2>
	<выполняем действия перехватчика 2>
	<вызываем следующий перехватчик>
<конец перехватчика>
  
<перехватчик 3>
	<выполняем действия перехватчика 3>
	<вызываем перехватываемую функцию>
<конец перехватчика>

Каждый перехватчик есть ни что иное как отдельная функция. И, соответственно, в ходе перехватов мы поочередно вызываем функции, в которых прописаны Ваши действия перехватчика.

 

Перехваты нативных функций и функций, вызывающихся автоматически, несколько отличаются. Поэтому урок мы немного разделим.

  перехват нативных функций (открыть спойлер)

 

  перехват автовызываемых функций (открыть спойлер)

 

Как правило, перехваты применяются тогда, когда одну и ту же функцию необходимо использовать по-разному в разных файлах. С помощью перехватов мы можем в каждом файле перехватывать отдельные функции и вносить корректировки в их работу.

 

3. Перехваты функций: за и против.

В каждой ситуации есть сторонники какой-либо идеи и ее противники. Сейчас я постараюсь рассказать основные аспекты использования перехвата функций. А использовать их или нет - решать Вам.

 

1. Вы можете манипулировать одной и той же функцией по-разному в разных файлах. Это значит, что Вам не придется каждый раз добавлять различные проверки на то, подключен ли какой-либо файл, чтобы внести код "под него". Так, Вам достаточно лишь подключить нужный файл, чтобы вся цепочка вызовов работала как следует. Соответственно, при отключении файла проблем также не возникнет.

2. Перехват функций есть ни что иное как последовательные вызовы функций. Несомненно, на вызов функций уходит какая-то часть времени, но это время ничтожно для того, чтобы Ваш сервер действительно стал подтормаживать.

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

stock ПерехватываемаяФункцияEx(аргументы функции)
{
	// ваш код
	return ПерехватываемаяФункция(аргументы функции);
}

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

 

4. Авторское право.

Автор данной статьи: @odosenok

Отдельное спасибо за разъяснения: Daniel_Cortez

Отредактировано пользователем odosenok
Причина: исправление опечатки.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

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

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!


Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.


Войти

  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу

  • Похожий контент

    • watson
      От watson
      Продаётся проект Criminal RolePlay с 8-летней историей.

      Проект заморожен и не используется длительное время.
      Потратил на него около 250.000 рублей, продаю за приемлимую цену.

      В комплекте:
      Полноценный игровой мод Мобильный лаунчер с Figma-дизайном Кэш клиентской части Все версии оформления проекта Все группы проекта Criminal RolePlay Шаблоны всех версий сайта, включая ранее не выпущенный шаблон Модуль автодоната YooMoney Помощь с установкой игрового мода на хостинг Цена:
      49 900₽ — за весь комплект.
      Возможен торг при адекватных предложениях.

      Важное:
      Проект продаётся в одни руки. Если в течение месяца не найдётся покупатель, будет рассмотрена продажа по частям.
      Связаться: https://vk.com/rosetta
    • watson
      От watson
      Продаётся проект Criminal RolePlay с 8-летней историей.

      Проект заморожен и не используется длительное время.
      Потратил на него около 250.000 рублей, продаю за приемлимую цену.

      В комплекте:
      Полноценный игровой мод Мобильный лаунчер с Figma-дизайном Кэш клиентской части Все версии оформления проекта Все группы проекта Criminal RolePlay Шаблоны всех версий сайта, включая ранее не выпущенный шаблон Модуль автодоната YooMoney Помощь с установкой игрового мода на хостинг Цена:
      49 900₽ — за весь комплект.
      Возможен торг при адекватных предложениях.

      Важное:
      Проект продаётся в одни руки. Если в течение месяца не найдётся покупатель, будет рассмотрена продажа по частям.
      Связаться: https://vk.com/rosetta
    • Elvis
      От Elvis
      Настоящим информируем о начале набора сотрудников в нашу студию "AlinSA Studios". В рамках текущего проекта "VanguardRP", основанного на мотивах CRMP, мы ищем профессионалов и энтузиастов для выполнения следующих должностей:
       
      1. Технические специалисты
       
      Требования:
       
      | Базовые знания в области информационных технологий
      | Понимание структур кода и принципов работы компиляторов
      | Готовность к обучению и развитию профессиональных навыков
      | Иметь базовое представлении ЯП "Pawn" или "Kotlin" и "Java".
       
      Обязанности:
       
      | Поддержка технической инфраструктуры проекта
      | Участие в разработке и оптимизации программных решений
      | Взаимодействие с командой разработки для внедрения новых функций
       
      2. Пиар-ассистенты
       
      Требования:
       
      | Опыт работы в сфере SMM, маркетинга или PR
      | Навыки взаимодействия с аудиторией и ведения социальных сетей
       
      Обязанности:
       
      | Продвижение проекта в социальных сетях
       
      3. Дизайнеры
       
      Требования:
       
      | Наличие портфолио с примерами выполненных работ (не обязательно, желательно)
      | Владение графическими редакторами ! (Photoshop и Figma)
      | Креативность, внимательность к деталям и способность работать в сжатые сроки
       
      Обязанности:
       
      | создание графического контента для соцсетей, сайта и внутриигровых материалов
      | Разработка дизайна интерфейсов, баннеров, логотипов и иллюстраций
      | Участие в визуальном оформлении проекта
       
      4. Геймдизайнеры
       
      Обязанности:
       
      | Разработка игровых механик, правил взаимодействия и систем баланса
      | Проработка сюжета, персонажей и сценариев для создания эмоциональной связи с игроками
      | Проектирование уровней, задач и сценариев для обеспечения разнообразия игрового процесса
      | Взаимодействие с командой разработчиков, художников и звукорежиссёров для достижения согласованности элементов игры
      | Участие в тестировании прототипов, выявление проблем и балансировка игрового процесса
       
      5. Рупоры
       
      Цель роли: Обеспечить эффективное взаимодействие с целевой аудиторией, формировать положительный имидж проекта, своевременно информировать участников о новостях, обновлениях и
      мероприятиях, а также модерировать сообщества для поддержания комфортной и безопасной среды.
       
      -————————-
      Условия работы:
       
      Обучение и постоянная поддержка со стороны команды
      Гибкий график работы / удалённый формат (обсуждается индивидуально)
       
       
      Если вы заинтересованы в присоединении к нашей команде или хотите получить дополнительную информацию, обращайтесь по следующему контакту:
      Telegram: @AntonLegost
       
       
      Благодарим за внимание! Надеемся на плодотворное сотрудничество.
       
      p.s Новички приветствуются. Для пополнение портфолио и наработки опыта.
       
      С уважением,
      Команда "AlinSA Studios"
    • Kutuzov
      От Kutuzov
      Автор данного канала снимает уроки по программированию на Pawn, также скоро будет на 20 подписчиков снимать мод с нуля в samp. 
      Приглашаем всех на канал, а также особенно новичков. Даже если вы уже знаете pawn, подпишитесь пожалуйста на его канал и поддержите его.
      Автор канала не требует денег!!! Он обучает всех бесплатно!!!
      Ссылка на канал: https://www.youtube.com/@prog_samp_easy
       
      Также у него есть свой тг канал, но начнет вести его, как только будет не менее 10 подписчиков.
       Ссылка на тг канал: https://t.me/pawndevelop
       
      Всем удачи
    • Sleash
      От Sleash
      Всем доброго времени суток. Сегодня мне бы хотелось вам рассказать от таких функциях в PAWN-языке, как SetTimer и SetTimerEx.
      Сразу сделаю такое примечание: Для SetTimer и SetTimerEx можно использовать ТОЛЬКО public!!!
      SetTimer
      Итак, для начала приступим к лёгкому и пойдём по нарастающей:
      Первое, это SetTimer. Функция включает в себя 3 параметра:
      native SetTimer(funcname[], interval, repeating); funcname[] - Это название функции, по сути - название вашего pablic в кавычках.
      interval - Интервалы от вызова таймера до срабатывания pablic
                     Так же если стоит повторение таймера, то будет работать как интервал между таймерами.
                     Измеряется в миллисекундах. 1000 миллисекунд равно 1 секунде
      repating - Тут всё просто: будет ли повторяться ваша функция. Может иметь значения: true - будет выполняться повторение ИЛИ false - вызывается 1 раз.
      Давайте разберём пример для наглядности:
      forward Info(); public Info() {     SendClientMessageToAll(0xFFFFFFFF, "Наш сайт: pawno-rus.ru"); } // И теперь давайте вызовем данный таймер при запуске мода public OngameModeInit() {     SetTimer("Info", 1000*60*20, true);     return true } Давайте разберёмся по интервалу: 1000*60*20. Так как я писал ранее, что 1000 млСек = 1 сек, то: 1 сек * 60 = 1 минута; 1 минута * 20 = 20 минут.
      Таким образом данный таймер будет выводить каждые 20 минут для всех игроков на сервере в чат: "pawno-rus.ru".
       
      SetTimerEx
       
      По сути с SetTimer - всё, теперь перейдём к следующей функции: SetTimerEx:
      native SetTimerEx(funcname[], interval, repeating, const format[], {Float,_}:...); Тут добавляются ещё 2 параметра:
      const format[] - формат данных для ввода в функцию. (Такие как: s, d, f);
      {Float,_}:... - переменные или значение для данных из const fromat[]
      Из данных объяснения мало что можно понять незнающему или начинающему скриптеру, поэтому давайте разберём на примере кода, который при входу даёт на авторизацию две минуты игроку:
      forward autorez(playerid); public autorez(playerid) {     if(/*проверка на то залогинился ли игрок*/)     {         SendClientMessage(playerid, 0xFFFFFFFF, "Вы были кикнуты по причине: Время на авторизацию истекло.");         Kick(playerid);         return true;     }     return true; } //Дальше уже добавлям сам таймер public OnPlayerConnect(playerid) {     SetTimerEx("autorez", 1000*60*2, false, "d", playerid);     return true; } Если первые три пункта мы уже разбирали. то начнём сразу с 4-го:
      4. Тут в кавычках надо вставлять тип данных. Наподобие функции format(output[], len, "%s %d %f", string, int, float), только без знака процента (%)
      5. Тут уже указывают сами данные, так же разберём как и предыдущий: format(output[], len, "%s %d %f ", string, int, float)
       
      Я надеюсь что кому-то помог, а если что непонятно, то спрашивайте, всегда помогу.