Month: December 2012

ソシレミでエラーが出た時

 - by Don

これは伺かアドベントカレンダー2012の24日目の記事です。

SoSiReMiアップローダー

手前で管理しているアップローダーの宣伝めいた記事になります。

SoSiReMiというアップローダーがあります。NARをアップロードすると、中のファイルを全部ZIP展開してサーバ内に配置します。また、updates2.dauを作成し、descript.txtにhomeurlを追記してZIPに詰め直すという、およそアップローダーらしからぬ処理を行います。

descript.txtのhomeurlを読み取るのはSSPの独自仕様なのでSSP専用となりますが、NARをアップロードするだけでネットワーク更新に対応できるという触れ込みで多くのゴーストマスタの方々にご利用頂いております。

ただ、複雑な処理を行うわりに設計が雑でバグも多く、さらに1日の転送量が1GBに達すると使えなくなるという制約があります。また、NARの中身に不十分な点があればエラーを返すようにしていますが、メッセージがわかりにくいという不親切な設計となっていて新規利用者の方々にご迷惑をお掛けしております。

エラーが起きたら

NAR-Station / issuesまでご報告お願いします。特に「500 Internal Server Error」というメッセージが出たら100%アップローダー側のバグです。その時アップロードしようとしたNARも添付して頂けると調査の際に再現できると思うので助かります。

その次に多いと思われるのが「install.txtが無い」旨のメッセージです。これは十中八九、ゴーストフォルダを右クリックしてZIPを作成したため、ディレクトリが一段深くなったものと思われます。NARの実態がZIPなのは確かですが、この方法によるNARの作成は推奨されません(前述のようなことが起こるため)。ゴーストにフォルダをDnDして作るか、SSPのゴーストエクスプローラから右クリックで「NAR作成」を選んで作成するのを推奨します。その際、developer_options.txtを含めておくと良いです。私自身はゴースト配布系自動化システムを使ってNARを作成しています。これが一番間違いがなく便利です。

参考

SoSiReMiの今後

ボロくなってきたので作り直しを考えていますが、無駄に複雑な処理を組んでいるので思うように改修が進まず途方に暮れています。現状しばらくは新規利用も問題ないですが、容量の大きいNARが新規にアップされると転送量の増大に繋がってよく落ちるので、容量の削減にご協力頂ければ幸いです。

SATORI as MAKOTO

 - by Don

これは伺かアドベントカレンダー2012の23日目の記事です。

里々をMAKOTOとして使う

昨日の記事で里々はSAORI以外のプロトコルには対応していないと言ったな。あれは嘘だ。

よく調べたらMAKOTOにもなるって書いてありました。ごめんなさい。

MAKOTOを使った多機能な追加シェル

GHOST側でMAKOTOを使う理由は今となってはほとんどありません。OnTranslateイベントを利用すればいいのですから。

このため廃れていく運命にあったMAKOTOですが、思わぬところで日の目を見ることとなりました。追加シェルでの利用です。

MAKOTOについてでも紹介されている通り、MAKOTOには語尾や口調を変えるといった王道的利用法の他に、SHELL側で時刻を見てサーフィスを切り替える「時間帯によって外見が変化するシェル」や、「Osuwari」を使ってウィンドウに座らせる追加シェルの作成が可能となります。いずれもYAYA as MAKOTOを使用していますが、里々もMAKOTOになるのであればSATORI as MAKOTOとして機能的で反則的な追加シェルを作ることもできるはず。というわけで作ってみます。

shell/masterをコピーしてshell/another_shellというディレクトリ名の追加シェルとし、適宜descript.txtを書き換えます。satori.dllをanother_shellディレクトリ内に放り込みます。makoto.dllとリネームしてもいいのですが、今回はdescript.txtに以下の一行を加えることでMAKOTOを認識させることにします。

makoto,satori.dll

ついでにssu.dllも同ディレクトリ内に放り込んで、satori_conf.txtを作成して以下のように記述します。

@SAORI
replace,ssu.dll,replace

最後にdic_xxx.txtというファイルを作成して、以下の記述をして完成です。

