#-----------------------------------------------------------#
#  罪と罰++ 二律背反										#
#  Copyright(C) 2001-2002 by Vivid Studio. BLANK BOARD		#
#  Vivid Studio.[ http://www17.big.or.jp/~obochan/vivid/ ]	#
#  BLANK BOARD [ http://pom.to/ ]							#
#-----------------------------------------------------------#
# 共通サブルーチン Version 1.0
#--- [注意事項] --------------------------------------------#
# 1.このスクリプトは以下の利用規程に従って配布しています。	#
#   http://www24.big.or.jp/~obo/game/ore_/gild/				#
#-----------------------------------------------------------#

#-------------------------------------------------------------------------------
# ファイル IN 関連

#---------------------------------------#
# 参加者データ全取得                    #
#---------------------------------------#
# 参加者データファイル一覧取得
sub usrdata_read{
	opendir(DIR,"$usrdata") || &error("유저 데이터 로딩 오류",1);
	@usrfile = grep /\.cgi/,readdir(DIR);
	closedir(DIR);
}
# 参加者データ一括読み込み
sub usrdata_open{
	foreach (0 .. $#usrfile) {
		open(IN,"$usrdata$usrfile[$_]") || &error("Can't open $usrfile[$_]",1);
		$line = <IN>;
		close(IN);
		push(@tdat,$line);
	}
}

#---------------------------------------#
# 参加者データ個別取得                  #
#---------------------------------------#
# 参加者データ個別読み込み
sub usr_file_open{

	open(IN,"$usrdata$id\.cgi") || &error("유저 ID가 틀렸거나 등록되어 있지 않습니다.<br>Open Error : $usrdata$id\.cgi",1);
	@dat = <IN>;
	close(IN);

	%DAT = '';
#	chop $dat[0];
	my @prats = split(/,/,$dat[0]);
	foreach (0 .. $#prats){
		my($key,$v) = split(/;/,$prats[$_]);
		$DAT{$key} = $v;
	}
	&error("비밀번호가 틀렸습니다",1) if($pw ne $DAT{'pw'} && $admin_pass ne $pw);

	&hash_data;

	# 行動セッションリセット
	$act_cnt=0	if($time-$la>3600*24);

}

# ハッシュ割り当て
sub hash_data{
	$pw			= $DAT{'pw'};		# パスワード
	$gold		= $DAT{'gold'};		# お金
	$nm			= $DAT{'nm'};		# 名前
	$lv			= $DAT{'lv'};		# レベル
	$sei		= $DAT{'sei'};		# 性別
	$hp			= $DAT{'hp'};		# 体力
	$max_hp		= $DAT{'max_hp'};	# 最大体力
	$mp			= $DAT{'mp'};		# 魔力
	$max_mp		= $DAT{'max_mp'};	# 最大魔力
	$ua			= $DAT{'ua'};		# 攻撃力
	$ud			= $DAT{'ud'};		# 防御力
	$lr			= $DAT{'lr'};		# 指揮力
	$ag			= $DAT{'ag'};		# 敏捷力
	$exe		= $DAT{'exe'};		# 経験値
	$rank		= $DAT{'rank'};		# 階級
	$rank_exe	= $DAT{'rank_exe'};	# 貢献値
	$camp		= $DAT{'camp'};		# 所属国
	$sol		= $DAT{'sol'}; 		# 部隊数
	$sol_lv		= $DAT{'sol_lv'};	# 部隊訓練度
	$nation		= $DAT{'nation'};	# 対象国
	$we			= $DAT{'we'};		# 討伐 回数
	$dg_a		= $DAT{'dg_a'};		# 武具
	$dg_cnt		= $DAT{'dg_cnt'};	# 武具 回数
	$df_a		= $DAT{'df_a'};		# 防具
	$df_cnt		= $DAT{'df_cnt'};	# 防具 回数
	$di_a		= $DAT{'di_a'};		# 道具
	$di_cnt		= $DAT{'di_cnt'};	# 道具 回数
	$sogo		= $DAT{'sogo'};		# 称号
	$type		= $DAT{'type'};		# 行動判定(行動フラグ)
	$tm			= $DAT{'tm'};		# 行動判定(行動フラグ)
	$bt			= $DAT{'bt'};		# 戦闘時敵キャラ判別(行動フラグ)
	$bst		= $DAT{'bst'};		# 技による能力上昇の判定
	$ck			= $DAT{'ck'};		# 戦闘判定(行動フラグ)
	$pr			= $DAT{'pr'};		# 拘束時間 残り(行動フラグ)
	$la			= $DAT{'la'};		# 更新時間
	$roku		= $DAT{'roku'};		# 前回給料が払われた時間(仕官した時間)
	$mes		= $DAT{'mes'};		# メッセージ
	$tnm		= $DAT{'tnm'};		# 名前 敵
	$tid		= $DAT{'tid'};		# ID 敵
	$thp		= $DAT{'thp'};		# 体力 敵
	$thp_max	= $DAT{'thp_max'};	# 最大体力 敵
	$tmp		= $DAT{'tmp'};		# 魔力 敵
	$tlv		= $DAT{'tlv'};		# レベル 敵
	$tua		= $DAT{'tua'};		# 攻撃力 敵
	$tud		= $DAT{'tud'};		# 防御力 敵
	$tlr		= $DAT{'tlr'};		# 指揮力 敵
	$tag		= $DAT{'tag'};		# 敏捷力 敵
	$tdf_a		= $DAT{'tdf_a'};	# 防具 敵
	$tdg_a		= $DAT{'tdg_a'};	# 武器 敵
	$tcp		= $DAT{'tcp'};		# 所属国 敵
	$tsol		= $DAT{'tsol'};		# 部隊数 敵
	$tsg		= $DAT{'tsg'};		# 称号 敵
	$tsol_lv	= $DAT{'tsol_lv'};	# 敵部隊訓練度
	$b_n		= $DAT{'b_n'};		# 戦闘限界ターン
	$b_v		= $DAT{'b_v'};		# 現在のターン数
	$n			= $_;				# 配列インデックス

	$act_cnt	= $DAT{'act_cnt'};	# 行動セッション値
	$age_time	= $DAT{'age_time'};	# 前回のレベルアップ < time式
	$info_mes	= $DAT{'info_mes'};	# 情報時に表示されるコメント

	$pr			-= $time-$la;
	$pr			= 0 if($pr<0);
}

