This project has moved and is read-only. For the latest updates, please go here.

Руководство по написанию плагинов для клиента

Краткое описание внутренностей клиента

В основе клиента лежит некий "конвейер" (класс - Conveyor), по которому "перемещаются" сообщения (класс Message) и команды (класс Command).
Конвейер состоит из частей, называемых юнитами (класс - ConveyorUnit). При поступлении сообщения/команды на конвейер, оно/она последовательно обрабатывается каждым юнитом до тех пор, пока:
  • какой-либо юнит не пометит команду/сообщение как "обработанную" (свойство Handled)
  • сообщение/команда не достигнет конца конвейера
Примерный интерфейс базового класса
    public abstract class ConveyorUnit : IDisposable
    {
        public virtual void HandleCommand(Command command);
        public virtual void HandleMessage(Message message);
        protected void PushCommandToConveyor(Command command);
        protected void PushMessageToConveyor(Message message);
    }


Переопределяя методы HandleCommand и/или HandleMessage в дочерних классах, можно писать свою логику обработки отдельных команд и/или сообщений соответственно.

Сообщения на конвейере могут появиться двумя способами:
  • какой-либо юнит добавляет новое сообщение используя PushMessageToConveyor метод
  • от сервера приходят данные
Во-втором случае есть небольшая проблема: данные от сервера приходят в виде потока байт и необходима логика для преобразования этого потока в один из наследников класса Message. Этим занимаются наследники класса MessageDeserializer. На данный момент наследник один - TextMessageDeserializer: преобразует полученные байты в экземпляры класса TextMessage. Собственно все это задумывалось для возможности получения нестандартных сообщений от сервера, но так как таковых пока нет, то тут без подробностей.

Аналогичная ситуация и с командами: когда команда достигает конца конвейера ее нужно как-то преобразовать в поток байт для отправки на сервер. Для этого есть CommandSerializer и его наследник TextCommandSerializer.

Расширение возможностей триггеров, хоткеев и алиасов

С каждым триггером/хоткеем/алиасом можно связать набор действий (наследники класса ActionBase), которые будут выполняться при срабатывании этого триггера/хоткея/алиаса.
В клиенте предусмотрена возможность расширения списка возможных типов действий. Вот тут все несколько сложнее ибо помимо самого действия нужно сказать клиенту как это действие редактируется (см ActionViewModelBase) для этого и существует класс ActionDescription.

Также некоторые действия могут требовать один или несколько параметров (класс ActionParameterBase). Например, у действия "колд !благо! %1", "%1" является параметром зависящим от контекста. Плагин также может добавлять свои типы параметров. (см ActionParameterViewModelBase и ParameterDescription).

Создание плагина

Для создания плагина необходимо:
  • создать проект типа Class library
  • добавить референс на сборку Adan.Client.Common
  • создать класс наследник от PluginBase и пометить его атрибутом Export(typeof(PluginBase))
  • переопределив соответствующие проперти указать какие юниты, дейсвия, параметры, виджеты, MessageDeserializer'ы и CommandSerializer'ы ваш плагин добавит к существующим.
  • поместить откомпилированную сборку в папку Plugins.

Виджеты

Ну собственно виджет это обычный System.Windows.Controls.Control плюс DisplayName (то, что отображается в заголовке виджета) и уникальный Namе (необходим для сохранения/восстановления расположения виджетов при закрытии/открытии клиента).

Собственно можно долго и нудно описывать как оно устроено, но лучше таки смотреть код. Пример работающего плагина находится в проекте Adan.Client.Plugins.OutputWindow.

Last edited Sep 27, 2011 at 4:34 PM by petka, version 1

Comments

No comments yet.