#!/usr/local/bin/perl
#
######################################################################
###
###                     WebSameGame  Version 0.02
###
###              http://homepage3.nifty.com/masas/sdir/
###
###            Copyright(C)2002 Masa, All Rights Reserved.
######################################################################

#=====================================================================
#                         変数の設定 (ここから)
#=====================================================================

# 管理用パスワード
$admin_pwd = '1675';

# 戻り先のURL
$backurl = '../../index.html';

# 戻り先の名称
$backstr = 'ホームへ戻る';

# ランキング何位まで保存するか (当月、前月、通算共通)
$savedata = 100;

# ランキング表示の１ページあたりの件数 (当月、前月、通算共通)
$recshow = 100;

# n時間以内の新規投稿にNewマークを付ける (付けないなら 0 にする)
$newhour = 24;

# 表示設定ファイル
require './view.ini';

#=====================================================================
#       ここまでの設定で一応ＯＫです (以降の設定は必要があれば)
#=====================================================================

# このCGIを設置しているURLの一部 (自分のサイトを特定できれば良い)
# 例えば、"http://www.abc.ne.jp/~xyz/" など。
# CGIとHTMLでドメインが異なる場合は、CGI側のドメインで記述。
# 外部からのコメント投稿を防止しないなら "" としておく。
# サーバによっては機能しない場合もあります。
# @nifty など、cgiが別ドメインの場合は、cgi側のURLを記述します。
$arrow_url = '';

# HOSTによるアクセス制限
# ホスト名またはアドレスの一部を '' で囲み、カンマで区切って記述。
@denyhost = ('aabbcc.ne.jp', '127.1.1.');

# フォームの送信方法 (postでうまく行かない場合は get にします)
$method = 'post';

# コメントの最大長（全角での文字数）
$max_words = 25;

# jcode.plの位置
require './jcode.pl';

# 文字コード
$code = 'sjis';

# タイトル
$titlestr = 'WebSameGame';

# スクリプト名
$script = './index.cgi';

# 当月用データファイル名
$datafile = './thismon.txt';

# 前月用データファイル名
$ldatafile = './lastmon.txt';

# 通算用データファイル名
$tdatafile = './total.txt';

# ロックのタイプ (通常は 1、1で動作しないまたはWindows系は 2 )
$locktype = 2;

# ロックファイル
$lockfile = './lockdir/wsame.lock';

# タイムゾーン
$timezone = 'JST-9';

# クッキーの有効期限（日）
$cookie_lifetime = 30;

# クッキーのPATHの設定／非設定
$enable_cookiepath = 1;

# ホスト名取得に gethostbyaddrを(1:使う,0:使わない)
$usegethostbyaddr = 0;

# 広告等の挿入
$ads_top = '<!--上-->';	# 上部
$ads_bot = '<!--下-->';	# 下部

#=====================================================================
#                         変数の設定 (ここまで)
#=====================================================================

$koma[0] = $koma0;
$koma[1] = $koma1;
$koma[2] = $koma2;
$koma[3] = $koma3;
$koma[4] = $koma4;
$komaov[0] = $komaov0;
$komaov[1] = $komaov1;
$komaov[2] = $komaov2;
$komaov[3] = $komaov3;
$komaov[4] = $komaov4;
$gt_w = 20;	# table cols
$gt_h = 10;	# table rows
$pcalc = 'Math.pow(matchcnt-2,2)';
$pcalcaclear = '1000';

$verno = '0.02';

&main;

########## メイン
sub main{
	&lock;
	&init_variables;
	&check_input;
	&open_datafiles;
	&add_newdata;
	&del_by_admin;
	&update_datafiles;
	&deal_cookie;
	&show_html;
	&unlock;
}

########## 変数の初期化
sub init_variables{
	### ホスト名
	$addr = $ENV{'REMOTE_ADDR'};
	$host = $ENV{'REMOTE_HOST'};
	if ($usehostbyaddr) {
		($addr eq $host) && ($host = gethostbyaddr(pack("C4", split(/\./, $addr)), 2));
	}
	$host = $host || $addr || "";
	### 時刻（秒、時間）
	$ENV{'TZ'} = $timezone;
	$time_now = time;
	$date_now = &get_time($time_now);

	# ブラウザ別フォーム幅調整率
	$agent = $ENV{'HTTP_USER_AGENT'};
	if ($agent =~ /MSIE/) {
		$fwrate = 1;
	} elsif ($agent =~ /Gecko/) {
		$fwrate = 1;
	} else {
		$fwrate = 0.7;
	}
}

########## 入力の受け取り、チェック
sub check_input{
	local($buffer, $vn, $pair, @pairs);
	
	if ($ENV{'REQUEST_METHOD'} eq "POST") {
		read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
	}
	else {
		$buffer = $ENV{'QUERY_STRING'};
	}
	
	@pairs = split(/&/, $buffer);
	foreach $pair (@pairs) {
		($vn, $value) = split(/=/, $pair);
		$F{$vn} .= $value;
	}
	
	$mode = &decode($F{'mode'});
	$vmonth = &decode($F{'vmonth'});
	$name = &decode($F{'name'});
	$mail = &decode($F{'mail'});
	$url  = &decode($F{'url'});
	$msg = &decode($F{'msg'});
	$score = $F{'sscore'};
	$stage  = $F{'sstage'};
	$stime = $F{'stime'};
	$etime = $F{'etime'};
	$pwd  = $F{'pwd'};
	$cook = $F{'cook'};
	$sline = $F{'sline'};
	$admpwd = &decode($F{'admpwd'});
	$delnum = &decode($F{'delnum'});

	(!$mail) || ($mail =~ /^[\w\-\+\.]+\@[\w\-\+\.]+$/) || &error(5);
	(!$url) || ($url =~ /^http:\/\/+./) || &error(6);

	if (($admpwd ne "") && ($admpwd ne $admin_pwd)) {
		&error(13);
	}
	if (($mode eq "rmes") && ($etime ne "") && ($name eq "")) {
		&error(7);
	}
	if (($mode eq "rmes") && ($etime ne "") && ($msg eq "")) {
		&error(7);
	}

	$msg = &killtag($msg);
	if (length($msg) > $max_words * 2) {
		&error(10);
	}

	# 呼出元チェック
	if ($mode ne "") {
#		if (($ENV{'HTTP_REFERER'} ne "") && ($arrow_url ne "")) {
		if ($arrow_url ne "") {
			if ($ENV{'HTTP_REFERER'} !~ /$arrow_url/) {
				&error(14);
			}
		}
	}

	# ホストによるアクセス制限
	foreach(@denyhost) {
		if ($host =~ /$_/) {
			&error(17);
		}
	}

	$playf = 1;
}

########## ファイルのオープン
sub open_datafiles{
	&openfile($datafile, *datas);
	&openfile($ldatafile, *ldatas);
	&openfile($tdatafile, *tdatas);
}