@OnMakoto
(replace(バイト値,1)(R0)(バイト値,1)。(バイト値,1)にゅ。)

このシェルを使用した時に限り、語尾が「にゅ。」となります。

冒頭でも述べた通り、MAKOTOの真髄は語尾変化のみならず音声再生や時刻に応じたサーフィス切り替えなど、工夫次第でインパクトのある演出が可能な点にあります。今まで「YAYAわからないし…」と断念していた方は、上記の通り里々でも同じ事ができますので、チャレンジしてみてはいかがでしょうか。

里々でプラグインを作る

 - by Don

これは伺かアドベントカレンダー2012の22日目の記事です。

YAYA as PLUGIN + SATORI as SAORI

YAYAは大変カスタマイズ性が高く、SAORI(YAYA as SAORI)にも、MAKOTO(YAYA as MAKOTO)にも、PLUGIN(YAYA as PLUGIN)にもなります。一方、里々はSAORI以外のプロトコルには対応していません(たぶん)。

しかし、SAORIとして呼び出せるのであれば、入り口はYAYAにまかせて、里々をSAORIとして呼んでもらって、中身は里々で書いてしまう、という手もあります。

以下、第弐版仮想麦酒飛散拡張(バーチャルビールかけ)をテンプレートとして、里々をSAORIとして呼び出すよう改造してみます。

satoriディレクトリを作成してその中にsatori.dllを入れ、同ディレクトリ内にdic_xxx.txtという名前のテキストファイルを作成して以下のような関数を定義します。

@MyFunc
\h\s[5]すぽんっ!\w9\nぶしゅー。\w5ばしゃー。\w9\nどぼどぼどぼどぼ。\w9\w9\u\s[11]…\w5…\w5…\w5…\w5…。\e

そしてメインのSHIORIであるYAYAからSAORIとしてコールします。以下は改造後のyaya_plugin_main.txtの一部です。

OnMenuExec
{
  res_event = 'OnBeerShower'

  SAORI('satori/satori.dll', 'MyFunc')
}

これで改造前と等価なPLUGINとなります。後は好きなように、mciaudior.dllを使って音を鳴らすとか、httpc.dllを使ってWebから情報を持ってくるとか、機能を足していくことができます。SAORIとして呼ばれた里々も通常通りsatori_conf.txtにSAORIを登録することでSAORIをコールすることができます。必要に応じてssu.dllも含めておくと良いです。

SATORI as SAORI

 - by Don

これは伺かアドベントカレンダー2012の21日目の記事です。

里々はSAORIにもなる

里々はSHIORIだけでなく、SAORIにもなります。YAYAをSAORIとして使うYAYA as SAORIというモジュールがありますが、原理はあれと同じです。

以下、里々から里々をSAORIとして呼んでみるサンプルです。saoriディレクトリ内にsatori.dllをコピーし、同ディレクトリ内にdic_xxx.txtという名前のテキストファイルを作成して以下のような関数を定義します。

@MyFunc
はろー

そしてメインのSHIORIである里々から呼ぶためにsatori_conf.txtにSAORIを登録しておきます。

@SAORI
satori,saori/satori.dll

後は、以下のような感じで呼び出せます。

*里々をSAORIとして呼ぶサンプル
:(satori,MyFunc)

何がウレシイのか

高機能なYAYAの力を借りるために里々からYAYAをSAORIとして利用することはあっても、他のSHIORIから里々をSAORIとして利用する機会なんてないじゃん。と思われるかもしれませんが、そんなことはありません。里々にだけできて、他のSHIORIにはできないことだってあります。例えば、SAORI-basicをコールすること。他のSHIORIがSAORI-basicをコールするためにはProxy DLLを経由しなければなりませんが、里々は自分だけの力でコールできてしまいます。里々をProxy DLL代わりに利用することができるわけです。

他にも里々は同時起動中のゴーストのウインドウハンドルとかサクッと取得できちゃうし、わりと難しいことをするための仕組みが用意されていたりするので侮れません。

Webから何か持ってくる

 - by Don

これは伺かアドベントカレンダー2012の18日目の記事です。

