Skip to content

Latest commit

 

History

History
935 lines (647 loc) · 41.3 KB

api.md

File metadata and controls

935 lines (647 loc) · 41.3 KB

Документция для DeskChan API

Все взаимодействия между плагинами происходят с помощью сообщений. Любое сообщение имеет тег и данные (данные могут быть равны null, если они не нужны).

На каждое сообщение могут быть подписаны ноль или несколько плагинов. Каждый подписанный на тег плагин получает все сообщения, которые отправлены с этим тегом.

Если требуется выбор из нескольких альтернативных реализаций (то есть сообщение должен получить один плагин, а не все сразу), то рекомендуется использовать механизм "альтернатив" (см. core:register-alternative).

Рекомендуется ограничиться следующими типами данных для сообщения: String, Integer, Float, Double, Map<String, Object>, List. При этом последние два типа должны содержать только объекты вышеперечисленных типов.

В редких случаях возможно применение других типов.

Это необходимо для того, чтобы любое сообщение могло быть сериализовано и десериализовано в JSON.

Для экспериментов возможно использовать вкладку Debug (Отладка) диалога настроек DeskChan. В верхнем поле ввода можно указать тег сообщения, а в нижнем - данные в формате JSON. При нажатии кнопки сообщение будет отправлено от имени плагина gui.

Уведомления от плагина core

core-events:plugin-load

Данные (String)

id плагина

Описание

Посылается ядром каждый раз, когда загружается новый плагин.

Это не обычное сообщение. При подписке на него подписчику сразу же будут присланы сообщения на каждый уже загруженный плагин. Таким образом вы можете узнать начальный список плагинов.

core-events:plugin-unload

Данные: String

id плагина

Описание

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

Сообщения для плагина core

core:quit

Данные: Integer или Map<String, Object>

delay: Integer (опционально)

Описание

Инициирует завершение приложения. Все плагины будут выгружены. Отменить завершение приложения штатными средствами нельзя. Параметр delay позволяет задать задержку в миллисекундах.

core:register-alternative

Данные: Map<String, Object>

srcTag: String
dstTag: String
priority: Integer

Описание

Регистрирует новую альтернативу dstTag для тега srcTag с приоритетом priority. Плагин core подписывается на srcTag. При поступлении сообщения оно будет перенаправлено на srcTag (при этом отправитель останется таким как был, а не изменится на core). Если существует несколько альтернатив для srcTag, то будет выбрана та, которая имеет наибольшее числовое значение приоритета.

Плагин core запоминает id плагина, который зарегистрировал альтернативу. При его выгрузке все альтернативы, которые он зарегистрировал, будут удалены.

Для регистрации нескольких альтернатив можно воспользоваться сообщением с тегом core:register-alternatives. Оно принимает те же данные, но обёрнутые в список (List<Map<String, Object>>).

core:unregister-alternative

Данные: Map<String, Object>

srcTag: String
dstTag: String

Описание

Удаление альтернативы dstTag для тега srcTag. Альтернатива будет удалена только если данное сообщение отправлено тем же плагином, что и зарегистрировал данную альтернативу.

См. также: core:register-alternative.

core:change-alternative-priority

Данные: Map<String, Object>

srcTag: String
dstTag: String
priority: Integer

Описание

Изменяет числовое значение приоритета для альтернативы dstTag для тега srcTag. Изменить приоритет альтернативы может любой плагин, а не только тот, который её зарегистрировал.

В нормальных условиях изменять приоритет альтернативы следует только по запросу пользователя.

См. также: core:register-alternative

core:query-alternatives-map

Данные: Map<String, Object>

seq: Object (рекомендуется Integer)

Ответное сообщение: Map<String, Object>

seq: Object
map:  Map<String, Object>
    Ключи: srcTag
    Значения: Map<String, Object>
        tag: String (dstTag)
        priority: Integer
        plugin: String (id плагина)

Описание

Служит для запроса списка всех зарегистрированных альтернатив. Полезно для предоставления пользователю возможности настройки приоритетов.

Тег ответного сообщения соответствует идентификатору плагина, пославшего запрос. seq в ответном сообщении равен seq в запросе.

См. также: core:register-alternative

core:get-plugin-data-dir

Данные: Map<String, Object>

seq: Object (рекомендуется Integer)

Ответное сообщение: Map<String, Object>

seq: Object
path: String

Описание

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

Тег ответного сообщения соответствует идентификатору плагина, пославшего запрос. seq в ответном сообщении равен seq в запросе.

core:create-pipe

Данные (String)

Тег пайпа

Описание

Создаёт пайп (конвейер) с указанным именем (тегом). После этого ядро подписывается на указанный тег и реализует некоторую логику. А именно:

Пайп содержит в себе последовательность тегов сообщений, слушатели которых по сути дела являются обработчиками пайпа. При приходе сообщения на тег пайпа, его данные будут по очереди отправлены на каждый тег, который составляет конвейер. При этом действует следующее соглашение: данные проходящие через пайп обязательно имеют тип Map<String, Object> (если отправить на пайп данные другого типа, то они будут преобразованы в Map с ключом "data" равным исходному значению), этот Map содержит ключ "seq", который никто не должен изменять кроме плагина core. Каждый обработчик конвейера должен отправлять данные снова в конвейер (на тот же тег), при этом допустимо изменять все ключи кроме "seq". Когда весь конвейер пройден, итоговые данные отправляются в сообщении с тегом равным идентификатору плагина, который отправил сообщение в пайп.

core:destroy-pipe

Данные (String)

Тег пайпа

Описание

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

core:append-pipe-stage

Данные (Map<String, Object>)

pipe: String
tag: String

Описание

Добавляет тег tag в конец конвейера pipe. Теперь вы обязаны слушать тег tag и пересылать данные каждого сообщения с тегом pipe. При этом данные всегда имеют тип Map<String, Object> и вы можете менять любые его ключи кроме seq и pipeReplyTo.

core:prepend-pipe-stage

Данные (Map<String, Object>)

pipe: String
tag: String

Описание

Добавляет тег tag в начало конвейера pipe. Требования те же, что и для core:append-pipe-stage.

core:remove-pipe-stage

Данные (Map<String, Object>)

pipe: String
tag: String

Описание

Удаляет тег tag из конвейера pipe. Теперь вы не обязаны слушать тег tag. Также теги автоматически удаляются из конвейера при выгрузке плагина, который их добавил. Удалить тег из конвейера может только тот плагин, который его туда добавил.

Сообщения для плагина core-utils

core-utils:notify-after-delay

Данные (Map<String, Object>)

seq: Object (рекомендуется Integer)
delay: int или long (опционален)

Ответное сообщение: Map<String, Object>

seq: Object

Описание

Вместо использования стандартных Java-таймеров или таймеров, предоставляемых различными тулкитами, рекомендуется пользоваться этим сообщением, которое использует самый эффективный способ, доступный в текущей среде.

Спустя delay миллисекунд после отправки сообщения будет вызвана callback-функция, передаваемая третьим параметром метода sendMessage (см. описание Groovy Plugin API). Ей будет передан тот же seq, что и при вызове.

Если указать seq тайматута, который уже идёт, то он будет перезапущен с новым временем. Если время отрицительное (по умолчанию delay равен -1), то таймаут будет отменён.

Уведомления от плагина gui

Все события, связанные с мышью, возвращают как минимум 4 параметра:

  • screenX / screenY - координаты мыши относительно экрана;
  • nodeX / nodeY - координаты мыши относительно элемента, над которым она находится.

gui-events:character-left-click

Пользователь кликнул левой кнопкой мыши по персонажу

gui-events:character-right-click

Пользователь кликнул правой кнопкой мыши по персонажу

gui-events:character-middle-click

Пользователь кликнул средней кнопкой мыши по персонажу

gui-events:character-double-click

