#仕様:国名に空白文字がある場合は誤動作します # そのまえにEBS本体がまともに動かないと思いますが(汗 use AnyDBM_File; #データーベース使用宣言 ###登録系初期化処理 sub allianceStart{ #初期化処理(自国,相手国) #必要がある場合は書き換えてください $gDBName = "./$LOG_FOLDER/al_data"; #DBファイル名 $gLock = 'al_lock'; #ロックに使用するファイル #これ以下は自信のある方以外は書き換えないでください $gMName = $_[0]; #自国名 $gPName = $_[1]; #相手国名 @gMJoin = (); #自国締結リスト @gMCancel = (); #自国破棄リスト @gPJoin = (); #相手国締結リスト @gPCancel = (); #相手国破棄リスト $gMJoinKey = "$gMName".'1'; #自国締結リストキー $gMCancelKey= "$gMName".'2'; #自国破棄リストキー $gPJoinKey = "$gPName".'1'; #相手国締結リストキー $gPCancelKey= "$gPName".'2'; #相手国破棄リストキー $gWriteFlag = 0; #終了時書き込みフラグ $gErrMSG = ''; #エラーメッセージ $gStatus = 0; #同盟状態 @gStatusFlag =( hex("1"), #自国締結フラグ hex("2"), #相手国締結フラグ hex("4"), #自国破棄フラグ hex("8")); #相手国破棄フラグ #国名が入っていない、自国=相手国の場合はエラー if(!$gMName or !$gPName or ($gMName eq $gPName)){ $gErrMSG = 'パラメータエラーです。'; return -1; } &allianceLock(); #DBロック(アンロックはallianceEnd()で行う) &allianceGetList(); #自国、相手国リストをDBから取得 &allianceGetStatus(); #自国と相手国の状態を取得 return 0; } ###登録系終了処理 sub allianceEnd{ #終了処理 if($gWriteFlag){ #自国、相手国リストをDBに書き込み dbmopen (%ALLIANCE,"$gDBName",0666); $ALLIANCE{"$gMJoinKey"} = join ' ',@gMJoin; $ALLIANCE{"$gMCancelKey"} = join ' ',@gMCancel; $ALLIANCE{"$gPJoinKey"} = join ' ',@gPJoin; $ALLIANCE{"$gPCancelKey"} = join ' ',@gPCancel; dbmclose %ALLIANCE; } #DBアンロック(ロックはallianceStart()で行う) &allianceUnlock(); return 0; } ###国のリストを取得 sub allianceGetList{ #国リスト取得 #自国、相手国リストをDBから取得 tie %ALLIANCE , AnyDBM_File,"$gDBName",O_RDONLY,0666; foreach (keys %ALLIANCE){ if ($_ eq $gMJoinKey){ @gMJoin = split /\s/,$ALLIANCE{"$gMJoinKey"}; @gMCancel = split /\s/,$ALLIANCE{"$gMCancelKey"}; } elsif ($_ eq $gPJoinKey){ @gPJoin = split /\s/,$ALLIANCE{"$gPJoinKey"}; @gPCancel = split /\s/,$ALLIANCE{"$gPCancelKey"}; } } untie %ALLIANCE; return 0; } ### sub allianceGetStatus{ #自国と相手国の状態を取得 foreach(@gMJoin){ #自国締結リスト if($_ eq $gPName){ $gStatus |= $gStatusFlag[0];} } foreach(@gPJoin){ #相手国締結リスト if($_ eq $gMName){ $gStatus |= $gStatusFlag[1];} } foreach(@gMCancel){ #自国破棄リスト if($_ eq $gPName){ $gStatus |= $gStatusFlag[2];} } foreach(@gPCancel){ #相手国破棄リスト if($_ eq $gMName){ $gStatus |= $gStatusFlag[3];} } return 0; } ###指定されたリストから国を取り除く sub allianceDelete{ #リストから国を消す(リストフラグ) my $aCount=0; if($_[0] & $gStatusFlag[0]){ #自国の締結リスト foreach(@gMJoin){ if($_ eq $gPName){ splice(@gMJoin,$aCount,1); last; } $aCount++; } } $aCount=0; if($_[0] & $gStatusFlag[1]){ #相手国の締結リスト foreach(@gPJoin){ if($_ eq $gMName){ splice(@gPJoin,$aCount,1); last; } $aCount++; } } $aCount=0; if($_[0] & $gStatusFlag[2]){ #自国の破棄リスト foreach(@gMCancel){ if($_ eq $gPName){ splice(@gMCancel,$aCount,1); last; } $aCount++; } } $aCount=0; if($_[0] & $gStatusFlag[1]){ #相手国の締結リスト foreach(@gPCancel){ if($_ eq $gMName){ splice(@gPCancel,$aCount,1); last; } $aCount++; } } } ###自国から相手国へ同盟を申し込む形をとる。 ###相手からも同盟を申し込まれなければ同盟は成立しないこととする。 sub allianceJoin{ #締結リスト登録(自国,相手国) if( &allianceStart($_[0],$_[1]) != 0) #初期化処理 { return -1; } if($gStatus & $gStatusFlag[0]){ #自国の締結リストに相手国がある if($gStatus & $gStatusFlag[1]){ #相手国の締結リストに自国がある $gErrMSG = 'すでに同盟が結ばれています'; } $gErrMSG = 'すでに同盟を申し込んでいます'; &allianceEnd(); return -1; } #自国の締結リストに相手国を加える push @gMJoin,"$gPName"; $gWriteFlag =1; &allianceEnd(); #終了処理 return 0; } ###自国、相手国双方から同盟破棄が申し込まれているとき ###または、自国からしか同盟を申し込んでいないとき、同盟を破棄する。 sub allianceCancel{ #通常同盟破棄(自国,相手国) if( &allianceStart($_[0],$_[1]) != 0) #初期化処理 { return -1; } #同盟を申し込んでいない if(!($gStatus & $gStatusFlag[0])){ $gErrMSG = '同盟を申し込んでいません'; &allianceEnd(); return -1; } #すでに破棄を申し込んでいる if($gStatus & $gStatusFlag[2]){ $gErrMSG = 'すでに同盟破棄を申し込んでいます'; &allianceEnd(); return -1; } #相手から破棄を申し込まれている if($gStatus & $gStatusFlag[3]){ &allianceDelete($gStatusFlag[0]|$gStatusFlag[1]|$gStatusFlag[3]); } #同盟を結んでいる elsif($gStatus & $gStatusFlag[1]){ push @gMCancel,"$gPName"; } #同盟申し込みをしている else{ &allianceDelete($gStatusFlag[0]); } $gWriteFlag =1; &allianceEnd(); #終了処理 return 0; } ###自国のみで同盟を破棄する。 sub allianceForceCancel{ #強制同盟破棄(自国,相手国) if( &allianceStart($_[0],$_[1]) != 0) #初期化処理 { return -1; } #同盟を結んでいない if(!(($gStatus & $gStatusFlag[0]) and ($gStatus & $gStatusFlag[1]))){ $gErrMSG = '同盟を結んでいません'; &allianceEnd(); return -1; } #相手から破棄を申し込まれている if($gStatus & $gStatusFlag[3]){ $gErrMSG = 'すでに同盟破棄が申し込まれています\n破棄を選択してください。'; &allianceEnd(); return -1; } #立っているフラグを全部おろす &allianceDelete($gStatus); $gWriteFlag =1; &allianceEnd(); #終了処理 return 0; } ###自国、相手国双方の同盟が申し込まれている時のみ同盟国と見なす。 sub allianceCheck{ #同盟国か判定(自国,相手国) if( &allianceStart($_[0],$_[1]) != 0) #初期化処理 { return -1; } if(($gStatus & $gStatusFlag[0]) and ($gStatus & $gStatusFlag[1])){ &allianceEnd(); #終了処理 return 0; } $gErrMSG = '同盟は結ばれていません'; &allianceEnd(); #終了処理 return -1; } ###相手国がなくなってしまった場合ゴミが残らないようにする sub allianceLost{ #ゴミを消す(自国,なくなった国) if( &allianceStart($_[0],$_[1]) != 0) #初期化処理 { return -1; } #立っているフラグを全部おろす &allianceDelete($gStatus); $gWriteFlag =1; &allianceEnd(); #終了処理 return 0; } ###ファイルをロック、アンロックする関数 ###EBS本体との同期をとる必要がないため別関数とする ###本体と同期がとりたい場合は入れ替えてくださいな sub allianceLock{ open ALLOCK , "$gLock"; flock ALLOCK , 2; } sub allianceUnlock{ flock ALLOCK , 8; close ALLOCK; } 1;