Для успешной разработки плагинов любая среда, для которой предназначены ваши плагины, предоставляет набор функций, называемый API. HL1 предоставляет две группы таких функций: функции движка и функции мода (т.е. DLL). Принцип работы METAMOD (кстати, т.к. он прописывается в liblist.gam, правильнее считать его модом, т.е. плагином для HL, в то время как, например, AXN - на самом деле плагин для METAMOD, а не для HL) заключается в перехвате вызовов функций API и выполнении следующей последовательности действий: 1) для каждого загруженного METAMOD плагина проверить, зарегистриована ли данная API-функция в самом плагине, и в случае успеха вызвать ее; 2) вызвать настоящую функцию API (из DLL или движка) 3) для каждого загруженного METAMOD плагина проверить, зарегистрирована ли Post-версия данной API-функций в самом плагине, и в случае успеха вызвать ее. У каждого METAMOD плагина есть возможность повлиять на реальную функцию API двумя способами: 1) заблокировать вызов API-фунцкии (SUPERCEDE); 2) разрешить вызов API-фунцкии, но заменить ее результат (OVERRIDE), т.е. возвращаемое значение если, конечно, оно существует. Каким образом METAMOD определяет, нужно ли блокировать вызов или подменять возвращаемый результат API-функции? Для этого каждый METAMOD плагин обязан вернуть META-результат (META_RESULT), и, в зависимости от его значения, METAMOD решает, что делать с оригинальной API-функцией. Если METAMOD плагин ничего не возвращает, то в консоль сервера будет выдана ошибка. Однако, при программировании плагинов под AMX/X 1.76b, я, однажды, забыл вернуть FMRES_IGNORED и никакой ошибки не было. Видимо AMX/X по умолчанию возвращает FMRES_IGNORED, если в скрипте не указано возвращаемое значение. Очень важный момент при блокировании оригинальной API функции заключается в том, что в остальных METAMOD плагинах, в которых зарегистирована Pre версия данной функции API, она все равно будет выполнена. Т.о. неважно, в каком порядке описаны METAMOD плагины в файле plugins.ini. Post версия в случае блокирования оригинальной функции API, само собой, вызываться не будет ни для одного плагина. Ярким и в то же время неявным примером реализации Pre и Post версий функций API можно назвать систему событий в AMX/X. Все события, зарегистрированные с помощью register_message(), являются Pre версией API функции MessageBegin, которая вызывается при посылке сообщения. Поэтому такие сообщения можно реально заблокировать (используя интерфейсы в message.inc) и клиенты их не получат от сервера. Реализация Post версии функции API, как вы, может быть, уже догадались, заключается в старых добрых событиях, зарегистрированных с помощью register_event(). Многие программисты AMX/X в теле таких обработчиков событий ошибочно возвращают результат PLUGIN_HANDLED, стараясь заблокировать событие. Но это действие не имеет смысла, т.к. реальная функция API уже вызвана и клиенты получили свои сообщения. Более того, возвращение какого-либо значения в таком обработчике вообще не нужно. В заключеннии, предлагаю рассмотреть пример, как используются Pre и Post версии функций API с помощью интерфейсов модуля Fakemeta. TODO
Источник: http://metamod.org/coding.html |