# 国ﾃﾞｰﾀ読み込み
sub cdata_open{
	open (IN,"$cdatfile") || &error("국가 데이터 파일을 열 수 없습니다",1);
	@cdat = <IN>;
	close(IN)    or die "Can't close   : $!";

	%CP = '';
	my @prats = split(/,/,$cdat[0]);
	foreach $prats (@prats){
		my($k,$v) = split(/;/,$prats);
		$CP{$k} = $v;
	}

	$cn1=$CP{'cn1'};# 国1の国力
	$cg1=$CP{'cg1'};# 国1の財政
	$cf1=$CP{'cf1'};# 国1の蓄米
	$cs1=$CP{'cs1'};# 国1の予備兵
	$ce1=$CP{'ce1'};# 国1の現状
	$c1	=$CP{'c1'};	# 国1の参加人数
	$c1a=$CP{'c1a'};# 国1の定員数
	$cn2=$CP{'cn2'};
	$cg2=$CP{'cg2'};
	$cf2=$CP{'cf2'};
	$cs2=$CP{'cs2'};
	$ce2=$CP{'ce2'};
	$c2	=$CP{'c2'};
	$c2a=$CP{'c2a'};
	$cn3=$CP{'cn3'};
	$cg3=$CP{'cg3'};
	$cf3=$CP{'cf3'};
	$cs3=$CP{'cs3'};
	$ce3=$CP{'ce3'};
	$c3	=$CP{'c3'};
	$c3a=$CP{'c3a'};
	$cn4=$CP{'cn4'};
	$cg4=$CP{'cg4'};
	$cf4=$CP{'cf4'};
	$cs4=$CP{'cs4'};
	$ce4=$CP{'ce4'};
	$c4	=$CP{'c4'};
	$c4a=$CP{'c4a'};
	$cn5=$CP{'cn5'};
	$cg5=$CP{'cg5'};
	$cf5=$CP{'cf5'};
	$cs5=$CP{'cs5'};
	$ce5=$CP{'ce5'};
	$c5	=$CP{'c5'};
	$c5a=$CP{'c5a'};
	$set=$CP{'set'};
	$all_mem=$CP{'all_mem'};
	$goal_no=$CP{'goal_no'};	# 現在何期か。
	$hasya=$CP{'hasya'};
	$hcamp=$CP{'hcamp'};
	$wr_mes=$CP{'wr_mes'};

	if($camp==1){
		$my_cn=$cn1;
		$my_cg=$cg1;
		$my_cf=$cf1;
		$my_cs=$cs1;
		$my_ce=$ce1;
	}elsif($camp==2){
		$my_cn=$cn2;
		$my_cg=$cg2;
		$my_cf=$cf2;
		$my_cs=$cs2;
		$my_ce=$ce2;
	}elsif($camp==3){
		$my_cn=$cn3;
		$my_cg=$cg3;
		$my_cf=$cf3;
		$my_cs=$cs3;
		$my_ce=$ce3;
	}elsif($camp==4){
		$my_cn=$cn4;
		$my_cg=$cg4;
		$my_cf=$cf4;
		$my_cs=$cs4;
		$my_ce=$ce4;
	}elsif($camp==5){
		$my_cn=$cn5;
		$my_cg=$cg5;
		$my_cf=$cf5;
		$my_cs=$cs5;
		$my_ce=$ce5;
	}
}

