document

SAKURA Script/2.0
SHIORI の定義
Windows における SHIORI の実装
SHIORI プロトコル
SHIORI/3.0 ID
Owned SSTP
補足

SAKURA Script/2.0


アルファベット順に羅列

状態を変化させるコマンド(\_q 等)は特に断りがない限り 1セッションで失効


  • \0
  • \1

    \0 でスコープを sakura 側に移動。\1 でスコープを kero 側に移動。


  • \_a[symbol]

    \_a で囲った部分がキャラクタ型ジャンパ、いわゆる「リンク」となる。キャラクタ型ジャンパはクリックによって OnAnchorSelect イベントを raise する。Reference0 に symbol で指定した識別子。例示

    \_a[hoge]ほげ\_a



    GET Sentence SHIORI/2.2
    Event: OnAnchorSelect
    Reference0: hoge


  • \b[n]

    現スコープのバルーンのサーフィスを ID n に切り替え


  • \_b[s,x,y]

    s で指定されたファイルをバルーン内座標 x,y に張り込み
    x が数値でなく文字列 centerx だった場合 x センタリング処理
    y が数値でなく文字列 centery だった場合 y センタリング処理

    s の基準ディレクトリは home\ghost\name\ghost\master


  • \c

    現スコープのバルーンをクリア。カーソルはホームポジションへ


  • \e

    えんいー
    終端記号


  • \i[n]

    アニメーショングループ n を起動させる。アニメについては SERIKO の項を参照。


  • \j[s]

    s が http:// で始まる文字列だった場合、設定されたブラウザを用いて s で指定された URL を開く
    s が file:// で始まる文字列だった場合、OS の拡張子関連付けを用いて s で指定されたファイルを開く


  • \_l[x,y]

    カーソル位置を絶対座標 x,y に移動


  • \m[wm,w,l]

    SSTP が受けた直前の HWnd に対し postmessage(hwnd,wm,w,l) を発行


  • \n
  • \n[half]

    改行(キャリッジリターン+ラインフィード)
    [half] がつくと半分の高さ改行


  • \_n

    \_n で囲まれたエリアは自動改行が行われない


  • \_q

    \_q で囲まれたエリアはノーウエイトで表示される。クイックセクション


  • \s[n]

    現スコープのサーフィスを ID n に切り替え


  • \_s

    \_s で囲まれたエリアは両方のキャラクタが同じセリフを喋る。シンクロナイズセクション


  • \_v[s]

    s で指定された音声ファイルを再生。再生できるフォーマットは、wav、mp3、wma


  • \_V

    \_v で再生されたファイルの再生完了を待つ


  • \w?

    ?*50ms ウエイト。簡易書式。


  • \_w[n]

    n ms ウエイト。高精度。


  • \x

    一時停止状態に入り、ページめくり(バルーンクリック)待機


  • \![*]

    SSTP マーカーを流用した段落点

    オフセットコントロールあり。文字扱い


  • \*

    同セッション内の選択肢がタイムアウトしない

    depracated


  • \-

    MATERIA システムをシャットダウン


  • \![set,desktopalignment,s]

    現スコープのデスクトップ上での位置アラインメントを識別子 s に従って設定する。

    top
    画面上端
    bottom
    画面下端

  • \![set,choicetimeout,n]

    選択肢のタイムアウトを n ミリ秒に設定する。-1 の場合タイムアウトしない。永続。デフォルト値は 16000 ミリ秒


  • \![change,ghost,name]

    ゴースト切り替え。name が名指しだとそのゴーストへ。name が random の場合ランダムチェンジ。sequential の場合シーケンシャルチェンジ。名指しした相手がいなかった場合はスルー。例示

    \![change,ghost,さくら]


  • \![updatebymyself]
  • \![executesntp]
  • \![biff]
  • \![open,configurationdialog]
  • \![open,ghostexplorer]
  • \![open,shellexplorer]
  • \![open,balloonexplorer]
  • \![open,headlinesensorexplorer]
  • \![open,rateofusegraph]
  • \![open,rateofusegraphballoon]
  • \![open,rateofusegraphtotal]

    システムファンクションをコール。何が呼ばれるかは概ね見た通り


  • \![vanishbymyself]

    自身を Vanish

  • SHIORI の定義


    SHIORI は本システムの kernel にあたり、その実体は個々のゴースト固有のユニークコードを格納し、SHIORI プロトコルを用いて本体 GUI と高速に通信し続ける 1つの独立したネイティブプログラムである。

    SHIORI は単なる辞書、文字列リソース、もしくはスクリプトシステムであってはならず、任意のネイティブコードを所有できる独立したネイティブプログラムでなくてはならない。

    本文書では Windows プラットフォームにおける SHIORI の実装方法について記述する。Windows プラットフォームでは上記条件を満たすため、SHIORI は DLL として実装されている。

    Windows における SHIORI の実装


    最も高速な継続的通信手段として DLL を用いている。

    load、unload、request は、それぞれ関数として実装されている。SHIORI DLL がこれらの関数をエクスポートし MATERIA がこれをインポートすることで通信経路が確保される。

    シングルサーバ/シングルクライアントであり、SHIORI DLL は複数のクライアントの接続を受け入れることは想定しなくてよい。

    MATERIA はリクエスト後レスポンスが返るまでブロッキングする。スレッドセーフであることは考慮しなくてよい。


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


    通信データは Windows API globalalloc によって確保される gptr を用いて作成される。リクエスト文字列、レスポンス文字列ともにこの形式のバッファを用いて送受信される。

    バッファのライフサイクルを以下に示す。

    MATERIA リクエストメモリ確保
    リクエスト
    SHIORI リクエスト受信
    リクエストデータ取り出し
    リクエストデータメモリ破棄
    処理
    レスポンスメモリ確保
    レスポンス
    MATERIA レスポンス受信
    レスポンスデータ取り出し
    レスポンスデータメモリ破棄

    通常のポインタを用いた関数呼び出しと異なり、送信側が自らバッファを確保し直すことに注意が必要。この方式には、送受信可能なデータの大きさが確実に無限長で、かつデータがバイナリかテキストか問われないというメリットがある。一方難点としては通信のオーバヘッドが大きいことが挙げられる。

    SHIORI プロトコル


    リクエスト文字列は以下の形式で構成される。

    GET SHIORI/3.0
    Sender: Materia
    ID: hoge
    Reference0: uge
    Reference1: ....
    ....
    ..

    行単位処理の発想であり、CR+LF で各行がセパレートされ、空行でターミネートされる。第1行目はコマンド行であり、コマンド文字列とこのリクエストのバージョンナンバがセットされる。第2行目以降はヘッダ行であり、Key: Value の形式で任意の数のヘッダが続く。このヘッダの最大数は無限であり、順不同である。


    レスポンス文字列は以下の形式で構成される。

    SHIORI/3.0 200 OK
    Sender: F.I.R.S.T
    Value: hoge
    ....
    ..

    1行目はリザルトコード行であり、このレスポンスのバージョンナンバとリザルトコードがセットされる。他はリクエスト文字列と全く同じ。


    備考:わざわざ長々と説明したが、この形式は HTTP と全く同じである。

    SHIORI プロトコル例外存在


    レスポンスの Reference0 が話し掛ける相手の名前を表す。

    異常な仕様だが他によい方法が思いつかないので暫定的にこの位置に置く。

    SHIORI/3.0 ID


    リクエスト原型

    GET SHIORI/3.0
    ID:
    Reference0:
    ....


    全ての ID は GET でも NOTIFY でも来る可能性がある。GET のときは戻り値が求められており、NOTIFY のときは戻り値は求められていない。

    アルファベット順に羅列。


    イベント系(戻り値:スクリプト)


    ID で識別されるイベントの発生の通知。対応するスクリプトが求められている。


  • OnAnchorSelect

    r0: ユーザ定義識別子

    キャラクタ型ジャンパがクリックされた瞬間に発生。\_a 参照。


  • OnBoot

    起動した瞬間に発生。


  • OnChoiceEnter

    r0: 選択肢のタイトル
    r1: ジャンプラベル
    r*: 拡張情報

    ブロック型選択肢の上にカーソルが乗った瞬間および外れた瞬間に発生。外れた際は全 Reference に null が入る。サイレント。


  • OnClose

    終了が指示された瞬間に発生。


  • OnCommunicate

    r0: 送り元の名前
    r1: スクリプト
    r*: 拡張情報


    外部から話し掛けられた瞬間に発生。ユーザから話し掛けられた場合 r0 は user、ゴーストから話し掛けられた場合はそのゴーストの名前。


  • OnFirstBoot

    r0: vanish カウント

    初回起動した際に発生。


  • OnFileDropEx

    r0: ドロップされたファイル

    ファイルが DnD された際に発生。複数のファイルが同時にドロップされた場合はバイト値 1 でセパレートされる。


  • OnGhostChanged

    r0: 前のゴーストの名前

    ゴースト切り替えが完了した際に発生。


  • OnGhostChanging

    r0: 次のゴーストの名前
    r1: 切り替えメソッド(manual/automatic)

    ゴースト切り替えが指示された際に発生。


  • OnInstallBegin

    インストール開始の際に発生。


  • OnInstallComplete

    r0: インストールされたオブジェクトの識別子(ghost/shell/balloon/plugin)
    r1: インストールされたオブジェクトの名前0
    r2: インストールされたオブジェクトの名前1

    インストールが成功した際に発生。


  • OnInstallFailure

    r0: 失敗事由(invalid type)

    インストールが失敗した際に発生。


  • OnInstallRefuse

    r0: 指名されているゴーストの名前

    指名つきインストール時に自分が指名されたゴーストと異なる場合に発生。


  • OnKeyPress

    r0: なし
    r1: Win32 仮想キーコード

    クライアント領域内でキーが押された際に発生。


  • OnMinuteChange

    r0: 連続起動時間(単位時)
    r1: 見切れフラグ(bool)
    r2: 重なりフラグ(bool)
    r3: cantalk フラグ(bool)

    分変化した際に発生。cantalk が 0 のときはサイレント。


  • OnMouseClick

    r0: x 座標
    r1: y 座標
    r2: ホイール回転量(正負で回転方向判別)
    r3: イベントのオーナー(0: sakura / 1: kero)
    r4: 当たり判定識別子
    r5: クリックされたボタン(0: left / 1: right)

    クライアント領域内でマウスがクリックされた際に発生。右クリックに対してスクリプトを返すとレガシーインターフェース(ポップアップメニュー)が出ない。


  • OnMouseDoubleClick

    r0: x 座標
    r1: y 座標
    r2: ホイール回転量(正負で回転方向判別)
    r3: イベントのオーナー(0: sakura / 1: kero)
    r4: 当たり判定識別子

    クライアント領域内でマウスがダブルクリックされた際に発生。


  • OnMouseMove

    r0: x 座標
    r1: y 座標
    r2: ホイール回転量(正負で回転方向判別)
    r3: イベントのオーナー(0: sakura / 1: kero)
    r4: 当たり判定識別子

    クライアント領域内でマウスが移動した際に発生。


  • OnMouseWheel

    r0: x 座標
    r1: y 座標
    r2: ホイール回転量(正負で回転方向判別)
    r3: イベントのオーナー(0: sakura / 1: kero)
    r4: 当たり判定識別子

    クライアント領域内でマウスホイールが動いた際に発生。


  • OnSecondChange

    r0: 連続起動時間(単位時)
    r1: 見切れフラグ(bool)
    r2: 重なりフラグ(bool)
    r3: cantalk フラグ(bool)

    秒変化した際に発生。cantalk が 0 のときはサイレント。


  • OnSurfaceRestore

    r0: sakura 側の surface id
    r1: kero 側の surface id

    アイドル状態を検出した際に発生。


  • OnShellChanged

    r0: 今のシェルの名前

    シェル切り替えが完了した際に発生。


  • OnGhostChanging

    シェル切り替えが指示された際に発生。


  • OnWindowStateMinimize

    最小化が指示された瞬間に発生。サイレント。


  • OnWindowStateRestore

    最小化状態を解除された瞬間に発生。


    リソース参照系


    ID が指定した種類のリソースが求められている。リソースの多くは文字列。


  • craftman

    この SHIORI をプログラムした人間の名前。7ビット文字のみ使用可能


  • craftmanw

    この SHIORI をプログラムした人間の名前。8ビット文字およびデフォルトエンコーディングのマルチバイト文字も使用可能


  • homeurl

    ネットワーク更新時の基準 URL。ネットワーク更新の頁を参照


  • name

    この SHIORI の名前。ゴーストの名前ではないことに注意。7ビット文字のみ使用可能


  • username

    ゴーストが認識している現ユーザの名前。

    ※使用しているのは %username のみ


  • version

    この SHIORI のバージョンナンバ。SHIORI プロトコルのバージョンではないことに注意。7ビット文字のみ使用可能


    本体情報系


  • hwnd

    r0: shell HWnd
    r1: balloon HWnd

    ウインドウハンドル。バイト値1でセパレート

    sakura[1]kero


  • installedghostname

    r0: name
    r1: ...
    r2: ..

    インストールされているゴーストの名前のリスト。reference の最大数は不定


  • otherghostname

    r0: name
    r1: ...
    r2: ..

    インストールされているゴーストの名前のリスト。バイト値1でセパレート。reference の最大数は不定

    name[1]sakura-surfaceid[1]kero-surfaceid


  • uniqueid

    r0: ユニークID

    Owned SSTP での認証に用いるユニークID


    コミュニケート系(戻り値:スクリプト)


    外部からのスクリプト伝達。


  • OnCommunicate

    r0: 話し掛けてきた主体の名前
    r1: スクリプト

    r0 はゴーストの場合ゴーストの名前。ユーザの場合は固定で「User」。ゴースト名はレスポンス時 Reference0 にセットすることで直接返信可能

  • Owned SSTP


    特殊なヘッダ ID が付与された SSTP の Send リクエストは Owned SSTP となり無限権限で再生される。特徴は以下の通り。

    全コマンド使用可能
    タイムクリティカルセクションを無視(Conflict しない)
    SSTP サービスが無効になっていても届く


    ID は捏造されにくい文字列であり SHIORI ロード時に NOTIFY によって通知される。


    リクエスト原型

    SEND SSTP/1.0
    ID: bdf45602c68c26e4e8ed3de82225aaba
    Sender: test
    Script: \![vanishbymyself]

    補足


    regionULW
  • 技術的に枯れておりどのような環境でも確実に一定速度で動作
  • ウインドウ形状が動かない限りは最速
  • 形状の制御と描画が分離されていて自然
  • region を設定したこと自体によって描画に悪影響が出ることはない
  • 既に完成した画像から毎回 region を新規作成する処理が必要
  • メッシュ等 region 構造と相性の悪いパターンが出ると OS が腐る
  • ウインドウ形状が変化した後の再描画を OS シェルが面倒みないため、背後に存在するウインドウの再描画領域を自力で計算して尻を拭いてやるというアホな処理が必要
  • 比較的新しくマイナーな技術であるためビデオカードやビデオドライバによって速度や安定性が適当
  • 描画手段が GDI に拘束される
  • 平均的に描画が遅い
  • ウインドウ形状が動いても動かなくても描画のパフォーマンスが変わらない。逆に言えば形状の動かない描画は region より遅い
  • 部分描画できない。描画するときは常に全画面再描画。当然遅い
  • 形状を動かすにあたって余計な処理が不要
  • 裏に入ったウインドウの描画まで平均的に遅くなる
  • 完全に裏に入っていなくても不可視領域にカスっただけで遅くなる
  • 必ず 32bit DIB
  • 大元の資料にすら「Layered Window はできるだけ面積を小さくして下さい」等とえらく弱気な説明が書かれている
  • windows9x には API 自体がない

  • 素人考えとは正にこのこと


    ULW はビデオドライバに深く依存しており、また比較的新しくマイナーなファンクションである。従って、対応の甘いビデオドライバで動作させたとき、特定の解像度/特定のビット深度で正常な表示が行えない、という現象が起きても別に不思議はない。これはドライバレベルの問題であるためこちらで改善できる点はない。region ではこのような問題は起きない

    バックスクロールさせたいと思う限り表示可能行数の限界は突破できない。バックスクロールさえなければ無限行数にすることはできる

    120行程度で表示可能行数の限界を超えるが、超えても特にハングアップ等はしない

    SSTP を受けたあと再生せずに寝てしまうのは最も眠い状態のとき

    寝ている間トレイアイコンからポップアップメニューを出せないのは正常

    wm_copydata のハンドリング中に別のウインドウに wm_copydata を送る(Direct SSTP)と win9x は落ちたような気がする。つまり返値があって落ちるか、返値がなくて落ちないかどちらか。にも関わらず最近まで送れていたらしいのが不思議。なお NT にはこういった問題はない

    今さら書くことでもないが first.dll をいわゆる「汎用」にするのは不可能。プログラム的に言えば first.dll はむしろ児戯であり「汎用」であること方がよほど偉大

    mahoro はあれ以降多数の思いつき変更が施され、現状 slayer では materia は起動できない状態。slayer の方が速いのは間違いないが、自分以外では責任が取れないようないい加減な変更が頻繁に発生するため、どうも頼みづらい

    メッシュ状の画像は region 生成に非常に長い時間を必要とする。またそうして完成した region は GDI リソースの消費が大きい。ULW ではこのような問題は起きない

    あらゆる状況で常に ULW が最速とは言えない。ULW にはいくつか致命的な欠点がある

    SHIORI は「SHIORI プロトコルで標準 GUI(本体)とコネクション張りっぱなしで通信し、任意のネイティブコードを実行できる独立したプログラム」と定義できる。それが Windows プラットフォームではたまたま DLL だったというだけ

    OnMouseMove は、どのみち撫で等でしか使われないなら、当たり判定領域内でマウスが動いた時のみ送るという手もある。オセロ等にも影響が出るが、surface 全面に当たり判定を設定すれば従来どおりイベントが来るので、おそらく大した問題はない

    SHIORI/2.x は http を模しているせいで解釈にパーサが必要で、重い。しかし、これが問題となるほど高密度なコールバックは SHIORI が自分でやれ、というように考えれば、特に問題はないとも言える

    最も重い(高密度にコールされる)イベントは OnMouseMove。次点で OnSurfaceChange

    コマンドタグの命名規則には首を傾げざるを得ないものが多い

    現在 SHIORI のリクエストヘッダが http リクエストのように「中身を表す名称」になっており、リクエストによってバラバラであるが、いっそ全て ReferenceX 形式にした方がシンプルで分かりやすい気がする

    サイレントイベントは意味合いとしては GET Sentence ではなく NOTIFY であるが…

    \_v は開発環境ではなぜか正常動作している

    ネットワーク更新で zip をダウンロードすると自動的に復元する。復元後 zip は delete

    region モードでの GDI リソース消費量は region のサイズと複雑性に依存

    null になる Reference はヘッダ自体が来ない場合がある

    右ボタンの OnMouseClick に対してスクリプトを返せばシステム依存のポップアップメニューは出なくなる

    現在のアニメーションエンジンは delay 値の扱いが異常

    透過色に rgb(0,0,0) を用いると、ULW モード時に黒で塗り直す処理がスキップされ、僅かながら読み込みが速くなる

    戻る