홀짝 버그 수정

This commit is contained in:
2020-06-09 01:10:21 +09:00
parent 832536f403
commit c46c8a010f
+447 -447
View File
@@ -1,448 +1,448 @@
<?php <?php
namespace sammo; namespace sammo;
use sammo\Command\GeneralCommand; use sammo\Command\GeneralCommand;
use sammo\Command\NationCommand; use sammo\Command\NationCommand;
function getGeneralTurnBrief(General $generalObj, array $turnList) { function getGeneralTurnBrief(General $generalObj, array $turnList) {
$result = []; $result = [];
foreach($turnList as $turnIdx => [$action, $arg]){ foreach($turnList as $turnIdx => [$action, $arg]){
$commandObj = buildGeneralCommandClass($action, $generalObj, [], $arg); $commandObj = buildGeneralCommandClass($action, $generalObj, [], $arg);
$turnText = $commandObj->getBrief(); $turnText = $commandObj->getBrief();
$result[$turnIdx] = $turnText; $result[$turnIdx] = $turnText;
} }
return $result; return $result;
} }
function getNationTurnBrief(General $generalObj, array $turnList) { function getNationTurnBrief(General $generalObj, array $turnList) {
$result = []; $result = [];
$tmpTurn = new LastTurn(); $tmpTurn = new LastTurn();
foreach($turnList as $turnIdx => [$action, $arg]){ foreach($turnList as $turnIdx => [$action, $arg]){
$commandObj = buildNationCommandClass($action, $generalObj, [], $tmpTurn, $arg); $commandObj = buildNationCommandClass($action, $generalObj, [], $tmpTurn, $arg);
$turnText = $commandObj->getBrief(); $turnText = $commandObj->getBrief();
$result[$turnIdx] = $turnText; $result[$turnIdx] = $turnText;
} }
return $result; return $result;
} }
function pushGeneralCommand(int $generalID, int $turnCnt=1){ function pushGeneralCommand(int $generalID, int $turnCnt=1){
if($turnCnt == 0){ if($turnCnt == 0){
return; return;
} }
if($turnCnt < 0){ if($turnCnt < 0){
pullGeneralCommand($generalID, -$turnCnt); pullGeneralCommand($generalID, -$turnCnt);
return; return;
} }
if($turnCnt >= GameConst::$maxTurn){ if($turnCnt >= GameConst::$maxTurn){
return; return;
} }
$db = DB::db(); $db = DB::db();
$db->update('general_turn', [ $db->update('general_turn', [
'turn_idx'=>$db->sqleval('turn_idx + %i', $turnCnt) 'turn_idx'=>$db->sqleval('turn_idx + %i', $turnCnt)
], 'general_id=%i ORDER BY turn_idx DESC', $generalID); ], 'general_id=%i ORDER BY turn_idx DESC', $generalID);
$db->update('general_turn', [ $db->update('general_turn', [
'turn_idx'=>$db->sqleval('turn_idx - %i', GameConst::$maxTurn), 'turn_idx'=>$db->sqleval('turn_idx - %i', GameConst::$maxTurn),
'action'=>'휴식', 'action'=>'휴식',
'arg'=>'{}', 'arg'=>'{}',
'brief'=>'휴식' 'brief'=>'휴식'
], 'general_id=%i AND turn_idx >= %i', $generalID, GameConst::$maxTurn); ], 'general_id=%i AND turn_idx >= %i', $generalID, GameConst::$maxTurn);
} }
function pullGeneralCommand(int $generalID, int $turnCnt=1){ function pullGeneralCommand(int $generalID, int $turnCnt=1){
if($turnCnt == 0){ if($turnCnt == 0){
return; return;
} }
if($turnCnt < 0){ if($turnCnt < 0){
pushGeneralCommand($generalID, -$turnCnt); pushGeneralCommand($generalID, -$turnCnt);
return; return;
} }
if($turnCnt >= GameConst::$maxTurn){ if($turnCnt >= GameConst::$maxTurn){
return; return;
} }
$db = DB::db(); $db = DB::db();
$db->update('general_turn', [ $db->update('general_turn', [
'turn_idx'=>$db->sqleval('turn_idx + %i', GameConst::$maxTurn), 'turn_idx'=>$db->sqleval('turn_idx + %i', GameConst::$maxTurn),
'action'=>'휴식', 'action'=>'휴식',
'arg'=>'{}', 'arg'=>'{}',
'brief'=>'휴식' 'brief'=>'휴식'
], 'general_id=%i AND turn_idx < %i', $generalID, $turnCnt); ], 'general_id=%i AND turn_idx < %i', $generalID, $turnCnt);
$db->update('general_turn', [ $db->update('general_turn', [
'turn_idx'=>$db->sqleval('turn_idx - %i', $turnCnt) 'turn_idx'=>$db->sqleval('turn_idx - %i', $turnCnt)
], 'general_id=%i ORDER BY turn_idx ASC', $generalID); ], 'general_id=%i ORDER BY turn_idx ASC', $generalID);
} }
function repeatGeneralCommand(int $generalId, int $turnCnt){ function repeatGeneralCommand(int $generalId, int $turnCnt){
if($turnCnt <= 0){ if($turnCnt <= 0){
return; return;
} }
if($turnCnt >= GameConst::$maxTurn){ if($turnCnt >= GameConst::$maxTurn){
return; return;
} }
$db = DB::db(); $db = DB::db();
$reqTurn = $turnCnt; $reqTurn = $turnCnt;
if($turnCnt * 2 > GameConst::$maxTurn){ if($turnCnt * 2 > GameConst::$maxTurn){
$reqTurn = GameConst::$maxTurn - $turnCnt; $reqTurn = GameConst::$maxTurn - $turnCnt;
} }
$turnList = $db->query('SELECT turn_idx, `action`, arg, brief FROM general_turn WHERE general_id=%i AND turn_idx < %i', $generalId, $reqTurn); $turnList = $db->query('SELECT turn_idx, `action`, arg, brief FROM general_turn WHERE general_id=%i AND turn_idx < %i', $generalId, $reqTurn);
foreach($turnList as $turnItem){ foreach($turnList as $turnItem){
$turnIdx = $turnItem['turn_idx']; $turnIdx = $turnItem['turn_idx'];
$turnTarget = iterator_to_array(Util::range($turnIdx+$turnCnt, GameConst::$maxTurn, $turnCnt)); $turnTarget = iterator_to_array(Util::range($turnIdx+$turnCnt, GameConst::$maxTurn, $turnCnt));
$db->update('general_turn', [ $db->update('general_turn', [
'action'=>$turnItem['action'], 'action'=>$turnItem['action'],
'arg'=>$turnItem['arg'], 'arg'=>$turnItem['arg'],
'brief'=>$turnItem['brief'] 'brief'=>$turnItem['brief']
], 'general_id=%i AND turn_idx IN %li', $generalId, $turnTarget); ], 'general_id=%i AND turn_idx IN %li', $generalId, $turnTarget);
} }
} }
function pushNationCommand(int $nationID, int $officerLevel, int $turnCnt=1){ function pushNationCommand(int $nationID, int $officerLevel, int $turnCnt=1){
if($nationID == 0){ if($nationID == 0){
return; return;
} }
if($officerLevel < 5){ if($officerLevel < 5){
return; return;
} }
if($turnCnt == 0){ if($turnCnt == 0){
return; return;
} }
if($turnCnt < 0){ if($turnCnt < 0){
pullNationCommand($nationID, $officerLevel, -$turnCnt); pullNationCommand($nationID, $officerLevel, -$turnCnt);
return; return;
} }
if($turnCnt >= GameConst::$maxChiefTurn){ if($turnCnt >= GameConst::$maxChiefTurn){
return; return;
} }
$db = DB::db(); $db = DB::db();
$db->update('nation_turn', [ $db->update('nation_turn', [
'turn_idx'=>$db->sqleval('turn_idx + %i', $turnCnt) 'turn_idx'=>$db->sqleval('turn_idx + %i', $turnCnt)
], 'nation_id=%i AND officer_level=%i ORDER BY turn_idx DESC', $nationID, $officerLevel); ], 'nation_id=%i AND officer_level=%i ORDER BY turn_idx DESC', $nationID, $officerLevel);
$db->update('nation_turn', [ $db->update('nation_turn', [
'turn_idx'=>$db->sqleval('turn_idx - %i', GameConst::$maxChiefTurn), 'turn_idx'=>$db->sqleval('turn_idx - %i', GameConst::$maxChiefTurn),
'action'=>'휴식', 'action'=>'휴식',
'arg'=>'{}', 'arg'=>'{}',
'brief'=>'휴식' 'brief'=>'휴식'
], 'nation_id=%i AND officer_level=%i AND turn_idx >= %i ORDER BY turn_idx ASC', $nationID, $officerLevel, GameConst::$maxChiefTurn); ], 'nation_id=%i AND officer_level=%i AND turn_idx >= %i ORDER BY turn_idx ASC', $nationID, $officerLevel, GameConst::$maxChiefTurn);
} }
function pullNationCommand(int $nationID, int $officerLevel, int $turnCnt=1){ function pullNationCommand(int $nationID, int $officerLevel, int $turnCnt=1){
if($nationID == 0){ if($nationID == 0){
return; return;
} }
if($officerLevel < 5){ if($officerLevel < 5){
return; return;
} }
if($turnCnt == 0){ if($turnCnt == 0){
return; return;
} }
if($turnCnt < 0){ if($turnCnt < 0){
pushNationCommand($nationID, $officerLevel, -$turnCnt); pushNationCommand($nationID, $officerLevel, -$turnCnt);
return; return;
} }
if($turnCnt >= GameConst::$maxChiefTurn){ if($turnCnt >= GameConst::$maxChiefTurn){
return; return;
} }
$db = DB::db(); $db = DB::db();
$db->update('nation_turn', [ $db->update('nation_turn', [
'turn_idx'=>$db->sqleval('turn_idx + %i', GameConst::$maxChiefTurn), 'turn_idx'=>$db->sqleval('turn_idx + %i', GameConst::$maxChiefTurn),
'action'=>'휴식', 'action'=>'휴식',
'arg'=>'{}', 'arg'=>'{}',
'brief'=>'휴식', 'brief'=>'휴식',
], 'nation_id=%i AND officer_level=%i AND turn_idx < %i', $nationID, $officerLevel, $turnCnt); ], 'nation_id=%i AND officer_level=%i AND turn_idx < %i', $nationID, $officerLevel, $turnCnt);
$db->update('nation_turn', [ $db->update('nation_turn', [
'turn_idx'=>$db->sqleval('turn_idx - %i', $turnCnt) 'turn_idx'=>$db->sqleval('turn_idx - %i', $turnCnt)
], 'nation_id=%i AND officer_level=%i ORDER BY turn_idx ASC', $nationID, $officerLevel); ], 'nation_id=%i AND officer_level=%i ORDER BY turn_idx ASC', $nationID, $officerLevel);
} }
function _setGeneralCommand(GeneralCommand $command, array $turnList):void { function _setGeneralCommand(GeneralCommand $command, array $turnList):void {
if(!$turnList){ if(!$turnList){
return; return;
} }
$db = DB::db(); $db = DB::db();
$generalID = $command->getGeneral()->getID(); $generalID = $command->getGeneral()->getID();
$commandName = $command->getRawClassName(); $commandName = $command->getRawClassName();
$arg = $command->getArg(); $arg = $command->getArg();
$brief = $command->getBrief(); $brief = $command->getBrief();
$db->update('general_turn', [ $db->update('general_turn', [
'action'=>$commandName, 'action'=>$commandName,
'arg'=>Json::encode($arg, JSON::EMPTY_ARRAY_IS_DICT), 'arg'=>Json::encode($arg, JSON::EMPTY_ARRAY_IS_DICT),
'brief'=>$brief 'brief'=>$brief
], 'general_id = %i AND turn_idx IN %li', $generalID, $turnList); ], 'general_id = %i AND turn_idx IN %li', $generalID, $turnList);
} }
function _setNationCommand(NationCommand $command, array $turnList):void { function _setNationCommand(NationCommand $command, array $turnList):void {
if(!$turnList){ if(!$turnList){
return; return;
} }
$db = DB::db(); $db = DB::db();
$nationID = $command->getNationID(); $nationID = $command->getNationID();
$officerLevel = $command->getOfficerLevel(); $officerLevel = $command->getOfficerLevel();
$commandName = $command->getRawClassName(); $commandName = $command->getRawClassName();
$arg = $command->getArg(); $arg = $command->getArg();
$brief = $command->getBrief(); $brief = $command->getBrief();
$db->update('nation_turn', [ $db->update('nation_turn', [
'action'=>$commandName, 'action'=>$commandName,
'arg'=>Json::encode($arg, JSON::EMPTY_ARRAY_IS_DICT), 'arg'=>Json::encode($arg, JSON::EMPTY_ARRAY_IS_DICT),
'brief'=>$brief 'brief'=>$brief
], 'nation_id = %i AND officer_level = %i AND turn_idx IN %li', $nationID, $officerLevel, $turnList); ], 'nation_id = %i AND officer_level = %i AND turn_idx IN %li', $nationID, $officerLevel, $turnList);
} }
function sanitizeArg(?array $args):?array{ function sanitizeArg(?array $args):?array{
if($args === null){ if($args === null){
return $args; return $args;
} }
$result = []; $result = [];
foreach($args as $key=>$value){ foreach($args as $key=>$value){
if(is_array($value)){ if(is_array($value)){
$result[$key] = sanitizeArg($value); $result[$key] = sanitizeArg($value);
} }
else if(is_string($value)){ else if(is_string($value)){
$result[$key] = StringUtil::neutralize(StringUtil::removeSpecialCharacter($value)); $result[$key] = StringUtil::neutralize(StringUtil::removeSpecialCharacter($value));
} }
else{ else{
$result[$key] = $value; $result[$key] = $value;
} }
} }
return $result; return $result;
} }
function checkCommandArg(?array $arg):?string{ function checkCommandArg(?array $arg):?string{
if($arg === null){ if($arg === null){
return null; return null;
} }
$defaultCheck = [ $defaultCheck = [
/*'string'=>[ /*'string'=>[
'nationName', 'optionText', 'itemType', 'nationType' 'nationName', 'optionText', 'itemType', 'nationType'
],*/ ],*/
'integer'=>[ 'integer'=>[
'crewType', 'destGeneralID', 'destCityID', 'destNationID', 'crewType', 'destGeneralID', 'destCityID', 'destNationID',
'amount', 'colorType', 'amount', 'colorType',
'srcArmType', 'destArmType', //숙련전환 전용 'srcArmType', 'destArmType', //숙련전환 전용
], ],
'boolean'=>[ 'boolean'=>[
'isGold', 'buyRice', 'isGold', 'buyRice',
], ],
'between'=>[ 'between'=>[
['month', [1, 12]] ['month', [1, 12]]
], ],
'min'=>[ 'min'=>[
['year', 0], ['year', 0],
['destGeneralID', 1], ['destGeneralID', 1],
['destCityID', 1], ['destCityID', 1],
['destNationID', 1], ['destNationID', 1],
['amount', 1], ['amount', 1],
['crewType', 0] ['crewType', 0]
], ],
'integerArray'=>[ 'integerArray'=>[
'destNationIDList', 'destGeneralIDList', 'amountList' 'destNationIDList', 'destGeneralIDList', 'amountList'
], ],
'stringWidthBetween'=>[ 'stringWidthBetween'=>[
['nationName', 1, 18] ['nationName', 1, 18]
] ]
]; ];
$v = new Validator($arg); $v = new Validator($arg);
$v->rules($defaultCheck); $v->rules($defaultCheck);
if (!$v->validate()){ if (!$v->validate()){
return $v->errorStr(); return $v->errorStr();
} }
return null; return null;
} }
function setGeneralCommand(int $generalID, array $rawTurnList, string $command, ?array $arg = null):array{ function setGeneralCommand(int $generalID, array $rawTurnList, string $command, ?array $arg = null):array{
$turnList = []; $turnList = [];
foreach($rawTurnList as $turnIdx){ foreach($rawTurnList as $turnIdx){
if(!is_int($turnIdx) || $turnIdx < -3 || $turnIdx >= GameConst::$maxTurn){ if(!is_int($turnIdx) || $turnIdx < -3 || $turnIdx >= GameConst::$maxTurn){
return [ return [
'result'=>false, 'result'=>false,
'reason'=>'올바른 턴이 아닙니다. : '.$turnIdx, 'reason'=>'올바른 턴이 아닙니다. : '.$turnIdx,
'test'=>'turnIdx', 'test'=>'turnIdx',
'target'=>$turnIdx, 'target'=>$turnIdx,
]; ];
} }
if($turnIdx >= 0){ if($turnIdx >= 0){
$turnList[$turnIdx] = true; $turnList[$turnIdx] = true;
} }
else if($turnIdx == -1){ else if($turnIdx == -1){
//홀수 //홀수, 0부터 맞다.
foreach(Util::range(1, GameConst::$maxTurn, 2) as $subIdx){ foreach(Util::range(0, GameConst::$maxTurn, 2) as $subIdx){
$turnList[$subIdx] = true; $turnList[$subIdx] = true;
} }
} }
else if($turnIdx == -2){ else if($turnIdx == -2){
//짝수 //짝수, 1부터 맞다.
foreach(Util::range(0, GameConst::$maxTurn, 2) as $subIdx){ foreach(Util::range(1, GameConst::$maxTurn, 2) as $subIdx){
$turnList[$subIdx] = true; $turnList[$subIdx] = true;
} }
} }
else if($turnIdx == -3){ else if($turnIdx == -3){
//모두 //모두
foreach(Util::range(GameConst::$maxTurn) as $subIdx){ foreach(Util::range(GameConst::$maxTurn) as $subIdx){
$turnList[$subIdx] = true; $turnList[$subIdx] = true;
} }
} }
} }
$turnList = array_keys($turnList); $turnList = array_keys($turnList);
$arg = sanitizeArg($arg); $arg = sanitizeArg($arg);
$argBasicTestResult = checkCommandArg($arg); $argBasicTestResult = checkCommandArg($arg);
if($argBasicTestResult !== null){ if($argBasicTestResult !== null){
return [ return [
'result'=>false, 'result'=>false,
'reason'=>'턴이 입력되지 않았습니다.', 'reason'=>'턴이 입력되지 않았습니다.',
'test'=>'checkCommandArg', 'test'=>'checkCommandArg',
'target'=>'arg' 'target'=>'arg'
]; ];
} }
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
$env = $gameStor->getAll(); $env = $gameStor->getAll();
$general = General::createGeneralObjFromDB($generalID); $general = General::createGeneralObjFromDB($generalID);
try{ try{
$commandObj = buildGeneralCommandClass($command, $general, $env, $arg); $commandObj = buildGeneralCommandClass($command, $general, $env, $arg);
} }
catch (\InvalidArgumentException $e){ catch (\InvalidArgumentException $e){
return [ return [
'result'=>false, 'result'=>false,
'reason'=>$e->getMessage(), 'reason'=>$e->getMessage(),
'test'=>'build', 'test'=>'build',
'target'=>'arg' 'target'=>'arg'
]; ];
} }
catch (\Exception $e){ catch (\Exception $e){
return [ return [
'result'=>false, 'result'=>false,
'reason'=>$e->getCode().$e->getMessage(), 'reason'=>$e->getCode().$e->getMessage(),
'test'=>'build', 'test'=>'build',
'target'=>'arg' 'target'=>'arg'
]; ];
} }
if(!$commandObj->isArgValid()){ if(!$commandObj->isArgValid()){
return [ return [
'result'=>false, 'result'=>false,
'reason'=>'올바르지 않은 argument', 'reason'=>'올바르지 않은 argument',
'test'=>'isArgValid', 'test'=>'isArgValid',
'target'=>'arg' 'target'=>'arg'
]; ];
} }
if(!$commandObj->hasPermissionToReserve()){ if(!$commandObj->hasPermissionToReserve()){
return [ return [
'result'=>false, 'result'=>false,
'reason'=>'예약 불가능한 커맨드 :'.$commandObj->testPermissionToReserve(), 'reason'=>'예약 불가능한 커맨드 :'.$commandObj->testPermissionToReserve(),
'test'=>'hasPermissionToReserve', 'test'=>'hasPermissionToReserve',
'target'=>'command' 'target'=>'command'
]; ];
} }
_setGeneralCommand($commandObj, $turnList); _setGeneralCommand($commandObj, $turnList);
return [ return [
'result'=>true, 'result'=>true,
'reason'=>'success' 'reason'=>'success'
]; ];
} }
function setNationCommand(int $generalID, array $turnList, string $command, ?array $arg = null):array{ function setNationCommand(int $generalID, array $turnList, string $command, ?array $arg = null):array{
$turnList = array_unique($turnList); $turnList = array_unique($turnList);
foreach($turnList as $turnIdx){ foreach($turnList as $turnIdx){
if(!is_int($turnIdx) || $turnIdx < 0 || $turnIdx >= GameConst::$maxChiefTurn){ if(!is_int($turnIdx) || $turnIdx < 0 || $turnIdx >= GameConst::$maxChiefTurn){
return [ return [
'result'=>false, 'result'=>false,
'reason'=>'올바른 턴이 아닙니다. : '.$turnIdx, 'reason'=>'올바른 턴이 아닙니다. : '.$turnIdx,
'test'=>'turnIdx', 'test'=>'turnIdx',
'target'=>$turnIdx, 'target'=>$turnIdx,
]; ];
} }
} }
$arg = sanitizeArg($arg); $arg = sanitizeArg($arg);
$argBasicTestResult = checkCommandArg($arg); $argBasicTestResult = checkCommandArg($arg);
if($argBasicTestResult !== null){ if($argBasicTestResult !== null){
return [ return [
'result'=>false, 'result'=>false,
'reason'=>'턴이 입력되지 않았습니다.', 'reason'=>'턴이 입력되지 않았습니다.',
'test'=>'checkCommandArg', 'test'=>'checkCommandArg',
'target'=>'arg' 'target'=>'arg'
]; ];
} }
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
$env = $gameStor->getAll(); $env = $gameStor->getAll();
$general = General::createGeneralObjFromDB($generalID); $general = General::createGeneralObjFromDB($generalID);
if($general->getVar('officer_level') < 5){ if($general->getVar('officer_level') < 5){
return [ return [
'result'=>false, 'result'=>false,
'reason'=>'수뇌가 아닙니다' 'reason'=>'수뇌가 아닙니다'
]; ];
} }
try{ try{
$commandObj = buildNationCommandClass($command, $general, $env, $general->getLastTurn(), $arg); $commandObj = buildNationCommandClass($command, $general, $env, $general->getLastTurn(), $arg);
} }
catch (\InvalidArgumentException $e){ catch (\InvalidArgumentException $e){
return [ return [
'result'=>false, 'result'=>false,
'reason'=>$e->getMessage(), 'reason'=>$e->getMessage(),
'test'=>'build', 'test'=>'build',
'target'=>'arg' 'target'=>'arg'
]; ];
} }
catch (\Exception $e){ catch (\Exception $e){
return [ return [
'result'=>false, 'result'=>false,
'reason'=>$e->getCode().$e->getMessage(), 'reason'=>$e->getCode().$e->getMessage(),
'test'=>'build', 'test'=>'build',
'target'=>'arg' 'target'=>'arg'
]; ];
} }
if(!$commandObj->isArgValid()){ if(!$commandObj->isArgValid()){
return [ return [
'result'=>false, 'result'=>false,
'reason'=>'올바르지 않은 argument', 'reason'=>'올바르지 않은 argument',
'test'=>'isArgValid', 'test'=>'isArgValid',
'target'=>'arg' 'target'=>'arg'
]; ];
} }
if(!$commandObj->hasPermissionToReserve()){ if(!$commandObj->hasPermissionToReserve()){
return [ return [
'result'=>false, 'result'=>false,
'reason'=>'예약 불가능한 커맨드 :'.$commandObj->testPermissionToReserve(), 'reason'=>'예약 불가능한 커맨드 :'.$commandObj->testPermissionToReserve(),
'test'=>'hasPermissionToReserve', 'test'=>'hasPermissionToReserve',
'target'=>'command' 'target'=>'command'
]; ];
} }
_setNationCommand($commandObj, $turnList); _setNationCommand($commandObj, $turnList);
return [ return [
'result'=>true, 'result'=>true,
'arg_test'=>true, 'arg_test'=>true,
'reason'=>'success' 'reason'=>'success'
]; ];
} }