########## 新規記録の追加
sub add_newdata{
	($name && $playf && $msg) || return;
	local($chknum, $chkname, $chkhost, $chkmail, $chkurl, $chkscore, $chkstage, $chkstime, $chketime, $chkmsg, $chkdate);
	local($checkdatacnt, $datanowcnt, $newdata, $newcnt, $addflag, $taddflag, $tfrom, $tto);

	# 二重投稿チェック
	if ($msg) {
		$checkdatacnt = 0;
		@chkdatas = reverse(@datas);
		foreach (@chkdatas) {
			($chknum, $chkname, $chkhost, $chkmail, $chkurl, $chkscore, $chkstage, $chkstime, $chketime, $chkmsg, $chkdate) = split("\t");
			if (($host eq $chkhost) && ($score eq $chkscore) && ($stime eq $chkstime) && ($etime eq $chketime)) {
				$upf_data = 0;
				&error(15);
				return;
			}
		}
	}

	# 保存データの作成
	if ($datas[0] eq "") {	# 当月データファイルが空の場合
		$datanowcnt = 0;
		push(@datas, "$datanowcnt\t$ymonth\t\n");
	}
	if ($tdatas[0] eq "") {	# 通算用データが空の場合
		push(@tdatas, "$ymonth\t\t\t\n");
	}

	($datanowcnt, $zymonth) = split("\t", $datas[0]);
	$datanowcnt++;

	# 前月用データの処理
	if ($zymonth ne $ymonth) {
		@ldatas = @datas;
		@datas = ();
		$datanowcnt = 1;
		push(@datas, "$datanowcnt\t$ymonth\t\n");
		$upf_data = 1;
		$upf_ldata = 1;
	}

	# 当月用データの処理
	$addflag = 0;
	if ($#datas > 0) {
		if ($#datas < $savedata) {
			$addflag = 1;
		} else {
			($chknum, $chkname, $chkhost, $chkmail, $chkurl, $chkscore, $chkstage, $chkstime, $chketime, $chkmsg, $chkdate) = split("\t", $datas[$#datas]);
			if ($score > $chkscore) {
				$addflag = 1;
			}
		}
	} else {
		$addflag = 1;
	}
	if ($addflag) {
		$newdata = "$datanowcnt\t$name\t$host\t$mail\t$url\t$score\t$stage\t$stime\t$etime\t$msg\t$date_now\t$time_now\t\t\n";
		push(@datas, $newdata);
		$newcnt = "$datanowcnt\t$ymonth\t$zranks\t\n";
		$datas[0] = $newcnt;
		&sort_data(*datas);
		$upf_data = 1;
	}

	# 通算用データの処理
	$taddflag = 0;
	if ($#tdatas > 0) {
		if ($#tdatas < $savedata) {
			$taddflag = 1;
		} else {
			($chknum, $chkname, $chkhost, $chkmail, $chkurl, $chkscore, $chkstage, $chkstime, $chketime, $chkmsg, $chkdate) = split("\t", $tdatas[$#tdatas]);
			if ($score > $chkscore) {
				$taddflag = 1;
			}
		}
	} else {
		$taddflag = 1;
	}
	if ($taddflag) {
		($tfrom, $tto) = split("\t", $tdatas[0]);
		$newdata = "$ymonth/$datanowcnt\t$name\t$host\t$mail\t$url\t$score\t$stage\t$stime\t$etime\t$msg\t$date_now\t$time_now\t\t\n";
		push(@tdatas, $newdata);
		$newcnt = "$tfrom\t$ymonth\t\n";
		$tdatas[0] = $newcnt;
		&sort_data(*tdatas);
		$upf_tdata = 1;
	}
}

########## データソート　スコア(降順)、日付(昇順）
sub sort_data{
	local (*stdatas) = @_;
	local ($rknum, $rkname, $rkhost, $rkmail, $rkurl, $rkscore, $rkstage, $rkstime, $rketime, $rkmsg, $rkdate);
	local ($rank, $rankrec, $tmpscore);

	$dataline0 = $stdatas[0];
	@tmpdata = @stdatas;
	splice(@tmpdata, 0, 1);

	@tmp1 = @tmp2 = ();
	foreach (@tmpdata) {
		my ($rknum, $rkname, $rkhost, $rkmail, $rkurl, $rkscore, $rkstage, $rkstime, $rketime, $rkmsg, $rkdate) = split /\t/;
		push(@tmp1, $rkscore);
		push(@tmp2, $rkdate);
	}
	@tmpdata = @tmpdata[sort {$tmp1[$b] <=> $tmp1[$a] or
				$tmp2[$a] cmp $tmp2[$b]} 0 .. $#tmp1];

	splice(@tmpdata, $savedata);
	unshift(@tmpdata, $dataline0);
	@stdatas = @tmpdata;
}

########## 管理者によるデータ削除
sub del_by_admin{
	local($dnum, $dname, $dhost, $dmail, $durl, $dscore, $dstage, $dstime, $detime, $dmsg, $ddate);
	local($deldataoffset, $delflag);

	($admpwd) || return;
	($delnum) || return;
	$deldataoffset = 0;
	$delflag = 0;
	if ($vmonth eq "last") {
		foreach(@ldatas) {
			if ($deldataoffset > 0) {
				($dnum, $dname, $dhost, $dmail, $durl, $dscore, $dstage, $dstime, $detime, $dmsg, $ddate) = split("\t");
				if ($dnum eq $delnum) {
					$delflag = 1;
					last;
				}
			}
			$deldataoffset++;
		}
		if ($delflag) {
			splice(@ldatas, $deldataoffset, 1);
			$upf_ldata = 1;
		}
	} elsif ($vmonth eq "total") {
		foreach(@tdatas) {
			if ($deldataoffset > 0) {
				($dnum, $dname, $dhost, $dmail, $durl, $dscore, $dstage, $dstime, $detime, $dmsg, $ddate) = split("\t");
				if ($dnum eq $delnum) {
					$delflag = 1;
					last;
				}
			}
			$deldataoffset++;
		}
		if ($delflag) {
			splice(@tdatas, $deldataoffset, 1);
			$upf_tdata = 1;
		}
	} elsif ($vmonth eq "this") {
		foreach(@datas) {
			if ($deldataoffset > 0) {
				($dnum, $dname, $dhost, $dmail, $durl, $dscore, $dstage, $dstime, $detime, $dmsg, $ddate) = split("\t");
				if ($dnum eq $delnum) {
					$delflag = 1;
					last;
				}
			}
			$deldataoffset++;
		}
		if ($delflag) {
			splice(@datas, $deldataoffset, 1);
			$upf_data = 1;
		}
	}
}

########## データファイルの更新
sub update_datafiles{
	($upf_data) && &updatefile($datafile, *datas);
	($upf_tdata) && &updatefile($tdatafile, *tdatas);
	($upf_ldata) && &updatefile($ldatafile, *ldatas);
}

########## 画面表示
sub show_html{

	print $cookieline;
	print "Content-type: text/html\n\n";
	&html_header;
	print "<p>\n";
	print "|";
	print " <a href=\"$backurl\">$backstr</a> |";
	if ($mode ne "game") {
		print " <a href=\"$script?mode=game\">ゲーム画面</a> |";
	}
	if ($vmonth ne "this") {
		print " <a href=\"$script?mode=rmes&vmonth=this\">当月ランキング</a> |";
	}
	if ($vmonth ne "last") {
		print " <a href=\"$script?mode=rmes&vmonth=last\">前月ランキング</a> |";
	}
	if ($vmonth ne "total") {
		print " <a href=\"$script?mode=rmes&vmonth=total\">通算ランキング</a> |";
	}
	if ($mode ne "") {
		print " <a href=\"$script\">あそびかた</a> |";
	}
	if ($admpwd ne "") {
		print " <a href=\"$script?mode=admin\">管理者ログイン</a> |";
	} else {
		print " <a href=\"$script?mode=admin\">管理用</a> |";
	}
	print "</p>\n";

	if ($mode eq "rmes") {
		&html_body_readmes;
	} elsif ($mode eq "wmes") {
		&html_body_writemes;
	} elsif ($mode eq "game") {
		&html_body_game;
	} elsif ($mode eq "admin") {
		&html_admin;
	} else {
		&html_usage;
	}
	&html_footer;
}


########## ヘッダ
sub html_header
{
	local($backpage, $bodytag, $bgimgstr, $onloadstr);

	if ($mode eq "game") {
		$onloadstr = "onload=\"init()\"";
	} else {
		$onloadstr = "";
	}

	print <<"EOM1";
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=SHIFT_JIS">
<meta name="content-language" content="ja">
<title>$titlestr</title>
<style type="text/css">
<!--
body {
	color: $color;
	font-family: $font,sans-serif;
	font-size: $fontsize;
}
th,td {
	color: $color;
	font-family: $font,sans-serif;
	font-size: $fontsize;
}
input,select,option {
	font-size: $fontsize;
}
big {
	font-size: $bfontsize;
}
small {
	font-size: $sfontsize;
}
.title {
	font-family: $titlefont,sans-serif;
	font-size: $titlesize;
	color: $titlecolor;
}
$addstyle
-->
</style>
EOM1

	if ($mode eq "game") { &gamejs; }

	if ($bgimg ne "") { $bgimgstr = "background=\"$imgdir$bgimg\""; } else { $bgimgstr = ""; }

	print <<"EOM2";
</head>
<body bgcolor=\"$bgcolor\" $bgimgstr text=\"$color\" link=\"$lcolor\" alink=\"$alcolor\" vlink=\"$vlcolor\" $onloadstr>
<div align="center">
<p>
$ads_top
</p>
EOM2

	print "<p>\n";
	if ($titleimg) {
		print "<img src=\"$imgdir$titleimg\" width=\"$titleimg_w\" height=\"$titleimg_h\">\n";
	} else {
		print "<span class=\"title\">$titlestr</span>\n";
	}
	print "</p>\n";


}



########## ボディ (メッセージ書込みフォーム)
sub html_body_writemes
{
	local($playerimg, $formtitle, $rankin, $fw40, $fw60, $submitbtn);
	local($rnum, $rname, $rhost, $rmail, $rurl, $rscore, $rstage, $dstime, $retime, $rmsg, $rdate);

	$fw40 = int(40 * $fwrate);
	$fw60 = int(60 * $fwrate);

	print "<p>\n";
	print "<big><b>今回の結果</b></big> \n";
	print "</p>\n";
	print "<table border=\"0\" bgcolor=\"$ftfbgcolor\" cellpadding=\"5\">\n";
	print "<tr><td>\n";
	print "<table border=\"0\" bgcolor=\"$ftibgcolor\" cellpadding=\"20\">\n";
	print "<tr><td align=\"center\">\n";
	print "<big><b><font color=\"$resultcolor\">$score</font></b> points</big><br>\n";
	print "</td></tr>\n";
	print "</table>\n";
	print "</td></tr>\n";
	print "</table>\n";

	print "<p>\n";

	$rankin = 0;

	($datanowcnt, $zymonth) = split("\t", $datas[0]);
	if ($zymonth ne $ymonth) {	# 月変わりなら無条件登録
		$rscore = 0;
		$numofdata = 0;
	} else {
		$lastrank = $datas[$#datas];
		($rnum, $rname, $rhost, $rmail, $rurl, $rscore, $rstage, $dstime, $retime, $rmsg, $rdate) = split("\t", $lastrank);
		$numofdata = $#datas;
	}

	if ($score >= $rscore || $numofdata < $savedata) {
		print "当月ランキング $savedata 位以内に入った可能\性あり！<br><br>記録を残すなら下のフォームからどうぞ<br>\n";
	} else {
		print "$savedata 位以内に入れませんでした。<br><br>また挑戦してくださいね。<br><br><br><br><br>\n";
		print "</p>\n";
		return;
	}

	$totalrank = $tdatas[$#tdatas];
	($rnum, $rname, $rhost, $rmail, $rurl, $rscore, $rstage, $dstime, $retime, $rmsg, $rdate) = split("\t", $totalrank);
	$trankin = 0;
	if ($score >= $rscore || $#tdatas < $savedata) {
		print "<br>さらに、通算ランキング $savedata 位以内にも入った可能\性あり！<br>\n";
	}
	print "</p>\n";


	($cook) && ($cookbuf = "CHECKED");

	$submitbtn = "<input type=\"submit\" name=\"write\" value=\"投稿\">";

	print <<"EOM";
<form name="form1" action="$script" method="$method">
<input type="hidden" name="mode" value="rmes">
<input type="hidden" name="vmonth" value="this">
<input type="hidden" name="sscore" value="$score">
<input type="hidden" name="sstage" value="$stage">
<input type="hidden" name="stime" value="$stime">
<input type="hidden" name="etime" value="$etime">
<table border="0" bgcolor="$ftfbgcolor" cellspacing="0" cellpadding="5">
<tr><td>
<table border="0" cellspacing="0" cellpadding="3">
  <tr bgcolor="$ftibgcolor"><td colspan="2"><br></td></tr>
  <tr bgcolor="$ftibgcolor"><td align="right" nowrap>おなまえ</th><td><input type="text" name="name" size="$fw40" value="$name"></td></tr>
  <tr bgcolor="$ftibgcolor"><td align="right" nowrap>メールアドレス</th><td><input type="text" name="mail" size="$fw40" value="$mail"></td></tr>
  <tr bgcolor="$ftibgcolor"><td align="right" nowrap>ホームページ</th><td><input type="text" name="url" size="$fw40" value="$url"></td></tr>
  <tr bgcolor="$ftibgcolor"><td align="right" nowrap>コメント</th><td><input type="text" name="msg" size="$fw60"></td></tr>
  <tr bgcolor="$ftibgcolor"><td><br></th><td nowrap>おなまえとコメントは必須です。<br>コメントは全角$max_words文字以内です。</td></tr>
  <tr bgcolor="$ftibgcolor"><td><br></th><td>$submitbtn
         　<input type="checkbox" name="cook" value="1" $cookbuf> クッキーに保存</td></tr>
  <tr bgcolor="$ftibgcolor"><td colspan="2"><br></td></tr>
</table>
</td></tr></table>
</form>
EOM

}

########## ボディー (ランキングリスト)
sub html_body_readmes
{
	local($showfrom, $showto, $frag_rest, $allline, $rdcnt, $rymonth);
	local($rnum, $rname, $rhost, $rmail, $rurl, $rscore, $rstage, $rstime, $retime, $rmsg, $rdate, $rtime);

	print "<p>\n";
	if ($vmonth eq "last") {
		@showdatas = @ldatas;
		print "<big><b>前月ランキング</b></big><br> \n";
	} elsif ($vmonth eq "total") {
		@showdatas = @tdatas;
		print "<big><b>通算ランキング</b></big><br> \n";
	} else {
		@showdatas = @datas;
		print "<big><b>当月ランキング</b></big><br> \n";
	}
	print "</p>\n";

	($rdcnt, $rymonth) = split("\t", $showdatas[0]);
	if ($rymonth eq "") {
		print "<p>データがありません。</p>\n";
		return;
	}
	print "<p>\n";
	if ($vmonth eq "total") {
		print "since $rdcnt\n";
	} else {
		print "$rymonth\n";
	}
	print "</p>\n";

	print "<table><tr><td>\n";
	print "上位 $savedata位までのランキングです。<br>\n";
	if ($newhour > 0) {
		print "$newhour時間以内の投稿には\n";
		if ($newicon) {
			print " <img src=\"$imgdir$newicon\" width=\"$newicon_w\" height=\"$newicon_h\">";
		} else {
			print " <font color=\"$newstrcol\">$newstr</font>";
		}
		print " が表\示されます。\n";
	}
	print "";
	print "</td></tr></table>\n";

	splice(@showdatas, 0, 1);	# カウンタ行削除

	if ($sline < 1) {
		$sline = 1;
	}
	$showfrom = $sline;
	$showto = $sline + $recshow -1;
	$allline = $#showdatas + 1;
	if ($showto > $allline) { $showto = $allline; }

	if ($admpwd) {
		print "【管理モード】\n";
		print "　各データ行の[削除]ボタンでデータを削除できます。<br>\n";
	}

	print "<table border=\"0\" width=\"500\" bgcolor=\"$rtfbgcolor\" cellspacing=\"0\" cellpadding=\"5\">\n";
	print "<tr><td>\n";
	print "<table border=\"0\" width=\"500\" cellspacing=\"1\" cellpadding=\"2\">\n";
	print "<tr>";
	print "<th nowrap><font color=\"$rtffncolor\">順位</font></th>\n";
	print "<th nowrap><font color=\"$rtffncolor\">スコア</font></th>\n";
	print "<th nowrap><font color=\"$rtffncolor\">名　前</font></th>\n";
	print "<th width=\"99%\" nowrap><font color=\"$rtffncolor\">コメント</font></th>\n";
	print "<th nowrap><font color=\"$rtffncolor\">日　時</font></th>\n";
	if ($admpwd) {
		print "<th nowrap><font color=\"$rtffncolor\">ホスト</font></th><th></th>\n";
	}
	print "</tr>\n";

	### 記録の表示
	$rankline = 0;
	$frag_rest = 0;
	$lastline_rank = 0;
	foreach (@showdatas) {
		($rnum, $rname, $rhost, $rmail, $rurl, $rscore, $rstage, $rstime, $retime, $rmsg, $rdate, $rtime) = split("\t");
		$rankline++;
		if ($rankline > $showto) {
			$frag_rest = 1;
			last;
		}
		if (($rankline >= $showfrom) && ($rankline <= $showto)) {
			$lastline_rank = $rankline;

			print "<tr bgcolor=\"$rtibgcolor\">";
			print "<td nowrap align=\"right\">$rankline</td>\n";
			print "<td nowrap align=\"right\">$rscore</td>\n";
			print "<td><table border=\"0\" cellpadding=\"0\"><tr>\n";
			if ($rmail ne "") {
				print "<td nowrap><a href=\"mailto:$rmail\">$rname</a></td>";
			} else {
				print "<td nowrap>$rname</td>";
			}
			if ($rurl ne "") {
				if ($homeicon) {
					print "<td nowrap align=\"right\"><a href=\"$rurl\" target=\"_blank\"><img src=\"$imgdir$homeicon\" width=\"$homeicon_w\" height=\"$homeicon_h\" border=\"0\"></a></td>";
				} else {
					print "<td nowrap align=\"right\"><a href=\"$rurl\" target=\"_blank\">$homestr</a></td>";
				}
			} else {
				print "<td><br></td>\n";
			}
			print "</tr></table></td>\n";

			if ($rmsg ne "") {
				print "<td nowrap>$rmsg</td>\n";
			} else {
				print "<td><br></td>\n";
			}
			print "<td nowrap>$rdate";
			if (($newhour > 0) && ($time_now - $rtime) / 3600 < $newhour) {
				if ($newicon) {
					print " <img src=\"$imgdir$newicon\" width=\"$newicon_w\" height=\"$newicon_h\">";
				} else {
					print " <font color=\"$newstrcol\">$newstr</font>";
				}
			}
			print "</td>";
			if ($admpwd) {
				print "<td>$rhost</td>\n";
			}
			if ($admpwd) {
				print "<td><form name=\"delform\" action=\"$script\" method=\"$method\">\n";
				print "<input type=\"hidden\" name=\"mode\" value=\"rmes\">\n";
				print "<input type=\"hidden\" name=\"vmonth\" value=\"$vmonth\">\n";
				print "<input type=\"hidden\" name=\"delnum\" value=\"$rnum\">\n";
				print "<input type=\"hidden\" name=\"admpwd\" value=\"$admpwd\">\n";
				print "<input type=\"submit\" name=\"deldata\" value=\"削除\">\n";
				print "</td></form>\n";
			}
			print "</tr>\n";
		}
	}
	print "</table>\n";
	print "</td></tr></table>\n";

	print "<table border=\"0\" cellspacing=\"5\"><tr>";

	$bsline = $sline - $recshow;
	if ($bsline < 1) {
		$bsline = 1;
	}
	$nsline = $sline + $recshow;

	if ($showfrom > 1) {
		print "<td>\n";
		print "<form name=\"formback\" action=\"$script\" method=\"$method\">\n";
		print "<input type=\"hidden\" name=\"mode\" value=\"$mode\">\n";
		print "<input type=\"hidden\" name=\"vmonth\" value=\"$vmonth\">\n";
		print "<input type=\"hidden\" name=\"sline\" value=\"$bsline\">\n";
		print "<input type=\"hidden\" name=\"admpwd\" value=\"$admpwd\">\n";
		print "<input type=\"submit\" name=\"backp\" value=\"前ページ\">\n";
		print "</form>\n";
		print "</td>\n";
	}
	if ($frag_rest) {
		print "<td>\n";
		print "<form name=\"formnext\" action=\"$script\" method=\"$method\">\n";
		print "<input type=\"hidden\" name=\"mode\" value=\"$mode\">\n";
		print "<input type=\"hidden\" name=\"vmonth\" value=\"$vmonth\">\n";
		print "<input type=\"hidden\" name=\"sline\" value=\"$nsline\">\n";
		print "<input type=\"hidden\" name=\"admpwd\" value=\"$admpwd\">\n";
		print "<input type=\"submit\" name=\"next\" value=\"次ページ\">\n";
		print "</form>\n";
		print "</td>\n";
	}
	print "</tr></table>\n";
}


#------------#
# 管理者認証 #
#------------#
sub html_admin {
	local($fw10, $loginbtn);

	$fw10 = int(10 * $fwrate);

	$loginbtn = "<input type=\"submit\" name=\"write\" value=\"ログイン\">";

	print <<"EOM";
<form name="formadm" action="$script" method="$method">
<input type="hidden" name="mode" value="rmes">
<br>
<br>
<p>
<table border="0" bgcolor="$ftfbgcolor" cellpadding="5" cellspacing="0">
 <tr>
  <td>
  
   <table border="0" cellpadding="5" cellspacing="0">
     <tr><th colspan="2"><font color="$ftffncolor">管理者ログイン</font></th></tr>
     <tr bgcolor="$ftibgcolor"><td align="center" nowrap>対象データ</td>
      <td><select name="vmonth"><option value="this">当月<option value="last">前月<option value="total">通算</select></td></tr>
     <tr bgcolor="$ftibgcolor"><td align="center" nowrap>パスワード</td>
      <td><input type="password" name="admpwd" size="$fw10"></td></tr>
     <tr bgcolor="$ftibgcolor"><td align="center" colspan="2">$loginbtn</td></tr>
   </table>

  </td>
 </tr>
</table>
</p>
</form>
EOM

}



#################### クッキーの処理

########## メイン
sub deal_cookie{
	# 名前が空欄ならクッキーの取得
	($name) || &get_cookie;
	# クッキーの保存
	($name && $cook) && &set_cookie;
}


########## クッキーを取り出す
sub get_cookie{
	local($cookbuf);
	
	# 現在のBOOK向けクッキーがなければ終了
	(($cookbuf) = $ENV{'HTTP_COOKIE'} =~ m|SAMEM2=([^;]+)|) || return;
	
	$cookbuf =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("C", hex($1))/eg;
	($name, $mail, $url, $addr, $pwd) = split("\t", $cookbuf);
	$cook = 1;
}


########## クッキーの発行
sub set_cookie{
	local($expires, $path, $value);
	
	$expires = &get_time_GMT($^T + 60 * 60 * 24 * $cookie_lifetime);
	if($enable_cookiepath){
		($path) = $ENV{'SCRIPT_NAME'} =~ m|^(.+/)[^/]+$|;
		$path = "path=" . $path;
	}
	
	$value = "$name\t$mail\t$url\t$addr\t$pwd";
	$value =~ s/(\W)/sprintf("%%%02X", unpack("C", $1))/eg;
	$cookieline = "Set-Cookie: SAMEM2=$value; expires=$expires; $path\n";
}


########## 日本語のデコード
sub decode{
	local($w, $frag) = @_;
	
	$w =~ tr/+/ /;
	$w =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
	
	unless($frag){
		$w =~ s/</&LT;/g;
		$w =~ s/>/&GT;/g;
		$w =~ s/"/&#34;/g;
		$w =~ s/'/&#39;/g;
	}
	
	$w =~ s/\t//g;
	$w =~ s/\cM//g;
	$w =~ s/\n{2,}/<P>/g;
	$w =~ s/\n/<BR>/g;
	
	&jcode'convert(*w, $code);
	$w;
}


##### タグを殺す
sub killtag{
	local($w) = @_;
	
	$w =~ s/</&LT;/g;
	$w =~ s/>/&GT;/g;
	$w =~ s/"/&#34;/g;
	$w =~ s/'/&#39;/g;
	
	$w;
}


##### 現在の時刻を得る
sub get_time{
	local($stime) = @_;
	$stime += $time_fix * 60 * 60;
	local($sec, $min, $hour, $mday, $mon, $year) = localtime($stime);
	$mon++;
	$year += 1900;
	$ymonth = sprintf("%04d/%02d", $year, $mon);
	return sprintf("%04d/%02d/%02d %02d:%02d", $year, $mon, $mday, $hour, $min);
}

###### ファイルを開いて、中身を配列に代入する
sub openfile{
	local ($filename, *buf) = @_;
	open(FILE, "$filename") || &error(1, $filename);
	@buf = <FILE>;
	close(FILE);
}


###### ファイルを更新する
sub updatefile{
	local ($filename, *buf, $frag) = @_;
	
	# フラグあり→追加、なし→更新
	if($frag){
		open(FILE, ">>$filename") || &error(1, $filename);
	}
	else{
		open(FILE, ">$filename") || &error(1, $filename);
	}
	print FILE @buf;
	close(FILE);
}


##### ＧＭＴを得る（クッキー用）
sub get_time_GMT{
	local($tsec) = @_;
	local($sec, $min, $hour, $mday, $mon, $year, $wday) = gmtime($tsec);
	$wday = ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat')[$wday];
	$mon = ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec')[$mon];
	$year += 1900;
	return sprintf("$wday, %02d-$mon-$year %02d:%02d:%02d GMT", $mday, $hour, $min, $sec);
}


##### ロック
sub lock{

	if ($locktype == 1) {
		$try = 0;
		while(!(symlink("$$", $lockfile))){
			(++$try > 3) && &error(0);
			sleep(1);
		}
	} elsif ($locktype == 2) {	# symlink が使えないサーバー用
		$try = 0;
		while(-f $lockfile){
			(++$try > 3) && &error(0);
			sleep(1);
		}
		open(FILE,">$lockfile") || &error(0,$lockfile);
		close(FILE);
	}
}


##### ロック解除
sub unlock{
	unlink($lockfile);
}


##### エラーメッセージ
sub error{
	local ($error_header, $error_footer);
	local ($id, $msg) = @_;
	local (@sts) = lstat($lockfile);
	local ($tn) = time();
	
	$fmid[0] = 0; $msg[0] = 'ロック中です';
	$fmid[1] = 1; $msg[1] = 'ファイルが開けません';
	$fmid[2] = 1; $msg[2] = 'ファイルに書き込めません';				# 不使用
	$fmid[3] = 0; $msg[3] = 'データファイルが指定されていません';	# 不使用
	$fmid[4] = 0; $msg[4] = 'データファイルが不正です';				# 不使用
	$fmid[5] = 0; $msg[5] = 'メールアドレスが不正です';
	$fmid[6] = 0; $msg[6] = 'URLが不正です';
	$fmid[7] = 0; $msg[7] = '名前とコメントは必須です';
	$fmid[8] = 0; $msg[8] = '既に同じ名前の人がいるか、パスワードが間違っています';	# 不使用
	$fmid[9] = 0; $msg[9] = 'パスワードが入力されていません';						# 不使用
	$fmid[10] = 0; $msg[10] = "文章が長すぎます。全角で$max_words文字以下にして下さい";
	$fmid[11] = 0; $msg[11] = "変数が不正です";							# 不使用
	$fmid[12] = 0; $msg[12] = "返信は名前、コメント両方とも必須です";	# 不使用
	$fmid[13] = 0; $msg[13] = "管理用パスワードが違います";
	$fmid[14] = 0; $msg[14] = "外部からのアクセスはできません";
	$fmid[15] = 0; $msg[15] = "二重投稿はできません";
	$fmid[16] = 0; $msg[16] = "結果データが正しくありません";
	$fmid[17] = 0; $msg[17] = "アクセスを許可されていません";
	
	
	$fmsg[0] = "ブラウザの戻るボタンで戻ってください。";
	$fmsg[1] = "管理者に連絡してください。";
	
	$fid = $fmid[$id];
	($msg) && ($detail = "<I>（$msg）</I>");
	
	$mode = "error";

	print "Content-type: text/html\n\n";
	&html_header;
	print "
<p>
<big><b>ERROR!</b></big><br>
</p>
<b>$msg[$id]</b> $detail
<p>
$fmsg[$fid]
</p>
<br>
<br>
	";
	&html_footer;

	($id) && &unlock; # ID が 0 以外の場合はロック解除
	($tn - $sts[9] > 15) && &unlock; # 約15秒以上ロックが続いてたら自動解除
	exit;
}

#--------------------------------------------------------------------------------------#

########## フッタ
sub html_footer{

	print <<"EOM";
<br>
<p>
$ads_bot
</p>
<p>
$dsgncopy
</p>
<p>
<a href="http://homepage3.nifty.com/masas/sdir/" target="_top">WebSameGame Ver.$verno</a>
</p>
</div>
</BODY>
</HTML>
EOM

}


#---------#
# game js #
#---------#
sub gamejs {
	my ($karray,$kovarray,$cnt);
	$karray = "kimg = new Array(";
	$cnt = 0;
	foreach (@koma) {
		if ($cnt++ > 0) { $karray .= ","; }
		$karray .= "\"$imgdir$_\"";
	}
	$karray .= ");";

	$kovarray = "kovimg = new Array(";
	$cnt = 0;
	foreach (@komaov) {
		if ($cnt++ > 0) { $kovarray .= ","; }
		$kovarray .= "\"$imgdir$_\"";
	}
	$kovarray .= ");";

	print <<"EOM";
<script language="JavaScript">
<!--
var tw = $gt_w;
var th = $gt_h;
var dfimg = "$imgdir$k_df";
$karray
$kovarray
dfimgcash = new Image(); dfimgcash.src = dfimg;
imgcash = new Array();
for (i = 0; i < kimg.length; i++) {
	imgcash[i] = new Image(); imgcash[i].src = kimg[i];
}
ovimgcash = new Array();
for (i = 0; i < kovimg.length; i++) {
	ovimgcash[i] = new Image(); ovimgcash[i].src = kovimg[i];
}
imgtbl = new Array();
imgtblp = new Array();
imgtblbk = new Array();
ckftbl = new Array();
objcash = new Array();
imgcnt = new Array();
imgcntp = new Array();
for (i = 0; i < tw; i++) {
	imgtbl[i] = new Array();
	imgtblp[i] = new Array();
	imgtblbk[i] = new Array();
	ckftbl[i] = new Array();
	objcash[i] = new Array();
}
var matchcnt;
var restcnt;
var restcntp;
var srestcnt;
var srestcntp;
var score;
var scorep;
var sscore;
var sscorep;
var tsumemin;
var tsumemax;
var drawmin;
var drawmax;
var gameover;
var stageclear;
var firstclick = 1;
var stime;
var etime;
var stage = 0;
var sstage = 0;
var kimgonst = 4;

function init()
{
	document.navif.message.value = "$mes_ready";

	// New Game
	if (restcnt != 0) {
		score = 0;
		sscore = 0;
		stage = 0;
		sstage = 0;
		kimgonst = 4;
	}

	// Rest Count Clear
	restcnt = th * tw;
	srestcnt = restcnt;
	for (i = 0; i < kimg.length; i++) {
		imgcnt[i] = 0;
		imgcntp[i] = 0;
	}

	stage++;
	sstage = stage;
	if (kimgonst < kimg.length) { kimgonst++; }

	// Locate Image
	for (ix = 0; ix < tw; ix++) {
		for (iy = 0; iy < th; iy++) {
			objcash[ix][iy] = eval("document.X" + ix + "Y" + iy);
			imgtbl[ix][iy] = Math.floor(Math.random() * kimgonst);
			imgcnt[imgtbl[ix][iy]] += 1;
			imgtblp[ix][iy] = -1;
			imgtblbk[ix][iy] = -1;
		}
	}
	drawmin = 0;
	drawmax = tw - 1;
	draw();
	gameover = 0;
	stageclear = 0;
	document.navif.message.value = "$mes_letsgo";
	return;
}

function writemes()
{
	dd = new Date();
    etime = dd.getTime();
	document.form1.stime.value = stime;
	document.form1.etime.value = etime;
	document.form1.sscore.value = sscore;
    document.form1.sstage.value = sstage;
	document.form1.submit();

	return;
}

function draw()
{
	if ((restcnt == tw * th) && (zan(0) == 0)) { init(); return; }

	for (dx = drawmin; dx < drawmax + 1; dx++) {
		for (dy = 0; dy < th; dy++) {
			if (imgtbl[dx][dy] < 0) {
				objcash[dx][dy].src = dfimgcash.src;
			} else {
				objcash[dx][dy].src = imgcash[imgtbl[dx][dy]].src;
			}
		}
	}
	document.navif.stage.value = stage;
	document.navif.score.value = score;
	document.navif.rest.value = restcnt;

	for (ki = 0; ki < kimgonst; ki++) {
		eval("document.navif.i" + ki + "cnt").value = imgcnt[ki];
	}
	for (ki = kimgonst; ki < kimg.length; ki++) {
		eval("document.navif.i" + ki + "cnt").value = "---";
	}
	return;
}

function tsume()
{
	drawmin = tsumemin;
	drawmax = tsumemax;
	for (tx = tsumemax; tx >= tsumemin; tx--) {
		cppos = th - 1;
		for (ty = th - 1; ty >= 0; ty--) {
			if (imgtbl[tx][ty] >= 0) {
				imgtbl[tx][cppos] = imgtbl[tx][ty];
				cppos--;
			}
		}
		for (ty = cppos; ty >= 0; ty--) {
			imgtbl[tx][ty] = -1;
		}
		if (imgtbl[tx][th-1] == -1) {
			for (txi = tx; txi < tw - 1; txi++) {
				for (ty = 0; ty < th; ty++) {
					imgtbl[txi][ty] = imgtbl[txi+1][ty];
				}
			}
			for (ty = 0; ty < th; ty++) {
				imgtbl[tw-1][ty] = -1;
			}
			drawmax = tw - 1;
		}
	}
	return;
}

function zan(mode)
{
	for (zx = 0; zx < tw-1; zx++) {
		for (zy = th-1; zy > 0; zy--) {
			if (imgtbl[zx][zy] < 0) { break; }
			if (zx < tw-1) {
				if (imgtbl[zx][zy] == imgtbl[zx+1][zy]) {
					if (mode == 1) {
						 hintx = zx;
						 hinty = zy;
					}
					 return(1);
				}
			}
			if (zy > 0) {
				if (imgtbl[zx][zy] == imgtbl[zx][zy-1]) {
					if (mode == 1) {
						 hintx = zx;
						 hinty = zy;
					}
					 return(1);
				}
			}
		}
	}
	if (mode == 1) {
		 hintx = -1;
		 hinty = -1;
	}
	return(0);
}

var hintx;
var hinty;
var hinton = 0;
function hint()
{
	if (gameover == 1) { return; }
	if (hinton == 0) {
		zan(1);
		if (hintx > -1) {
			mouseact(hintx,hinty,2);
			document.navif.message.value = "$mes_hint";
		}
		hinton = 1;
	} else {
		mouseact(hintx,hinty,3);
		document.navif.message.value = "$mes_ohen";
		hinton = 0;
	}
	return;
}

function undo()
{
	if (gameover == 1) { return; }
	if (restcnt == tw * th) { return; }
	for (i = 0; i < tw; i++) {
		for (j = 0; j < th; j++) {
			imgtbl[i][j] = imgtblbk[i][j];
		}
	}
	for (i = 0; i < kimgonst; i++) {
		imgcnt[i] = imgcntp[i];
	}
	restcnt = restcntp;
	srestcnt = srestcntp;
	score = scorep;
	sscore = sscorep;
	draw();
	return;
}

function mouseact(clkx, clky, act)
{
	if (gameover == 1) { return; }
	if (stageclear == 1) { return; }
	// check //
	if (imgtbl[clkx][clky] == -1) {
		document.navif.message.value = "$mes_ohen";
		return;
	}
	procflag = 0;
	if (clky > 0) { if (imgtbl[clkx][clky] == imgtbl[clkx][clky-1]) { procflag = 1; } }
	if (clky < th - 1) { if (imgtbl[clkx][clky] == imgtbl[clkx][clky+1]) { procflag = 1; } }
	if (clkx > 0) { if (imgtbl[clkx][clky] == imgtbl[clkx-1][clky]) { procflag = 1; } }
	if (clkx < tw - 1) { if (imgtbl[clkx][clky] == imgtbl[clkx+1][clky]) { procflag = 1; } }
	if (procflag == 0) {
		document.navif.message.value = "$mes_toren";
		return;
	}

	if (firstclick == 1 && act == 1) {
		dd = new Date();
		stime = dd.getTime();
		firstclick = 0;
	}

	// backup //
	for (i = 0; i < tw; i++) {
		for (j = 0; j < th; j++) {
			imgtblp[i][j] = imgtbl[i][j];
			ckftbl[i][j] = 1;
		}
	}
	if (act == 1) {
		for (i = 0; i < tw; i++) {
			for (j = 0; j < th; j++) {
				imgtblbk[i][j] = imgtbl[i][j];
			}
		}
		for (i = 0; i < kimgonst; i++) {
			imgcntp[i] = imgcnt[i];
		}
		scorep = score;
		sscorep = scorep;
		restcntp = restcnt;
		srestcntp = srestcnt;
		// process //
		tsumemin = tw - 1;
		tsumemax = 0;
	}
	matchcnt = 0;
	match(clkx,clky,act);
	checker(clkx, clky, 1, 1, 1, 1, imgtblp[clkx][clky],act);
	if (act == 1) {
			tsume();
			score += eval("$pcalc");
			sscore = score;
			restcnt -= matchcnt;
			srestcnt = restcnt;
			imgcnt[imgtblp[clkx][clky]] -= matchcnt;
			draw();
			if (zan(0) == 0) {
				if (restcnt == 0) {
					stageclear = 1;
					score += eval("$pcalcaclear");
					sscore = score;
					document.navif.message.value = "$mes_allclear";
					setTimeout("init()", 1500);
				} else {
					gameover = 1;
					document.navif.message.value = "$mes_gameover";
					setTimeout("writemes()", 500);
				}
			}
	}
	if (act == 2) {
		document.navif.message.value = "$mes_guide1 " + matchcnt + " $mes_guide2 " + eval("$pcalc") + " $mes_guide3";
	}
	if (act == 3) {
		document.navif.message.value = "$mes_ohen";
	}
	return;
}

function checker(cx,cy,o,u,l,r,cnum,act)
{
	if ((o == 1 && cy > 0) && (ckftbl[cx][cy-1] == 1) && (imgtblp[cx][cy] == imgtblp[cx][cy-1])) {
		match(cx,cy-1,act);
		checker(cx,cy-1,1,0,1,1,cnum,act);
	}
	if ((u == 1 && cy < th - 1) && (ckftbl[cx][cy+1] == 1) && (imgtblp[cx][cy] == imgtblp[cx][cy+1])) {
		match(cx,cy+1,act);
		checker(cx,cy+1,0,1,1,1,cnum,act);
	}
	if ((l == 1 && cx > 0) && (ckftbl[cx-1][cy] == 1) && (imgtblp[cx][cy] == imgtblp[cx-1][cy])) {
		match(cx-1,cy,act);
		checker(cx-1,cy,1,1,1,0,cnum,act);
	}
	if ((r == 1 && cx < tw - 1) && (ckftbl[cx+1][cy] == 1) && (imgtblp[cx][cy] == imgtblp[cx+1][cy])) {
		match(cx+1,cy,act);
		checker(cx+1,cy,1,1,0,1,cnum,act);
	}
	return;
}
function match(mx, my, act)
{
	ckftbl[mx][my] = 0;
	matchcnt++;
	if (act == 1) {
		imgtbl[mx][my] = -1;
		if (mx < tsumemin) { tsumemin = mx; }
		if (mx > tsumemax) { tsumemax = mx; }
	} else if (act == 2) {
		objcash[mx][my].src = ovimgcash[imgtbl[mx][my]].src;
	} else if (act == 3) {
		objcash[mx][my].src = imgcash[imgtbl[mx][my]].src;
	}
	return;
}

// -->
</script>
EOM

}


########## ボディ (入口兼ゲーム)
sub html_body_game
{
	local($tx, $ty, $imgid, $fw32, $fw6, $fw2, $fw4);

	$fw32 = int(35 * $fwrate);
	$fw6 = int(7 * $fwrate);
	$fw3 = int(3 * $fwrate);
	$fw4 = int(4 * $fwrate);

	print <<"EOM";
<form name="navif">
<table border="0" cellspacing="0" cellpadding="5" bgcolor="$gtfbgcolor"><tr><td>
<table border="0" cellspacing="0" cellpadding="3">
<tr><td colspan="2" align="center">
 <table><tr>
  <td nowrap>
      <input type="text" name="message" size="$fw32">
  </td>
  <td width="20"><br></td>
  <td nowrap>
      <font color="$gtffncolor"><b>スコア</b></font> <input type="text" name="score" size="$fw6">
  </td>
</tr></table>
</td></tr>
<tr>
EOM

	print "<td align=\"center\">\n";
	print "<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\" bgcolor=\"$gtibgcolor\">\n";

	for ($ty = 0; $ty < $gt_h; $ty++) {
		print "<tr>";
		for ($tx = 0; $tx < $gt_w; $tx++) {
			print "<td>";
#            print "<a href=\"#\" onclick=\"mouseact($tx,$ty,1)\" onmouseover=\"mouseact($tx,$ty,2)\" onmouseout=\"mouseact($tx,$ty,3)\">";
            print "<a href=\"JavaScript:mouseact($tx,$ty,1)\" onmouseover=\"mouseact($tx,$ty,2)\" onmouseout=\"mouseact($tx,$ty,3)\">";
			$imgid = "X" . "$tx" . "Y" . "$ty";
            print "<img name=\"$imgid\" src=\"$imgdir$k_df\" width=\"$k_w\" height=\"$k_h\" border=\"0\">";
			print "</a>";
            print "</td>\n";
	    }
		print "</tr>\n";
    }
	print "</table>\n";
	print "</td>\n";

	print "<td align=\"center\" valign=\"top\">\n";
	print "<font color=\"$gtffncolor\"><b>ステージ</b></font><br>\n";
	print "<input type=\"text\" name=\"stage\" size=\"$fw3\"><br>\n";
	print "<br>\n";
	print "<font color=\"$gtffncolor\"><b>残コマ数</b></font><br>\n";
	print "<input type=\"text\" name=\"rest\" size=\"$fw3\"><br>\n";
	print "<br>\n";
	print "<input type=\"button\" value=\"リセット\" onClick=\"init()\"><br>\n";
	print "<br>\n";
	print "<input type=\"button\" value=\"もどす\" onClick=\"undo()\"><br>\n";
	print "<br>\n";
	print "<input type=\"button\" value=\"ヒント\" onClick=\"hint()\"><br>\n";
	print "</td></tr>\n";

	print "<tr><td align=\"center\" colspan=\"2\">\n";
	print "<table border=\"0\" cellpadding=\"0\"><tr>\n";
	$icnt = 0;
	foreach (@koma) {
		$icname = "i" . $icnt . "cnt";
		print "<td><img src=\"$imgdir$koma[$icnt]\" width=\"$k_w\" height=\"$k_h\"></td>\n";
#		print "<td><img src=\"$imgdir$komaov[$icnt]\" width=\"$k_w\" height=\"$k_h\"></td>\n";
		print "<td><input type=\"text\" name=\"$icname\" size=\"$fw3\"></td>\n";
		$icnt++;
	}
	print "</tr></table>\n";
	print "</td>\n";
	print "</tr>";
	print "</table>";
	print "</td></tr></table>";
	print "</form>\n";

	print <<"EOM";
<form name="form1" action="$script" method="$method">
<input type="hidden" name="mode" value="wmes">
<input type="hidden" name="sscore">
<input type="hidden" name="sstage">
<input type="hidden" name="stime">
<input type="hidden" name="etime">
</form>

EOM

}

#------------#
#   使い方   #
#------------#

sub html_usage {

	print <<"EOM";
<p>
<big><b>あそびかた</b></big>
</p>
<p>
<table border="0" bgcolor="$ftfbgcolor" cellpadding="5" cellspacing="0">
<tr><td>
<table border="0" width=\"500\" cellpadding="5" cellspacing="0">
 <tr bgcolor="$ftibgcolor">
  <td>

<b>ゲームのルール</b>
<ul>
<li>ゲーム画面には、下のようなコマがランダムに並んでいます。
  <table border="0"><tr>
    <td><img src="$imgdir$koma0" width="$k_w" height="$k_h"></td>
    <td><img src="$imgdir$koma1" width="$k_w" height="$k_h"></td>
    <td><img src="$imgdir$koma2" width="$k_w" height="$k_h"></td>
    <td><img src="$imgdir$koma3" width="$k_w" height="$k_h"></td>
    <td><img src="$imgdir$koma4" width="$k_w" height="$k_h"></td>
  </tr></table>
</li>
<li>コマが縦または横に２個以上並んでいれば、クリックしてコマを取ることができます。</li>
<li>その上にコマが積まれていた場合は、取ったすきまにコマが落ちてきます。</li>
<li>列にコマが無くなると、左方向へ列がつめられます。</li>
<li>取れるコマが無くなると、ゲームオーバーです。</li>
<li>すべてのコマを取ることができたら、次のステージへ進みます。</li>
</ul>
<b>各ボタンについて</b>
<ul>
<li>[リセット] --- それまでのプレイを捨てて、新しくゲームを始めます。</li>
<li>[もどす] --- コマを消すひとつ前の状態に戻すことができます。</li>
<li>[ヒント] --- 取れるコマがどこにあるか分かります。もう一度押せば解除。</li>
</ul>
<b>スコアについて</b>
<ul>
<li>コマを取る毎に加算される得点 => (取ったコマ数 - 2)の2乗<br>
    （例えば、２コは０点、３コは１点、４コは４点、５コは９点、....）</li>
<li>全てのコマを取ったときに加算される得点 => 1000 点</li>
</ul>
<b>ランキングについて</b>
<ul>
<li>ゲームが終了した時点でランキングに入った場合は、記録を投稿できます。</li>
<li>投稿した時点でランキングから外れた場合は、残念ですが記録に残りません。</li>
<li>同スコアの場合は、記録を投稿した順にランキングされます。</li>
<li>ランキングは月間の上位 $savedata 位までが記録されます。</li>
<li>前月のランキング、通算のランキングも同様に見ることができます。</li>
</ul>
<b>動作条件</b>
<ul>
<li>ゲーム部は JavaScript ですので、対応しているブラウザでプレイしてください。</li>
</ul>

   <br>
   <br>
  </td>
 </tr>
</table>
</td></tr>
</table>
</p>

EOM

}

