false, 'reason'=>'장수를 선택하지 않았습니다' ]); } $session = Session::requireLogin([])->setReadOnly(); $userID = Session::getUserID(); $db = DB::db(); $gameStor = KVStorage::getStorage($db, 'game_env'); $rootDB = RootDB::db(); $oNow = new \DateTimeImmutable(); $now = $oNow->format('Y-m-d H:i:s'); $hasGeneralID = $db->queryFirstField('SELECT no FROM general WHERE owner = %i', $userID); if($hasGeneralID){ Json::die([ 'result'=>false, 'reason'=>'이미 장수를 생성했습니다.' ]); } $env = $gameStor->getValues(['startyear', 'year', 'month', 'maxgeneral', 'npcmode', 'show_img_level', 'icon_path', 'turnterm', 'turntime']); $env['fiction'] = false; $npcmode = $env['npcmode']; $maxgeneral = $env['maxgeneral']; if($npcmode!=2){ Json::die([ 'result'=>false, 'reason'=>'선택 가능한 서버가 아닙니다' ]); } $selectInfo = $db->queryFirstField('SELECT info FROM select_pool WHERE `owner` = %i AND `reserved_until`>=%s AND `unique_name`=%s', $userID, $now, $pick); if(!$selectInfo){ Json::die([ 'result'=>false, 'reason'=>'유효한 장수 목록이 없습니다.' ]); } $selectInfo = Json::decode($selectInfo); $ownerInfo = RootDB::db()->queryFirstRow( 'SELECT `name`,`picture`,`imgsvr`,`grade` FROM member WHERE `NO`=%i', $userID ); if(!$ownerInfo){ Json::die([ 'result'=>false, 'reason'=>'멤버 정보를 가져오지 못했습니다.' ]); } if ($isCentennialAllStar) { if (!in_array($pictureSource, ['selected', 'own'], true)) { Json::die([ 'result' => false, 'reason' => '올바르지 않은 전콘 선택입니다.', ]); } if ($pictureSource === 'own') { $canUseOwnPicture = in_array('picture', GameConst::$generalPoolAllowOption, true) && $env['show_img_level'] >= 1 && $ownerInfo['grade'] >= 1 && $ownerInfo['picture'] !== ''; if (!$canUseOwnPicture) { Json::die([ 'result' => false, 'reason' => '사용할 수 있는 내 전콘이 없습니다.', ]); } } } $gencount = $db->queryFirstField('SELECT count(`no`) FROM general WHERE npc<2'); if ($gencount >= $maxgeneral) { Json::die([ 'result'=>false, 'reason'=>'더 이상 등록 할 수 없습니다.' ]); } $poolClass = getGeneralPoolClass(GameConst::$targetGeneralPool); /** @var AbsGeneralPool */ if ($isCentennialAllStar) { $rng = new RandUtil(new LiteHashDRBG(Util::simpleSerialize( UniqueConst::$hiddenSeed, 'selectPickedGeneral', $userID, $pick ))); $pickedGeneral = new $poolClass($db, $rng, $selectInfo, $now); } else { $pickedGeneral = new $poolClass($db, $selectInfo, $now); } $builder = $pickedGeneral->getGeneralBuilder(); if ($isCentennialAllStar) { CentennialAllStarGrowthService::prepareInitialUser($builder, $selectInfo); } foreach(GameConst::$generalPoolAllowOption as $allowOption){ if($allowOption == 'stat' && !$isCentennialAllStar){ $leadership = Util::valueFit($leadership, GameConst::$defaultStatMin, GameConst::$defaultStatMax); $strength = Util::valueFit($strength, GameConst::$defaultStatMin, GameConst::$defaultStatMax); $intel = Util::valueFit($intel, GameConst::$defaultStatMin, GameConst::$defaultStatMax); if($leadership + $strength + $intel > GameConst::$defaultStatTotal){ Json::die([ 'result'=>false, 'reason'=>'스탯의 총 합이 올바르지 않습니다.' ]); } $builder->setStat($leadership, $strength, $intel); } else if( $allowOption == 'picture' && ( (!$isCentennialAllStar && $use_own_picture) || ($isCentennialAllStar && $pictureSource === 'own') ) ){ $builder->setPicture($ownerInfo['imgsvr'], $ownerInfo['picture']); } else if($allowOption == 'ego'){ if(!$personal || $personal == 'Random'){ $personal = Util::choiceRandom(GameConst::$availablePersonality); } $invalidPersonal = $isCentennialAllStar ? !in_array($personal, GameConst::$availablePersonality, true) : !array_search($personal, GameConst::$availablePersonality); if($invalidPersonal){ Json::die([ 'result'=>false, 'reason'=>'올바르지 않은 성격입니다.' ]); } $builder->setEgo($personal); } } $userNick = $ownerInfo['name']; $builder->setOwner($userID); $builder->setOwnerName($userNick); $builder->setKillturn(5); $builder->setNPCType(0); $builder->setAuxVar('next_change', TimeUtil::nowAddMinutes(12 * $env['turnterm'])); $builder->fillRemainSpecAsZero($env); if ($isCentennialAllStar) { $candidateCities = $db->queryFirstColumn( 'SELECT city FROM city WHERE level >= 5 AND level <= 6 AND nation = 0' ); if (!$candidateCities) { $candidateCities = $db->queryFirstColumn( 'SELECT city FROM city WHERE level >= 5 AND level <= 6' ); } if (!$candidateCities) { Json::die([ 'result' => false, 'reason' => '장수를 생성할 소·중성이 없습니다.', ]); } $builder->setCityID($rng->choice($candidateCities)); } $builder->build($env); $generalID = $builder->getGeneralID(); if(!$generalID){ Json::die([ 'result'=>false, 'reason'=>'장수 등록에 실패했습니다.' ]); } $pickedGeneral->occupyGeneralName(); $db->update('select_pool',[ 'owner'=>null, 'reserved_until'=>null, ], '(owner=%i or reserved_until < %s) AND general_id is NULL', $userID, $now); $josaYi = JosaUtil::pick($userNick, '이'); $generalName = $builder->getGeneralName(); $josaRo = JosaUtil::pick($generalName, '로'); $cityName = CityConst::byID($builder->getCityID())->name; $logger = new ActionLogger($generalID, 0, $env['year'], $env['month']); $logger->pushGeneralHistoryLog("{$generalName}, {$cityName}에서 등장"); $logger->pushGlobalActionLog("{$cityName}에서 {$userNick}{$josaYi} {$generalName}{$josaRo} 등장합니다."); $logger->flush(); pushAdminLog(["가입 : {$userID} // {$session->userName} // {$pick} // ".getenv("REMOTE_ADDR")]); $rootDB->insert('member_log', [ 'member_no' => $userID, 'date'=>TimeUtil::now(), 'action_type'=>'make_general', 'action'=>Json::encode([ 'server'=>DB::prefix(), 'type'=>'select', 'generalID'=>$generalID, 'generalName'=>$generalName ]) ]); Json::die([ 'result'=>true, 'reason'=>'success' ]);