スコア、名前、ボーナスアイテム数、機体の種類、平均fps、日時、チェックサムを記録するperlスクリプトを紹介する。
basicなりcなりを多少扱えれば、すぐに理解できると思う。なぜなら、このオレにも作れたからだ。
ソースは一番下に載っている。
// 初期設定
#!/usr/local/bin/perl
おまじない
print “Content-type: text/html\r
\r
“;
cgi単体で呼び出したときにエラーメッセージが出ないようにする。
なくてもいい。
// データ受け取り
$data = $ENV{ ‘QUERY_STRING’ };
$dataに「.cgi?」以降の文字列を代入する。
perlでは変数の型宣言が無いので、数値でも文字でも好きなように代入できる。
$env{***}は環境変数というもので、
‘REMOTE_HOST’とすればアクセスした人のリモートホスト
‘HTTP_REFERER’とすればcgiを呼び出したページのアドレス
が代入できる。
環境変数はほかにもいっぱいあるから調べてみると賢くなれる。
// データ分割
($score,$name,$pow,$kitai,$fps,$date,$rnk,$sum) = split(/&/, $data);
データを「&」で区切って左辺の変数に代入していく。
ここでは、1234567&nanashi&111&0&60&061010&1&678 という感じのデータが送られてくるので、
$score=1234567
$name=nanashi
$pow=111
$kitai=0
$fps=60
$date=061010
$rnk=1
$sum=678
という感じで格納していく。
splitというのが文字列の分割用関数。
$dataを、/と/の間の文字「&」で区切って左辺に代入する。区切り文字のほかに「正規表現」といっていろんなパターンで分割できる。
正規表現、パターンマッチ、split関数を調べてみると賢くなる。
// ログファイル読み込み
$fn=”gal02_0.log”;
if ($rnk == “0”) {$fn=”gal02_0.log”; }
if ($rnk == “1”) {$fn=”gal02_1.log”; }
if ($rnk == “2”) {$fn=”gal02_2.log”; }
open(IN,$fn);
@file =
close(IN);
$rnkの数値によって、扱うログファイルを変える。
perlの配列はBASICとはずいぶん違っていて、自由度は高そうだけどbasic脳にはわかりにくい。
$fnのファイル名でファイルを開き、@fileという配列変数にまとめて読み込む。
$file[0]=56789,nanasi2,100,0,59,061011
$file[1]=12345,nanasi,111,0,60,061010
$file[2]=987,aaa,50,0,50,061012
といった感じになる。
この配列には便利なワザもあり、
$num = @file;
で要素数を$numに代入できる。
// ログファイルのソート
@file = sort { $b < => $a } (@file);
@fileの中身を降順にソートする。
これだけでソートができるというのは驚きだ。
文字でもソートできてしまう。
$a、$bというのは変数じゃないんだろうか。謎である。
この驚くべき便利関数についてもっと知りたければ、「sort関数」を調べよう。
配列の中身を逆順に並べ替える関数というのもある。
// ログデータの分割、重複チェック
$num=100;
$err=0;
for ($i=0;$i< $num;$i++) {
($score2,$name2,$pow2,$kitai2,$fps2,$date2) = split(/\,/, $file[$i]);
if ($score2==$score) {
$err=1;
}
}
ランキングは100位($numの数)まで保存できる。
先ほど読み込んだファイルを「,」で分割し、それぞれの変数に入れる。
「,」は特殊な文字なので、「/,/」じゃなくて「/\,/」になる。
「エスケープシーケンス」を参照
$rnk2と$sum2がなぜないかというと、rnkはログファイルを選ぶためのものなのでもう必要はなく、sumはチェックサム用で現在は機能していないから必要ないのだ。
スコアが重複していたら$errを1にする。つまりエラーである。
// スコア等のデータを挿入
if ($err==0) {
if ($score2[$num-1]<$score) {
@file[$num-1]="$score,$name,$pow,$kitai,$fps,$date\r
";
}
最下位のスコアよりも受け取ったデータのスコアのほうが高かったら、最下位のデータに受け取ったデータを上書き。
上書きの際には、各データの間に「,」をはさみ、最後に改行記号「\r
」をつけた文字列として書き込む。
//ソートして保存
@file = sort { $b <=> $a } (@file);
open (OUT,”>”,”$fn”);
print OUT @file;
close(OUT);
}
新しいデータは最下位に入れてあるので、もう一度ソートして正しい順番にする。
ここでソートするなら、上のソートは必要ないじゃんと思う方もいよう。まったくだ。しかし、データを自分で書き換えて実験するときもあるので、事前にソートしておくのも一つの手なのだ。
// 終了
exit;
このexitの文字で、スクリプトは感動のフィナーレを迎える。
いちばんめんどくさそうなソートがたったの一行、読み込み書き込みも一行でできるので、ものすごく短いソースになった。まったくもって、新しいプログラム言語というのはすごい。
さて、cgiが完成したらば、あとは
http://localhost/test.cgi?123456&nanashi&111&0&60&061010&1&678
このurlの?以降のデータをいろいろ変更してブラウザのurl欄に入れてみよう。
cgiのあるフォルダに、得点順にソートされたログファイルができているはずだ。ワーイワーイ!
おかしなデータが来た場合のチェックをしていないので、いつデータが壊れるかスリリングである。
また、みなさんすでにお気づきのように、cgiのurlがわかればインチキデータを送信できてしまう。公正なランキングを運営したいものは、そのへんも注意しておこう。チェックサムでデータをはじくのが良さそうだぞ。データの各項目の下一桁を加算するなど、単純なものでいいだろう。
ネット上をいくら探しても、ゲームのネットランキングの作り方なんて載っていないから、我流で強引に作ってみた。正直言って、perlもまだサッパリわかっていないから、とんでもないおバカな処理をしているかもしれない。
だから、賢い読者ならば、自分で作るときはオレのブログは参考程度にしておいて、perlの入門サイトで勉強するのがいいだろう。
オレは以下のサイトで学ばせてもらった。
http://perl.misty.ne.jp/
http://x-web.pobox.ne.jp/fcgi/fcgi_index.html
///////////////////////////////////////////////////////
//ソース
#!/usr/local/bin/perl
print “Content-type: text/html\r
\r
“;
# データ受け取り
$data = $ENV{ ‘QUERY_STRING’ };
# データ分割
($score,$name,$pow,$kitai,$fps,$date,$rnk,$sum) = split(/&/, $data);
# ログファイル読み込み
$fn=”gal02_0.log”;
if ($rnks == “0”) {$fn=”gal02_0.log”; }
if ($rnks == “1”) {$fn=”gal02_1.log”; }
if ($rnks == “2”) {$fn=”gal02_2.log”; }
open(IN,$fn);
@file =
close(IN);
# ログファイルのソート
@file = sort { $b < => $a } (@file);
# ログデータの分割、重複チェック
$num=100;
$err=0;
for ($i=0;$i< $num;$i++) {
($score2,$name2,$pow2,$kitai2,$fps2,$date2) = split(/\,/, $file[$i]);
if ($score2==$score) {
$err=1;
}
}
# スコア等のデータをログファイルに挿入
if ($err==0) {
if ($dscore2[$num-1]<$score) {
@file[$num-1]="$score,$name,$pow,$kitai,$fps,$date\r
";
}
#ソートして保存
@file = sort { $b <=> $a } (@file);
open (OUT,”>”,”$fn”);
print OUT @file;
close(OUT);
}
exit;
参考になったらクリック!
2006 年 10 月 16 日
ネットランキング用のperlスクリプト
コメントはまだありません »
No comments yet.
RSS feed for comments on this post. TrackBack URL