Пользователь дважды кликнул по персонажу

gui-events:character-mouse-moved

Пользователь перемещает курсор по персонажу

gui-events:character-scroll

Пользователь прокручивает колёсико мышки над персонажем. В качестве параметра delta приходит либо 1 при прокрутке вниз, либо -1 при прокрутке вверх.

gui-events:balloon-left-click

Пользователь кликнул по сообщению левой кнопкой мыши

gui-events:balloon-right-click

Пользователь кликнул по сообщению правой кнопкой мыши

gui-events:balloon-middle-click

Пользователь кликнул по сообщению средней кнопкой мыши

gui-events:balloon-double-click

Пользователь дважды кликнул по сообщению кнопкой мыши

gui-events:balloon-mouse-moved

Пользователь перемещает курсор по сообщению

gui-events:balloon-scroll

Пользователь прокручивает колёсико мышки над сообщением. В качестве параметра приходит либо 1 при прокрутке вниз, либо -1 при прокрутке вверх.

Сообщения плагину gui

gui:say

Данные: Map<String, Object>

text: String
characterImage: String (опционально)
timeout: Integer (опционально)
priority: Integer (опционально)

Описание

Вывести текстовое сообщение. При этом на время показа сообщения может быть изменена картинка персонажа на указанную (из скина, если текущий скин не содержит данного изображения, будет использовано normal).

Сообщение будет закрыто по клику пользователя или по таймауту (указывается в миллисекундах, нулевое значение отключает автоматическое закрытие сообщения, при отсутствии значения будет использоваться значение по умолчанию, которое можно настраивать пользователь).

При закрытии сообщения картинка персонажа изменится на текущую.

Для сообщения можно задать приоритет. По умолчанию он равен 1000. Каждое сообщение висит как минимум половину своего таймаута. Если посылается запрос на отображение сообщения, когда уже висит "облачко" с другим, то программа руководствуется следующими правилами:

  • если приоритет нового сообщения больше, чем предыдущего, то через половину таймаута старого новое отображается сразу поверх старого;
  • если приоритет равен или ниже, то сообщение будет отображено после полного таймаута предыдущего и всех остальных более приоритетных сообщений в очереди;
  • если приоритет равен нулю или меньше, то сообщение считается неважным и не будет запланировано к отображению вообще.

Рекомендуется вместо прямого обращения к плагину gui использовать альтернативу DeskChan:say.

gui:set-image

Данные: String

Название картинки

Описание

Изменить текущую картинку персонажа. Используется, если никакое сообщение не отображается, либо текущее сообщение не переопределяет картинку.

Если картинка с таким именем не содержится в текущем скине, то используется normal.

gui:change-skin

Данные: String или Path

Путь к скину

Описание

Меняет текущий скин. Изменение будет сохранено в настройках.

gui:change-skin-opacity

Данные: Map<String, Object>

absolute: float
  или
relative: float

save: boolean (опционально)

Описание

Изменяет непрозрачность персонажа. Чем меньше значение, тем прозрачнее изображение. Значение можно задать абсолютно (absolute) либо относительно текущего уровня (relative).

Дополнительный параметр save позволяет указать, нужно ли сохранить изменение в настройках. По умолчанию все изменения выполняются только в рамках текущей сессии.

gui:resize-character

Данные: Map<String, Object>

scaleFactor: float
  или
zoom: float
  или
width: int
  или
height: int

save: boolean (опционально)

Описание

Увеличивает или уменьшает размер спрайта в зависимости от заданного параметра, в качестве которого может быть либо абсолютное значение масштаба (scaleFactor), либо его относительное изменение в зависимости от текущего значения (zoom), либо конкретные значения ширины (width) или высоты (height).

Параметры рассматриваются в указанном порядке. Если будет передано несколько аргументов, то будет использован первый совпавший, а остальные будут проигнорированы. Поэтому, например, ширина и высота не могут использоваться одновременно! Программа следит за сохранением пропорций изображения.

