[FAQ] Как писать плагины для OpenKore. (перевод)

FAQ. Ответы на часто задаваемые вопросы.

Модератор: 4epT

Правила форума
Этот раздел является руководством и тут разрешено оставлять сообщения лишь для уточнения и внесения корректив в существующие материалы. Для вопросов существует ряд других разделов.
Ответить
manticora
Грамотный
Сообщения: 437
Зарегистрирован: Ср авг 29, 2007 12:45 pm

[FAQ] Как писать плагины для OpenKore. (перевод)

Сообщение manticora » Ср апр 15, 2009 5:03 pm

Как писать плагины для OpenKore (перевод How to write plugins for OpenKore)

Плагин - это файл с кодом программы. Плагин не является частью OpenKore и может быть подгружен уже после запуска OpenKore. Плагины могут добавлять новые возможности в OpenKor'у или менять обычное поведение OpenKor'ы (используя механизм хуков - hook). Плагины пишут на языке Perl. Устройство плагина зависит от внутреннего устройства OpenKore. Поэтому, чтобы писать плагины, нужно хорошо знать внутреннее устройство OpenKore.

Содержание
  • Ваш первый плагин: "Hello World"
    • Разбор
  • Использование хуков
    • Регистрация плагина
    • Хуки
    • Выгружаем плагин
    • Перезагружаем плагин
  • Хуки сетевых пакетов
  • Куда и как складывать плагины?
  • Как найти папку с плагином
Ваш первый плагин: "Hello World"
Вот пример плагина "Hello World". Сохраните код плагина в файле helloworld.pl и поместите файл в папку openkore\plugins.

Код: Выделить всё

package HelloWorld;

use strict;

print "Hello World!\n";

1;
Когда вы запустите OpenKore вы увидите это в консоли:
Loading plugin helloworld.pl...
Hello World!
Разбор
Как вы видите, перловый код в вашем плагине сразу после загрузки плагина был запущен на исполнение. Код любого плагина следует начинать со строки вида "package <имя package>;". Это не обязательно, но это хорошая мысль, потому что таким образом предотвращаяется конфликт имен функций вашего плагина с остальной OpenKore. (Если не понятно, читайте документацию Perl по части ключевого слова "package"). Каждый плагин должен кончаться строкой "1;" или "return 1;". Иначе после загрузки плагина будет выведено сообщение об ошибке.


Использование хуков

Вышеизложенный плагин не очень полезен. Вот более сложный плагин, который пишет "Hello!" каждый раз, когда OpenKore вызывает функцию AI().

Код: Выделить всё

package ExamplePlugin;

use strict;
use Plugins ;
use Log qw(message);

Plugins::register("example", "Example  Plugin ", \&on_unload, \&on_reload);
my $aiHook = Plugins::addHook("AI_pre", \&on_AI);

sub on_unload {
	# This plugin is about to be unloaded; remove hooks
	Plugins::delHook($aiHook);
}

sub on_reload {
	&on_unload;
}

sub on_AI {
	message "Hello!\n";
}

1;
Регистрация плагина
Каждый плагин должен зарегистрировать себя командой "Plugins::register()". Эта команда добавляет имя плагина в список плагинов. Зная имя плагина, можно его выгрузить из памяти OpenKore. В данном примере "example" - имя плагина, а "Example Plugin" его более детальное описание.

Хуки (hook)
В приведенном примере добавляется хук для функции "AI_pre". Каждый раз, когда OpenKore вызывает фунцию AI(), будет также вызываться функция данного плагина "on_AI()". Внутри вашей функции "on_AI()" вы можете писать что хотите, расширяя таким образом возможности OpenKore.

Заметка: если вы хотите добавить несколько хуков, вам следует использовать Plugins::addHooks() (обращаем внимание на 's' - множественное число). Таким образом вам не придется потом удалять каждый хук по отдельности.

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

