From a06ded552d5173975b89d11aab012ebb5db3760d Mon Sep 17 00:00:00 2001 From: hide_d Date: Sat, 6 Jun 2020 13:20:01 +0900 Subject: [PATCH] =?UTF-8?q?=EC=9C=A0=EC=A0=80=EC=9E=A5=EC=9D=80=20?= =?UTF-8?q?=EC=9E=90=EB=8F=99=20=EC=82=AC=EB=A0=B9=ED=84=B4=20=EC=BC=AC?= =?UTF-8?q?=EB=81=94=20=EA=B0=80=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hwe/b_myPage.php | 315 +++++------ hwe/j_set_my_setting.php | 157 +++--- hwe/js/myPage.js | 331 +++++------ hwe/sammo/GeneralAI.php | 3 + hwe/sammo/TurnExecutionHelper.php | 888 +++++++++++++++--------------- 5 files changed, 855 insertions(+), 839 deletions(-) diff --git a/hwe/b_myPage.php b/hwe/b_myPage.php index 33280f78..6413b7ba 100644 --- a/hwe/b_myPage.php +++ b/hwe/b_myPage.php @@ -1,154 +1,161 @@ -setReadOnly(); -$userID = Session::getUserID(); -$generalID = $session->generalID; - -$db = DB::db(); -$gameStor = KVStorage::getStorage($db, 'game_env'); - -increaseRefresh("내정보", 1); - -$me = General::createGeneralObjFromDB($generalID); - -$myset = $me->getVar('myset'); -if ($myset > 0) { - $submit = 'button'; -} else { - $submit = 'hidden'; -} - -$targetTime = addTurn($me->getVar('lastrefresh'), $gameStor->turnterm, 2); -if($gameStor->turntime <= $gameStor->opentime){ - //서버 가오픈시 할 수 있는 행동 - if($me->getNPCType() == 0){ - $showDieImmediatelyBtn = true; - if($targetTime <= TimeUtil::now()){ - $availableDieImmediately = true; - } - } -} - -$use_treatment = $me->getAuxVar('use_treatment')??10; - -?> - - - - - - -<?=UniqueConst::$serverName?>: 내정보 - - - - - - - - - - - - - -
내 정 보
- - - - - - - - - - - - - - - - - - - - - -
- - - - 토너먼트 【 - getVar('tnmt')==0?"checked":""; ?>>수동참여 - getVar('tnmt')==1?"checked":""; ?>>자동참여 - 】
- ∞개막직전 남는자리가 있을경우 랜덤하게 참여합니다.

- - 환약 사용 【
- ∞부상을 입었을 때 환약을 사용하는 기준입니다.

- - 수비 【 - 】

- id='set_my_setting' name=btn style=background-color:;color:white;width:160px;height:30px;font-size:13px; value=설정저장>
- ∞설정저장은 이달중 회 남았습니다.

- autorun_user['limit_minutes']??false)): ?> - 휴 가 신 청
-

- - - - - 가오픈 기간 내 장수 삭제 ( 부터)
-

- - - 개인용 CSS
- -
개인 기록전투 기록
-
- -
- -
-
- -
- -
장수 열전전투 결과
- - -
- -
- -
- - - -
- - - +setReadOnly(); +$userID = Session::getUserID(); +$generalID = $session->generalID; + +$db = DB::db(); +$gameStor = KVStorage::getStorage($db, 'game_env'); +$gameStor->cacheValues(['turntime', 'opentime', 'autorun_user']); + +increaseRefresh("내정보", 1); + +$me = General::createGeneralObjFromDB($generalID); + +$myset = $me->getVar('myset'); +if ($myset > 0) { + $submit = 'button'; +} else { + $submit = 'hidden'; +} + +$targetTime = addTurn($me->getVar('lastrefresh'), $gameStor->turnterm, 2); +if($gameStor->turntime <= $gameStor->opentime){ + //서버 가오픈시 할 수 있는 행동 + if($me->getNPCType() == 0){ + $showDieImmediatelyBtn = true; + if($targetTime <= TimeUtil::now()){ + $availableDieImmediately = true; + } + } +} + +$use_treatment = $me->getAuxVar('use_treatment')??10; +$use_auto_nation_turn = $me->getAuxVar('use_auto_nation_turn')??1; +?> + + + + + + +<?=UniqueConst::$serverName?>: 내정보 + + + + + + + + + + + + + +
내 정 보
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + 토너먼트 【 + getVar('tnmt')==0?"checked":""; ?>>수동참여 + getVar('tnmt')==1?"checked":""; ?>>자동참여 + 】
+ ∞개막직전 남는자리가 있을경우 랜덤하게 참여합니다.

+ + 환약 사용 【
+ ∞부상을 입었을 때 환약을 사용하는 기준입니다.

+autorun_user['options']['chief'])??false) : ?> + 자동 사령턴 허용 【
+ ∞수뇌가 되었을 때 휴식 턴이어도 적당한 턴을 알아서 넣는 것을 허용합니다.

+ + 수비 【 + 】

+ id='set_my_setting' name=btn style=background-color:;color:white;width:160px;height:30px;font-size:13px; value=설정저장>
+ ∞설정저장은 이달중 회 남았습니다.

+ autorun_user['limit_minutes']??false)): ?> + 휴 가 신 청
+

+ + + + + 가오픈 기간 내 장수 삭제 ( 부터)
+