Дополнительный параметр save позволяет указать, нужно ли сохранить изменение масштаба в настройках. По умолчанию все изменения выполняются только в рамках текущей сессии.

gui:register-simple-action

Данные: Map<String, Object>

name: String
msgTag: String
msgData: Object (опционально)

Описание

Регистрирует простое действие. Оно доступно через контекстное меню персонажа. При выборе действия будет послано сообщение с тегом msgTag и msgData (null, если не указать).

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

В будущем способ вызова простого действия пользователем может быть изменён.

Рекомендуется не обращаться напрямую к плагину gui, а использовать альтернативу DeskChan:register-simple-action.

Для регистрации нескольких действий рекомендуется использовать сообщение с тегом DeskChan:register-simple-actions. В качестве данных оно принимает список таких же наборов параметров (List<Map<String, Object>>).

gui:show-notification

Данные: Map<String, Object>

name: String
text: String

Показывает окно сообщения с названием name и текстом text.

gui:setup-options-tab

Данные: Map<String, Object>

name: String
msgTag: String (опционально)
controls: List<Map<String, Object>>

Описание

Создаёт или обновляет уже существующую вкладку настроек для плагина, отправившего это сообщение (автоматически удаляется при его выгрузке).

Если указан параметр msgTag, то на вкладку будет добавлена кнопка "Сохранить", которая при нажатии отправляет сообщение с указанным тегом и со значениями элементов управления.

controls является списком элементов управления, которые должны быть размещены на вкладке.

Каждый элемент управления имеет как минимум три параметра:

type: String
id: String (опционально)
label: String (опционально)

type задаёт тип элемента управления (в зависимости от него могут добавлять другие обязательные и опциональные параметры), label позволяет разместить текстовую подпись рядом с элементом управления. Если же у элемента задан id, то при нажатии на кнопку сохранения, он будет добавлен в Map, который будет отправлен в качестве данных сообщения (при этом ключом будет id, а значением - текущее значение элемента управления).

Доступные элементы управления

Label
value: String

Самый простой элемент управления. Статичная надпись.

TextField
value: String (опционально)
hideText: Boolean (опционально)

Однострочное текстовое поле.

Spinner (или IntSpinner)
value: Integer (опционально)
min: Integer (опционально)
max: Integer (опционально)
step: Integer (опционально)
onChange: Map<String, Object> (опционально)
    msgTag: String
    newValueField: String (опционально)
    oldValueField: String (опционально)
    multiplier: Double (опционально)
    data: Map<String, Object> (опционально)

Поле ввода для целых числовых значений.

При заданном параметре onChange при каждом изменении значения поля будет отправляться сообщение на тег msgTag. По умолчанию новое значение в сообщении будет под ключом value, а старое — oldValue, но это можно изменить с помощью параметров newValueField и oldValueField. Также с помощью параметра multiplier можно установить число, на которое реальное значение поля будет умножаться при отправке сообщения. Наконец, в параметре data можно указать различные дополнительные данные, которые следует отправить в сообщении.

FloatSpinner
value: Double (опционально)
min: Double (опционально)
max: Double (опционально)
step: Double (опционально)
onChange: Map<String, Object> (опционально)
    msgTag: String
    newValueField: String (опционально)
    oldValueField: String (опционально)
    multiplier: Double (опционально)
    data: Map<String, Object> (опционально)

Поле ввода для числовых значений с плавающей запятой.

Информация о параметре onChange представлена в описании к элементу Spinner.

Slider
value: Double (опционально)
min: Double (опционально)
max: Double (опционально)
step: Double (опционально)
onChange: Map<String, Object> (опционально)
    msgTag: String
    newValueField: String (опционально)
    oldValueField: String (опционально)
    multiplier: Double (опционально)
    data: Map<String, Object> (опционально)

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

Информация о параметре onChange представлена в описании к элементу Spinner.

CheckBox
value: boolean (опционально)

Переключатель. Может быть установлен (true) или сброшен (false).

