ばぐとらぶごる

開発者もすなるぶろぐといふものを、エンバグ野郎もしてみむとてするなり。

SSTP SENDをすべて拒否する

キャラ崩れ防止のために、SSTPをすべて拒否する選択肢も必要だという提案がありましたので、対応策をここに書くことにします。

と、その前に、SSTPとはなんたるかの説明から。各所を見ていると相当勘違いしているようですので……

SSTPの種類と問題点

SSTPは、Sakura Script Transfer Protocolの略で、元は外部から任意のスクリプトを送信し喋らせるための規格です。ただし、現行のSSTPは、下記に示す種類の通り、汎用のゴースト間通信規格となっているためです。

SSTPの種類

  • SSTP SEND = 最初に実装された、スクリプトを喋らせるためだけの規格。実はちょっとした選択肢分岐もつけられる。
  • SSTP NOTIFY = 指定したイベントを通知し、ゴーストの反応を期待する。要は\![raiseother]。反応がなかった時の保険用スクリプトもつけられる。
  • SSTP COMMUNICATE = ゴースト間コミュニケート規格。

他にもEXECUTEとかGIVEとかあったりしますが、ほとんど使われずまた今回の話とは関係しないため割愛します。

このうち、キャラ崩れで問題になり、拒否実装を考えるべきなのは、このうちのSSTP SENDと、SSTP NOTIFYの「保険用スクリプト」でしょう。確かに外からいつでも任意のスクリプトを実行できるというのは色々気持ち悪いものがあります。(セキュリティ面は一応考慮していますが、それはともかく)

残りのCOMMUNICATEと、NOTIFYのイベント部分は、完全にゴースト側で制御できるので関係ありませんね。

SSTP SENDのみ拒否

さて、これを拒否するための実装は、3年前ぐらいからそれなりに可能になっていたわけですが、今日リリースの2.2.86でより対応が容易になりました。まずは2.2.86以降にアップデートした上で、以下の変更を試してみてください。

descript.txt

ghost/master/descript.txt に

sstp.alwaystranslate,1

という行を追加してください。これで処理漏れを防ぐことができます。

OnTranslateイベントの処理

ほとんどのSakuraScriptは、実行直前にOnTranslateというイベントで通知され、ゴースト側で処理する最後の機会を与えられます。特に上記の通りalwaystranslateを設定した状態では、すべてのスクリプトがこのイベントを通ります。

なので、「SSTP SENDでスクリプトが打ち込まれた時だけ、OnTranslateで何かダミースクリプトに置き換えて喋れなくすれば良い」わけです。ただ、2.2.85までは、できないことはないのですが面倒でした。

2.2.86からは簡単で、Reference1に"sstp-send"という文字列が含まれるかどうか調べれば良いだけです。これだけで、SSTP SENDと、SSTP NOTIFYの保険用スクリプトを拒否できます。(NOTIFYの保険スクリプトも内部ではSSTP SEND扱いされています)

詳しい仕様は

http://ukadoc.googlecode.com/svn/trunk/manual/list_shiori_event.html#OnTranslate

をご覧ください。この程度の処理だけではもったいないぐらいに盛ってあります。

以降、里々向けサンプル実装です。
華和梨ユーザーと文・YAYAユーザー、あるいは他SHIORIの方向けサンプルは宿題とします。

*OnTranslate
>トランスレートSSTPSEND【タブ】(count、(R1)、sstp-send)>0
(R0)

*トランスレートSSTPSEND
:何か電波が飛んできたね。
:ワイらはSSTPには対応しとらんで。

【タブ】はキーボードのタブ文字に置き換えてください。

無言のダミーに置き換えても良いのかもしれませんが、それだとバグと区別がつかないので、何か使えない旨を示すスクリプトを実行するようにしましょう。

でないともれなくSSPのToDoに「SSTP SENDで喋らない」というバグ報告が溢れかえって、私がひっくりかえることになります。何か働きかけがあれば、それに対して必ず何か返答があるべきです。

なお、OnTranslateは本来、このようなことに使うものではなく、また何かを拒否する実装をすることは、その分可能性を失うということなので、実装者の立場からは完全に拒否するこの方法は強く非推奨であり、使うとしても熟慮した上で最小限の使用にとどめるようにしてください。

もちろん、拒否しないと色々致命的なことになるという場合は、躊躇なく使うべきですが。

また、この実装では、NanikaSongPlayer等、明らかに有用なアプリケーションのSSTP通信までも完全無効化します。Senderを確認することで特定のアプリケーションのみパスする実装は可能です。

FAQ

悪意あるスクリプトでゴーストのキャラが蹂躙されるのが心配です。

心配しすぎです。そんなヘンなことを他のキャラに強要するゴーストは、全ての人からNo!を突きつけられて自然淘汰されます。

それでもどうしても心配だというのであれば、上記アイデアを原点として、完全な安全装置を組んでみてください。必要な部品は揃っているはずです。

悪意がなくても、わずかなキャラ崩れでも納得できません。

そりゃそうでしょうね。でも、せっかくのキャラを作者の枠内だけにはめ込んでしまうのもそれはそれでもったいないですよ。

どうしてSSTPという外部連携機能があるのですか。
  1. 歴史的事情によるものです。SSTPは気の遠くなるくらい昔、おそらくこの記事を読む9割の方が、ゴーストに触れる前からの実装です。それは伺かというシステムの一つの特徴でもあります。
  2. そのほうが技術的に面白いでしょう?
SSTPを受信したら、バルーンではなく通知領域バルーンに表示する提案もありましたけど?

SSTPのセキュリティ機能により、\![set,trayballoon]や\![raise]系は無効ですので、OnTranslateの出力でこれらを使っても何も起こりません。ただ、回避手段はあります。

ヒント:受信時にフラグを立ててOnSecondChangeで処理

descript.txtにsstp.accept,0とか書く仕様提案もありましたけど?

問答無用でSSTP全カットすると影響がデカすぎです。また、SSTP SENDだけを常に拒否する書き方を作っても、後から「○×だけは通したい」という要求が出た時に対応できないでしょう。