画像を持ってくる

デスクトップに閉じこもっているよりも、外の世界から何か持ってこれたほうが夢が広がります。今回はとりあえずSiReFaSoの最近更新されたゴーストの立ち絵をバルーンに表示することを目標にします。

Webから何か持ってくるSAORIといえばhttpc.dllです。このSAORIはかなり多機能なのですが、まずは引数を3つ指定して画像のリンクアドレスを取得してみます。

*シレファソの外部画像リンクを列挙する
:\_qhttp://(httpc,http://sirefaso.appspot.com/,<img src="http://,")
(loop,foo,0,(calc,(Sの数)-1))
@foo
ttp://(S(fooカウンタ))\n

<img src=" と " で挟まれているのが画像リンクのURLになります。相対リンクのサイト内画像は無視するために http:// で始まるリンクのみ抽出し、後で http:// を付け足しています。

URLが分かったので、次は画像をダウンロードします。 httpc.dll を再度使うか、 \![execute,http-get,...] で取得してもいいのですが、最終的にバルーンに表示すればよいので、ここで裏ワザを使います。バルーンに画像を表示するには \_b[(ファイルパス)] ですが、実はURLを指定するとSSPは画像をダウンロードして表示してくれます。なので、たったこれだけ。

*シレファソの最新ゴーストの立ち絵を表示する
:\b[2]\_b[http://(httpc,http://sirefaso.appspot.com/,<img src="http://,"),centerx,centery]

結構手軽に外の世界と繋がれることが実感できます。

DirectSSTPでプロパティシステムを使う

 - by Don

これは伺かアドベントカレンダー2012の17日目の記事です。

単一イベント内で処理を完結する

前回バルーンのサイズを取得するで紹介したプロパティシステムですが、\![get,property,...]を使うとイベントを発生させなければならず、単一イベント内で処理を完了できないのであまりスマートではありません。実際にゴーストに組み込む時には、バルーンサイズの取得などは関数として定義して簡単に利用できるようにしておきたいものです。

こんな時はDirectSSTPを使ってプロパティシステムにアクセスするとcoolです。里々なら以下のような感じです。

*ベースウェアバージョンを知る
:(HandUtil,DSSTPSend,(FMO0hwnd),result,EXECUTE SSTP/1.1,Charset: Shift_JIS,Sender: SATORI,Command: GetProperty[baseware.version])
(S0)
(S1)

ここではDirectSSTPを送信するためにHandUtil.dllを使います。Executeリクエストを使用してベースウェアのバージョンを取得するサンプルです。

ただ、残念なことにバルーンサイズであれば縦と横の2つを取得する必要がありますが、DirectSSTPでは1つずつしか取得することができません。\![get,property,...]は複数の値が一度に取得できるのに比べて、スマートではないですね。

しかしSakuraScriptを使わずに取得できればSHIORIログが汚れないですし(代わりにSSTPログが汚れるけど)、PLUGINなどから利用するにもGHOSTにSakuraScriptを再生させずに済むので私はDirectSSTPによるアクセスを好んで利用しています。場面によって使いやすい方を使えるとよいですね。

絵日記の終わり

 - by Don

びーふれんずの日記投稿機能はland.toサーバを経由していたのですが、今日Google App Engineの方に移植して引き上げてきました。それに伴い、移植が困難であると判断したため、デスクトップのスクリーンショットを投稿する「絵日記」機能を廃止しました。また、投稿先はTwitterはてなハイクの2箇所のみとなります。

land.toに置いていたBOTはこれで全部引き上げたはずです。今の場所もいつまで続くかわかりませんが、長く続くといいですね。

Unicodeの使い方

 - by Don

これは伺かアドベントカレンダー2012の13日目の記事です。

バルーンに特殊文字を表示する

バルーンに ♥ とか ★ とか出したいですよね。 ☀ とか ☂ とかも実用的です。

そんな時は \_u[0x0000] というSakuraScriptを使います。 ♥ は \_u[0x2655], ★ は \_u[0x2605], ☀ は \_u[0x2600], ☂ は \_u[0x2602] です。

この謎の数字の対応はどこでわかるかというと、Unicode表というものがあるので、ここからお目当ての記号を探して対応する番号を\_u[]に突っ込んでやるだけです。私はチェックボックス ☑ とかよく使います。

SSPではさらにフォントを自在に操ることができるので、様々な演出が可能になります。ここぞというイベントでぜひお試しください。

時間の掛かる処理を別スレッドで実行する

 - by Don

これは伺かアドベントカレンダー2012の12日目の記事です。

時間のかかる処理を行うSAORI

プログラムは通常「スレッド」と呼ばれるものの上で動作していますが、並行して別の処理を行いたい場合があります。この時、もう一つスレッドを立ち上げ、処理が完了したら元のスレッドに通知するという方法がとられます。

SAORIの中には時間のかかる処理を行うものがあります。いずれも別のスレッドに処理を任せて、終わったらメインスレッドを司るベースウェアに対してDirectSSTPにより処理の完了を通知する方法をとっています。

httpc.dll
HTTPクライアントSAORI。Web上のリソースのダウンロードを非同期で行うオプションがあります。
mciaudior.dll
音楽再生SAORI。再生が終了するまでゴーストがフリーズするのはさすがにあり得ないので、別スレッドで再生処理が完了次第DirectSSTPで通知されます。
dialog.dll
ダイアログを表示してユーザの入力を受け付けるSAORI。ユーザの入力が完了するまでゴーストをフリーズさせておくわけにはいかないので、入力が完了してダイアログがクローズする時にDirectSSTPで結果が通知されます。

マルチスレッドをサポートしたSHIORI

SHIORIの中にはスレッドの作成ができるものがあります。最近でいうとというSIHORIが話題になりました。時間のかかる処理を行うゴーストを作る際には利用を検討してみてはいかがでしょうか。

時間の掛かる処理を実行する

 - by Don

これは伺かアドベントカレンダー2012の11日目の記事です。

フリーズしたと誤解されないように

ゴーストで時間の掛かる重い処理をする必要がある時、どうすればいいでしょうか。10秒程度なら、まあ待っていてもいい気がします。でも1分以上となると、ユーザはフリーズしたものと判断し、SSPごと強制終了するかもしれません。

これを回避する策は2つほど思い付きますが、そのうちの1つを今日のネタにしたいと思います。

プログレスバーを表示する

SSPのネットワーク更新でも表示される、アレです。プログレスバーといいます。アレは現在の進捗状況が徐々に増えていくのが目に見えるので、フリーズしたという誤解を与えず、ユーザに安心感をもたらします。

ただ、ゴーストがそんな高度なことができるわけもないので、ちょっと小賢しい技を使います。

YAYAの例

重い処理(テキストファイルを読み込むなど)を100回行うことを想定します。素直に100回ループ処理で実行していたらしばらく固まってしまいます。

ExecHeavyProcess
{
  _tasks = ('a', 'b', 'c',...) // 100個
  for _i = 0; _i < ARRAYSIZE(_tasks); _i++ {
    ExecMyTask(_tasks[_i]) //重い処理
  }
}

なので、時々SSPに処理を戻さなければなりません。

ExecHeavyProcess
{
  grobal_count = 0
  '\![raise,OnExecutingHeavyProcess]'
}
OnExecutingHeavyProcess
{
  _tasks = ('a', 'b', 'c',...) // 100個
  for _i = grobal_count; _i < ARRAYSIZE(_tasks); _i++ {
    ExecMyTask(_tasks[_i]) //重い処理
    grobal_count++
    if grobal_count % 10 == 9 { // 10回に1回
      '\0 ' + grobal_count + '\![raise,OnExecutingHeavyProcess]' // 現在の進捗状況を表示
      return
    }
  }
}

10回に1回、進捗状況を表示し、\![raise]で次回も現在の処理の続きをするよう予約しておき、SSPに処理を戻します。若干苦しいですがユーザの不安を取り除くには有効な手段です。

もう一つ、正攻法としてマルチスレッドプログラミングによる解法がありますが、これはまた、別のお話。