ComboBox
values: List<String>
value: Integer (опционально)

Поле выбора из фиксированного набора вариантов. Значением поля является индекс выбранного элемента.

ListBox
values: List<String>
value: List<Integer>

Поле выбора из фиксированного набора вариантов. При этом пользователь имеет возможность выбрать несколько элементов сразу. Значением является список индексов выбранных элементов.

Button
value: String
msgTag: String
msgData: Object (опционально)

Кнопка. Посылает сообщение с тегом msgTag и данными msgData при нажатии.

FileField
value: String (опционально)
initialDirectory: String (опционально)
filters: List<Map<String, Object>> (опционально)

Поле выбора файла. Можно указать начальную директорию.

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

  • description (String) — описание фильтра;
  • extensions (List<String>) — список расширений в формате *.<расширение>.
DatePicker
value: String (опционально)
format: String (опционально)

Поле для выбора даты.
Несмотря на то, что значение в поле отображается в зависимости от локали, по умолчанию его следует задавать и получать в формате ISO (например, 2017-04-09). Формат можно изменить с помощью параметра format. Например для РФ (9.04.2017), это будет d.M.y.

gui:show-custom-window

Данные: Map<String, Object>

name: String (опционально)
msgTag: String (опционально)
controls: List<Map<String, Object>>

Создаёт и отображает обычное отдельное окно с указанными элементами, список которых перечислен для сообщения gui:setup-options-tab.

gui:choose-files

Данные: Map<String, Object>

title: String (опционально)
multiple: boolean (опционально)
initialDirectory: String (опционально)
initialFilename: String (опционально)
saveDialog: boolean (опционально)
filters: List<Map<String, Object>> (опционально)

Ответное сообщение: Map<String, Object>

seq: Object
path: String
  или
paths: List<String>

Отображает диалоговое окно, позволяющее пользователю выбрать файл(ы). В ответ приходит строка (path) или список строк с путями (paths) до выбранных файлов. Параметр multiple как раз отвечает за то, можно ли выбирать несколько файлов. По умолчанию он равен false.

С помощью title можно изменить заголовок окна, используя initialDirectory — начальную директорию, а с помощью initialFilename — предложить название файла. Для выбора несуществующего файла или файла, разрешённого пользователем к перезаписи, установите saveDialog в true.

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

  • description (String) — описание фильтра;
  • extensions (List<String>) — список расширений в формате *.<расширение>.

gui:choose-directory

Данные: Map<String, Object>

title: String (опционально)
initialDirectory: String (опционально)

Ответное сообщение: Map<String, Object>

seq: Object
path: String

Отображает диалоговое окно, позволяющее пользователю выбрать папку. В ответ приходит строка с путём (path) до выбранной директории. С помощью параметра title можно изменить заголовок окна, а используя initialDirectory — начальную директорию.

Система характеров (говорилка)

talk:request

Данные: Map<String, Object>

purpose: String (опционально)

Описание

Выбирает из списка доступных подходящих фраз одну с заданным назначением, компонует её и отправляет в DeskChan:say. Список назначений можно посмотреть в описании системы характеров.

talk:make-influence

Данные: Map<String, Object>

type: String, возможные значения - character, emotional
feature: String
multiplier: Float

Описание

Оказывает влияние на характер (в случае type=character) или на эмоциональное состояние (в случае type=emotional). Значение feature указывает, на какую компоненту системы оказывается влияние. В случае type=character стандартное значение - sympathy, В случае type=emotional стандартное значение - happiness, полный список можно посмотреть в описании системы характеров. multiplier - число, на которое сдвигается шкала.

talk:register-perk

Данные: Map<String, Object>

priority: Integer

Описание

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

talk:unregister-perk

Описание

Удаляет плагин из списка перков.

talk:create-quotes-base

Данные: Map<String, Object>

url: String
filename: String

Описание

Обращается к JSON файлу фраз по указанной в url ссылке и сохраняет его в качестве списка фраз в формате xml под названием filename.quotes.