# ログデータ読み込み
sub read_data{

	# キャラデータ読み込み
	&usr_file_open;

	# リロード規制
	foreach(0 .. $#act_limit){
		# エラー表示式(リロード抑制を明示的に行いたい方はコチラがオススメ。)
#		&error("行動は $act_limit[$_][1]秒以上間隔を空けて行なってください",1) if($time<=$la+$act_limit[$_][1] && $hour==$act_limit[$_][0]);
		# リロード無効式
		if($time<=$la+$act_limit[$_][1] && $hour==$act_limit[$_][0]){
			print "Status: 204\n\n";
			if($mode ne "mes_write"){
				&unlock($lock) if $lock_check;
			}
			exit;
		}
	}

	# 国データ読み込み
	&cdata_open;

	$id_p = $id;
	$pw_p = $pw;

	$next_lv	= int(($lv*$lv)*10);
	$max_sol	= $g_p[$rank];
	$sol_lv		= 1		if($sol_lv<1);
	$sol_lv		= 100	if($sol_lv>100);
	$max_hp		= 9999	if($max_hp>9999);
	$max_mp		= 9999	if($max_mp>9999);
	$mp			= 1		if($mp<1);
	$ua			= 999	if($ua>999);
	$ud			= 999	if($ud>999);
	$lr			= 999	if($lr>999);
	$ag			= 999	if($ag>999);
	$rank		= 14	if($rank>14);
	$rank_exe	= 0		if($rank_exe<1);
	$lv			= 1		if($lv<1);
	$hp			= $max_hp	if($hp>$max_hp);
	$mp			= $max_mp	if($mp>$max_mp);

	if($pr<1){
		&settei;#設定読み込み
		&status;#ステータス表示
	}
	$bmes="최신 정보 ◎ $wr_mes\n" if $wr_mes;

	$data_reset = int(($cn1+$cn2+$cn3+$cn4+$cn5) * $reset_point);

}

#-------------------------------------------------------------------------------
# ファイル OUT 関連

# 国データ＆キャラデータ書き込み
sub write_data{
	&cdat_write;
	&dat_write;
}

# 国データ書き込み
sub cdat_write{
	$cdat = "cn1;$cn1,cg1;$cg1,cf1;$cf1,cs1;$cs1,ce1;$ce1,c1;$c1,c1a;$c1a,cn2;$cn2,cg2;$cg2,cf2;$cf2,cs2;$cs2,ce2;$ce2,c2;$c2,c2a;$c2a,cn3;$cn3,cg3;$cg3,cf3;$cf3,cs3;$cs3,ce3;$ce3,c3;$c3,c3a;$c3a,cn4;$cn4,cg4;$cg4,cf4;$cf4,cs4;$cs4,ce4;$ce4,c4;$c4,c4a;$c4a,cn5;$cn5,cg5;$cg5,cf5;$cf5,cs5;$cs5,ce5;$ce5,c5;$c5,c5a;$c5a,set;$set,all_mem;$all_mem,goal_no;$goal_no,hasya;$hasya,hcamp;$hcamp,ad;$addr,ht;$host,date;$date,wr_mes;$wr_mes,\n";

	open (OUT,">$cdatfile") || &error("open error:$cdatfile",1);
	print OUT $cdat;
	close(OUT)		or die "Can't close   : $!";
}