+ + + 개인용 CSS
+ +
개인 기록전투 기록
+
+ +
+ +
+
+ +
+ +
장수 열전전투 결과
+ + +
+ +
+ +
+ + + +
+ + + diff --git a/hwe/j_set_my_setting.php b/hwe/j_set_my_setting.php index cc0df838..1bec80e1 100644 --- a/hwe/j_set_my_setting.php +++ b/hwe/j_set_my_setting.php @@ -1,77 +1,82 @@ -setReadOnly(); -$userID = Session::getUserID(); -$generalID = $session->generalID; - -increaseRefresh("내정보 수정", 0); - -$action = Util::getPost('action'); -$tnmt = Util::getPost('tnmt', 'int', 1); -$defence_train = Util::getPost('defence_train', 'int', 80); -$use_treatment = Util::getPost('use_treatment', 'int', 10); -//$detachNPC = Util::getPost('detachNPC', 'bool'); -$detachNPC = false; - -if ($defence_train <= 40) { - $defence_train = 40; -} - -if($defence_train <= 90){ - $defence_train = Util::round($defence_train, -1); -} -else{ - $defence_train = 999; -} - -if($tnmt < 0 || $tnmt > 1){ - $tnmt = 1; -} - -$db = DB::db(); -$me = General::createGeneralObjFromDB($generalID); - - -if($defence_train != $me->getVar('defence_train')){ - if($defence_train == 999){ - $me->increaseVar('myset', -1); - $me->setVar('defence_train', $defence_train); - $me->increaseVar('train', -3); - $me->increaseVar('atmos', -3); - } - else{ - $me->increaseVar('myset', -1); - $me->setVar('defence_train', $defence_train); - } -} - -$me->setAuxVar('use_treatment', Util::valueFit($use_treatment, 10, 100)); - -if($me->getVar('tnmt') != $tnmt){ - $me->setVar('tnmt', $tnmt); -} - -if($me->getNPCType() == 1 && $detachNPC){ - $turnterm = $gameStor->turnterm; - - if($turnterm < 10){ - $targetKillTurn = 30 / $turnterm; - } - else{ - $targetKillTurn = 60 / $turnterm; - } - $me->setVar('killturn', $targetKillTurn); -} - -$me->applyDB($db); - -Json::die([ - 'result'=>true, - 'reason'=>'success' +setReadOnly(); +$userID = Session::getUserID(); +$generalID = $session->generalID; + +increaseRefresh("내정보 수정", 0); + +$action = Util::getPost('action'); +$tnmt = Util::getPost('tnmt', 'int', 1); +$defence_train = Util::getPost('defence_train', 'int', 80); +$use_treatment = Util::getPost('use_treatment', 'int', 10); +$use_auto_nation_turn = Util::getPost('use_auto_nation_turn', 'int', 1); +//$detachNPC = Util::getPost('detachNPC', 'bool'); +$detachNPC = false; + +if ($defence_train <= 40) { + $defence_train = 40; +} + +if($defence_train <= 90){ + $defence_train = Util::round($defence_train, -1); +} +else{ + $defence_train = 999; +} + +if($tnmt < 0 || $tnmt > 1){ + $tnmt = 1; +} + +$db = DB::db(); +$me = General::createGeneralObjFromDB($generalID); + + +if($defence_train != $me->getVar('defence_train')){ + if($defence_train == 999){ + $me->increaseVar('myset', -1); + $me->setVar('defence_train', $defence_train); + $me->increaseVar('train', -3); + $me->increaseVar('atmos', -3); + } + else{ + $me->increaseVar('myset', -1); + $me->setVar('defence_train', $defence_train); + } +} + +if($use_auto_nation_turn != $me->getAuxVar('use_auto_nation_turn')){ + $me->setAuxVar('use_auto_nation_turn', $use_auto_nation_turn); +} + +$me->setAuxVar('use_treatment', Util::valueFit($use_treatment, 10, 100)); + +if($me->getVar('tnmt') != $tnmt){ + $me->setVar('tnmt', $tnmt); +} + +if($me->getNPCType() == 1 && $detachNPC){ + $turnterm = $gameStor->turnterm; + + if($turnterm < 10){ + $targetKillTurn = 30 / $turnterm; + } + else{ + $targetKillTurn = 60 / $turnterm; + } + $me->setVar('killturn', $targetKillTurn); +} + +$me->applyDB($db); + +Json::die([ + 'result'=>true, + 'reason'=>'success' ]); \ No newline at end of file diff --git a/hwe/js/myPage.js b/hwe/js/myPage.js index 29d2160b..153c65aa 100644 --- a/hwe/js/myPage.js +++ b/hwe/js/myPage.js @@ -1,166 +1,167 @@ -jQuery(function($){ - - - var initCustomCSSForm = function(){ - var lastTimeOut = null; - var $obj = $('#custom_css'); - var key = 'sam_customCSS'; - - var text = localStorage.getItem(key); - if(text){ - $obj.val(text); - console.log(text); - } - - if($obj.on('change keyup paste', function(){ - var newText = $obj.val(); - if(text == newText){ - return; - } - if(lastTimeOut){ - clearTimeout(lastTimeOut); - } - $obj.css('background-color', '#222222'); - lastTimeOut = setTimeout(function(){ - text = $obj.val(); - localStorage.setItem(key, text); - $obj.css('background-color', 'black'); - }, 500); - })); - - } - - $('.load_old_log').click(function(){ - var $thisBtn = $(this); - var logType = $thisBtn.data('log_type'); - var $last = $('.log_{0}:last'.format(logType)); - var reqTo = null; - if($last.length){ - reqTo = $last.data('seq'); - } - - $.post({ - url:'j_general_log_old.php', - dataType:'json', - data:{ - to:reqTo, - type:logType - } - }).then(function(data){ - if(!data){ - return quickReject('로그를 받아오지 못했습니다.'); - } - if(!data.result){ - return quickReject('로그를 받아오지 못했습니다. : '+data.reason); - } - - var keys = Object.keys(data.log); - if(keys.length > 1 && keys[0] < keys[1]){ - keys.reverse(); - } - - if(keys == 0){ - $thisBtn.hide(); - return; - } - - var html = []; - $.each(keys, function(_, key){ - if($('#log_{0}_{1}'.format(logType, key)).length){ - return true; - } - var item = data.log[key]; - html.push("
{2}
".format(logType, key, item)); - }); - - $('#{0}Plate'.format(logType)).append(html); - }, errUnknown) - .fail(function(reason){ - alert(reason); - location.reload(); - }); - }) - - initCustomCSSForm(); - - - $('#die_immediately').click(function(){ - if(!confirm('정말로 삭제하시겠습니까?')){ - return false; - } - $.post({ - url:'j_die_immediately.php', - dataType:'json', - }).then(function(data){ - if(!data){ - return quickReject('실패했습니다.'); - } - if(!data.result){ - return quickReject(data.reason); - } - - location.replace('..'); - - }, errUnknown) - .fail(function(reason){ - alert(reason); - location.reload(); - }); - return false; - return false; - }); - - $('#vacation').click(function(){ - if(!confirm('휴가 기능을 신청할까요?')){ - return false; - } - $.post({ - url:'j_vacation.php', - dataType:'json', - }).then(function(data){ - if(!data){ - return quickReject('실패했습니다.'); - } - if(!data.result){ - return quickReject(data.reason); - } - - location.reload(); - - }, errUnknown) - .fail(function(reason){ - alert(reason); - location.reload(); - }); - return false; - return false; - }); - - $('#set_my_setting').click(function(){ - $.post({ - url:'j_set_my_setting.php', - dataType:'json', - data:{ - tnmt:$('.tnmt:checked').val(), - defence_train:$('#defence_train').val(), - use_treatment:$('#use_treatment').val(), - } - }).then(function(data){ - if(!data){ - return quickReject('실패했습니다.'); - } - if(!data.result){ - return quickReject(data.reason); - } - - location.reload(); - - }, errUnknown) - .fail(function(reason){ - alert(reason); - location.reload(); - }); - return false; - return false; - }); +jQuery(function($) { + + + var initCustomCSSForm = function() { + var lastTimeOut = null; + var $obj = $('#custom_css'); + var key = 'sam_customCSS'; + + var text = localStorage.getItem(key); + if (text) { + $obj.val(text); + console.log(text); + } + + if ($obj.on('change keyup paste', function() { + var newText = $obj.val(); + if (text == newText) { + return; + } + if (lastTimeOut) { + clearTimeout(lastTimeOut); + } + $obj.css('background-color', '#222222'); + lastTimeOut = setTimeout(function() { + text = $obj.val(); + localStorage.setItem(key, text); + $obj.css('background-color', 'black'); + }, 500); + })); + + } + + $('.load_old_log').click(function() { + var $thisBtn = $(this); + var logType = $thisBtn.data('log_type'); + var $last = $('.log_{0}:last'.format(logType)); + var reqTo = null; + if ($last.length) { + reqTo = $last.data('seq'); + } + + $.post({ + url: 'j_general_log_old.php', + dataType: 'json', + data: { + to: reqTo, + type: logType + } + }).then(function(data) { + if (!data) { + return quickReject('로그를 받아오지 못했습니다.'); + } + if (!data.result) { + return quickReject('로그를 받아오지 못했습니다. : ' + data.reason); + } + + var keys = Object.keys(data.log); + if (keys.length > 1 && keys[0] < keys[1]) { + keys.reverse(); + } + + if (keys == 0) { + $thisBtn.hide(); + return; + } + + var html = []; + $.each(keys, function(_, key) { + if ($('#log_{0}_{1}'.format(logType, key)).length) { + return true; + } + var item = data.log[key]; + html.push("
{2}
".format(logType, key, item)); + }); + + $('#{0}Plate'.format(logType)).append(html); + }, errUnknown) + .fail(function(reason) { + alert(reason); + location.reload(); + }); + }) + + initCustomCSSForm(); + + + $('#die_immediately').click(function() { + if (!confirm('정말로 삭제하시겠습니까?')) { + return false; + } + $.post({ + url: 'j_die_immediately.php', + dataType: 'json', + }).then(function(data) { + if (!data) { + return quickReject('실패했습니다.'); + } + if (!data.result) { + return quickReject(data.reason); + } + + location.replace('..'); + + }, errUnknown) + .fail(function(reason) { + alert(reason); + location.reload(); + }); + return false; + return false; + }); + + $('#vacation').click(function() { + if (!confirm('휴가 기능을 신청할까요?')) { + return false; + } + $.post({ + url: 'j_vacation.php', + dataType: 'json', + }).then(function(data) { + if (!data) { + return quickReject('실패했습니다.'); + } + if (!data.result) { + return quickReject(data.reason); + } + + location.reload(); + + }, errUnknown) + .fail(function(reason) { + alert(reason); + location.reload(); + }); + return false; + return false; + }); + + $('#set_my_setting').click(function() { + $.post({ + url: 'j_set_my_setting.php', + dataType: 'json', + data: { + tnmt: $('.tnmt:checked').val(), + defence_train: $('#defence_train').val(), + use_treatment: $('#use_treatment').val(), + use_auto_nation_turn: $('#use_auto_nation_turn').val(), + } + }).then(function(data) { + if (!data) { + return quickReject('실패했습니다.'); + } + if (!data.result) { + return quickReject(data.reason); + } + + location.reload(); + + }, errUnknown) + .fail(function(reason) { + alert(reason); + location.reload(); + }); + return false; + return false; + }); }); \ No newline at end of file diff --git a/hwe/sammo/GeneralAI.php b/hwe/sammo/GeneralAI.php index f74512a6..eb2ed702 100644 --- a/hwe/sammo/GeneralAI.php +++ b/hwe/sammo/GeneralAI.php @@ -3251,6 +3251,9 @@ class GeneralAI $month = $this->env['month']; if($npcType >= 2){ + if(!($general->getAuxVar('use_auto_nation_turn')??1)){ + $general->setAuxVar('use_auto_nation_turn', 1); + } if($general->getVar('officer_level') == 12){ if (in_array($month, [3, 6, 9, 12])) { $this->choosePromotion(); diff --git a/hwe/sammo/TurnExecutionHelper.php b/hwe/sammo/TurnExecutionHelper.php index b6532979..f5680d9d 100644 --- a/hwe/sammo/TurnExecutionHelper.php +++ b/hwe/sammo/TurnExecutionHelper.php @@ -1,445 +1,445 @@ -generalObj = $general; - } - - public function __destruct() - { - $this->applyDB(); - } - - public function applyDB(){ - $db = DB::db(); - $this->generalObj->applyDB($db); - } - - public function getGeneral():General{ - return $this->generalObj; - } - - public function preprocessCommand(array $env){ - $general = $this->getGeneral(); - $caller = $general->getPreTurnExecuteTriggerList($general); - $caller->merge(new GeneralTriggerCaller( - new GeneralTrigger\che_부상경감($general), - new GeneralTrigger\che_병력군량소모($general) - )); - - $caller->fire($env); - } - - public function processBlocked():bool{ - $general = $this->getGeneral(); - - $blocked = $general->getVar('block'); - if($blocked < 2){ - return false; - } - - $date = $general->getTurnTime($general::TURNTIME_HM); - $logger = $general->getLogger(); - if($blocked == 2){ - $general->increaseVarWithLimit('killturn', -1, 0); - $logger->pushGeneralActionLog("현재 멀티, 또는 비매너로 인한블럭 대상자입니다. <1>$date"); - } - else if($blocked == 3){ - $general->increaseVarWithLimit('killturn', -1, 0); - $logger->pushGeneralActionLog("현재 악성유저로 분류되어 블럭 대상자입니다. <1>$date"); - } - else{ - //Hmm? - return false; - } - - return true; - } - - public function processNationCommand(Command\NationCommand $commandObj):LastTurn{ - $general = $this->getGeneral(); - - while(true){ - if(!$commandObj->hasFullConditionMet()){ - $date = $general->getTurnTime($general::TURNTIME_HM); - $failString = $commandObj->getFailString(); - $text = "{$failString} <1>{$date}"; - $general->getLogger()->pushGeneralActionLog($text); - break; - } - - if(!$commandObj->addTermStack()){ - $date = $general->getTurnTime($general::TURNTIME_HM); - $termString = $commandObj->getTermString(); - $text = "{$termString} <1>{$date}"; - $general->getLogger()->pushGeneralActionLog($text); - break; - } - - $result = $commandObj->run(); - if($result){ - break; - } - - - $alt = $commandObj->getAlternativeCommand(); - if($alt === null){ - break; - } - $commandObj = $alt; - $commandClassName = $alt->getName(); - } - - return $commandObj->getResultTurn(); - } - - public function processCommand(Command\GeneralCommand $commandObj, bool $autorunMode){ - - $general = $this->getGeneral(); - - $db = DB::db(); - $gameStor = KVStorage::getStorage($db, 'game_env'); - $commandClassName = $commandObj->getName(); - - while(true){ - if(!$commandObj->hasFullConditionMet()){ - $date = $general->getTurnTime($general::TURNTIME_HM); - $failString = $commandObj->getFailString(); - $text = "{$failString} <1>{$date}"; - $general->getLogger()->pushGeneralActionLog($text); - break; - } - - if(!$commandObj->addTermStack()){ - $date = $general->getTurnTime($general::TURNTIME_HM); - $termString = $commandObj->getTermString(); - $text = "{$termString} <1>{$date}"; - $general->getLogger()->pushGeneralActionLog($text); - break; - } - - $result = $commandObj->run(); - if($result){ - break; - } - $alt = $commandObj->getAlternativeCommand(); - if($alt === null){ - break; - } - $commandObj = $alt; - $commandClassName = $alt->getName(); - } - - - $general->clearActivatedSkill(); - - $killTurn = $gameStor->killturn; - - if($general->getNPCType() >= 2){ - $general->increaseVarWithLimit('killturn', -1); - } - else if($general->getVar('killturn') > $killTurn){ - $general->increaseVarWithLimit('killturn', -1); - } - else if($autorunMode){ - $general->increaseVarWithLimit('killturn', -1); - } - else if($commandClassName == '휴식'){ - $general->increaseVarWithLimit('killturn', -1); - } - else{ - $general->setVar('killturn', $killTurn); - } - - return $commandObj->getResultTurn(); - } - - function updateTurnTime(){ - $db = DB::db(); - $gameStor = KVStorage::getStorage($db, 'game_env'); - - $general = $this->getGeneral(); - $generalID = $general->getID(); - $logger = $general->getLogger(); - $general->setVar('con', 0); - - $generalName = $general->getName(); - - // 삭턴장수 삭제처리 - if($general->getVar('killturn') <= 0){ - // npc유저 삭턴시 npc로 전환 - if($general->getNPCType() == 1 && $general->getVar('deadyear') > $gameStor->year){ - - $ownerName = $general->getVar('owner_name'); - $josaYi = JosaUtil::pick($ownerName, '이'); - - $logger->pushGlobalActionLog("{$ownerName}{$josaYi} {$generalName}의 육체에서 유체이탈합니다!"); - - $general->setVar('killturn', ($general->getVar('deadyear') - $gameStor->year) * 12); - $general->setVar('npc', $general->getVar('npc_org')); - $general->setVar('owner', 1); - $general->setVar('defence_train', 80); - $general->setVar('owner_name', null); - } - else{ - $general->applyDB($db); - storeOldGeneral($generalID, $gameStor->year, $gameStor->month); - $general->kill($db); - return; - } - } - - //은퇴 - if($general->getVar('age') >= GameConst::$retirementYear && $general->getNPCType() == 0) { - if($gameStor->isunited == 0) { - $general->applyDB($db); - CheckHall($generalID); - } - - $general->rebirth(); - } - - $turntime = addTurn($general->getTurnTime(), $gameStor->turnterm); - $general->setVar('turntime', $turntime); - - } - - - static public function executeGeneralCommandUntil(string $date, \DateTimeInterface $limitActionTime, int $year, int $month){ - $db = DB::db(); - $generalsTodo = $db->query( - 'SELECT no,name,turntime,killturn,block,npc,deadyear FROM general WHERE turntime < %s ORDER BY turntime ASC, `no` ASC', - $date - ); - - $currentTurn = null; - - $gameStor = KVStorage::getStorage($db, 'game_env'); - $autorun_user = $gameStor->autorun_user; - - foreach($generalsTodo as $rawGeneral){ - $currActionTime = new \DateTimeImmutable(); - if($currActionTime > $limitActionTime){ - return [true, $currentTurn]; - } - - $general = General::createGeneralObjFromDB($rawGeneral['no']); - $turnObj = new static($general); - - $env = $gameStor->getAll(true); - - $hasNationTurn = false; - if($general->getVar('nation') != 0 && $general->getVar('officer_level') >= 5){ - $nationStor = KVStorage::getStorage($db, $general->getNationID(), 'nation_env'); - $lastNationTurnKey = "turn_last_{$general->getVar('officer_level')}"; - //수뇌 몇 없는데 매번 left join 하는건 낭비인것 같다. - $rawNationTurn = $db->queryFirstRow( - 'SELECT action, arg FROM nation_turn WHERE nation_id = %i AND officer_level = %i AND turn_idx =0', - $general->getVar('nation'), - $general->getVar('officer_level') - )??[]; - $hasNationTurn = true; - $nationCommand = $rawNationTurn['action']??null; - $nationArg = Json::decode($rawNationTurn['arg']??null); - $lastNationTurn = LastTurn::fromRaw($nationStor->getValue($lastNationTurnKey)); - $nationCommandObj = buildNationCommandClass($nationCommand, $general, $env, $lastNationTurn, $nationArg); - } - - $autorunMode = false; - $ai = null; - - $turnObj->preprocessCommand($env); - $generalCommandObj = $general->getReservedTurn(0, $env); - - if($general->getNPCType() >= 2 || ($autorun_user['limit_minutes']??false)){ - $ai = new GeneralAI($turnObj->getGeneral()); - } - - if(!$turnObj->processBlocked()){ - - if($hasNationTurn){ - if($ai){ - $nationCommandObj = $ai->chooseNationTurn($nationCommandObj); - $cityName = CityConst::byID($general->getCityID())->name; - LogText("NationTurn", "General, {$general->getName()}, {$general->getID()}, {$cityName}, {$general->getStaticNation()['name']}, {$nationCommandObj->getBrief()}, {$nationCommandObj->reason}, "); - } - $resultNationTurn = $turnObj->processNationCommand( - $nationCommandObj - ); - $nationStor->setValue($lastNationTurnKey, $resultNationTurn->toRaw()); - } - - if($ai){ - $newGeneralCommandObj = $ai->chooseGeneralTurn($generalCommandObj); // npc AI 처리 - if($generalCommandObj !== $newGeneralCommandObj){ - $autorunMode = true; - $generalCommandObj = $newGeneralCommandObj; - } - $cityName = CityConst::byID($general->getCityID())->name; - LogText("turn", "General, {$general->getName()}, {$general->getID()}, {$cityName}, {$general->getStaticNation()['name']}, {$generalCommandObj->getBrief()}, {$generalCommandObj->reason}, "); - } - - $turnObj->processCommand($generalCommandObj, $autorunMode); - } - pullNationCommand($general->getVar('nation'), $general->getVar('officer_level')); - pullGeneralCommand($general->getID()); - - $currentTurn = $general->getTurnTime(); - $general->increaseVarWithLimit('myset', 3, null, 9); - - $turnObj->updateTurnTime(); - $turnObj->applyDB(); - - - } - - return [false, $currentTurn]; - } - - static public function executeAllCommand(){ - //if(!timeover()) { return; } - - $db = DB::db(); - - $gameStor = KVStorage::getStorage($db, 'game_env'); - - if(TimeUtil::now(true) < $gameStor->turntime){ - //턴 시각 이전이면 아무것도 하지 않음 - return true; - } - - if(!tryLock()){ - return; - } - - if ($gameStor->isunited == 2) { - //천통시에는 동결 - return; - } - - $gameStor->cacheAll(); - // 1턴이상 갱신 없었으면 서버 지연 - checkDelay(); - // 접속자수, 접속국가, 국가별 접속장수 갱신 - updateOnline(); - //접속자 수 따라서 갱신제한 변경 - CheckOverhead(); - - $date = TimeUtil::now(true); - // 최종 처리 월턴의 다음 월턴시간 구함 - $prevTurn = cutTurn($gameStor->turntime, $gameStor->turnterm); - $nextTurn = addTurn($prevTurn, $gameStor->turnterm); - - $maxActionTime = Util::toInt(ini_get('max_execution_time')); - if($maxActionTime == 0){ - $maxActionTime = 60; - } - else { - $maxActionTime = max($maxActionTime * 2 / 3, $maxActionTime - 10); - } - - $limitActionTime = (new \DateTimeImmutable())->add(TimeUtil::secondsToDateInterval($maxActionTime)); - - // 현재 턴 이전 월턴까지 모두처리. - //최종 처리 이후 다음 월턴이 현재 시간보다 전이라면 - while ($nextTurn <= $date) { - - [$executionOver, $currentTurn] = static::executeGeneralCommandUntil( - $nextTurn, $limitActionTime, $gameStor->year, $gameStor->month - ); - - // 트래픽 업데이트 - updateTraffic(); - - if($executionOver){ - if($currentTurn !== null){ - $gameStor->turntime = $currentTurn; - } - unlock(); - return; - } - - - // 1달마다 처리하는 것들, 벌점 감소 및 건국,전턴,합병 -1, 군량 소모 - if(!preUpdateMonthly()){ - $gameStor->resetCache(true); - unlock(); - throw new \RuntimeException('preUpdateMonthly() 처리 에러'); - } - - turnDate($nextTurn); - - $logger = new ActionLogger(0, 0, $gameStor->year, $gameStor->month, false); - - // 분기계산. 장수들 턴보다 먼저 있다면 먼저처리 - if($gameStor->month == 1) { - processGoldIncome(); - processSpring(); - updateYearly(); - updateQuaterly(); - disaster(); - tradeRate(); - addAge(); - // 새해 알림 - $logger->pushGlobalActionLog("{$gameStor->year}년이 되었습니다."); - $logger->flush(); //TODO: globalAction류는 전역에서 관리하는것이 좋을 듯. - } elseif($gameStor->month == 4) { - updateQuaterly(); - disaster(); - } elseif($gameStor->month == 7) { - processRiceIncome(); - processFall(); - updateQuaterly(); - disaster(); - tradeRate(); - } elseif($gameStor->month == 10) { - updateQuaterly(); - disaster(); - } - - // 이벤트 핸들러 동작 - foreach (DB::db()->query('SELECT * from event') as $rawEvent) { - $eventID = $rawEvent['id']; - $cond = Json::decode($rawEvent['condition']); - $action = Json::decode($rawEvent['action']); - $event = new Event\EventHandler($cond, $action); - - $event->tryRunEvent(['currentEventID'=>$eventID] + $gameStor->getAll(true)); - } - - postUpdateMonthly(); - - // 다음달로 넘김 - $prevTurn = $nextTurn; - $nextTurn = addTurn($prevTurn, $gameStor->turnterm); - $gameStor->turntime = $prevTurn; - } - - // 그 시각 년도,월 저장 - turnDate($prevTurn); - // 현재시간의 월턴시간 이후 분단위 장수 처리 - - [$executionOver, $currentTurn] = static::executeGeneralCommandUntil( - $date, $limitActionTime, $gameStor->year, $gameStor->month - ); - - if($currentTurn !== null){ - $gameStor->turntime = $currentTurn; - } - - //토너먼트 처리 - processTournament(); - //거래 처리 - processAuction(); - // 잡금 해제 - $gameStor->resetCache(true); - unlock(); - } +generalObj = $general; + } + + public function __destruct() + { + $this->applyDB(); + } + + public function applyDB(){ + $db = DB::db(); + $this->generalObj->applyDB($db); + } + + public function getGeneral():General{ + return $this->generalObj; + } + + public function preprocessCommand(array $env){ + $general = $this->getGeneral(); + $caller = $general->getPreTurnExecuteTriggerList($general); + $caller->merge(new GeneralTriggerCaller( + new GeneralTrigger\che_부상경감($general), + new GeneralTrigger\che_병력군량소모($general) + )); + + $caller->fire($env); + } + + public function processBlocked():bool{ + $general = $this->getGeneral(); + + $blocked = $general->getVar('block'); + if($blocked < 2){ + return false; + } + + $date = $general->getTurnTime($general::TURNTIME_HM); + $logger = $general->getLogger(); + if($blocked == 2){ + $general->increaseVarWithLimit('killturn', -1, 0); + $logger->pushGeneralActionLog("현재 멀티, 또는 비매너로 인한블럭 대상자입니다. <1>$date"); + } + else if($blocked == 3){ + $general->increaseVarWithLimit('killturn', -1, 0); + $logger->pushGeneralActionLog("현재 악성유저로 분류되어 블럭 대상자입니다. <1>$date"); + } + else{ + //Hmm? + return false; + } + + return true; + } + + public function processNationCommand(Command\NationCommand $commandObj):LastTurn{ + $general = $this->getGeneral(); + + while(true){ + if(!$commandObj->hasFullConditionMet()){ + $date = $general->getTurnTime($general::TURNTIME_HM); + $failString = $commandObj->getFailString(); + $text = "{$failString} <1>{$date}"; + $general->getLogger()->pushGeneralActionLog($text); + break; + } + + if(!$commandObj->addTermStack()){ + $date = $general->getTurnTime($general::TURNTIME_HM); + $termString = $commandObj->getTermString(); + $text = "{$termString} <1>{$date}"; + $general->getLogger()->pushGeneralActionLog($text); + break; + } + + $result = $commandObj->run(); + if($result){ + break; + } + + + $alt = $commandObj->getAlternativeCommand(); + if($alt === null){ + break; + } + $commandObj = $alt; + $commandClassName = $alt->getName(); + } + + return $commandObj->getResultTurn(); + } + + public function processCommand(Command\GeneralCommand $commandObj, bool $autorunMode){ + + $general = $this->getGeneral(); + + $db = DB::db(); + $gameStor = KVStorage::getStorage($db, 'game_env'); + $commandClassName = $commandObj->getName(); + + while(true){ + if(!$commandObj->hasFullConditionMet()){ + $date = $general->getTurnTime($general::TURNTIME_HM); + $failString = $commandObj->getFailString(); + $text = "{$failString} <1>{$date}"; + $general->getLogger()->pushGeneralActionLog($text); + break; + } + + if(!$commandObj->addTermStack()){ + $date = $general->getTurnTime($general::TURNTIME_HM); + $termString = $commandObj->getTermString(); + $text = "{$termString} <1>{$date}"; + $general->getLogger()->pushGeneralActionLog($text); + break; + } + + $result = $commandObj->run(); + if($result){ + break; + } + $alt = $commandObj->getAlternativeCommand(); + if($alt === null){ + break; + } + $commandObj = $alt; + $commandClassName = $alt->getName(); + } + + + $general->clearActivatedSkill(); + + $killTurn = $gameStor->killturn; + + if($general->getNPCType() >= 2){ + $general->increaseVarWithLimit('killturn', -1); + } + else if($general->getVar('killturn') > $killTurn){ + $general->increaseVarWithLimit('killturn', -1); + } + else if($autorunMode){ + $general->increaseVarWithLimit('killturn', -1); + } + else if($commandClassName == '휴식'){ + $general->increaseVarWithLimit('killturn', -1); + } + else{ + $general->setVar('killturn', $killTurn); + } + + return $commandObj->getResultTurn(); + } + + function updateTurnTime(){ + $db = DB::db(); + $gameStor = KVStorage::getStorage($db, 'game_env'); + + $general = $this->getGeneral(); + $generalID = $general->getID(); + $logger = $general->getLogger(); + $general->setVar('con', 0); + + $generalName = $general->getName(); + + // 삭턴장수 삭제처리 + if($general->getVar('killturn') <= 0){ + // npc유저 삭턴시 npc로 전환 + if($general->getNPCType() == 1 && $general->getVar('deadyear') > $gameStor->year){ + + $ownerName = $general->getVar('owner_name'); + $josaYi = JosaUtil::pick($ownerName, '이'); + + $logger->pushGlobalActionLog("{$ownerName}{$josaYi} {$generalName}의 육체에서 유체이탈합니다!"); + + $general->setVar('killturn', ($general->getVar('deadyear') - $gameStor->year) * 12); + $general->setVar('npc', $general->getVar('npc_org')); + $general->setVar('owner', 1); + $general->setVar('defence_train', 80); + $general->setVar('owner_name', null); + } + else{ + $general->applyDB($db); + storeOldGeneral($generalID, $gameStor->year, $gameStor->month); + $general->kill($db); + return; + } + } + + //은퇴 + if($general->getVar('age') >= GameConst::$retirementYear && $general->getNPCType() == 0) { + if($gameStor->isunited == 0) { + $general->applyDB($db); + CheckHall($generalID); + } + + $general->rebirth(); + } + + $turntime = addTurn($general->getTurnTime(), $gameStor->turnterm); + $general->setVar('turntime', $turntime); + + } + + + static public function executeGeneralCommandUntil(string $date, \DateTimeInterface $limitActionTime, int $year, int $month){ + $db = DB::db(); + $generalsTodo = $db->query( + 'SELECT no,name,turntime,killturn,block,npc,deadyear FROM general WHERE turntime < %s ORDER BY turntime ASC, `no` ASC', + $date + ); + + $currentTurn = null; + + $gameStor = KVStorage::getStorage($db, 'game_env'); + $autorun_user = $gameStor->autorun_user; + + foreach($generalsTodo as $rawGeneral){ + $currActionTime = new \DateTimeImmutable(); + if($currActionTime > $limitActionTime){ + return [true, $currentTurn]; + } + + $general = General::createGeneralObjFromDB($rawGeneral['no']); + $turnObj = new static($general); + + $env = $gameStor->getAll(true); + + $hasNationTurn = false; + if($general->getVar('nation') != 0 && $general->getVar('officer_level') >= 5){ + $nationStor = KVStorage::getStorage($db, $general->getNationID(), 'nation_env'); + $lastNationTurnKey = "turn_last_{$general->getVar('officer_level')}"; + //수뇌 몇 없는데 매번 left join 하는건 낭비인것 같다. + $rawNationTurn = $db->queryFirstRow( + 'SELECT action, arg FROM nation_turn WHERE nation_id = %i AND officer_level = %i AND turn_idx =0', + $general->getVar('nation'), + $general->getVar('officer_level') + )??[]; + $hasNationTurn = true; + $nationCommand = $rawNationTurn['action']??null; + $nationArg = Json::decode($rawNationTurn['arg']??null); + $lastNationTurn = LastTurn::fromRaw($nationStor->getValue($lastNationTurnKey)); + $nationCommandObj = buildNationCommandClass($nationCommand, $general, $env, $lastNationTurn, $nationArg); + } + + $autorunMode = false; + $ai = null; + + $turnObj->preprocessCommand($env); + $generalCommandObj = $general->getReservedTurn(0, $env); + + if($general->getNPCType() >= 2 || ($autorun_user['limit_minutes']??false)){ + $ai = new GeneralAI($turnObj->getGeneral()); + } + + if(!$turnObj->processBlocked()){ + + if($hasNationTurn){ + if($ai && ($general->getAuxVar('use_auto_nation_turn')??1)){ + $nationCommandObj = $ai->chooseNationTurn($nationCommandObj); + $cityName = CityConst::byID($general->getCityID())->name; + LogText("NationTurn", "General, {$general->getName()}, {$general->getID()}, {$cityName}, {$general->getStaticNation()['name']}, {$nationCommandObj->getBrief()}, {$nationCommandObj->reason}, "); + } + $resultNationTurn = $turnObj->processNationCommand( + $nationCommandObj + ); + $nationStor->setValue($lastNationTurnKey, $resultNationTurn->toRaw()); + } + + if($ai){ + $newGeneralCommandObj = $ai->chooseGeneralTurn($generalCommandObj); // npc AI 처리 + if($generalCommandObj !== $newGeneralCommandObj){ + $autorunMode = true; + $generalCommandObj = $newGeneralCommandObj; + } + $cityName = CityConst::byID($general->getCityID())->name; + LogText("turn", "General, {$general->getName()}, {$general->getID()}, {$cityName}, {$general->getStaticNation()['name']}, {$generalCommandObj->getBrief()}, {$generalCommandObj->reason}, "); + } + + $turnObj->processCommand($generalCommandObj, $autorunMode); + } + pullNationCommand($general->getVar('nation'), $general->getVar('officer_level')); + pullGeneralCommand($general->getID()); + + $currentTurn = $general->getTurnTime(); + $general->increaseVarWithLimit('myset', 3, null, 9); + + $turnObj->updateTurnTime(); + $turnObj->applyDB(); + + + } + + return [false, $currentTurn]; + } + + static public function executeAllCommand(){ + //if(!timeover()) { return; } + + $db = DB::db(); + + $gameStor = KVStorage::getStorage($db, 'game_env'); + + if(TimeUtil::now(true) < $gameStor->turntime){ + //턴 시각 이전이면 아무것도 하지 않음 + return true; + } + + if(!tryLock()){ + return; + } + + if ($gameStor->isunited == 2) { + //천통시에는 동결 + return; + } + + $gameStor->cacheAll(); + // 1턴이상 갱신 없었으면 서버 지연 + checkDelay(); + // 접속자수, 접속국가, 국가별 접속장수 갱신 + updateOnline(); + //접속자 수 따라서 갱신제한 변경 + CheckOverhead(); + + $date = TimeUtil::now(true); + // 최종 처리 월턴의 다음 월턴시간 구함 + $prevTurn = cutTurn($gameStor->turntime, $gameStor->turnterm); + $nextTurn = addTurn($prevTurn, $gameStor->turnterm); + + $maxActionTime = Util::toInt(ini_get('max_execution_time')); + if($maxActionTime == 0){ + $maxActionTime = 60; + } + else { + $maxActionTime = max($maxActionTime * 2 / 3, $maxActionTime - 10); + } + + $limitActionTime = (new \DateTimeImmutable())->add(TimeUtil::secondsToDateInterval($maxActionTime)); + + // 현재 턴 이전 월턴까지 모두처리. + //최종 처리 이후 다음 월턴이 현재 시간보다 전이라면 + while ($nextTurn <= $date) { + + [$executionOver, $currentTurn] = static::executeGeneralCommandUntil( + $nextTurn, $limitActionTime, $gameStor->year, $gameStor->month + ); + + // 트래픽 업데이트 + updateTraffic(); + + if($executionOver){ + if($currentTurn !== null){ + $gameStor->turntime = $currentTurn; + } + unlock(); + return; + } + + + // 1달마다 처리하는 것들, 벌점 감소 및 건국,전턴,합병 -1, 군량 소모 + if(!preUpdateMonthly()){ + $gameStor->resetCache(true); + unlock(); + throw new \RuntimeException('preUpdateMonthly() 처리 에러'); + } + + turnDate($nextTurn); + + $logger = new ActionLogger(0, 0, $gameStor->year, $gameStor->month, false); + + // 분기계산. 장수들 턴보다 먼저 있다면 먼저처리 + if($gameStor->month == 1) { + processGoldIncome(); + processSpring(); + updateYearly(); + updateQuaterly(); + disaster(); + tradeRate(); + addAge(); + // 새해 알림 + $logger->pushGlobalActionLog("{$gameStor->year}년이 되었습니다."); + $logger->flush(); //TODO: globalAction류는 전역에서 관리하는것이 좋을 듯. + } elseif($gameStor->month == 4) { + updateQuaterly(); + disaster(); + } elseif($gameStor->month == 7) { + processRiceIncome(); + processFall(); + updateQuaterly(); + disaster(); + tradeRate(); + } elseif($gameStor->month == 10) { + updateQuaterly(); + disaster(); + } + + // 이벤트 핸들러 동작 + foreach (DB::db()->query('SELECT * from event') as $rawEvent) { + $eventID = $rawEvent['id']; + $cond = Json::decode($rawEvent['condition']); + $action = Json::decode($rawEvent['action']); + $event = new Event\EventHandler($cond, $action); + + $event->tryRunEvent(['currentEventID'=>$eventID] + $gameStor->getAll(true)); + } + + postUpdateMonthly(); + + // 다음달로 넘김 + $prevTurn = $nextTurn; + $nextTurn = addTurn($prevTurn, $gameStor->turnterm); + $gameStor->turntime = $prevTurn; + } + + // 그 시각 년도,월 저장 + turnDate($prevTurn); + // 현재시간의 월턴시간 이후 분단위 장수 처리 + + [$executionOver, $currentTurn] = static::executeGeneralCommandUntil( + $date, $limitActionTime, $gameStor->year, $gameStor->month + ); + + if($currentTurn !== null){ + $gameStor->turntime = $currentTurn; + } + + //토너먼트 처리 + processTournament(); + //거래 처리 + processAuction(); + // 잡금 해제 + $gameStor->resetCache(true); + unlock(); + } } \ No newline at end of file