talk:perk-answer

Данные: Map<String, Object>

url: String
filename: String

Описание

На этот тип сообщений плагины должны присылать ответы на запросы, присланные им от talking_system. Подробнее не будет, лезьте в код, конкретно файл PerkContainer.java.

Уведомления от плагина talking_system

perk:operate

Запросы к перкам от talking_system. Подробнее не будет, лезьте в код, конкретно файл PerkContainer.java.

Groovy Plugin API

Рекомендуется писать плагины на языке программирования Groovy. Плагином является каталог, содержащий файл plugin.groovy. В этом же каталоге можно также сохранить какие-либо статичные файлы, необходимые плагину. Для хранения настроек и кеша следует использовать другой каталог (см. core:get-plugin-data-dir).

Скрипт должен отправить все необходимые сообщения и подписаться на все необходимые ему сообщения.

Помимо всех стандартных функций Java ему доступны следующие функции DeskChan Plugin API:

void sendMessage(String tag, Object data);
void sendMessage(String tag, Object data, ResponseListener responseListener);
void addMessageListener(String tag, MessageListener listener);
void removeMessageListener(String tag, MessageListener listener);
void addCleanupHandler(Runnable handler);

sendMessage позволяет отправить сообщение с тегом tag и данными data. Версия с тремя аргументами преобразует data в Map, если он им не является (при этом прошлое значение data будет сохранено с ключом "data"). В этот словарь будет добавлено числовое поле seq, которое будет монотонно возврастать с каждым вызовом данной функции (то есть его можно считать уникальным первые несколько миллиардов вызовов sendMessage). В качестве последнего аргумента можно передать лямбда-функцию, которая будет вызвана, когда будет получен ответ с тем же seq и с тегом соответствующим id текущего плагина. Лямбда-функция должна принимать два аргумента: sender (String) и data (Object).

addMessageListener и removeMessageListener соответственно добавляют и удаляют подписку на сообщение с указанным тегом (плагин может подписываться несколько раз на одно и то же сообщения разными слушателями). Слушателем может выступать лямбда-функция, принимающая три аргумента: sender (String), tag (String), data (Object). Можно использовать одного и того же слушателя для разных сообщений (различать их по аргументу tag, если требуется). При выгрузке плагина все его слушатели удаляются автоматически.

addCleanupHandler позволяет зарегистрировать обработчик выгрузки плагина. Он должен уничтожить те объекты, которые в ином случае уничтожены не будут. В качестве него может выступать лямбда-функция без аргументов.

JavaScript (Nashorn) Plugin API

Данное API не является стандартным, запилено другим человеком и может быть изменено в будущем.

По сути тут всё аналогично вышеописанному Groovy Plugin API. Обратить внимание нужно на буквально несколько моментов:

  1. В отличие от Groovy-плагинов, JavaScript-плагины не являются наследниками никаких классов и, соответственно, не имеют встроенных методов sendMessage(), addMessageListener() и т. п. Но в исполяемую среду "инжектится" специальный объект — так называемая шина (bus) — с помощью которой плагин "общается" с приложением. Она предоставляет ему описанные в предыдущем разделе методы.
  2. Типы данных на ходу преобразуются между типами одного языка в другой. В случае каких-либо проблем стоит иметь это в виду, поскольку возможны различные проблемы (в том числе по причине ошибок в компиляторе Nashorn).
    Для примера использования API смотрите приложенный плагин-пример (test_javascript).
  3. У шины есть нестандартный метод say(), представляющий собой метод-сокращение для облегчения вывода сообщений. Он поддерживает все опциональные параметры сообщения gui:say (priority, timeout, characterImage). Также для строк с символами, выходящими за рамки таблицы ASCII, не забывайте указывать их u"юникодную природу"!
  4. Методы getDataDirPath(), getPluginDirPath() и getRootDirPath() возвращают не объекты Java-класса Path, а обычные строки.