# キャラデータ書き込み
sub dat_write{

	&error("open error no such a file!",1) if(!$nm || !$id);

	$dat[0] = "la;$time,nm;$nm,pw;$pw,id;$id,sei;$sei,type;$type,age_time;$age_time,act_cnt;$act_cnt,hp;$hp,max_hp;$max_hp,lv;$lv,mp;$mp,max_mp;$max_mp,rank;$rank,ua;$ua,ud;$ud,lr;$lr,ag;$ag,ck;$ck,tm;$tm,bt;$bt,bst;$bst,exe;$exe,rank_exe;$rank_exe,sol;$sol,sol_lv;$sol_lv,nation;$nation,we;$we,camp;$camp,pr;$pr,tnm;$tnm,tid;$tid,thp;$thp,tlr;$tlr,tag;$tag,tsol;$tsol,tsg;$tsg,tsol_lv;$tsol_lv,b_n;$b_n,b_v;$b_v,thp_max;$thp_max,tlv;$tlv,tdg_a;$tdg_a,tdf_a;$tdf_a,tua;$tua,tud;$tud,tmp;$tmp,tcp;$tcp,gold;$gold,roku;$roku,dg_a;$dg_a,dg_cnt;$dg_cnt,df_a;$df_a,df_cnt;$df_cnt,di_a;$di_a,di_cnt;$di_cnt,sogo;$sogo,mes;$mes,info_mes;$info_mes,\n";
	$dat[1] = "$date<>$addr<>$host<>$agent<>\n";

	open (OUT,">$usrdata$id\.cgi") || &error("open error:$usrdata$id\.cgi",1);
	print OUT @dat;
	close(OUT)		or die "Can't close   : $!";
}

# 過去の栄光書き込み＆バックアップ処理
sub hist_write{

	$cdat = "cn1;$cn1,cg1;$cg1,cf1;$cf1,cs1;$cs1,ce1;$ce1,c1;$c1,c1a;$c1a,cn2;$cn2,cg2;$cg2,cf2;$cf2,cs2;$cs2,ce2;$ce2,c2;$c2,c2a;$c2a,cn3;$cn3,cg3;$cg3,cf3;$cf3,cs3;$cs3,ce3;$ce3,c3;$c3,c3a;$c3a,cn4;$cn4,cg4;$cg4,cf4;$cf4,cs4;$cs4,ce4;$ce4,c4;$c4,c4a;$c4a,cn5;$cn5,cg5;$cg5,cf5;$cf5,cs5;$cs5,ce5;$ce5,c5;$c5,c5a;$c5a,set;$set,all_mem;$all_mem,goal_no;$goal_no,hasya;$hasya,hcamp;$hcamp,ad;$addr,ht;$host,date;$date,wr_mes;$wr_mes,\n";

	open (DB,">>$histfile") || &error("open error:$histfile",1);
	print DB $cdat;
	close(DB)		or die "Can't close   : $!";
}

#-------------------------------------------------------------------------------
# ファイルロック関連(rename式)

#	$lock = &lock if($lock_check);
#	&unlock($lock) if($lock_check);
# -----ロック-----
sub lock {
	my %lock = (dir => "$lockdir", basename => "$lockfile", timeout => 30, trytime => 10, @_);
	$lock{path} = $lock{dir} . $lock{basename};
	for (my $i = 0; $i < $lock{trytime}; $i++, sleep 1) {
		return \%lock if (rename($lock{path}, $lock{current} = $lock{path} . time));
	}
	opendir(LOCKDIR, $lock{dir});
	my @filelist = readdir(LOCKDIR);
	closedir(LOCKDIR);
	foreach (@filelist) {
		if (/^$lock{basename}(\d+)/) {
			return \%lock if (time - $1 > $lock{timeout} and
			rename($lock{dir} . $_, $lock{current} = $lock{path} . time));
			last;
		}
	}
	undef;
	&error("파일이 잠겨 있습니다");
}

# -----ロック解除-----
sub unlock {
	rename($_[0]->{current}, $_[0]->{path});
}

#-------------------------------------------------------------------------------
# フォームデータ関連