Выгружаем плагин
Функция "Plugins::register()" позволяет вам определить функцию-деструктор - реакцию на выгрузку плагина (unload). Если юзер скажет выгрузить или перезагрузить плагин, или OpenKore вот-вот закроется, то будет вызвана функция-деструктор. Цель функции-деструктора удалить все добавленные вами хуки, завершить все текущие действия перед выгрузкой плагина (закрыть сокеты, удалить временные файлы, и т.д.). Вам не нужно писать функцию-деструктор если в вашем плагине не добавляются хуки и вам не нужно ничего за собой убирать.

Перзагружаем плагин
Аналогично определяется реакция на перезагрузку плагина (reload). Если юзер говорит перезагрузить плагин, вызывается только функция-реакция на перезагрузку плагина. Цель - закончить только часть дел. Зная, что плагин будет тут же загружен вновь, вам не нужно будет делать всё заново. Например ваш плагин открыл сокет с текущим игровым сервером и сразу после перезагруки плагина вы можете пользоваться уже готовым сокетом, потому что в реакции на перезагрузку вы предусмотрительно оставили сокет открытым.

Хуки сетевых пакетов (Network packet handler hooks)
Версии OpenKore 1.9 и выше имеют новый парсер сетевых пакетов. При инициализации этого парсера определяется список "packet switches" и связанные с ними функции-обработчики. Это хук для всех поддерживаемых OpenKor'ой сетевых пакетов.

Список поддерживаемых сетевых пакетов (так называемый the packet handler definition list) инициализируется в методе "new()" файла "src/Network/Receive.pm". Вот, например, фрагмент кода:

Код: Выделить всё

# Defines a list of Packet Handlers and decoding information
# 'packetSwitch' => ['handler function','unpack string',[qw(argument names)]]

