mabimml.inc.phpのプランニング

マビノギのMMLをWikiで再生できるように出来ないか考え中。色々調べた結果、特殊なActiveXのスクリプトを使って再生しているのかと思っていたら、単にMMLをその都度MIDIに変換して再生しているらしい。となると、PukiWikiからすれば、

#mabimml(曲名,楽器){チャンネル1,チャンネル2,チャンネル3};

みたいな感じで入力し、出力は

<div id="mabimml_{$count}">
<dl>
 <dt>曲名</dt>
 <dd id="mabimml_{$count}_ch1">チャンネル1</dd>
 <dd id="mabimml_{$count}_ch2">チャンネル2</dd>
 <dd id="mabimml_{$count}_ch3">チャンネル3</dd>
</dl>
<script type="text/javascript"><![CDATA[<!--
mmlplayer(mabimml_{$count});
// -->]]>
</div>

となるように作ればいいわけだ。ちなみに、{$count}は、複数楽譜を載せたときの配慮。で、必要になりそうなボタンはJavaScriptで追記させるとしよう。

ヘッダー部に移って、テキストをMMLに変換したりするスクリプトを挿入。getElementByIdあたりで、JavaScriptに文字渡せばいいだろう。残りは、しっぽのうたのmml.jsを流用すればいっか。

function text2mml(no) {
 var buf = [
  document.getElementById('mabimml_' + no + '_ch1').value,
  document.getElementById('mabimml_' + no + '_ch2').value,
  document.getElementById('mabimml_' + no + '_ch3').value
 ];
 for(var i=0; i<3; i++) {
  buf[i] = buf[i].replace(/[^0-9a-glnortvA-GLNORTV#<>.,&+-]/g,"");
 }
return("MML@" + buf.join(",") + ";");
}

で、次に再生用のボタンを追記

function mabimml_player(no){
 document.write('<input type="button" onclick="mabimml_play(' + no + ');" />');
以下略

php、JavaScript個々を見る限り、プログラム的には非常に簡単に作れそうだ。ま、肝となるのは、PHP,JavaScript、DHTMLのクロススクリプティングだ。

あとは、再生用のコマンド用のスクリプトが続く。まぁ、結構mmlを貼り付けるためのスクリプト公開されているからそれを流用すれば問題ないだろう。

問題なのは、それらのスクリプトが合奏に対応してない点である。自分としては、合奏用のMMLも作っているし、実際コンサートなども開かれているようなので、これにも対応すべきだろう。

となると、上記の仕様では問題が残ることになる。一応PSGConverter.phpの仕様を見る限りでは、別に3チャンネルのみとして作られているようだが、単純に3チャンネル分しか処理してないことに起因することなので、MMLの規格上許される範囲内であれば、少しの修正で3チャンネル以上でも使用できると思われる。

GETメソッドの罠

しかし、このPSGConverterの使い方自体も自分から見ると無茶な仕様だなぁと思う。というのは、データーの受け渡しに全てGETメソッドを使っているからである。GETメソッドって確か256文字じゃなかったっけ?たとえば、PukiWikiでは、256文字以上のページ名を作ることはできない。これはスパム対策の為である。このため、プラグインにPSGConverter.phpの機能を持たせることはできても、再生させることができない。

わかりやすい例で言うと、例えば、サイト内検索にGoogleを使うサイトで検索をかけると、時々ページ全体が真っ白になってしまうという事があったという経験は無いだろうか?もちろん、普通のGoogleでそれをやるとちゃんと結果は出るという現象だ。これは、あまりにも送られてくるデーター量が多いため、Google側でスクリプトを停止しために起こる現象である。

表現に限界が多いとはいえ、256文字なんて練習レベル並みにしか表現できない。一応、HTTPの仕様書を読みあさってみるとGETメソッドで送ることができる字数制限は無いみたいだが・・・。スパム対策から見ると大きな脆弱性になりかねない。(PSGConverterに膨大な量のデーターを一気に送った事を想像してみて欲しい。)そうなると、キャッシュなどにMIDIとして保存し、それを再生するという形が望ましいが、その都度その都度修正するのが当たり前のWikiでは、あまり賢い選択では無いだろう。マビノギで扱うMMLの最大容量は、1200+800+500=2500なので、一般的な限界の10倍ものテキストをGETメソッドで送る事になる。

果たして、無視していい問題だろうか?PSGConverterをJavaScriptやhtaccessを工夫してで攻撃から隠したり、公式サイトのものを流用するなどすることはできるが・・・。