技術解説
Javascript ライブラリの解説
技術解説、と言った所で、このプログラム自体はたいしたことやっていません。
見てもらえばわかりますが、ふつーに Javascript プログラム。
逆アセンブラみたいなもので、データを順に取ってきては、整形して表示しているだけです。
使い方も簡単。SocialLlama の URL を div タグで括って、ライブラリを呼び出すと、イベントが表示されます。
各国語対応
イベント配布ツールは、最初から配布を目的にしていたわけではなく、SocialLlama を解析してみよう、という遊びでした。そのため自分が作りやすいようにプログラムを作り、文章データなどはすべてプログラム中に埋め込まれていました。最初のバージョンは 2012.10 に公開しています。
しかし、2012年末に「Llama の正式版」が発表されるにあたり、2ch の方々の意見を取り入れてメッセージをずいぶん変更しました。そうしたら、配布ツールの文面の変更が大変。…というより、やる気も起きないような状態に。
ところで、作者さんのページでは翻訳ボランティアを募集しており、javascript で作られた翻訳用のツールも設置されています。
ここで、javascript のデータとして、Llama で使用されるメッセージの一覧があるわけです。翻訳ツールでもこれを使用できれば、翻訳されてもすぐに対応が可能になります。
…というわけで作ったのが、メッセージ分離版。単に分離した、というより、Llama 内部の都合に合わせて作られたメッセージを利用するために、かなりの大改編になりました。(2012.3.7公開)
今までは、llama.js のプログラム本体のみで動作していましたが、今後は同じディレクトリに llamamessage_??.js というファイルが必要になります。
?? の部分は言語コード。現在、以下のファイルが準備されています。
en | 英語 |
ja | 日本語 |
ca | カタルーニャ語 |
de | ドイツ語 |
es | スペイン語 |
fr | フランス語 |
hr | クロアチア語 |
hu | ハンガリー語 |
it | イタリア語 |
lt | リトアニア語 |
pl | ポーランド語 |
ru | ロシア語 |
sl | スロベニア語 |
zh | 中国語 |
このうち、en は必須です。翻訳がない場合、英語のメッセージが使用されるためです。日本語表示は、ja があれば行えます。
llama.js と同じディレクトリにファイルを置いておきさえすれば、Javascript がブラウザの言語設定をみて、勝手に必要なファイルを読み込みます。
ところで、ブラウザの「言語設定」は、2種類あります。
一つは、WEB サーバーに対し、「解釈できる言語」のリストを渡すための設定です。複数言語を、優先順位付きで設定できます。
WEB サーバーが取得できるのはこちらの言語設定で、SocialLlama 配布ツールのページを「英語最優先」の状態で取得すると、英語のページを送ってきたりします。
(URL によっても英語ページを表示できるが、自動的にも選択されるのです)
もう一つは、ブラウザ自体のメッセージ(メニュー表示など)をどの言語で表示するかの設定で、Javascript が取得できるのは、こちらの言語設定です。
この二つは別の概念なので、llama.js で表示される部分については「英語で書かれたページだから英語で表示される」というような、単純な動作にはなりません。
ところで…作者さんの作る「翻訳データ」が古い、という場合があります。
時々、プログラムのソース(おそらく java)から、データを javascript にコンバートして、それで公開しているようですが、この作業は「暇なときに」行われるだけみたい。
2013.3.8 にこの記事を書いている段階では、最新機能の Signal Strength のメッセージは、英語版すら公開されていません。
また、日本語の翻訳データも一部が古いようです。
Signal Strength に関しては、「仮対応」で表示していますので、表示自体は可能です。翻訳データが古いのも、気づいた点は修正していますが、アプリ表示との食い違いもあるかもしれません。
ソーシャルLlama URL の解析説明
ソーシャルLlama の URL を解析したい、と言う人のために情報。
(お、ちょっと技術解説らしくなった)
まず、ソーシャル Llama の URL は、 / で区切られています。
先頭は http://llama.location.profiles/ で始まり、次のブロックは、この URL 自体に付けられた名前です。最終的には無視されるようなので、気にする必要はありません。
次のブロックから、イベントのデータ。とはいえ、Llama の「Share event」で作られるデータでは、ブロックは1つだけです。手動でブロックを切り張りすると、複数のイベントを1つのデータとして送ることが出来ます。(普通のイベントは2つが対になっていますからね)
では、ブロック内のデータについて解説。
まず、ブロック内のデータは URL Encode されているので、デコードする必要があります。Javascript の decodeURI/decodeURIComponent 関数では、歴史的経緯もあって正しくデコードできないので注意しましょう。
デコードしたら、 | で区切ります。区切られた一つづつが、データとなります。
先頭はイベントの名前です。つぎは、イベントの設定。- で区切られた数字の列で示されますが、最後だけは「グループ名」です。詳細はプログラム中に書いてあるので読んでね。
3番目には、必ず : が入るようです。そして、4番目からがイベントのデータ。
さて、データは | で区切られています。なので、データ内部には | を入れることが出来ません。そのため、データには Llama 独自のエンコードが掛けられています。
データ内に \p があれば、それは | (pipe) がエンコードされたものです。
同様に、\d は - (dash) 、\b は \ (backslash) を意味します。
区切ったデータをすべて、デコード処理する必要があります。
これで、やっと「素の」データが得られました。これらのデータは、コマンドとパラメータに分かれます。基本的に、1つのコマンドの後ろに、複数のパラメータが付随します。
コマンド名は、1文字か2文字のアルファベット。2文字目は数字になることもあります。
コマンドには「状況」と「行動」がありますが、区別するようなフラグはありません。コマンド名から判別します。
多くのコマンドは、パラメータを1つだけとります。このパラメータは、0が無効、1が有効、と言うものが多いですが、2がトグルだったり、もっと多い選択肢が示されることもあります。これも、詳しくは僕のプログラムを読むと理解しやすいかと思います。
パラメータが連続値をとる場合、-1 に特別な意味合いが与えられることがあります。文字列だったり、ビットマップになっているパラメータもあります。
パラメータを複数とる場合もあります。個数を識別するフラグは無いので、コマンド名から判断しますが、幸い「可変個数」というようなコマンドはありません。
パラメータの個数や扱いは、本当にコマンドごとにまちまち。個別処理するしかありません。
一部のパラメータは、Base64Encode されたバイナリです。大抵は表示するだけなら無視できるものですが、インテントの送信だけは、内部を解析しなくては表示が行えません。これについては後述。
OR や AND 、待ちイベントなどは、その内部に「イベントデータ」を内包しています。
この場合、パラメータとして与えられたイベントはやはり、 | で区切られています。再帰処理してイベントを解析してください。
注記
NFCタグは、16進数16桁(8byte)の数値です。この数値を直接扱うのはわかりにくいため、Llama では「名前」をつけて管理できます。
Social Llama URL では、「NFCタグの検出」状況のパラメータにタグの数値だけが入れられており、名前は入っていません。そのため、名前を表示することは出来ません。(常に「不明」になります)
これは、このプログラムに限ったことではなく、Llama 自体に読み込ませた場合も同様です。