$self{packet_list} = {
        '0069' => ['account_server_info', 'x2 a4 a4 a4 x30 C1 a*', [qw(sessionID accountID sessionID2 accountSex serverInfo)]],
        '006A' => ['login_error', 'C1', [qw(type)]],
        ...
Каждая функция-обработчик сетевого пакета имеет два хука: "до" и "после". (Назовем их дохук и послехук).
"Дохук" вызывается перед функцией-обработчиком сетевого пакета. Это позволяет вам менять отпарсенное содержимое пакета. В общем виде имя дохука выглядит так: "packet_pre/$handlerFunctionName". В данном фрагменте кода имя дохука для "account_server_info" выглядит так: "packet_pre/account_server_info".
"Послехук" вызывается после функции-обработчика сетевого пакета. В общем виде имя послехука выглядит так: "packet/$handlerFunctionName". В данном фрагменте кода имя послехука для "login_error" выглядит так: "packet/login_error". Опять обращаю ваше внимание, что эти хуки есть только в OpenKor'ах начиная с версии 1.9 и новее.

Куда и как складывать плагины?

Плагины обычно хранятся в специальной папке "openkore\plugins". Если папки нет - создайте. Файлы с расширением ".pl", лежащие в папке "openkore\plugins" автоматически подгружаются OpenKor'ой при старте. Также подгружаются файлы *.pl из подпапок первого уровня. Таким образом, если ваш плагин зависит от некоторых других файлов, удобно все эти файлы положить в одну папку внутри "openkore\plugins".

Пример структуры папок:

Код: Выделить всё

	openkore.pl
	wxstart.exe
	plugins\helloworld.pl (этот плагин будет загружен)
	plugins\MyPluginPack\blabla.pl (этот плагин тоже будет загружен)
	plugins\MyPluginPack\supericons.txt
	plugins\MyPluginPack\subfolder\abc.pl (а вот это НЕ будет загружено)
Помните, что папка с плагинами не обязательно называется "plugins". Юзер может выбрать другую папку для хранения плагинов, подсунув OpenKore опцию "-- plugins =(<имя папки>)".


Как найти папку с плагином (How to locate data files for your plugin)

Пусть ваш плагин использует файл с данными "supericons.txt". Вы можете потребовать от юзера ручками копировать "supericons.txt" в папку "openkore\controls". Но более гуманно будет положить файл "supericons.txt" в ту же самую папку, что и плагин. Таким образом юзер должен только распаковать все файлы в папку с плагинами и плагин заработает по принципу "С места в карьер" без "Доработки напильником".

Но как определить в коде плагина, где конкретно лежит "supericons.txt"? Нельзя же жестко прописать "plugins/MyPluginPack/supericons.txt", потому что юзер может выбрать совершенно другую папку для плагинов или переименовать "MyPluginPack" или еще чего. Как вы узнаете, где ваш .pl-файл лежит? Ответ кроется в переменной "$Plugins::current_ plugin _folder".
Когда OpenKore загружает ваш плагин, в этой переменной находится путь до вашего плагина (относительно корневой папки OpenKore). Вам следует немедленно сохранить значение этой переменной в своей собственной переменной. Потому что, когда будет загружаться следующий плагин, в этой переменной будет путь до следующего же плагина, а не до вашего.

Пример:

Код: Выделить всё

package BlaBla;

use strict;
use Plugins ;
use Log qw(message);

Plugins::register("blabla", "Example  plugin  which demonstrates how to locate data files", \&on_unload);
my $aiHook = Plugins::addHook("AI_pre", \&on_AI);
my $datadir = $Plugins::current_plugin_folder;

sub on_unload {
	Plugins::delHook($aiHook);
}

sub on_AI {
	message "supericons.txt is located in this folder: $datadir\n";
}

1;
Оригинальная статья находится по адресу "http://www.openkore.com/wiki/index.php/How_to_write_ plugins _for_ OpenKore", которая была в последний раз обновлена 22 июня 2007.

Перевод сделал manticora, который тусуется на https://ro-fan.ru
Последний раз редактировалось manticora Чт июл 16, 2009 6:17 pm, всего редактировалось 8 раз.

Аватара пользователя
4epT
macro-маньячина
Сообщения: 2775
Зарегистрирован: Чт дек 21, 2006 1:23 pm
Сервер RO:: 4game
Discord: ya4ept#8494
Контактная информация:

Re: [FAQ] Как писать плагины для OpenKore. (перевод)

Сообщение 4epT » Ср апр 15, 2009 8:09 pm

зачёт, даже я подчерпнул что-то новенькое ;)
у тебя в планах нету оформить статейку у них там?
Быстро и качественно напишу конфиг (макрос)! Стучи!
¤ Свежий бот ¤ Config checker ¤ Manual ¤
Изображение
Изображение

manticora
Грамотный
Сообщения: 437
Зарегистрирован: Ср авг 29, 2007 12:45 pm

Re: [FAQ] Как писать плагины для OpenKore. (перевод)

Сообщение manticora » Ср апр 15, 2009 10:00 pm

Можно запостить перевод на форуме www.openkore.com? Я о таком не думал. Но я бы с удовольствием увидел эту статью на местной Вики, ибо оригинальная англ. статья в дауне уж с недельку.

vit
Бывалый
Сообщения: 624
Зарегистрирован: Вс мар 25, 2007 9:18 pm
Сервер RO:: localhost
Откуда: Санкт-Петербург

Re: [FAQ] Как писать плагины для OpenKore. (перевод)

Сообщение vit » Чт апр 16, 2009 11:21 am

manticora писал(а):Но я бы с удовольствием увидел эту статью на местной Вики
Держи :wink:
http://wiki.rofan.ru/index.php?n=Plugin ... orOpenKore

manticora
Грамотный
Сообщения: 437
Зарегистрирован: Ср авг 29, 2007 12:45 pm

Re: [FAQ] Как писать плагины для OpenKore. (перевод)

Сообщение manticora » Чт апр 16, 2009 12:27 pm

Спасибо большое, vit.

Ответить