# フォームデコード処理
sub decode {
	local($buffer, @pairs, $name, $value);
	$post_flag=0;
	if($ENV{'REQUEST_METHOD'} eq "POST"){
		$post_flag=1;
		&error("게시글 용량이 너무 큽니다") if($ENV{'CONTENT_LENGTH'}>1024);
		read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
	}else{
		$buffer = $ENV{'QUERY_STRING'};
		&error("게시글 용량이 너무 큽니다") if(length($buffer)>800)
	}
	@pairs = split(/&/, $buffer);
	foreach (@pairs) {
		($name,$value) = split(/=/);
		$value =~ tr/+/ /;
		$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

		# 記号置換え
		$value =~ s/&/&amp;/g;
		$value =~ s/\;/&#59\;/g;
		$value =~ s/,/&#44\;/g;
		$value =~ s/</&lt;/g;
		$value =~ s/>/&gt;/g;
		$value =~ s/"/&quot;/g;
		$value =~ s/\//&#47\;/g;
		$value =~ s/\./&#46\;/g;
		$value =~ s/cgi/&#99\;&#103\;&#105\;/g;
		# 改行等処理
		$value =~ s/\r\n//g;
		$value =~ s/\r//g;
		$value =~ s/\n//g;

		# 文字コードをシフトJIS変換
		# &jcode'convert(*value, "sjis", "", "z");

		$in{$name} = $value;

		# 一括削除用
		if ($name eq "usr_del") { push(@USR_DEL,$value); }
	}
	$pw		= $in{'pw'};
	$cmd	= $in{'cmd'};
	$com	= $in{'com'};
	$id		= $in{'id'};
	$mode	= $in{'mode'};
}

#-------------------------------------------------------------------------------
# アクセス制御関連

# アクセスチェック(アクセス拒否)
sub axs_check {
	&get_host;

	local($flag)=0;
	foreach (@deny) {
		if (!$_) { next; }
		$_ =~ s/\*/\.\*/g;
		if ($host =~ /$_/i || $addr =~ /$_/i) { $flag=1; last; }
	}
	if ($flag) { &error("접속이 허용되지 않았습니다"); }
}

# ホスト情報取得
sub get_host {
	$host = $ENV{'REMOTE_HOST'};
	$addr = $ENV{'REMOTE_ADDR'};
	$agent= $ENV{'HTTP_USER_AGENT'};

	if ($get_remotehost) {
		if ($host eq "" || $host eq "$addr") {
			$host = gethostbyaddr(pack("C4", split(/\./, $addr)), 2);
		}
	}
	if ($host eq "") { $host = $addr; }
}

# 時間取得
sub get_time {
	$time = time;
	($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime($time);
	$min = "0$min" if($min<10);
	$sec = "0$sec" if($sec<10);
	$month++;
	@week=('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
	$date = "$month/$mday $hour:$min:$sec";
	srand($time);
}

# プレイ規制
sub safetime {
	foreach (0 .. $#safetime){
		&error("플레이 제한 시간입니다. 잠시 기다려 주십시오.") if $hour eq $safetime[$_];
	}
}

#-------------------------------------------------------------------------------
# 表示関連

# 圧縮転送
sub content_type {
	if($gzip){
		$|=1;
		if($ENV{'HTTP_ACCEPT_ENCODING'}=~/gzip/ ){
			print "Content-type: text/html; charset=UTF-8\n";
			print "Content-encoding: gzip\n\n";
			open(STDOUT,"| $gzip -1 -c");
		}else{
			print "Content-type: text/html; charset=UTF-8\n\n";
		}
		print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n";
	} else {
		print "Content-type: text/html; charset=UTF-8\n\n";
		print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n";
	}
}

#著作権表示(削除･変更不可)
sub copyright{
	if($mv_mode eq 'mv'){
		print qq|<hr color="white">죄와 벌++ 이율배반 $ver<br><a href="http://pom.to/">BLANK BOARD[네트 유원지♪]</a>| if(!$tm && !$log);
		print qq|</body></html>|;
	}else{
		print <<"EOM";
<div align="right" style="font-size:12px">
죄와 벌++ 이율배반 $ver<br>
<a href="http://www17.big.or.jp/~obochan/vivid/" target="_blank" style="font-size:13px">Vivid Studio.</a><br>
<a href="http://pom.to/" target="_blank" style="font-size:11px">BLANK BOARD[네트 유원지♪]<br>
<img src="$imgs/bb.gif" border="0" alt="BLANK BOARD[네트 유원지♪]"></a>
</div>
</body>
</html>
EOM
	}
}

# エラー表示
sub error{
	print "Content-type: text/html; charset=UTF-8\n\n";
	print "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"><title>CGI Error</title></head>\n";
	print "<body $body><h1>CGI Error</h1>\n";
	print "<p>This program encountered an internal error.</p>";
	print "<p><b>Error:</b> $_[0]</p>\n";
	print "</body></html>";
	if ($_[1] && $lock_check) { &unlock($lock); }
	exit;
}

1;#削除不可
