*PLUGIN/2.0 [#qc60837c]

この文書は未だ開発者版です。予告なくごっそり変更される可能性があります。

*はじめに [#cfe1855b]

*設計思想 [#ya9cba74]
-手軽に本体やゴーストとやりとりできるよう改修し、SAORI群としてゴーストごとに分散してしまったもののうち「便利機能」にあたる部分を統合し、利用者側の利便性を改善する。
-プラグイン開発者から実行環境へ負担を移すほうが良いでしょう……多分。


*影響評価 [#d70aa843]
**処理系作者 [#zaf37d9b]
処理系にいろいろ負担を移すことを前提としているので、覚悟してください(苦笑

**プラグイン作者 [#k1deb17e]
新たにコール用にrequestエクスポートを定義するので、PLUGIN/1.0との衝突は考慮する必要はありません。~
スクリプトやイベント等のゴーストへの通知が非常に楽になる。

**ゴースト作者 [#t0a2ab9d]
特定のプラグインにたとえ対応していなくてもデフォルトスクリプト仕様(後述)があるので致命的な事にならない。~
どうしてもデフォルトスクリプトで雰囲気を壊されたくない場合は対応しましょう……

**利用者 [#q259082b]
ゴーストごとにちりぢりになった機能群をまとめて扱えるので便利かつ楽。


*DLLエクスポート関数群 [#ia8c41b4]

''YAYA/KAWARI as PLUGIN利用者は読み飛ばして下さい''

-extern "C" __declspec(dllexport) BOOL __cdecl load(HGLOBAL h, long len);
-extern "C" __declspec(dllexport) BOOL __cdecl unload(void);
-extern "C" __declspec(dllexport) HGLOBAL __cdecl request(HGLOBAL h, long *len);

☆Borland系C/C++コンパイラでは_loadのように頭にアンダースコアがつくようですがそちらにも対応した方が良いでしょう。

**load [#r47e065c]
読み込み時にコールされます。HGLOBALにDLLの入るディレクトリのパスが入ります。~
GlobalAlloc(GMEM_FIXED,xxx) されたものなのでそのままポインタ(char *)にキャストして利用してください。~
また、必ずDLL側でGlobalFreeしてください。
***返り値 - 常にtrue [#af81f80e]
規定ではロード失敗時にfalseですが、falseを返しても何も処理されません。

**unload [#g4a78ba1]
DLL開放直前(=SSP/CROW終了時+上書きインストール時、DLL_PROCESS_DETACH前)にコールされます。~
return - 常にtrue 規定では開放失敗時にfalseですが、falseを返しても無視されます。

**request [#i9327bff]
ロード・アンロード以外の処理はすべてここで行われます。~
注意事項はloadと同じです。

***返り値 - 下記プロトコル説明のとおり [#xb77b084]
レスポンス用の返り値HGLOBALも、GlobalAlloc(GMEM_FIXED,xxx)で確保されたものにしてください。


*リクエスト規定 [#e1925f35]

典型的なリクエスト例は以下のとおりです。

 GET PLUGIN/2.0
 ID: OnGhostChange
 Charset: UTF-8
 Reference0: 54
 

 NOTIFY PLUGIN/2.0
 ID: OnMenuExec
 Charset: UTF-8
 Sender: 晶子
 Reference0: 17982

※改行コード=CR+LF

空行で終了。他のDLL仕様といっしょで、ゼロ終端とは限らないので注意してください。

PLUGIN/2.0のフォーマットは基本的にSHIORI/3.0仕様に準じています。~
イベント識別子のIDヘッダと、任意の数(8以降あり)の追加情報であるReferenceヘッダから構成されます。~
Referenceの内容はIDによって変わります。

Reference等の内容に改行等を含めたい場合、また含めなければならないと規定したい場合は、%8f%73のように、回避したい文字のみURLエンコードして渡すよう規定することを *強く推奨* します(仕様ではありませんが)

Senderの内容は、後述するゴースト側からの呼び出し仕様によって呼び出された場合、ゴースト名となります。~
本体側からコールされた場合はSenderヘッダ自体が消滅するか空文字列が代入されます。~
SHIORIのように「本体の名前(SSPとかCROWとか)」が入るわけではないので注意してください。

NOTIFYの方で来た場合、ゴースト側にイベントを送ったりすることはできません。~
EventヘッダやScriptヘッダを返しても無視されます。~
[NOTIFY]として特記されているもの以外は、GET/NOTIFYの双方で来る可能性があります。

**version [GET] [#a058879b]
Referenceなし
必ずロード直後に呼ばれ、プラグインの情報を要求してきています。~
Valueヘッダでプラグインのバージョン情報を返してください。~
(例:SwissArmyKnife/1.0)~
この時Charsetヘッダも同時に返すと、以降そのCharsetでリクエストが来るようになります。

versionリクエストのみレスポンス形式が特殊であることに注意してください。~
これ以外は基本的に下で述べるレスポンス形式に従ってください。

**installedplugin [NOTIFY] [#i435e227]
Reference0以降:プラグイン名[\1]プラグインID
インストール済のプラグインを列挙します。

**ghostpathlist    [NOTIFY] [#d1e09cbb]
**balloonpathlist  [NOTIFY] [#zc68ba96]
**headlinepathlist [NOTIFY] [#rbb697e8]
**pluginpathlist   [NOTIFY] [#vb295e7f]
Reference0以降:フォルダのフルパス
読み込み中のそれぞれ(ゴースト/バルーン/ヘッドライン/プラグイン)のフォルダを通知します。~
複数フォルダに対応する処理系では、Reference1以降もある可能性があります。

**OnSecondChange:秒変化 [#oe49235f]
Referenceなし

**OnGhostBoot:ゴースト起動 [#c1fffcbd]
**OnGhostExit:ゴースト終了 [NOTIFY] [#cac4aeef]
**OnGhostInfoUpdate:シェル変化やHWND変更など、ゴースト情報の更新(load直後にも送られる可能性あり) [NOTIFY] [#zf4e3eff]

Reference0:sakura HWND[\1]kero HWND[\1]3 HWND[\1]4 HWND ...~
Reference1:現在のゴースト名 ~
Reference2:現在のシェル名~
Reference3:ゴーストID (Authorized SSTP(Owned SSTP)で送られるものと同じ)~
Reference4:ゴーストのフルパス

リクエストされるHWND群は、まだ構築されていない場合0が渡される可能性もあります。十分注意して扱ってください。~
Reference3のゴーストIDを識別子として、プラグイン内でゴーストリストを作成しておくと良いでしょう。

**OnMenuExec [#a8e3ddb4]
Reference群:上記のゴースト起動・状態変更イベントと同じ形式で、メニュー呼び出し元ゴースト情報が通知される

プラグインメニュー等からそのプラグインが選択されたことを通知します。~
設定ダイアログ・メッセージボックス等を出す、スクリプトを返す等、何らかの反応を行うことを強く推奨します。

**OnInstallComplete : インストール終了 [#nd74d738]
Reference0 : インストールタイプ(\1区切り)~
Reference1 : インストールされたものの名前(\1区切り)~
Reference2 : インストールされたフルパス(\1区切り)

**OnChoiceSelect(Ex)/OnAnchorSelect(Ex)/\qに指定したイベント [#b39e4bf4]
下のレスポンス規定を参照してください。

*レスポンス規定 [#e616585d]
レスポンスの例は以下のとおりです。
CRLF区切りはリクエストと同様ですので[CRLF]は省略しています。

 PLUGIN/2.0 200 OK
 Charset: Shift_JIS
 Target: 54
 Event: OnResourceLow
 EventOption: notify
 Reference0: 19
 Reference1: 31
 Reference2: 65
 Script: すくりぷと~
 ScriptOption: nobreak,notranslate

※複数起動対応の処理系のみ※
現在起動中のゴーストでTargetに該当するゴーストがいたらそれで処理されます。~
"__SYSTEM_ALL_GHOST__"が指定されている場合は、「起動中の全ゴースト」に通知されます。

該当しない場合、何も指定しない場合は処理系に応じて適当なゴースト「1体」で処理されます。~
また、後述のゴースト側からの呼び出し仕様で呼ばれた場合は、Targetヘッダで明示的に指定がされない限り、呼んだゴーストに返ります。

※対応していない処理系ではそもそも1体しかありませんのでそのゴーストが毎度呼び出されます。

**Event/Reference [#mbf52a6b]
EventヘッダとReferenceヘッダはゴースト側に送るイベントです。~
これにゴーストが反応しない場合、デフォルトスクリプトであるScriptヘッダが再生されます。

**ScriptOption [#jad1d28c]
ScriptOptionは、スクリプトヘッダ内容にのみ適用されるオプション指定です。
:notranslate|ゴーストのトランスレートを介さない
:nobreak|現在喋っているトークを中断せず最後まで喋った後で指定したスクリプトを実行する

**EventOption [#mdb80f53]
EventOptionは、Eventヘッダ内容にのみ適用されるオプション指定です。
:notify|指定したイベントをゴーストにnotifyで通知する

Event,EventOption,Reference,Target,Script,ScriptOptionはすべて省略可能です。~
例えばイベントだけ送りたい、デフォルトスクリプトは要らん、という場合はScript/ScriptOptionヘッダを省略してください。~
※スクリプトだけ送りたい場合はその逆ですね。

*選択肢フック [#jabb6340]
プラグインのレスポンスでかえってきたスクリプト内、またはEventヘッダでゴーストにイベント通知して帰ってきたスクリプト内に選択肢があれば、その1回分だけOnChoiceSelect(Ex)/OnAnchorSelect(Ex)/On????をプラグインに横流しします。~
(汚い仕様ですが、これがあると選択肢をバルーンに出して設定、などもできますしね)

*プラグインID [#je8326ae]
プラグインごとに一意につけられるIDです。~
ぶつかる可能性が「極端に低い」63バイトまでの1バイト文字列なら何でもかまいません。~
通常、GUID/UUIDと呼ばれるものを使います。

それなりに開発環境をそろえておられる方なら、guidgen.exeのRegistry Formatが生成に使えると思います。~
ない人はこちら > http://ssp.shillest.net/docs/guid.zip~
処理系側は最低でも63バイトまで受け付ける必要がありますが、そもそも制限を設けないことを推奨します。

descript.txtのIDエントリに、次のように書いてください。~
例:id,3491996A-B383-4890-B863-5CE258678093

ゴースト側からはプラグイン名以外にこのIDを使ってプラグインを呼び出すことができます。~
意味的には、このIDが同じであるということは、たとえ名前が変っても互換性がある、という事を示すことになります。


*descript.txt [#o7b7ffaa]
プラグイン特有のエントリのみ記述します。

**secondchangeinterval [#e562faf0]
OnSecondChangeを呼ぶ間隔を指定します。もちろん標準値は1です。
0にするとOnSecondChage自体を送信しません。

**disableAllNotifyCall [#sdd665af]
上記の全てのリクエストを一切停止します。
load/unloadのみでアプリケーションにフックをかけ、他は要らないというプラグインに有用でしょう。


*ゴースト側拡張 [#cc8b7a0a]
**スクリプト拡張 [#s038cc4b]
 \![raiseplugin,プラグイン名,イベント,Reference0...]
 \![raiseplugin,プラグインID,イベント,Reference0...]

指定したプラグインに指定したイベントを(GETで)送信します。
プラグイン側でTarget指定がない限り(system_any)、プラグインからのレスポンスはraisepluginしたゴーストに優先的に割り振られますので、SAORIもどき的な使い方も可能です。

**SHIORIイベント拡張 [#jc374320]
 NOTIFY SHIORI/3.0
 ID: installedplugin
 Reference0以降:プラグイン名[\1]プラグインID
インストール済のプラグインを列挙します。バイト値1区切りでプラグイン名、プラグインIDとなります。
プラグインIDは必ず存在するものではありません。


*インストール [#h62cb9f6]
[[INSTALL/1.5>/SSP/仕様書/INSTALL-1.5]]を参照

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS