diff --git a/hwe/_admin1_submit.php b/hwe/_admin1_submit.php index 7c91ce3b..57df3a78 100644 --- a/hwe/_admin1_submit.php +++ b/hwe/_admin1_submit.php @@ -64,7 +64,7 @@ switch ($btn) { case "30분턴": case "60분턴": case "120분턴": - $admin = $gameStor->getDBValues(['turntime', 'turnterm', 'year', 'startyear', 'month']); + $admin = $gameStor->getValues(['turntime', 'turnterm', 'year', 'startyear', 'month']); switch ($btn) { case "1분턴": $turnterm = 1; break; case "2분턴": $turnterm = 2; break; diff --git a/hwe/j_getChiefTurn.php b/hwe/j_getChiefTurn.php index 66a64dd3..8d2fde62 100644 --- a/hwe/j_getChiefTurn.php +++ b/hwe/j_getChiefTurn.php @@ -70,11 +70,9 @@ foreach( $nationTurnBrief = []; foreach($nationTurnList as $level=>$turnBrief){ if(!key_exists($level, $generals)){ - $general = Util::array_first($generals); - } - else{ - $general = $generals[$level]; + continue; } + $general = $generals[$level]; $nationTurnBrief[$level] = [ 'name'=>$general->getName(), 'turnTime'=>$general->getTurnTime($general::TURNTIME_FULL), diff --git a/hwe/join_post.php b/hwe/join_post.php index c7e05b83..9e25125c 100644 --- a/hwe/join_post.php +++ b/hwe/join_post.php @@ -16,7 +16,6 @@ $v 'leadership', 'strength', 'intel', - 'character', ]) ->rule('stringWidthBetween', 'name', 1, 18) ->rule('min', [ @@ -29,8 +28,7 @@ $v 'strength', 'intel' ], GameConst::$defaultStatMax) -->rule('min', 'character', 0) -->rule('max', 'character', 11); +->rule('in', 'character', GameConst::$availablePersonality); if (!$v->validate()) { MessageBox($v->errorStr()); @@ -48,7 +46,7 @@ $name = StringUtil::removeSpecialCharacter($name); $name = WebUtil::htmlPurify($name); $name = StringUtil::textStrip($name); $pic = (int)Util::getReq('pic', 'bool', 0); -$character = Util::getReq('character', 'int', 0); +$character = Util::getReq('character'); $leadership = Util::getReq('leadership', 'int', 50); $strength = Util::getReq('strength', 'int', 50); diff --git a/hwe/sammo/ActionPersonality/che_유지.php b/hwe/sammo/ActionPersonality/che_유지.php index 3558d65f..e0cd39cc 100644 --- a/hwe/sammo/ActionPersonality/che_유지.php +++ b/hwe/sammo/ActionPersonality/che_유지.php @@ -7,7 +7,7 @@ class che_유지 implements iAction{ use \sammo\DefaultAction; protected $id = 8; - protected $name = '안전'; + protected $name = '유지'; protected $info = '훈련 -5, 징·모병 비용 -20%'; public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{ diff --git a/hwe/sammo/Command/BaseCommand.php b/hwe/sammo/Command/BaseCommand.php index 1c95c116..bed40760 100644 --- a/hwe/sammo/Command/BaseCommand.php +++ b/hwe/sammo/Command/BaseCommand.php @@ -250,7 +250,7 @@ abstract class BaseCommand{ 'nation'=>$this->nation, 'cmd_arg'=>$this->arg, - 'destGeneral'=>$this->destGeneralObj->getRaw(), + 'destGeneral'=>$this->destGeneralObj?$this->destGeneralObj->getRaw():null, 'destCity'=>$this->destCity, 'destNation'=>$this->destNation, ]; @@ -272,10 +272,6 @@ abstract class BaseCommand{ throw new \InvalidArgumentException('runnableConstraits가 제대로 설정되지 않았습니다'); } - if(!$this->isReservable()){ - return $this->testReservable(); - } - if($this->reasonNotRunnable){ return $this->reasonNotRunnable; } diff --git a/hwe/sammo/Command/Nation/che_불가침수락.php b/hwe/sammo/Command/Nation/che_불가침수락.php new file mode 100644 index 00000000..91a9b36c --- /dev/null +++ b/hwe/sammo/Command/Nation/che_불가침수락.php @@ -0,0 +1,286 @@ +arg === null){ + return false; + } + + if(!key_exists('destNationID', $this->arg)){ + return false; + } + $destNationID = $this->arg['destNationID']; + if(!is_int($destNationID)){ + return false; + } + if($destNationID < 1){ + return false; + } + + if(!key_exists('destGeneralID', $this->arg)){ + return false; + } + $destGeneralID = $this->arg['destGeneralID']; + if(!is_int($destGeneralID)){ + return false; + } + if($destGeneralID <= 0){ + return false; + } + if($destGeneralID == $this->generalObj->getID()){ + return false; + } + + if(!key_exists('year', $this->arg) || !key_exists('month', $this->arg) ){ + return false; + } + $year = $this->arg['year']; + $month = $this->arg['month']; + if(!is_int($year) || !is_int($month)){ + return false; + } + + if($month < 1 || 12 < $month){ + return false; + } + + if($year < $this->env['startyear']){ + return false; + } + + $this->arg = [ + 'destNationID'=>$destNationID, + 'destGeneralID'=>$destGeneralID, + 'year'=>$year, + 'month'=>$month, + ]; + return true; + } + + protected function init(){ + $general = $this->generalObj; + + $env = $this->env; + $relYear = $env['year'] - $env['startyear']; + + $this->setCity(); + $this->setNation(); + + $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['imgsvr', 'picture'], 1); + $this->setDestGeneral($destGeneral); + $this->setDestNation($this->arg['destNationID']); + + //NOTE: 개월에서 기한으로 바뀜 + $year = $this->arg['year']; + $month = $this->arg['month']; + + $currentMonth = $env['year'] * 12 + $env['month'] - 1; + $reqMonth = $year *12 + $month - 1; + + $nationID = $this->nation['nation']; + + $this->reservableConstraints = [ + ConstraintHelper::AlwaysFail('예약 불가능 커맨드') + ]; + + if ($reqMonth <= $currentMonth) { + $this->runnableConstraints = [ + ConstraintHelper::AlwaysFail('이미 기한이 지났습니다.') + ]; + return; + } + + $this->runnableConstraints=[ + ConstraintHelper::BeChief(), + ConstraintHelper::NotBeNeutral(), + ConstraintHelper::OccupiedCity(), + ConstraintHelper::SuppliedCity(), + ConstraintHelper::ExistsDestNation(), + ConstraintHelper::ExistsDestGeneral(), + ConstraintHelper::DisallowDiplomacyBetweenStatus([ + 0 => '아국과 이미 교전중입니다.', + 1 => '아국과 이미 선포중입니다.', + 3 => '아국과 외교 진행중입니다.', + 4 => '아국과 외교 진행중입니다.', + 5 => '아국과 외교 진행중입니다.', + 6 => '아국과 외교 진행중입니다.', + ]), + ]; + + } + + public function getCost():array{ + return [0, 0]; + } + + public function getPreReqTurn():int{ + return 0; + } + + public function getPostReqTurn():int{ + return 0; + } + + public function getBrief():string{ + $commandName = $this->getName(); + $destNationName = getNationStaticInfo($this->arg['destNationID'])['name']; + $year = $this->arg['year']; + $month = $this->arg['month']; + return "{$year}년 {$month}월까지 "; + } + + public function run():bool{ + if(!$this->isRunnable()){ + throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); + } + + $db = DB::db(); + $env = $this->env; + + $general = $this->generalObj; + + $nation = $this->nation; + $nationID = $nation['nation']; + $nationName = $nation['name']; + + $destNation = $this->destNation; + $destNationID = $destNation['nation']; + $destNationName = $destNation['name']; + + $year = $this->arg['year']; + $month = $this->arg['month']; + + $logger = $general->getLogger(); + $destLogger = new ActionLogger(0, $destNationID, $env['year'], $env['month']); + + $currentMonth = $env['year'] * 12 + $env['month'] - 1; + $reqMonth = $year *12 + $month - 1; + + $db->update('diplomacy',[ + 'state'=>7, + 'term'=>$reqMonth - $currentMonth + ], + '(me=%i AND you=%i) OR (you=%i AND me=%i)', + $nationID, $destNationID, + $nationID, $destNationID); + + $josaWa = JosaUtil::pick($destNationName, '와'); + $logger->pushGeneralActionLog("{$destNationName}{$josaWa} $year년 불가침에 성공했습니다.", ActionLogger::PLAIN); + $logger->pushGeneralHistoryLog("{$destNationName}{$josaWa} {$year}년 {$month}월까지 불가침 성공"); + + + $josaWa = JosaUtil::pick($nationName, '와'); + $destLogger->pushGeneralActionLog("{$nationName}{$josaWa} $year년 불가침에 성공했습니다.", ActionLogger::PLAIN); + $destLogger->pushGeneralHistoryLog("{$nationName}{$josaWa} {$year}년 {$month}월까지 불가침 성공"); + + $general->applyDB($db); + $destLogger->flush(); + + return true; + } + + public function getJSFiles(): array + { + return [ + 'js/defaultSelectNationByMap.js' + ]; + } + + public function getForm(): string + { + $generalObj = $this->generalObj; + $nationID = $generalObj->getNationID(); + + $db = DB::db(); + + $currYear = $this->env['year']; + + $diplomacyStatus = Util::convertArrayToDict( + $db->query('SELECT * FROM diplomacy WHERE me = %i', $nationID), + 'you' + ); + + $nationList = []; + foreach(getAllNationStaticInfo() as $destNation){ + if($destNation['nation'] == $nationID){ + continue; + } + + $testCommand = new static($generalObj, $this->env, $this->getLastTurn(), [ + 'destNationID'=>$destNation['nation'], + 'year'=>$currYear+1, + 'month'=>12 + ]); + if(!$testCommand->isRunnable()){ + $destNation['cssBgColor'] = 'background-color:red;'; + } + else if($diplomacyStatus[$destNation['nation']]['state'] == 7){ + $destNation['cssBgColor'] = 'background-color:blue;'; + } + else{ + $destNation['cssBgColor'] = ''; + } + + $nationList[] = $destNation; + } + + ob_start(); +?> +
+타국에게 불가침을 제의합니다.
+제의할 국가를 목록에서 선택하세요.
+불가침 기한 다음 달부터 선포 가능합니다.
+배경색은 현재 제의가 불가능한 국가는 붉은색, 현재 불가침중인 국가는 푸른색으로 표시됩니다.
+
+에게 +년 +월까지 + +nation['nation']; + if ($reqMonth < $currentMonth + 12) { + $this->reservableConstraints = [ + ConstraintHelper::AlwaysFail('기한은 1년 이상이어야 합니다.') + ]; + $this->runnableConstraints = [ ConstraintHelper::AlwaysFail('기한은 1년 이상이어야 합니다.') ]; @@ -100,6 +108,14 @@ class che_불가침제의 extends Command\NationCommand{ ConstraintHelper::OccupiedCity(), ConstraintHelper::SuppliedCity(), ConstraintHelper::ExistsDestNation(), + ConstraintHelper::DisallowDiplomacyBetweenStatus([ + 0 => '아국과 이미 교전중입니다.', + 1 => '아국과 이미 선포중입니다.', + 3 => '아국과 외교 진행중입니다.', + 4 => '아국과 외교 진행중입니다.', + 5 => '아국과 외교 진행중입니다.', + 6 => '아국과 외교 진행중입니다.', + ]), ]; } @@ -116,6 +132,14 @@ class che_불가침제의 extends Command\NationCommand{ return 0; } + public function getBrief():string{ + $commandName = $this->getName(); + $destNationName = getNationStaticInfo($this->arg['destNationID'])['name']; + $year = $this->arg['year']; + $month = $this->arg['month']; + return "【{$destNationName}】에게 {$year}년 {$month}월까지 {$commandName}"; + } + public function run():bool{ if(!$this->isRunnable()){ @@ -171,7 +195,7 @@ class che_불가침제의 extends Command\NationCommand{ Message::MSGTYPE_DIPLOMACY, $src, $dest, - "{$nationName}의 {$year}년 {$month}까지 불가침 제의 서신", + "{$nationName}와 {$year}년 {$month}월까지 불가침 제의 서신", $now, $validUntil, [ @@ -188,4 +212,80 @@ class che_불가침제의 extends Command\NationCommand{ return true; } + + public function getJSFiles(): array + { + return [ + 'js/defaultSelectNationByMap.js' + ]; + } + + public function getForm(): string + { + $generalObj = $this->generalObj; + $nationID = $generalObj->getNationID(); + + $db = DB::db(); + + $currYear = $this->env['year']; + + $diplomacyStatus = Util::convertArrayToDict( + $db->query('SELECT * FROM diplomacy WHERE me = %i', $nationID), + 'you' + ); + + $nationList = []; + foreach(getAllNationStaticInfo() as $destNation){ + if($destNation['nation'] == $nationID){ + continue; + } + + $testCommand = new static($generalObj, $this->env, $this->getLastTurn(), [ + 'destNationID'=>$destNation['nation'], + 'year'=>$currYear+1, + 'month'=>12 + ]); + if(!$testCommand->isRunnable()){ + $destNation['cssBgColor'] = 'background-color:red;'; + } + else if($diplomacyStatus[$destNation['nation']]['state'] == 7){ + $destNation['cssBgColor'] = 'background-color:blue;'; + } + else{ + $destNation['cssBgColor'] = ''; + } + + $nationList[] = $destNation; + } + + ob_start(); +?> +
+타국에게 불가침을 제의합니다.
+제의할 국가를 목록에서 선택하세요.
+불가침 기한 다음 달부터 선포 가능합니다.
+배경색은 현재 제의가 불가능한 국가는 붉은색, 현재 불가침중인 국가는 푸른색으로 표시됩니다.
+
+에게 +년 +월까지 + +test()){ - return [\sammo\Util::getClassNameFromObj($constraint), $constraint->reason()]; + + if($constraint->reason() === null){ + throw new \RuntimeException('Reason is not set:'.$constraintName); + } + return [$constraintName, $constraint->reason()]; } } diff --git a/hwe/sammo/Constraint/DisallowDiplomacyBetweenStatus.php b/hwe/sammo/Constraint/DisallowDiplomacyBetweenStatus.php index f5cf6cc0..74d30bdd 100644 --- a/hwe/sammo/Constraint/DisallowDiplomacyBetweenStatus.php +++ b/hwe/sammo/Constraint/DisallowDiplomacyBetweenStatus.php @@ -40,6 +40,7 @@ class DisallowDiplomacyBetweenStatus extends Constraint{ $db = DB::db(); + $state = $db->queryFirstField( 'SELECT state FROM diplomacy WHERE me = %i AND you = %i AND `state` IN %li LIMIT 1', $this->nationID, @@ -49,7 +50,7 @@ class DisallowDiplomacyBetweenStatus extends Constraint{ if($state === null){ return true; } - $this->msg = $this->disallowStatus[$state]; + $this->reason = $this->disallowStatus[$state]; return false; } } \ No newline at end of file diff --git a/hwe/sammo/Constraint/NearNation.php b/hwe/sammo/Constraint/NearNation.php index 3fe6e4f4..1ef59b8f 100644 --- a/hwe/sammo/Constraint/NearNation.php +++ b/hwe/sammo/Constraint/NearNation.php @@ -10,16 +10,6 @@ class NearNation extends Constraint{ return false; } - if(!key_exists('capital', $this->nation)){ - if(!$throwExeception){return false; } - throw new \InvalidArgumentException("require capital in nation"); - } - - if(!key_exists('capital', $this->destNation)){ - if(!$throwExeception){return false; } - throw new \InvalidArgumentException("require capital in destNation"); - } - return true; } @@ -27,19 +17,14 @@ class NearNation extends Constraint{ $this->checkInputValues(); $this->tested = true; - $srcCityID = $this->nation['capital']; $srcNationID = $this->nation['nation']; - - $destCityID = $this->destNation['capital']; $destNationID = $this->destNation['nation']; - - $dist = \sammo\searchDistanceListToDest($srcCityID, $destCityID, [$srcNationID, $destNationID]); - if(!$dist){ + if(!\sammo\isNeighbor($srcNationID, $destNationID, false)){ $this->reason = "인접 국가가 아닙니다."; return false; } - return false; + return true; } } \ No newline at end of file diff --git a/hwe/sammo/DiplomaticMessage.php b/hwe/sammo/DiplomaticMessage.php index 5bae6d63..462c01c7 100644 --- a/hwe/sammo/DiplomaticMessage.php +++ b/hwe/sammo/DiplomaticMessage.php @@ -40,7 +40,7 @@ class DiplomaticMessage extends Message{ case self::TYPE_STOP_WAR: $this->diplomacyName = '종전'; break; case self::TYPE_MERGE: $this->diplomacyName = '통합'; break; case self::TYPE_SURRENDER: $this->diplomacyName = '투항'; break; - default: throw \RuntimeException('diplomaticType이 올바르지 않음'); + default: throw new \RuntimeException('diplomaticType이 올바르지 않음'); } parent::__construct(...func_get_args()); @@ -74,32 +74,27 @@ class DiplomaticMessage extends Message{ } protected function noAggression(){ - $year = Util::array_get($this->msgOption['year']); - if($year < 1 || $year > 30){ - return [self::INVALID, '올바르지 않은 불가침 서신입니다.']; + + $gameStor = KVStorage::getStorage(DB::db(), 'game_env'); + + $destGeneralObj = General::createGeneralObjFromDB($this->dest->generalID, ['picture', 'imgsvr'], 1); + + $commandObj = buildNationCommandClass('che_불가침수락', $destGeneralObj, $gameStor->getAll(true), new LastTurn(), [ + 'destNationID'=>$this->src->nationID, + 'destGeneralID'=>$this->src->generalID, + 'year'=>$this->msgOption['year'], + 'month'=>$this->msgOption['month'] + ]); + + $this->diplomacyDetail = $commandObj->getBrief(); + + if(!$commandObj->isRunnable()){ + return [self::DECLINED, $commandObj->getFailString()]; } - $this->diplomacyDetail = "{$year}년"; + $commandObj->run(); - $helper = new Engine\Diplomacy($this->src->nationID, $this->dest->nationID); - $chk = $helper->noAggression($year); - if($chk[0] !== self::ACCEPTED){ - return $chk; - } - - $josa = JosaUtil::pick($this->dest->nationName, '와'); - $youlog[] = "{$this->dest->nationName}{$josa} $year년 불가침에 성공했습니다."; - - $josa = JosaUtil::pick($this->src->nationName, '와'); - $mylog[] = "{$this->src->nationName}{$josa} $year년 불가침에 합의했습니다."; - pushGenLog(['no'=>$this->dest->generalID], $mylog); - pushGenLog(['no'=>$this->src->generalID], $youlog); - $josaWa = JosaUtil::pick($this->src->nationName, '와'); - pushGeneralHistory(['no'=>$this->src->generalID], "●{$helper->year}년 {$helper->month}월:{$this->dest->nationName}{$josaWa} {$year}년 불가침 성공"); - $josaWa = JosaUtil::pick($this->dest->nationName, '와'); - pushGeneralHistory(['no'=>$this->dest->generalID], "●{$helper->year}년 {$helper->month}월:{$this->src->nationName}{$josaWa} {$year}년 불가침 수락"); - - return $chk; + return [self::ACCEPTED, '']; } protected function cancelNA(){ @@ -264,7 +259,7 @@ class DiplomaticMessage extends Message{ //NOTE: 올바른 유저가 agreeMessage() 호출을 한건지는 외부에서 체크 필요(Session->userID 등) if(!$this->id){ - throw \RuntimeException('전송되지 않은 메시지에 수락 진행 중'); + throw new \RuntimeException('전송되지 않은 메시지에 수락 진행 중'); } @@ -310,7 +305,7 @@ class DiplomaticMessage extends Message{ list($result, $reason) = $this->acceptSurrender(); break; default: - throw \RuntimeException('diplomaticType이 올바르지 않음'); + throw new \RuntimeException('diplomaticType이 올바르지 않음'); } if($result !== self::ACCEPTED){ @@ -373,7 +368,7 @@ class DiplomaticMessage extends Message{ public function declineMessage(int $receiverID, string &$reason):int{ if(!$this->id){ - throw \RuntimeException('전송되지 않은 메시지에 거절 진행 중'); + throw new \RuntimeException('전송되지 않은 메시지에 거절 진행 중'); } $db = DB::db(); diff --git a/hwe/sammo/Engine/Diplomacy.php b/hwe/sammo/Engine/Diplomacy.php index f7487eac..a3bef3a3 100644 --- a/hwe/sammo/Engine/Diplomacy.php +++ b/hwe/sammo/Engine/Diplomacy.php @@ -272,28 +272,6 @@ class Diplomacy{ return $prev; } - - public function noAggression(int $when){ - $chk = $this->checkValidNation(); - $chk = $this->checkNotWar($chk); - $chk = $this->checkAlreadyMerging($chk); - - list($result, $reason) = $chk; - if($result !== DiplomaticMessage::ACCEPTED){ - return $chk; - } - - $db = DB::db(); - $db->update('diplomacy',[ - 'state'=>7, - 'term'=>$when*12 - ], - '(me=%i AND you=%i) OR (you=%i AND me=%i)', - $this->srcNation['nation'], $this->destNation['nation'], - $this->srcNation['nation'], $this->destNation['nation']); - - return $chk; - } public function cancelNA(){ $chk = $this->checkValidNation(); diff --git a/hwe/sammo/Message.php b/hwe/sammo/Message.php index 157e1ad3..22d9dc5f 100644 --- a/hwe/sammo/Message.php +++ b/hwe/sammo/Message.php @@ -366,8 +366,18 @@ class Message if($this->msgType === self::MSGTYPE_NATIONAL && $this->src->nationID !== $this->dest->nationID){ return $this->sendRaw($this->src->nationID + self::MAILBOX_NATIONAL); } - if($this->msgType === self::MSGTYPE_DIPLOMACY && !key_exists('action', $this->msgOption)){ - return $this->sendRaw($this->src->nationID + self::MAILBOX_NATIONAL); + if($this->msgType === self::MSGTYPE_DIPLOMACY){ + if(key_exists('action', $this->msgOption)){ + $tmp = $this->msgOption; + $this->msgOption = null; + $retVal = $this->sendRaw($this->src->nationID + self::MAILBOX_NATIONAL); + $this->msgOption = $tmp; + return $retVal; + } + else{ + return $this->sendRaw($this->src->nationID + self::MAILBOX_NATIONAL); + } + } return [0, 0]; } @@ -411,7 +421,7 @@ class Message public function send(bool $sendDestOnly=false):int{ [$receiverMailbox, $receiveID] = $this->sendToReceiver(); if(!$receiveID && !$sendDestOnly){ - return $sendID; + throw new \RuntimeException('메시지 전송 불가'); } $this->mailbox = $receiverMailbox; $this->isInboxMail = true;