커맨드 유효성을 2개에서 3개구성으로 변경

This commit is contained in:
2020-05-04 19:51:11 +09:00
parent dbba6fa942
commit 76ac6cf5b5
100 changed files with 4124 additions and 3420 deletions
+57 -51
View File
@@ -1,55 +1,56 @@
<?php <?php
namespace sammo; namespace sammo;
define('ROOT', realpath(__DIR__.'/..')); define('ROOT', realpath(__DIR__ . '/..'));
setlocale(LC_ALL, 'ko_KR.UTF-8'); setlocale(LC_ALL, 'ko_KR.UTF-8');
date_default_timezone_set('Asia/Seoul'); date_default_timezone_set('Asia/Seoul');
mb_internal_encoding("UTF-8"); mb_internal_encoding("UTF-8");
mb_http_output('UTF-8'); mb_http_output('UTF-8');
mb_regex_encoding('UTF-8'); mb_regex_encoding('UTF-8');
ini_set("session.cache_expire", '10080'); // minutes ini_set("session.cache_expire", '10080'); // minutes
ini_set("session.gc_maxlifetime", '604800'); // seconds ini_set("session.gc_maxlifetime", '604800'); // seconds
function getFriendlyErrorType($type) function getFriendlyErrorType($type)
{ {
switch($type) switch ($type) {
{
case E_ERROR: // 1 // case E_ERROR: // 1 //
return 'E_ERROR'; return 'E_ERROR';
case E_WARNING: // 2 // case E_WARNING: // 2 //
return 'E_WARNING'; return 'E_WARNING';
case E_PARSE: // 4 // case E_PARSE: // 4 //
return 'E_PARSE'; return 'E_PARSE';
case E_NOTICE: // 8 // case E_NOTICE: // 8 //
return 'E_NOTICE'; return 'E_NOTICE';
case E_CORE_ERROR: // 16 // case E_CORE_ERROR: // 16 //
return 'E_CORE_ERROR'; return 'E_CORE_ERROR';
case E_CORE_WARNING: // 32 // case E_CORE_WARNING: // 32 //
return 'E_CORE_WARNING'; return 'E_CORE_WARNING';
case E_COMPILE_ERROR: // 64 // case E_COMPILE_ERROR: // 64 //
return 'E_COMPILE_ERROR'; return 'E_COMPILE_ERROR';
case E_COMPILE_WARNING: // 128 // case E_COMPILE_WARNING: // 128 //
return 'E_COMPILE_WARNING'; return 'E_COMPILE_WARNING';
case E_USER_ERROR: // 256 // case E_USER_ERROR: // 256 //
return 'E_USER_ERROR'; return 'E_USER_ERROR';
case E_USER_WARNING: // 512 // case E_USER_WARNING: // 512 //
return 'E_USER_WARNING'; return 'E_USER_WARNING';
case E_USER_NOTICE: // 1024 // case E_USER_NOTICE: // 1024 //
return 'E_USER_NOTICE'; return 'E_USER_NOTICE';
case E_STRICT: // 2048 // case E_STRICT: // 2048 //
return 'E_STRICT'; return 'E_STRICT';
case E_RECOVERABLE_ERROR: // 4096 // case E_RECOVERABLE_ERROR: // 4096 //
return 'E_RECOVERABLE_ERROR'; return 'E_RECOVERABLE_ERROR';
case E_DEPRECATED: // 8192 // case E_DEPRECATED: // 8192 //
return 'E_DEPRECATED'; return 'E_DEPRECATED';
case E_USER_DEPRECATED: // 16384 // case E_USER_DEPRECATED: // 16384 //
return 'E_USER_DEPRECATED'; return 'E_USER_DEPRECATED';
} }
return "{$type}"; return "{$type}";
} }
function getExceptionTraceAsString($exception) { function getExceptionTraceAsString($exception)
{
//https://gist.github.com/abtris/1437966 //https://gist.github.com/abtris/1437966
$rtn = ""; $rtn = "";
$count = 0; $count = 0;
@@ -73,75 +74,80 @@ function getExceptionTraceAsString($exception) {
$args[] = get_resource_type($arg); $args[] = get_resource_type($arg);
} else { } else {
$args[] = $arg; $args[] = $arg;
} }
} }
$args = join(", ", $args); $args = join(", ", $args);
} }
$rtn[] = sprintf( "#%s %s:%s %s(%s)", $rtn[] = sprintf(
$count, "#%s %s:%s %s(%s)",
isset($frame['file']) ? $frame['file'] : 'unknown file', $count,
isset($frame['line']) ? $frame['line'] : 'unknown line', isset($frame['file']) ? $frame['file'] : 'unknown file',
(isset($frame['class'])) ? $frame['class'].$frame['type'].$frame['function'] : $frame['function'], isset($frame['line']) ? $frame['line'] : 'unknown line',
$args ); (isset($frame['class'])) ? $frame['class'] . $frame['type'] . $frame['function'] : $frame['function'],
$args
);
$count++; $count++;
} }
return $rtn; return $rtn;
} }
function logError(string $err, string $errstr, string $errpath, array $trace){ function logError(string $err, string $errstr, string $errpath, array $trace)
$fdb = FileDB::db(ROOT.'/d_log/err_log.sqlite3', ROOT.'/f_install/sql/err_log.sql'); {
$fdb = FileDB::db(ROOT . '/d_log/err_log.sqlite3', ROOT . '/f_install/sql/err_log.sql');
$date = date("Ymd_His"); $date = date("Ymd_His");
$errpath = str_replace(ROOT, '{ROOT}', $errpath); $errpath = str_replace(ROOT, '{ROOT}', $errpath);
$trace = array_map(function(string $text){ $trace = array_map(function (string $text) {
return str_replace(ROOT, '{ROOT}', $text); return str_replace(ROOT, '{ROOT}', $text);
}, $trace); }, $trace);
$owner = Util::get_client_ip(); $owner = Util::get_client_ip();
$session = Session::getInstance(); $session = Session::getInstance();
if($session->isLoggedIn(true)){ if ($session->isLoggedIn(true)) {
$owner .= '('.$session->getUserID().','.$session->userName.')'; $owner .= '(' . $session->getUserID() . ',' . $session->userName . ')';
} }
$fdb->insert('err_log', [ $fdb->insert('err_log', [
'date'=>$date, 'date' => $date,
'err'=>$err, 'err' => $err,
'errstr'=>$errstr, 'errstr' => $errstr,
'errpath'=>$errpath, 'errpath' => $errpath,
'trace'=>Json::encode($trace), 'trace' => Json::encode($trace),
'webuser'=>$owner 'webuser' => $owner
]); ]);
} }
function logErrorByCustomHandler(int $errno, string $errstr, string $errfile, int $errline, array $errcontext){ function logErrorByCustomHandler(int $errno, string $errstr, string $errfile, int $errline, array $errcontext)
{
if (!(error_reporting() & $errno)) { if (!(error_reporting() & $errno)) {
// This error code is not included in error_reporting, so let it fall // This error code is not included in error_reporting, so let it fall
// through to the standard PHP error handler // through to the standard PHP error handler
return false; return false;
} }
$e = new \Exception(); $e = new \Exception();
logError( logError(
getFriendlyErrorType($errno), getFriendlyErrorType($errno),
$errstr, $errstr,
$errfile.':'.$errline, $errfile . ':' . $errline,
getExceptionTraceAsString($e) getExceptionTraceAsString($e)
); );
} }
set_error_handler("\sammo\logErrorByCustomHandler"); set_error_handler("\sammo\logErrorByCustomHandler");
function logExceptionByCustomHandler(\Throwable $e){ function logExceptionByCustomHandler(\Throwable $e)
{
logError( logError(
get_class($e), get_class($e),
$e->getMessage(), $e->getMessage(),
$e->getFile().':'.$e->getLine(), $e->getFile() . ':' . $e->getLine(),
getExceptionTraceAsString($e) getExceptionTraceAsString($e)
); );
echo $e->getTraceAsString(); echo $e->getTraceAsString();
throw $e; throw $e;
} }
set_exception_handler('\\sammo\\logExceptionByCustomHandler'); set_exception_handler('\\sammo\\logExceptionByCustomHandler');
+30 -29
View File
@@ -1,7 +1,8 @@
<?php <?php
namespace sammo; namespace sammo;
require(__DIR__.'/../vendor/autoload.php'); require(__DIR__ . '/../vendor/autoload.php');
session_start(); session_start();
session_destroy(); session_destroy();
@@ -10,24 +11,24 @@ $username = mb_strtolower(Util::getReq('username'), 'utf-8');
$password = Util::getReq('password', 'string'); $password = Util::getReq('password', 'string');
$nickname = Util::getReq('nickname'); $nickname = Util::getReq('nickname');
if(!$username || !$password || !$nickname){ if (!$username || !$password || !$nickname) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>'입력값이 설정되지 않았습니다.' 'reason' => '입력값이 설정되지 않았습니다.'
]); ]);
} }
if(strlen((string)$password)!=128){ if (strlen((string) $password) != 128) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>'올바르지 않은 비밀번호 해시 포맷입니다.' 'reason' => '올바르지 않은 비밀번호 해시 포맷입니다.'
]); ]);
} }
if(!class_exists('\\sammo\\RootDB')){ if (!class_exists('\\sammo\\RootDB')) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>'DB 설정이 완료되지 않았습니다.' 'reason' => 'DB 설정이 완료되지 않았습니다.'
]); ]);
} }
@@ -37,10 +38,10 @@ $rootDB = RootDB::db();
$rootDB->query('LOCK TABLES member WRITE, member_log WRITE'); $rootDB->query('LOCK TABLES member WRITE, member_log WRITE');
$memberCnt = $rootDB->queryFirstField('SELECT count(`NO`) from member'); $memberCnt = $rootDB->queryFirstField('SELECT count(`NO`) from member');
if($memberCnt > 0){ if ($memberCnt > 0) {
Json::die([ Json::die([
'result'=>'false', 'result' => 'false',
'reason'=>'이미 계정이 생성되어 있습니다' 'reason' => '이미 계정이 생성되어 있습니다'
]); ]);
} }
@@ -48,32 +49,32 @@ $userSalt = bin2hex(random_bytes(8));
$finalPassword = Util::hashPassword($userSalt, $password); $finalPassword = Util::hashPassword($userSalt, $password);
$nowDate = TimeUtil::now(); $nowDate = TimeUtil::now();
$rootDB->insert('member',[ $rootDB->insert('member', [
'oauth_type' => 'NONE', 'oauth_type' => 'NONE',
'id' => $username, 'id' => $username,
'email' => null, 'email' => null,
'token_valid_until'=>'2999-01-01 00:00:00', 'token_valid_until' => '2999-01-01 00:00:00',
'pw' => $finalPassword, 'pw' => $finalPassword,
'salt' => $userSalt, 'salt' => $userSalt,
'grade'=> 6, 'grade' => 6,
'name'=>$nickname, 'name' => $nickname,
'reg_date'=>$nowDate 'reg_date' => $nowDate
]); ]);
$userID = $rootDB->insertId(); $userID = $rootDB->insertId();
$rootDB->insert('member_log', [ $rootDB->insert('member_log', [
'member_no'=>$userID, 'member_no' => $userID,
'date'=>$nowDate, 'date' => $nowDate,
'action_type'=>'reg', 'action_type' => 'reg',
'action'=>Json::encode([ 'action' => Json::encode([
'type'=>'none', 'type' => 'none',
'aux'=>'admin', 'aux' => 'admin',
'id'=>$username, 'id' => $username,
'name'=>$nickname 'name' => $nickname
]) ])
]); ]);
Json::die([ Json::die([
'result'=>true, 'result' => true,
'reason'=>'success' 'reason' => 'success'
]); ]);
+13 -12
View File
@@ -1,38 +1,39 @@
<?php <?php
namespace sammo; namespace sammo;
require(__DIR__.'/../vendor/autoload.php'); require(__DIR__ . '/../vendor/autoload.php');
if(!class_exists('\\sammo\\RootDB')){ if (!class_exists('\\sammo\\RootDB')) {
Json::die([ Json::die([
'step'=>'config' 'step' => 'config'
]); ]);
} }
$rootDB = RootDB::db(); $rootDB = RootDB::db();
$rootDB->throw_exception_on_nonsql_error = false; $rootDB->throw_exception_on_nonsql_error = false;
$rootDB->nonsql_error_handler = function($params){ $rootDB->nonsql_error_handler = function ($params) {
Json::die([ Json::die([
'step'=>'conn_fail' 'step' => 'conn_fail'
]); ]);
}; };
$rootDB->error_handler = function($params){ $rootDB->error_handler = function ($params) {
Json::die([ Json::die([
'step'=>'sql_fail' 'step' => 'sql_fail'
]); ]);
}; };
$memberCnt = $rootDB->queryFirstField('SELECT count(`NO`) from member'); $memberCnt = $rootDB->queryFirstField('SELECT count(`NO`) from member');
if($memberCnt == 0){ if ($memberCnt == 0) {
Json::die([ Json::die([
'step'=>'admin', 'step' => 'admin',
'globalSalt'=>RootDB::getGlobalSalt() 'globalSalt' => RootDB::getGlobalSalt()
]); ]);
} }
Json::die([ Json::die([
'step'=>'done' 'step' => 'done'
]); ]);
+102 -100
View File
@@ -1,7 +1,8 @@
<?php <?php
namespace sammo; namespace sammo;
require(__DIR__.'/../vendor/autoload.php'); require(__DIR__ . '/../vendor/autoload.php');
$host = Util::getReq('db_host'); $host = Util::getReq('db_host');
$port = Util::getReq('db_port', 'int'); $port = Util::getReq('db_port', 'int');
@@ -19,70 +20,71 @@ $kakaoAdminKey = Util::getReq('kakao_admin_key', 'string', '');
if (!$host || !$port || !$username || !$password || !$dbName || !$servHost || !$sharedIconPath || !$gameImagePath) { if (!$host || !$port || !$username || !$password || !$dbName || !$servHost || !$sharedIconPath || !$gameImagePath) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>'입력 값이 올바르지 않습니다' 'reason' => '입력 값이 올바르지 않습니다'
]); ]);
} }
if (!filter_var($servHost, FILTER_VALIDATE_URL)) { if (!filter_var($servHost, FILTER_VALIDATE_URL)) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>'접속 경로가 올바르지 않습니다.' 'reason' => '접속 경로가 올바르지 않습니다.'
]); ]);
} }
if (file_exists(ROOT.'/d_setting/RootDB.php') && is_dir(ROOT.'/d_setting/RootDB.php')) { if (file_exists(ROOT . '/d_setting/RootDB.php') && is_dir(ROOT . '/d_setting/RootDB.php')) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>'d_setting/RootDB.php 가 디렉토리입니다' 'reason' => 'd_setting/RootDB.php 가 디렉토리입니다'
]); ]);
} }
if (class_exists('\\sammo\\RootDB')) { if (class_exists('\\sammo\\RootDB')) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>'이미 RootDB.php 파일이 있습니다' 'reason' => '이미 RootDB.php 파일이 있습니다'
]); ]);
} }
//파일 권한 검사 //파일 권한 검사
if (file_exists(AppConf::getUserIconPathFS()) && !is_dir(AppConf::getUserIconPathFS())) { if (file_exists(AppConf::getUserIconPathFS()) && !is_dir(AppConf::getUserIconPathFS())) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>AppConf::$userIconPath.' 이 디렉토리가 아닙니다' 'reason' => AppConf::$userIconPath . ' 이 디렉토리가 아닙니다'
]); ]);
} }
if (file_exists(ROOT.'/d_log') && !is_dir(ROOT.'/d_log')) { if (file_exists(ROOT . '/d_log') && !is_dir(ROOT . '/d_log')) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>'d_log 가 디렉토리가 아닙니다' 'reason' => 'd_log 가 디렉토리가 아닙니다'
]); ]);
} }
if (file_exists(ROOT.'/d_shared') && !is_dir(ROOT.'/d_shared')) { if (file_exists(ROOT . '/d_shared') && !is_dir(ROOT . '/d_shared')) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>'d_shared 가 디렉토리가 아닙니다' 'reason' => 'd_shared 가 디렉토리가 아닙니다'
]); ]);
} }
if (file_exists(ROOT.'/d_setting') && !is_dir(ROOT.'/d_setting')) { if (file_exists(ROOT . '/d_setting') && !is_dir(ROOT . '/d_setting')) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>'d_shared 가 디렉토리가 아닙니다' 'reason' => 'd_shared 가 디렉토리가 아닙니다'
]); ]);
} }
if (!file_exists(ROOT.'/d_log') if (
|| !file_exists(ROOT.'/d_shared') !file_exists(ROOT . '/d_log')
|| !file_exists(ROOT.'/d_setting') || !file_exists(ROOT . '/d_shared')
|| !file_exists(ROOT . '/d_setting')
|| !file_exists(AppConf::getUserIconPathFS()) || !file_exists(AppConf::getUserIconPathFS())
) { ) {
if (!is_writable(ROOT)) { if (!is_writable(ROOT)) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>'하위 디렉토리 생성 권한이 없습니다' 'reason' => '하위 디렉토리 생성 권한이 없습니다'
]); ]);
} }
@@ -91,56 +93,56 @@ if (!file_exists(ROOT.'/d_log')
mkdir(AppConf::getUserIconPathFS()); mkdir(AppConf::getUserIconPathFS());
} }
if (!file_exists(ROOT.'/d_log')) { if (!file_exists(ROOT . '/d_log')) {
mkdir(ROOT.'/d_log'); mkdir(ROOT . '/d_log');
} }
if (!file_exists(ROOT.'/d_setting')) { if (!file_exists(ROOT . '/d_setting')) {
mkdir(ROOT.'/d_setting'); mkdir(ROOT . '/d_setting');
} }
if (!file_exists(ROOT.'/d_shared')) { if (!file_exists(ROOT . '/d_shared')) {
mkdir(ROOT.'/d_shared'); mkdir(ROOT . '/d_shared');
} }
} }
if (!is_writable(AppConf::getUserIconPathFS())) { if (!is_writable(AppConf::getUserIconPathFS())) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>AppConf::$userIconPath.' 디렉토리의 쓰기 권한이 없습니다' 'reason' => AppConf::$userIconPath . ' 디렉토리의 쓰기 권한이 없습니다'
]); ]);
} }
if (!is_writable(ROOT.'/d_log')) { if (!is_writable(ROOT . '/d_log')) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>'d_log 디렉토리의 쓰기 권한이 없습니다' 'reason' => 'd_log 디렉토리의 쓰기 권한이 없습니다'
]); ]);
} }
if (!is_writable(ROOT.'/d_shared')) { if (!is_writable(ROOT . '/d_shared')) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>'d_shared 디렉토리의 쓰기 권한이 없습니다' 'reason' => 'd_shared 디렉토리의 쓰기 권한이 없습니다'
]); ]);
} }
if (!is_writable(ROOT.'/d_setting')) { if (!is_writable(ROOT . '/d_setting')) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>'d_setting 디렉토리의 쓰기 권한이 없습니다.' 'reason' => 'd_setting 디렉토리의 쓰기 권한이 없습니다.'
]); ]);
} }
if (!file_exists(ROOT.'/d_log/.htaccess')) { if (!file_exists(ROOT . '/d_log/.htaccess')) {
@file_put_contents(ROOT.'/d_log/.htaccess', 'Deny from all'); @file_put_contents(ROOT . '/d_log/.htaccess', 'Deny from all');
} }
if (!file_exists(ROOT.'/d_setting/.htaccess')) { if (!file_exists(ROOT . '/d_setting/.htaccess')) {
@file_put_contents(ROOT.'/d_setting/.htaccess', 'Deny from all'); @file_put_contents(ROOT . '/d_setting/.htaccess', 'Deny from all');
} }
//DB 접근 권한 검사 //DB 접근 권한 검사
@@ -151,21 +153,21 @@ $rootDB->connect_options[MYSQLI_OPT_INT_AND_FLOAT_NATIVE] = true;
$rootDB->throw_exception_on_nonsql_error = false; $rootDB->throw_exception_on_nonsql_error = false;
$rootDB->nonsql_error_handler = function ($params) { $rootDB->nonsql_error_handler = function ($params) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>'DB 접속에 실패했습니다.' 'reason' => 'DB 접속에 실패했습니다.'
]); ]);
}; };
$rootDB->error_handler = function ($params) { $rootDB->error_handler = function ($params) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>'SQL을 제대로 실행하지 못했습니다. DB상태를 확인해 주세요.' 'reason' => 'SQL을 제대로 실행하지 못했습니다. DB상태를 확인해 주세요.'
]); ]);
}; };
$mysqli_obj = $rootDB->get(); //로그인에 실패할 경우 자동으로 dbConnFail()이 실행됨. $mysqli_obj = $rootDB->get(); //로그인에 실패할 경우 자동으로 dbConnFail()이 실행됨.
if ($mysqli_obj->multi_query(file_get_contents(__DIR__.'/sql/common_schema.sql'))) { if ($mysqli_obj->multi_query(file_get_contents(__DIR__ . '/sql/common_schema.sql'))) {
while (true) { while (true) {
if (!$mysqli_obj->more_results()) { if (!$mysqli_obj->more_results()) {
break; break;
@@ -191,113 +193,113 @@ $globalSalt = bin2hex(random_bytes(16));
$sharedIconPath = WebUtil::resolveRelativePath($sharedIconPath, $servHost); $sharedIconPath = WebUtil::resolveRelativePath($sharedIconPath, $servHost);
$gameImagePath = WebUtil::resolveRelativePath($gameImagePath, $servHost); $gameImagePath = WebUtil::resolveRelativePath($gameImagePath, $servHost);
$imageRequestPath = WebUtil::resolveRelativePath($gameImagePath.'/../hook/git_pull.php', $servHost); $imageRequestPath = WebUtil::resolveRelativePath($gameImagePath . '/../hook/git_pull.php', $servHost);
$imageKeyInstallPath = WebUtil::resolveRelativePath($gameImagePath.'/../hook/InstallKey.php', $servHost); $imageKeyInstallPath = WebUtil::resolveRelativePath($gameImagePath . '/../hook/InstallKey.php', $servHost);
$result = Util::generateFileUsingSimpleTemplate( $result = Util::generateFileUsingSimpleTemplate(
__DIR__.'/templates/ServConfig.orig.php', __DIR__ . '/templates/ServConfig.orig.php',
ROOT.'/d_setting/ServConfig.php', ROOT . '/d_setting/ServConfig.php',
[ [
'serverBasePath'=>$servHost, 'serverBasePath' => $servHost,
'sharedIconPath'=>$sharedIconPath, 'sharedIconPath' => $sharedIconPath,
'gameImagePath'=>$gameImagePath, 'gameImagePath' => $gameImagePath,
'imageRequestPath'=>$imageRequestPath, 'imageRequestPath' => $imageRequestPath,
'imageRequestKey'=>$imageRequestKey 'imageRequestKey' => $imageRequestKey
], ],
true true
); );
if($imageRequestKey){ if ($imageRequestKey) {
@file_get_contents($imageKeyInstallPath.'?key='.$imageRequestKey); @file_get_contents($imageKeyInstallPath . '?key=' . $imageRequestKey);
} }
if ($result !== true) { if ($result !== true) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>$result 'reason' => $result
]); ]);
} }
$result = Util::generateFileUsingSimpleTemplate( $result = Util::generateFileUsingSimpleTemplate(
__DIR__.'/templates/common_path.orig.js', __DIR__ . '/templates/common_path.orig.js',
ROOT.'/d_shared/common_path.js', ROOT . '/d_shared/common_path.js',
[ [
'serverBasePath'=>$servHost, 'serverBasePath' => $servHost,
'sharedIconPath'=>$sharedIconPath, 'sharedIconPath' => $sharedIconPath,
'gameImagePath'=>$gameImagePath 'gameImagePath' => $gameImagePath
], ],
true true
); );
$result = Util::generateFileUsingSimpleTemplate( $result = Util::generateFileUsingSimpleTemplate(
__DIR__.'/templates/menu.orig.json', __DIR__ . '/templates/menu.orig.json',
ROOT.'/d_shared/menu.json', ROOT . '/d_shared/menu.json',
[], [],
true true
); );
if ($result !== true) { if ($result !== true) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>$result 'reason' => $result
]); ]);
} }
$result = Util::generateFileUsingSimpleTemplate( $result = Util::generateFileUsingSimpleTemplate(
__DIR__.'/templates/common.orig.css', __DIR__ . '/templates/common.orig.css',
ROOT.'/d_shared/common.css', ROOT . '/d_shared/common.css',
[ [
'serverBasePath'=>$servHost, 'serverBasePath' => $servHost,
'sharedIconPath'=>$sharedIconPath, 'sharedIconPath' => $sharedIconPath,
'gameImagePath'=>$gameImagePath 'gameImagePath' => $gameImagePath
], ],
true true
); );
if ($result !== true) { if ($result !== true) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>$result 'reason' => $result
]); ]);
} }
$result = Util::generateFileUsingSimpleTemplate( $result = Util::generateFileUsingSimpleTemplate(
__DIR__.'/templates/RootDB.orig.php', __DIR__ . '/templates/RootDB.orig.php',
ROOT.'/d_setting/RootDB.php', ROOT . '/d_setting/RootDB.php',
[ [
'host'=>$host, 'host' => $host,
'user'=>$username, 'user' => $username,
'password'=>$password, 'password' => $password,
'dbName'=>$dbName, 'dbName' => $dbName,
'port'=>$port, 'port' => $port,
'globalSalt'=>$globalSalt, 'globalSalt' => $globalSalt,
] ]
); );
$kakaoRedirectURI = WebUtil::resolveRelativePath('oauth_kakao/oauth.php', $servHost.'/'); $kakaoRedirectURI = WebUtil::resolveRelativePath('oauth_kakao/oauth.php', $servHost . '/');
Util::generateFileUsingSimpleTemplate( Util::generateFileUsingSimpleTemplate(
__DIR__.'/templates/KakaoKey.orig.php', __DIR__ . '/templates/KakaoKey.orig.php',
ROOT.'/d_setting/KakaoKey.php', ROOT . '/d_setting/KakaoKey.php',
[ [
'REST_API_KEY'=>$kakaoRESTKey, 'REST_API_KEY' => $kakaoRESTKey,
'ADMIN_KEY'=>$kakaoAdminKey, 'ADMIN_KEY' => $kakaoAdminKey,
'REDIRECT_URI'=>$kakaoRedirectURI 'REDIRECT_URI' => $kakaoRedirectURI
], ],
true true
); );
if ($result !== true) { if ($result !== true) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>$result 'reason' => $result
]); ]);
} }
Json::die([ Json::die([
'result'=>true, 'result' => true,
'reason'=>'success', 'reason' => 'success',
'globalSalt'=>$globalSalt 'globalSalt' => $globalSalt
]); ]);
+41 -44
View File
@@ -1,13 +1,14 @@
<?php <?php
namespace sammo; namespace sammo;
require(__DIR__.'/../vendor/autoload.php'); require(__DIR__ . '/../vendor/autoload.php');
$session = Session::requireLogin([])->setReadOnly(); $session = Session::requireLogin([])->setReadOnly();
if($session->userGrade < 6){ if ($session->userGrade < 6) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>'관리자 아님' 'reason' => '관리자 아님'
]); ]);
} }
@@ -15,11 +16,11 @@ $servHost = Util::getReq('serv_host');
$sharedIconPath = Util::getReq('shared_icon_path'); $sharedIconPath = Util::getReq('shared_icon_path');
$gameImagePath = Util::getReq('game_image_path'); $gameImagePath = Util::getReq('game_image_path');
if($servHost){ if ($servHost) {
if(!$sharedIconPath || $gameImagePath){ if (!$sharedIconPath || $gameImagePath) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>'serv_host가 지정된 경우, sharedIconPath와 gameImagePath가 모두 지정되어야합니다.' 'reason' => 'serv_host가 지정된 경우, sharedIconPath와 gameImagePath가 모두 지정되어야합니다.'
]); ]);
} }
@@ -27,58 +28,54 @@ if($servHost){
$gameImagePath = WebUtil::resolveRelativePath($gameImagePath, $servHost); $gameImagePath = WebUtil::resolveRelativePath($gameImagePath, $servHost);
$result = Util::generateFileUsingSimpleTemplate( $result = Util::generateFileUsingSimpleTemplate(
__DIR__.'/templates/ServConfig.orig.php', __DIR__ . '/templates/ServConfig.orig.php',
ROOT.'/d_setting/ServConfig.php', ROOT . '/d_setting/ServConfig.php',
[ [
'serverBasePath'=>$servHost, 'serverBasePath' => $servHost,
'sharedIconPath'=>$sharedIconPath, 'sharedIconPath' => $sharedIconPath,
'gameImagePath'=>$gameImagePath 'gameImagePath' => $gameImagePath
], ],
true true
); );
if ($result !== true) { if ($result !== true) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>$result 'reason' => $result
]); ]);
} }
} } else if ($sharedIconPath || $gameImagePath) {
else if($sharedIconPath || $gameImagePath){
$servHost = ServConfig::$serverWebPath; $servHost = ServConfig::$serverWebPath;
if($sharedIconPath){ if ($sharedIconPath) {
$sharedIconPath = WebUtil::resolveRelativePath($sharedIconPath, $servHost); $sharedIconPath = WebUtil::resolveRelativePath($sharedIconPath, $servHost);
} } else {
else{
$sharedIconPath = ServConfig::$sharedIconPath; $sharedIconPath = ServConfig::$sharedIconPath;
} }
if($gameImagePath){ if ($gameImagePath) {
$gameImagePath = WebUtil::resolveRelativePath($gameImagePath, $servHost); $gameImagePath = WebUtil::resolveRelativePath($gameImagePath, $servHost);
} } else {
else{
$gameImagePath = ServConfig::$gameImagePath; $gameImagePath = ServConfig::$gameImagePath;
} }
$result = Util::generateFileUsingSimpleTemplate( $result = Util::generateFileUsingSimpleTemplate(
__DIR__.'/templates/ServConfig.orig.php', __DIR__ . '/templates/ServConfig.orig.php',
ROOT.'/d_setting/ServConfig.php', ROOT . '/d_setting/ServConfig.php',
[ [
'serverBasePath'=>$servHost, 'serverBasePath' => $servHost,
'sharedIconPath'=>$sharedIconPath, 'sharedIconPath' => $sharedIconPath,
'gameImagePath'=>$gameImagePath 'gameImagePath' => $gameImagePath
], ],
true true
); );
if ($result !== true) { if ($result !== true) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>$result 'reason' => $result
]); ]);
} }
} } else {
else{
$servHost = ServConfig::$serverWebPath; $servHost = ServConfig::$serverWebPath;
$sharedIconPath = ServConfig::$sharedIconPath; $sharedIconPath = ServConfig::$sharedIconPath;
$gameImagePath = ServConfig::$gameImagePath; $gameImagePath = ServConfig::$gameImagePath;
@@ -87,31 +84,31 @@ else{
$result = Util::generateFileUsingSimpleTemplate( $result = Util::generateFileUsingSimpleTemplate(
__DIR__.'/templates/common_path.orig.js', __DIR__ . '/templates/common_path.orig.js',
ROOT.'/d_shared/common_path.js', ROOT . '/d_shared/common_path.js',
[ [
'serverBasePath'=>$servHost, 'serverBasePath' => $servHost,
'sharedIconPath'=>$sharedIconPath, 'sharedIconPath' => $sharedIconPath,
'gameImagePath'=>$gameImagePath 'gameImagePath' => $gameImagePath
], ],
true true
); );
$result = Util::generateFileUsingSimpleTemplate( $result = Util::generateFileUsingSimpleTemplate(
__DIR__.'/templates/common.orig.css', __DIR__ . '/templates/common.orig.css',
ROOT.'/d_shared/common.css', ROOT . '/d_shared/common.css',
[ [
'serverBasePath'=>$servHost, 'serverBasePath' => $servHost,
'sharedIconPath'=>$sharedIconPath, 'sharedIconPath' => $sharedIconPath,
'gameImagePath'=>$gameImagePath 'gameImagePath' => $gameImagePath
], ],
true true
); );
if ($result !== true) { if ($result !== true) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>$result 'reason' => $result
]); ]);
} }
+3 -1
View File
@@ -1,4 +1,5 @@
<?php <?php
namespace sammo; namespace sammo;
class RootDB class RootDB
@@ -30,7 +31,8 @@ class RootDB
self::$uDB = new \MeekroDB(self::$host, self::$user, self::$password, self::$dbName, self::$port, self::$encoding); self::$uDB = new \MeekroDB(self::$host, self::$user, self::$password, self::$dbName, self::$port, self::$encoding);
self::$uDB->connect_options[MYSQLI_OPT_INT_AND_FLOAT_NATIVE] = true; self::$uDB->connect_options[MYSQLI_OPT_INT_AND_FLOAT_NATIVE] = true;
self::$uDB->error_handler= function(){}; self::$uDB->error_handler = function () {
};
self::$uDB->throw_exception_on_error = true; self::$uDB->throw_exception_on_error = true;
self::$uDB->throw_exception_on_nonsql_error = true; self::$uDB->throw_exception_on_nonsql_error = true;
} }
+14 -13
View File
@@ -1,4 +1,5 @@
<?php <?php
namespace sammo; namespace sammo;
class ServConfig class ServConfig
@@ -13,32 +14,32 @@ class ServConfig
public static $imageRequestPath = "_tK_imageRequestPath_"; public static $imageRequestPath = "_tK_imageRequestPath_";
public static $imageRequestKey = '_tK_imageRequestKey_'; public static $imageRequestKey = '_tK_imageRequestKey_';
public static function getSharedIconPath(string $filepath='') : string public static function getSharedIconPath(string $filepath = ''): string
{ {
if($filepath){ if ($filepath) {
return static::$sharedIconPath."/{$filepath}"; return static::$sharedIconPath . "/{$filepath}";
} }
return static::$sharedIconPath; return static::$sharedIconPath;
} }
public static function getUserIconPath(string $filepath='') : string public static function getUserIconPath(string $filepath = ''): string
{ {
return AppConf::getUserIconPathWeb($filepath); return AppConf::getUserIconPathWeb($filepath);
} }
public static function getGameImagePath(string $filepath='') : string public static function getGameImagePath(string $filepath = ''): string
{ {
if($filepath){ if ($filepath) {
return static::$gameImagePath."/{$filepath}"; return static::$gameImagePath . "/{$filepath}";
} }
return static::$gameImagePath; return static::$gameImagePath;
} }
public static function getImagePullURI() : string public static function getImagePullURI(): string
{ {
$now = time(); $now = time();
$req_hash = Util::hashPassword(sprintf("%016x",$now), static::$imageRequestKey); $req_hash = Util::hashPassword(sprintf("%016x", $now), static::$imageRequestKey);
return static::$imageRequestPath."?req={$req_hash}&time={$now}"; return static::$imageRequestPath . "?req={$req_hash}&time={$now}";
} }
@@ -47,8 +48,8 @@ class ServConfig
* *
* @return string * @return string
*/ */
public static function getServerBasepath() : string public static function getServerBasepath(): string
{ {
return self::$serverWebPath; return self::$serverWebPath;
} }
} }
+1 -18
View File
@@ -6,24 +6,7 @@ include "func.php";
$session = Session::requireGameLogin()->setReadOnly(); $session = Session::requireGameLogin()->setReadOnly();
if($session->userGrade < 4) { if($session->userGrade < 4) {
?> die(requireAdminPermissionHTML());
<!DOCTYPE html>
<html>
<head>
<title>관리메뉴</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" />
<?=WebUtil::printCSS('../d_shared/common.css')?>
<?=WebUtil::printCSS('css/common.css')?>
</head>
<body>
관리자가 아닙니다.<br>
<?=banner()?>
</body>
</html>
<?php
exit();
} }
$db = DB::db(); $db = DB::db();
+86 -85
View File
@@ -1,4 +1,5 @@
<?php <?php
namespace sammo; namespace sammo;
include "lib.php"; include "lib.php";
@@ -6,7 +7,7 @@ include "func.php";
$session = Session::requireGameLogin()->setReadOnly(); $session = Session::requireGameLogin()->setReadOnly();
if($session->userGrade < 4){ if ($session->userGrade < 4) {
header('location:_119.php'); header('location:_119.php');
die(); die();
} }
@@ -16,7 +17,7 @@ $v->rule('integer', [
'minute', 'minute',
'minutes2' 'minutes2'
]); ]);
if(!$v->validate()){ if (!$v->validate()) {
Error($v->errorStr()); Error($v->errorStr());
} }
@@ -26,92 +27,92 @@ $minute2 = Util::getReq('minute2', 'int');
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
switch($btn) { switch ($btn) {
case "분당김": case "분당김":
$locked = false; $locked = false;
for($i = 0; $i < 10; $i++){ for ($i = 0; $i < 10; $i++) {
if(tryLock()){ if (tryLock()) {
$locked = true; $locked = true;
break; break;
}
usleep(500000);
} }
usleep(500000);
}
$gameStor->cacheValues(['turntime', 'starttime', 'tnmt_time']);
$turntime = (new \DateTimeImmutable($gameStor->turntime))->sub(new \DateInterval("PT{$minute}M"));
$starttime = (new \DateTimeImmutable($gameStor->starttime))->sub(new \DateInterval("PT{$minute}M"));
$tnmt_time = (new \DateTimeImmutable($gameStor->tnmt_time))->sub(new \DateInterval("PT{$minute}M"));
$gameStor->turntime = $turntime->format('Y-m-d H:i:s.u'); $gameStor->cacheValues(['turntime', 'starttime', 'tnmt_time']);
$gameStor->starttime = $starttime->format('Y-m-d H:i:s'); $turntime = (new \DateTimeImmutable($gameStor->turntime))->sub(new \DateInterval("PT{$minute}M"));
$gameStor->tnmt_time = $tnmt_time->format('Y-m-d H:i:s'); $starttime = (new \DateTimeImmutable($gameStor->starttime))->sub(new \DateInterval("PT{$minute}M"));
$tnmt_time = (new \DateTimeImmutable($gameStor->tnmt_time))->sub(new \DateInterval("PT{$minute}M"));
$db->update('general', [ $gameStor->turntime = $turntime->format('Y-m-d H:i:s.u');
'turntime'=>$db->sqleval('DATE_SUB(turntime, INTERVAL %i MINUTE)', $minute) $gameStor->starttime = $starttime->format('Y-m-d H:i:s');
], true); $gameStor->tnmt_time = $tnmt_time->format('Y-m-d H:i:s');
$db->update('auction', [
'expire'=>$db->sqleval('DATE_SUB(expire, INTERVAL %i MINUTE)', $minute) $db->update('general', [
], true); 'turntime' => $db->sqleval('DATE_SUB(turntime, INTERVAL %i MINUTE)', $minute)
if($locked){ ], true);
$db->update('auction', [
'expire' => $db->sqleval('DATE_SUB(expire, INTERVAL %i MINUTE)', $minute)
], true);
if ($locked) {
unlock();
}
break;
case "분지연":
$locked = false;
for ($i = 0; $i < 5; $i++) {
if (tryLock()) {
$locked = true;
break;
}
usleep(500000);
}
$gameStor->cacheValues(['turntime', 'starttime', 'tnmt_time']);
$turntime = (new \DateTimeImmutable($gameStor->turntime))->add(new \DateInterval("PT{$minute}M"));
$starttime = (new \DateTimeImmutable($gameStor->starttime))->add(new \DateInterval("PT{$minute}M"));
$tnmt_time = (new \DateTimeImmutable($gameStor->tnmt_time))->add(new \DateInterval("PT{$minute}M"));
$gameStor->turntime = $turntime->format('Y-m-d H:i:s.u');
$gameStor->starttime = $starttime->format('Y-m-d H:i:s');
$gameStor->tnmt_time = $tnmt_time->format('Y-m-d H:i:s');
$db->update('general', [
'turntime' => $db->sqleval('DATE_ADD(turntime, INTERVAL %i MINUTE)', $minute)
], true);
$db->update('auction', [
'expire' => $db->sqleval('DATE_ADD(expire, INTERVAL %i MINUTE)', $minute)
], true);
if ($locked) {
unlock();
}
break;
case "토너분당김":
$tnmt_time = new \DateTime($gameStor->tnmt_time);
$tnmt_time->sub(new \DateInterval("PT{$minute2}M"));
$gameStor->tnmt_time = $tnmt_time->format('Y-m-d H:i:s');
break;
case "토너분지연":
$tnmt_time = new \DateTimeImmutable($gameStor->tnmt_time);
$tnmt_time->add(new \DateInterval("PT{$minute2}M"));
$gameStor->tnmt_time = $tnmt_time->format('Y-m-d H:i:s');
break;
case "금지급":
processGoldIncome();
break;
case "쌀지급":
processRiceIncome();
break;
case "락걸기":
for ($i = 0; $i < 10; $i++) {
if (tryLock()) {
$locked = true;
break;
}
usleep(500000);
}
break;
case "락풀기":
unlock(); unlock();
} break;
break;
case "분지연":
$locked = false;
for($i = 0; $i < 5; $i++){
if(tryLock()){
$locked = true;
break;
}
usleep(500000);
}
$gameStor->cacheValues(['turntime', 'starttime', 'tnmt_time']);
$turntime = (new \DateTimeImmutable($gameStor->turntime))->add(new \DateInterval("PT{$minute}M"));
$starttime = (new \DateTimeImmutable($gameStor->starttime))->add(new \DateInterval("PT{$minute}M"));
$tnmt_time = (new \DateTimeImmutable($gameStor->tnmt_time))->add(new \DateInterval("PT{$minute}M"));
$gameStor->turntime = $turntime->format('Y-m-d H:i:s.u');
$gameStor->starttime = $starttime->format('Y-m-d H:i:s');
$gameStor->tnmt_time = $tnmt_time->format('Y-m-d H:i:s');
$db->update('general', [
'turntime'=>$db->sqleval('DATE_ADD(turntime, INTERVAL %i MINUTE)', $minute)
], true);
$db->update('auction', [
'expire'=>$db->sqleval('DATE_ADD(expire, INTERVAL %i MINUTE)', $minute)
], true);
if($locked){
unlock();
}
break;
case "토너분당김":
$tnmt_time = new \DateTime($gameStor->tnmt_time);
$tnmt_time->sub(new \DateInterval("PT{$minute2}M"));
$gameStor->tnmt_time = $tnmt_time->format('Y-m-d H:i:s');
break;
case "토너분지연":
$tnmt_time = new \DateTimeImmutable($gameStor->tnmt_time);
$tnmt_time->add(new \DateInterval("PT{$minute2}M"));
$gameStor->tnmt_time = $tnmt_time->format('Y-m-d H:i:s');
break;
case "금지급":
processGoldIncome();
break;
case "쌀지급":
processRiceIncome();
break;
case "락걸기":
for($i = 0; $i < 10; $i++){
if(tryLock()){
$locked = true;
break;
}
usleep(500000);
}
break;
case "락풀기":
unlock();
break;
} }
header('Location:_119.php', true, 303); header('Location:_119.php', true, 303);
+1 -18
View File
@@ -7,24 +7,7 @@ include "func.php";
$session = Session::requireGameLogin()->setReadOnly(); $session = Session::requireGameLogin()->setReadOnly();
if($session->userGrade < 5) { if($session->userGrade < 5) {
?> die(requireAdminPermissionHTML());
<!DOCTYPE html>
<html>
<head>
<title>관리메뉴</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" />
<?=WebUtil::printCSS('../d_shared/common.css')?>
<?=WebUtil::printCSS('css/common.css')?>
</head>
<body>
관리자가 아닙니다.<br>
<?=banner()?>
</body>
</html>
<?php
exit();
} }
$db = DB::db(); $db = DB::db();
+116 -115
View File
@@ -1,4 +1,5 @@
<?php <?php
namespace sammo; namespace sammo;
include "lib.php"; include "lib.php";
@@ -6,25 +7,8 @@ include "func.php";
//로그인 검사 //로그인 검사
$session = Session::requireGameLogin()->setReadOnly(); $session = Session::requireGameLogin()->setReadOnly();
if($session->userGrade < 5) { if ($session->userGrade < 5) {
?> die(requireAdminPermissionHTML());
<!DOCTYPE html>
<html>
<head>
<title>관리메뉴</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" />
<?=WebUtil::printCSS('../d_shared/common.css')?>
<?=WebUtil::printCSS('css/common.css')?>
</head>
<body>
관리자가 아닙니다.<br>
<?=banner()?>
</body>
</html>
<?php
exit();
} }
$db = DB::db(); $db = DB::db();
@@ -32,115 +16,132 @@ $db = DB::db();
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>회원관리</title> <title>회원관리</title>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" /> <meta name="viewport" content="width=1024" />
<?=WebUtil::printCSS('../d_shared/common.css')?> <?= WebUtil::printCSS('../d_shared/common.css') ?>
<?=WebUtil::printCSS('css/common.css')?> <?= WebUtil::printCSS('css/common.css') ?>
</head> </head>
<body> <body>
<table align=center width=1000 class='tb_layout bg0'> <table align=center width=1000 class='tb_layout bg0'>
<tr><td>회 원 관 리<br><?=backButton()?></td></tr> <tr>
</table> <td>회 원 관 리<br><?= backButton() ?></td>
<form name=form1 method=post action=_admin2_submit.php> </tr>
<table align=center width=1000 class='tb_layout bg0'> </table>
<tr> <form name=form1 method=post action=_admin2_submit.php>
<td width=80 align=center>접속제한</td> <table align=center width=1000 class='tb_layout bg0'>
<td width=713 align=center><input type=submit name=btn value='전체 접속허용'><input type=submit name=btn value='전체 접속제한'></td> <tr>
</tr> <td width=80 align=center>접속제한</td>
</table> <td width=713 align=center><input type=submit name=btn value='전체 접속허용'><input type=submit name=btn value='전체 접속제한'></td>
<table align=center width=1000 class='tb_layout bg0'> </tr>
<tr> </table>
<td width=80 align=center rowspan=12>회원선택<br><br><font color=cyan>NPC</font><br><font color=skyblue>NPC유저</font><br><font color=red>접속제한</font><br><b style=background-color:red;>블럭회원</b></td> <table align=center width=1000 class='tb_layout bg0'>
<td width=105 rowspan=12> <tr>
<?php <td width=80 align=center rowspan=12>회원선택<br><br>
<font color=cyan>NPC</font><br>
<font color=skyblue>NPC유저</font><br>
<font color=red>접속제한</font><br><b style=background-color:red;>블럭회원</b>
</td>
<td width=105 rowspan=12>
<?php
echo " echo "
<select name=genlist[] size=20 multiple style='color:white;background-color:black;font-size:13px'>"; <select name=genlist[] size=20 multiple style='color:white;background-color:black;font-size:13px'>";
$generalList = $db->query('SELECT `no`, `name`, npc, `block` FROM general ORDER BY npc, binary(`name`)'); $generalList = $db->query('SELECT `no`, `name`, npc, `block` FROM general ORDER BY npc, binary(`name`)');
foreach($generalList as $general){ foreach ($generalList as $general) {
$style = "style=;"; $style = "style=;";
if($general['block'] > 0) { $style .= "background-color:red;"; } if ($general['block'] > 0) {
if($general['npc'] >= 2) { $style .= "color:cyan;"; } $style .= "background-color:red;";
elseif($general['npc'] == 1) { $style .= "color:skyblue;"; } }
if ($general['npc'] >= 2) {
$style .= "color:cyan;";
} elseif ($general['npc'] == 1) {
$style .= "color:skyblue;";
}
echo " echo "
<option value={$general['no']} $style>{$general['name']}</option>"; <option value={$general['no']} $style>{$general['name']}</option>";
} }
echo " echo "
</select> </select>
</td> </td>
<td width=100 align=center>아이템 지급</td> <td width=100 align=center>아이템 지급</td>
<td width=504> <td width=504>
<select name=weapon size=1 style='color:white;background-color:black;font-size:13px'>"; <select name=weapon size=1 style='color:white;background-color:black;font-size:13px'>";
foreach(GameConst::$allItems as $itemCategories){ foreach (GameConst::$allItems as $itemCategories) {
foreach($itemCategories as $item=>$cnt){ foreach ($itemCategories as $item => $cnt) {
if($cnt == 0){ if ($cnt == 0) {
continue; continue;
} }
$itemObj = buildItemClass($item); $itemObj = buildItemClass($item);
if($itemObj->isBuyable()){ if ($itemObj->isBuyable()) {
continue; continue;
} }
}
} }
} for ($i = 0; $i < 27; $i++) {
for($i=0; $i < 27; $i++) { echo "
echo "
<option value={$i}>{$i}</option>"; <option value={$i}>{$i}</option>";
} }
?> ?>
</select> </select>
<input type=submit name=btn value='무기지급'> <input type=submit name=btn value='무기지급'>
<input type=submit name=btn value='책지급'> <input type=submit name=btn value='책지급'>
<input type=submit name=btn value='말지급'> <input type=submit name=btn value='말지급'>
<input type=submit name=btn value='도구지급'> <input type=submit name=btn value='도구지급'>
</td> </td>
</tr> </tr>
<tr> <tr>
<td width=100 align=center>블럭</td> <td width=100 align=center>블럭</td>
<td width=504> <td width=504>
<input type=submit name=btn value='블럭 해제'><input type=submit name=btn value='1단계 블럭'><input type=submit name=btn value='2단계 블럭'><input type=submit name=btn value='3단계 블럭'><input type=submit name=btn value='무한삭턴'><br> <input type=submit name=btn value='블럭 해제'><input type=submit name=btn value='1단계 블럭'><input type=submit name=btn value='2단계 블럭'><input type=submit name=btn value='3단계 블럭'><input type=submit name=btn value='무한삭턴'><br>
1단계:발언권, 2단계:턴블럭 1단계:발언권, 2단계:턴블럭
</td> </td>
</tr> </tr>
<tr> <tr>
<td align=center>강제 사망</td> <td align=center>강제 사망</td>
<td><input type=submit name=btn value='강제 사망'></td> <td><input type=submit name=btn value='강제 사망'></td>
</tr> </tr>
<tr> <tr>
<td align=center>이벤트</td> <td align=center>이벤트</td>
<td><input type=submit name=btn value='특기 부여'><input type=submit name=btn value='공헌치1000'><input type=submit name=btn value='경험치1000'></td> <td><input type=submit name=btn value='특기 부여'><input type=submit name=btn value='공헌치1000'><input type=submit name=btn value='경험치1000'></td>
</tr> </tr>
<tr> <tr>
<td align=center>이벤트2</td> <td align=center>이벤트2</td>
<td><input type=submit name=btn value='보숙10000'><input type=submit name=btn value='궁숙10000'><input type=submit name=btn value='기숙10000'><input type=submit name=btn value='귀숙10000'><input type=submit name=btn value='차숙10000'></td> <td><input type=submit name=btn value='보숙10000'><input type=submit name=btn value='궁숙10000'><input type=submit name=btn value='기숙10000'><input type=submit name=btn value='귀숙10000'><input type=submit name=btn value='차숙10000'></td>
</tr> </tr>
<tr> <tr>
<td align=center>접속제한</td> <td align=center>접속제한</td>
<td><input type=submit name=btn value='접속 허용'><input type=submit name=btn value='접속 제한'></td> <td><input type=submit name=btn value='접속 허용'><input type=submit name=btn value='접속 제한'></td>
</tr> </tr>
<tr> <tr>
<td align=center>턴 시각 설정</td> <td align=center>턴 시각 설정</td>
<td><input type=submit name=btn value='00턴'><input type=submit name=btn value='랜덤턴'></td> <td><input type=submit name=btn value='00턴'><input type=submit name=btn value='랜덤턴'></td>
</tr> </tr>
<tr> <tr>
<td align=center>명령 설정</td> <td align=center>명령 설정</td>
<td><input type=submit name=btn value='하야입력'><input type=submit name=btn value='방랑해산'></td> <td><input type=submit name=btn value='하야입력'><input type=submit name=btn value='방랑해산'></td>
</tr> </tr>
<tr> <tr>
<td align=center>메세지 전달</td> <td align=center>메세지 전달</td>
<td><input type=textarea size=60 maxlength=255 name=msg style=background-color:black;color:white;><input type=submit name=btn value='메세지 전달'></td> <td><input type=textarea size=60 maxlength=255 name=msg style=background-color:black;color:white;><input type=submit name=btn value='메세지 전달'></td>
</tr> </tr>
</table> </table>
</form> </form>
<table align=center width=1000 class='tb_layout bg0'> <table align=center width=1000 class='tb_layout bg0'>
<tr><td><?=backButton()?></td></tr> <tr>
<tr><td><?=banner()?> </td></tr> <td><?= backButton() ?></td>
</table> </tr>
<tr>
<td><?= banner() ?> </td>
</tr>
</table>
</body> </body>
</html>
</html>
+112 -119
View File
@@ -1,4 +1,5 @@
<?php <?php
namespace sammo; namespace sammo;
include "lib.php"; include "lib.php";
@@ -12,12 +13,12 @@ $msg = Util::getReq('msg', 'string');
//로그인 검사 //로그인 검사
$session = Session::requireLogin()->loginGame()->setReadOnly(); $session = Session::requireLogin()->loginGame()->setReadOnly();
if($session->userGrade < 5) { if ($session->userGrade < 5) {
header('location:_admin2.php'); header('location:_admin2.php');
} }
$generalID = $session->generalID; $generalID = $session->generalID;
if(!$generalID){ if (!$generalID) {
header('location:_admin2.php'); header('location:_admin2.php');
die(); die();
} }
@@ -29,331 +30,323 @@ $src = MessageTarget::buildQuick($session->generalID);
$genObjList = []; $genObjList = [];
$env = []; $env = [];
if($genlist){ if ($genlist) {
$genObjList = General::createGeneralObjListFromDB($genlist); $genObjList = General::createGeneralObjListFromDB($genlist);
$env = $gameStor->cacheAll(); $env = $gameStor->cacheAll();
} }
switch($btn) { switch ($btn) {
case "전체 접속허용": case "전체 접속허용":
$db->update('general', [ $db->update('general', [
'con'=>0 'con' => 0
], true); ], true);
break; break;
case "전체 접속제한": case "전체 접속제한":
$db->update('general', [ $db->update('general', [
'con'=>1000 'con' => 1000
], true); ], true);
break; break;
case "블럭 해제": case "블럭 해제":
$db->update('general', [ $db->update('general', [
'block'=>0 'block' => 0
], '`no` IN %li', $genlist); ], '`no` IN %li', $genlist);
DB::db()->query('update general set block=0 where no IN %li', $genlist); DB::db()->query('update general set block=0 where no IN %li', $genlist);
break; break;
case "1단계 블럭": case "1단계 블럭":
$date = TimeUtil::now(); $date = TimeUtil::now();
$db->update('general', [ $db->update('general', [
'block'=>1, 'block' => 1,
'killturn'=>24 'killturn' => 24
], '`no` IN %li', $genlist); ], '`no` IN %li', $genlist);
$uid = $db->queryFirstColumn('SELECT `owner` FROM general WHERE `no` IN %li', $genlist); $uid = $db->queryFirstColumn('SELECT `owner` FROM general WHERE `no` IN %li', $genlist);
RootDB::db()->update('member',[ RootDB::db()->update('member', [
'block_num'=>$db->sqleval('block_num+1'), 'block_num' => $db->sqleval('block_num+1'),
'block_date'=>$date 'block_date' => $date
], 'id IN %li', $uid); ], 'id IN %li', $uid);
break; break;
case "2단계 블럭": case "2단계 블럭":
$date = TimeUtil::now(); $date = TimeUtil::now();
$db->update('general', [ $db->update('general', [
'gold'=>0, 'gold' => 0,
'rice'=>0, 'rice' => 0,
'block'=>2, 'block' => 2,
'killturn'=>24 'killturn' => 24
], '`no` IN %li', $genlist); ], '`no` IN %li', $genlist);
$uid = $db->queryFirstColumn('select owner from general where no IN %li', $genlist); $uid = $db->queryFirstColumn('select owner from general where no IN %li', $genlist);
RootDB::db()->update('member',[ RootDB::db()->update('member', [
'block_num'=>$db->sqleval('block_num+1'), 'block_num' => $db->sqleval('block_num+1'),
'block_date'=>$date 'block_date' => $date
], 'id IN %li', $uid); ], 'id IN %li', $uid);
break; break;
case "3단계 블럭": case "3단계 블럭":
$date = TimeUtil::now(); $date = TimeUtil::now();
$db->update('general', [ $db->update('general', [
'gold'=>0, 'gold' => 0,
'rice'=>0, 'rice' => 0,
'block'=>3, 'block' => 3,
'killturn'=>24 'killturn' => 24
], '`no` IN %li', $genlist); ], '`no` IN %li', $genlist);
$uid = $db->queryFirstColumn('SELECT `owner` from general where no IN %li', $genlist); $uid = $db->queryFirstColumn('SELECT `owner` from general where no IN %li', $genlist);
RootDB::db()->update('member',[ RootDB::db()->update('member', [
'block_num'=>$db->sqleval('block_num+1'), 'block_num' => $db->sqleval('block_num+1'),
'block_date'=>$date 'block_date' => $date
], 'id IN %li', $uid); ], 'id IN %li', $uid);
break; break;
case "무한삭턴": case "무한삭턴":
$db->update('general', [ $db->update('general', [
'killturn'=>8000 'killturn' => 8000
], '`no` IN %li', $genlist); ], '`no` IN %li', $genlist);
break; break;
case "강제 사망": case "강제 사망":
$date = TimeUtil::now(true); $date = TimeUtil::now(true);
$db->update('general', [ $db->update('general', [
'killturn'=>0, 'killturn' => 0,
'turntime'=>$date, 'turntime' => $date,
], '`no` IN %li', $genlist); ], '`no` IN %li', $genlist);
$db->update('general_turn', [ $db->update('general_turn', [
'action'=>'휴식', 'action' => '휴식',
'arg'=>'{}', 'arg' => '{}',
'brief'=>'휴식', 'brief' => '휴식',
], 'general_id IN %li AND turn_idx = 0', $genlist); ], 'general_id IN %li AND turn_idx = 0', $genlist);
break; break;
case "특기 부여": case "특기 부여":
[$year, $month] = $gameStor->getValuesAsArray(['year', 'month']); [$year, $month] = $gameStor->getValuesAsArray(['year', 'month']);
$text = "특기 부여!"; $text = "특기 부여!";
foreach($db->query("SELECT `no`,leadership,strength,intel,dex1,dex2,dex3,dex4,dex5 FROM general WHERE `no` IN %li", $genlist) as $general){ foreach ($db->query("SELECT `no`,leadership,strength,intel,dex1,dex2,dex3,dex4,dex5 FROM general WHERE `no` IN %li", $genlist) as $general) {
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($general['no']), $text, new \DateTime(), new \DateTime('9999-12-31'), []); $msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($general['no']), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
$msg->send(true); $msg->send(true);
$specialWar = SpecialityHelper::pickSpecialWar($general); $specialWar = SpecialityHelper::pickSpecialWar($general);
$db->update('general', [ $db->update('general', [
'specage2'=>$db->sqleval('age'), 'specage2' => $db->sqleval('age'),
'special2'=>$specialWar 'special2' => $specialWar
], 'no=%i', $general['no']); ], 'no=%i', $general['no']);
$specialWarName = buildGeneralSpecialWarClass($specialWar)->getName(); $specialWarName = buildGeneralSpecialWarClass($specialWar)->getName();
$josaUl = JosaUtil::pick($specialWarName, '을'); $josaUl = JosaUtil::pick($specialWarName, '을');
pushGeneralHistory($general['no'], ["<C>●</>{$year}{$month}월:특기 【<b><C>{$specialWarName}</></b>】{$josaUl} 습득"]); pushGeneralHistory($general['no'], ["<C>●</>{$year}{$month}월:특기 【<b><C>{$specialWarName}</></b>】{$josaUl} 습득"]);
pushGenLog($general['no'], ["<C>●</>특기 【<b><L>{$specialWarName}</></b>】{$josaUl} 익혔습니다!"]); pushGenLog($general['no'], ["<C>●</>특기 【<b><L>{$specialWarName}</></b>】{$josaUl} 익혔습니다!"]);
} }
break; break;
case "경험치1000": case "경험치1000":
$text = $btn." 지급!"; $text = $btn . " 지급!";
foreach($genlist as $generalID){ foreach ($genlist as $generalID) {
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []); $msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
$msg->send(true); $msg->send(true);
} }
$db->update('general',[ $db->update('general', [
'experience'=>$db->sqleval('experience+1000') 'experience' => $db->sqleval('experience+1000')
], '`no` IN %li', $genlist); ], '`no` IN %li', $genlist);
break; break;
case "공헌치1000": case "공헌치1000":
$text = $btn." 지급!"; $text = $btn . " 지급!";
foreach($genlist as $generalID){ foreach ($genlist as $generalID) {
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []); $msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
$msg->send(true); $msg->send(true);
} }
$db->update('general',[ $db->update('general', [
'dedication'=>$db->sqleval('dedication+1000') 'dedication' => $db->sqleval('dedication+1000')
], '`no` IN %li', $genlist); ], '`no` IN %li', $genlist);
break; break;
case "보숙10000": case "보숙10000":
$text = "보병숙련도+10000 지급!"; $text = "보병숙련도+10000 지급!";
foreach($genlist as $generalID){ foreach ($genlist as $generalID) {
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []); $msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
$msg->send(true); $msg->send(true);
} }
$db->update('general',[ $db->update('general', [
'dex1'=>$db->sqleval('dex1+10000') 'dex1' => $db->sqleval('dex1+10000')
], '`no` IN %li', $genlist); ], '`no` IN %li', $genlist);
break; break;
case "궁숙10000": case "궁숙10000":
$text = "궁병숙련도+10000 지급!"; $text = "궁병숙련도+10000 지급!";
foreach($genlist as $generalID){ foreach ($genlist as $generalID) {
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []); $msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
$msg->send(true); $msg->send(true);
} }
$db->update('general',[ $db->update('general', [
'dex2'=>$db->sqleval('dex2+10000') 'dex2' => $db->sqleval('dex2+10000')
], '`no` IN %li', $genlist); ], '`no` IN %li', $genlist);
break; break;
case "기숙10000": case "기숙10000":
$src = MessageTarget::buildQuick($session->generalID); $src = MessageTarget::buildQuick($session->generalID);
$text = "기병숙련도+10000 지급!"; $text = "기병숙련도+10000 지급!";
foreach($genlist as $generalID){ foreach ($genlist as $generalID) {
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []); $msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
$msg->send(true); $msg->send(true);
} }
$db->update('general',[ $db->update('general', [
'dex3'=>$db->sqleval('dex3+10000') 'dex3' => $db->sqleval('dex3+10000')
], '`no` IN %li', $genlist); ], '`no` IN %li', $genlist);
break; break;
case "귀숙10000": case "귀숙10000":
$src = MessageTarget::buildQuick($session->generalID); $src = MessageTarget::buildQuick($session->generalID);
$text = "귀병숙련도+10000 지급!"; $text = "귀병숙련도+10000 지급!";
foreach($genlist as $generalID){ foreach ($genlist as $generalID) {
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []); $msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
$msg->send(true); $msg->send(true);
} }
$db->update('general',[ $db->update('general', [
'dex4'=>$db->sqleval('dex4+10000') 'dex4' => $db->sqleval('dex4+10000')
], '`no` IN %li', $genlist); ], '`no` IN %li', $genlist);
break; break;
case "차숙10000": case "차숙10000":
$src = MessageTarget::buildQuick($session->generalID); $src = MessageTarget::buildQuick($session->generalID);
$text = "차병숙련도+10000 지급!"; $text = "차병숙련도+10000 지급!";
foreach($genlist as $generalID){ foreach ($genlist as $generalID) {
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []); $msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
$msg->send(true); $msg->send(true);
} }
$db->update('general',[ $db->update('general', [
'dex5'=>$db->sqleval('dex5+10000') 'dex5' => $db->sqleval('dex5+10000')
], '`no` IN %li', $genlist); ], '`no` IN %li', $genlist);
break; break;
case "접속 허용": case "접속 허용":
$db->update('general',[ $db->update('general', [
'con'=>0 'con' => 0
], '`no` IN %li', $genlist); ], '`no` IN %li', $genlist);
break; break;
case "접속 제한": case "접속 제한":
$db->update('general',[ $db->update('general', [
'con'=>1000 'con' => 1000
], '`no` IN %li', $genlist); ], '`no` IN %li', $genlist);
break; break;
case "메세지 전달": case "메세지 전달":
$text = $msg??''; $text = $msg ?? '';
foreach($genlist as $generalID){ foreach ($genlist as $generalID) {
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []); $msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
$msg->send(true); $msg->send(true);
} }
break; break;
case "무기지급": case "무기지급":
if($item == 'None') { if ($item == 'None') {
$text = "무기 회수!"; $text = "무기 회수!";
} } else {
else { $text = getItemName($item) . " 지급!";
$text = getItemName($item)." 지급!";
} }
foreach($genlist as $generalID){ foreach ($genlist as $generalID) {
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []); $msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
$msg->send(true); $msg->send(true);
} }
if($item === 'None'){ if ($item === 'None') {
$db->update('general', [ $db->update('general', [
'weapon'=>'None' 'weapon' => 'None'
], '`no` IN %li', $genlist); ], '`no` IN %li', $genlist);
} } else {
else{
$db->update('general', [ $db->update('general', [
'weapon'=>$item 'weapon' => $item
], '`no` IN %li', $genlist, $item); ], '`no` IN %li', $genlist, $item);
} }
break; break;
case "책지급": case "책지급":
if($item == 'None') { if ($item == 'None') {
$text = "책 회수!"; $text = "책 회수!";
} } else {
else { $text = getItemName($item) . " 지급!";
$text = getItemName($item)." 지급!";
} }
foreach($genlist as $generalID){ foreach ($genlist as $generalID) {
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []); $msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
$msg->send(true); $msg->send(true);
} }
if($item == 'None'){ if ($item == 'None') {
$db->update('general', [ $db->update('general', [
'book'=>'None' 'book' => 'None'
], '`no` IN %li', $genlist); ], '`no` IN %li', $genlist);
} } else {
else{
$db->update('general', [ $db->update('general', [
'book'=>$item 'book' => $item
], '`no` IN %li', $genlist); ], '`no` IN %li', $genlist);
} }
break; break;
case "말지급": case "말지급":
if($item == 'None') { if ($item == 'None') {
$text = "말 회수!"; $text = "말 회수!";
} } else {
else { $text = getItemName($item) . " 지급!";
$text = getItemName($item)." 지급!";
} }
foreach($genlist as $generalID){ foreach ($genlist as $generalID) {
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []); $msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
$msg->send(true); $msg->send(true);
} }
if($item == 'None'){ if ($item == 'None') {
$db->update('general', [ $db->update('general', [
'horse'=>'None' 'horse' => 'None'
], '`no` IN %li', $genlist); ], '`no` IN %li', $genlist);
} } else {
else{
$db->update('general', [ $db->update('general', [
'horse'=>$item 'horse' => $item
], '`no` IN %li', $genlist); ], '`no` IN %li', $genlist);
} }
break; break;
case "도구지급": case "도구지급":
if($item == 'None') { if ($item == 'None') {
$text = "특수도구 회수!"; $text = "특수도구 회수!";
} } else {
else { $text = getItemName($item) . " 지급!";
$text = getItemName($item)." 지급!";
} }
foreach($genlist as $generalID){ foreach ($genlist as $generalID) {
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []); $msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
$msg->send(true); $msg->send(true);
} }
if($item == 'None'){ if ($item == 'None') {
$db->update('general', [ $db->update('general', [
'item'=>'None' 'item' => 'None'
], '`no` IN %li', $genlist); ], '`no` IN %li', $genlist);
} } else {
else{
$db->update('general', [ $db->update('general', [
'item'=>$item 'item' => $item
], '`no` IN %li AND item < %i', $genlist, $item); ], '`no` IN %li AND item < %i', $genlist, $item);
} }
break; break;
case "하야입력": case "하야입력":
$db->update('general_turn', [ $db->update('general_turn', [
'action'=>'che_하야', 'action' => 'che_하야',
'arg'=>'{}', 'arg' => '{}',
'brief'=>'하야', 'brief' => '하야',
], 'general_id IN %li AND turn_idx = 0', $genlist); ], 'general_id IN %li AND turn_idx = 0', $genlist);
break; break;
case "방랑해산": case "방랑해산":
$db->update('general_turn', [ $db->update('general_turn', [
'action'=>'che_방랑', 'action' => 'che_방랑',
'arg'=>'{}', 'arg' => '{}',
'brief'=>'방랑', 'brief' => '방랑',
], 'general_id IN %li AND turn_idx = 0', $genlist); ], 'general_id IN %li AND turn_idx = 0', $genlist);
$db->update('general_turn', [ $db->update('general_turn', [
'action'=>'che_해산', 'action' => 'che_해산',
'arg'=>'{}', 'arg' => '{}',
'brief'=>'해산', 'brief' => '해산',
], 'general_id IN %li AND turn_idx = 1', $genlist); ], 'general_id IN %li AND turn_idx = 1', $genlist);
break; break;
case "00턴": case "00턴":
$turnterm = $gameStor->turnterm; $turnterm = $gameStor->turnterm;
foreach($genlist as $generalID){ foreach ($genlist as $generalID) {
$turntime = getRandTurn($turnterm); $turntime = getRandTurn($turnterm);
$cutTurn = cutTurn($turntime, $turnterm); $cutTurn = cutTurn($turntime, $turnterm);
$db->update('general', [ $db->update('general', [
'turntime'=>$cutTurn 'turntime' => $cutTurn
], '`no` IN %li', $genlist); ], '`no` IN %li', $genlist);
} }
break; break;
case "랜덤턴": case "랜덤턴":
foreach($genlist as $generalID){ foreach ($genlist as $generalID) {
$turntime = getRandTurn($turnterm); $turntime = getRandTurn($turnterm);
$db->update('general', [ $db->update('general', [
'turntime'=>$turntime 'turntime' => $turntime
], '`no` IN %li', $genlist); ], '`no` IN %li', $genlist);
} }
break; break;
} }
header('location:_admin2.php'); header('location:_admin2.php');
+116 -112
View File
@@ -1,4 +1,5 @@
<?php <?php
namespace sammo; namespace sammo;
include "lib.php"; include "lib.php";
@@ -6,137 +7,140 @@ include "func.php";
//로그인 검사 //로그인 검사
$session = Session::requireGameLogin()->setReadOnly(); $session = Session::requireGameLogin()->setReadOnly();
if($session->userGrade < 5) { if ($session->userGrade < 5) {
?> die(requireAdminPermissionHTML());
<!DOCTYPE html>
<html>
<head>
<title>관리메뉴</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" />
<?=WebUtil::printCSS('../d_shared/common.css')?>
<?=WebUtil::printCSS('css/common.css')?>
</head>
<body>
관리자가 아닙니다.<br>
<?=banner()?>
</body>
</html>
<?php
exit();
} }
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
$connect=$db->get(); $connect = $db->get();
$conlimit = $gameStor->conlimit; $conlimit = $gameStor->conlimit;
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head>
<title>멀티관리</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" />
<?=WebUtil::printCSS('../d_shared/common.css')?>
<?=WebUtil::printCSS('css/common.css')?>
</head>
<body>
<table align=center width=1000 class='tb_layout bg0'>
<tr><td>멀 티 관 리<br><?=backButton()?></td></tr>
</table>
<form name=form1 method=post action=_admin4_submit.php>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td width=80 align=center rowspan=3>회원선택<br><br><font color=cyan>NPC</font><br><font color=skyblue>NPC유저</font><br><font color=red>접속제한</font><br><b style=background-color:red;>블럭회원</b></td>
<td width=105 rowspan=3>
<?php
echo " <head>
<title>멀티관리</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" />
<?= WebUtil::printCSS('../d_shared/common.css') ?>
<?= WebUtil::printCSS('css/common.css') ?>
</head>
<body>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td>멀 티 관 리<br><?= backButton() ?></td>
</tr>
</table>
<form name=form1 method=post action=_admin4_submit.php>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td width=80 align=center rowspan=3>회원선택<br><br>
<font color=cyan>NPC</font><br>
<font color=skyblue>NPC유저</font><br>
<font color=red>접속제한</font><br><b style=background-color:red;>블럭회원</b>
</td>
<td width=105 rowspan=3>
<?php
echo "
<select name=genlist[] size=20 multiple style='color:white;background-color:black;font-size:13px'>"; <select name=genlist[] size=20 multiple style='color:white;background-color:black;font-size:13px'>";
foreach($db->query('SELECT no,name,npc,block,con from general where ip!=\'\' order by npc,ip') as $general){ foreach ($db->query('SELECT no,name,npc,block,con from general where ip!=\'\' order by npc,ip') as $general) {
$style = "style=;"; $style = "style=;";
if($general['block'] > 0) { $style .= "background-color:red;"; } if ($general['block'] > 0) {
if($general['npc'] >= 2) { $style .= "color:cyan;"; } $style .= "background-color:red;";
elseif($general['npc'] == 1) { $style .= "color:skyblue;"; } }
if($general['con'] > $conlimit) { $style .= "color:red;"; } if ($general['npc'] >= 2) {
$style .= "color:cyan;";
} elseif ($general['npc'] == 1) {
$style .= "color:skyblue;";
}
if ($general['con'] > $conlimit) {
$style .= "color:red;";
}
echo " echo "
<option value={$general['no']} $style>{$general['name']}</option>"; <option value={$general['no']} $style>{$general['name']}</option>";
} }
echo " echo "
</select>"; </select>";
?> ?>
</td> </td>
<td width=100 align=center>블럭</td> <td width=100 align=center>블럭</td>
<td width=504> <td width=504>
<input type=submit name=btn value='블럭 해제'><input type=submit name=btn value='1단계 블럭'><input type=submit name=btn value='2단계 블럭'><input type=submit name=btn value='3단계 블럭'><input type=submit name=btn value='무한삭턴'><br> <input type=submit name=btn value='블럭 해제'><input type=submit name=btn value='1단계 블럭'><input type=submit name=btn value='2단계 블럭'><input type=submit name=btn value='3단계 블럭'><input type=submit name=btn value='무한삭턴'><br>
1단계:발언권, 2단계:턴블럭 1단계:발언권, 2단계:턴블럭
</td> </td>
</tr> </tr>
<tr> <tr>
<td align=center>강제 사망</td> <td align=center>강제 사망</td>
<td><input type=submit name=btn value='강제 사망'></td> <td><input type=submit name=btn value='강제 사망'></td>
</tr> </tr>
<tr> <tr>
<td align=center>메세지 전달</td> <td align=center>메세지 전달</td>
<td><input type=textarea size=60 maxlength=255 name=msg style=background-color:black;color:white;><input type=submit name=btn value='메세지 전달'></td> <td><input type=textarea size=60 maxlength=255 name=msg style=background-color:black;color:white;><input type=submit name=btn value='메세지 전달'></td>
</tr> </tr>
</table> </table>
<table align=center width=1000 class='tb_layout bg0'> <table align=center width=1000 class='tb_layout bg0'>
<tr> <tr>
<td align=center width=100>장수명</td> <td align=center width=100>장수명</td>
<td align=center width=180>최근로그인</td> <td align=center width=180>최근로그인</td>
<td align=center width=129>IP</td> <td align=center width=129>IP</td>
<td align=center width=100>ID</td> <td align=center width=100>ID</td>
</tr> </tr>
<tr> <tr>
<?php <?php
$query = "select substring_index(ip,'.',3) as ip2 from general where ip!='' and npc<2 group by ip2 having count(*)>1"; $query = "select substring_index(ip,'.',3) as ip2 from general where ip!='' and npc<2 group by ip2 having count(*)>1";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); $result = MYDB_query($query, $connect) or Error(__LINE__ . MYDB_error($connect), "");
$ipCount = MYDB_num_rows($result); $ipCount = MYDB_num_rows($result);
$genName = ""; $genName = "";
$genDate = ""; $genDate = "";
$genIP = ""; $genIP = "";
$genID = ""; $genID = "";
for($i=0; $i < $ipCount; $i++) { for ($i = 0; $i < $ipCount; $i++) {
$ip = MYDB_fetch_array($result); $ip = MYDB_fetch_array($result);
$query = "select name,ip,lastconnect,owner,block from general where ip like '{$ip['ip2']}%' and npc<2 order by ip"; $query = "select name,ip,lastconnect,owner,block from general where ip like '{$ip['ip2']}%' and npc<2 order by ip";
$genResult = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); $genResult = MYDB_query($query, $connect) or Error(__LINE__ . MYDB_error($connect), "");
$genCount = MYDB_num_rows($genResult); $genCount = MYDB_num_rows($genResult);
for($k=0; $k < $genCount; $k++) { for ($k = 0; $k < $genCount; $k++) {
$gen = MYDB_fetch_array($genResult); $gen = MYDB_fetch_array($genResult);
if($gen['block'] > 0) $genName .= "<font color=magenta>{$gen['name']}</font><br>"; if ($gen['block'] > 0) $genName .= "<font color=magenta>{$gen['name']}</font><br>";
else $genName .= $gen['name']."<br>"; else $genName .= $gen['name'] . "<br>";
$genDate .= $gen['lastconnect']."<br>"; $genDate .= $gen['lastconnect'] . "<br>";
$genIP .= $gen['ip']."<br>"; $genIP .= $gen['ip'] . "<br>";
$genID .= $gen['owner']."<br>"; $genID .= $gen['owner'] . "<br>";
} }
$genName .= "<br>"; $genName .= "<br>";
$genDate .= "<br>"; $genDate .= "<br>";
$genIP .= "<br>"; $genIP .= "<br>";
$genID .= "<br>"; $genID .= "<br>";
} }
echo " echo "
<td align=right>$genName</td> <td align=right>$genName</td>
<td>$genDate</td> <td>$genDate</td>
<td>$genIP</td> <td>$genIP</td>
<td>$genID</td>"; <td>$genID</td>";
?> ?>
</tr> </tr>
</table> </table>
<?php <?php
//NOTE: password의 md5 해시가 같은지 확인하는 방식으로는 앞으로 잡아낼 수 없다. 폐기 //NOTE: password의 md5 해시가 같은지 확인하는 방식으로는 앞으로 잡아낼 수 없다. 폐기
?> ?>
</form> </form>
<table align=center width=1000 class='tb_layout bg0'> <table align=center width=1000 class='tb_layout bg0'>
<tr><td><?=backButton()?></td></tr> <tr>
<tr><td><?=banner()?> </td></tr> <td><?= backButton() ?></td>
</table> </tr>
<tr>
<td><?= banner() ?> </td>
</tr>
</table>
</body> </body>
</html>
</html>
+15 -15
View File
@@ -1,4 +1,5 @@
<?php <?php
namespace sammo; namespace sammo;
include "lib.php"; include "lib.php";
@@ -6,27 +7,27 @@ include "func.php";
//로그인 검사 //로그인 검사
$session = Session::requireGameLogin()->setReadOnly(); $session = Session::requireGameLogin()->setReadOnly();
if($session->userGrade < 5) { if ($session->userGrade < 5) {
header('location:_admin4.php'); header('location:_admin4.php');
die(); die();
} }
$btn = Util::getReq('btn'); $btn = Util::getReq('btn');
$genlist = Util::getReq('genlist', 'array_int'); $genlist = Util::getReq('genlist', 'array_int');
$msg = Util::getReq('msg','string', '메시지'); $msg = Util::getReq('msg', 'string', '메시지');
$db = DB::db(); $db = DB::db();
//NOTE: 왜 기능이 admin2와 admin4가 같이 있는가? //NOTE: 왜 기능이 admin2와 admin4가 같이 있는가?
//NOTE: 왜 블럭 시 admin4에선 금쌀을 없애지 않는가? //NOTE: 왜 블럭 시 admin4에선 금쌀을 없애지 않는가?
switch($btn) { switch ($btn) {
case "블럭 해제": case "블럭 해제":
DB::db()->query('update general set block=0 where no IN %li', $genlist); DB::db()->query('update general set block=0 where no IN %li', $genlist);
break; break;
case "1단계 블럭": case "1단계 블럭":
$date = TimeUtil::now(); $date = TimeUtil::now();
$db = DB::db(); $db = DB::db();
$db->query('update general set block=1,killturn=24 where no IN %li',$genlist); $db->query('update general set block=1,killturn=24 where no IN %li', $genlist);
//FIXME: subquery로 하는게 더 빠를 듯. //FIXME: subquery로 하는게 더 빠를 듯.
$uid = $db->queryFirstColumn('select owner from general where no IN %li', $genlist); $uid = $db->queryFirstColumn('select owner from general where no IN %li', $genlist);
RootDB::db()->query('update member set block_num=block_num+1,block_date=%s where id IN %ls', $date, $uid); RootDB::db()->query('update member set block_num=block_num+1,block_date=%s where id IN %ls', $date, $uid);
@@ -34,36 +35,36 @@ switch($btn) {
case "2단계 블럭": case "2단계 블럭":
$date = TimeUtil::now(); $date = TimeUtil::now();
$db = DB::db(); $db = DB::db();
$db->query('update general set block=2,killturn=24 where no IN %li',$genlist); $db->query('update general set block=2,killturn=24 where no IN %li', $genlist);
$uid = $db->queryFirstColumn('select owner from general where no IN %li', $genlist); $uid = $db->queryFirstColumn('select owner from general where no IN %li', $genlist);
RootDB::db()->query('update member set block_num=block_num+1,block_date=%s where id IN %ls', $date, $uid); RootDB::db()->query('update member set block_num=block_num+1,block_date=%s where id IN %ls', $date, $uid);
break; break;
case "3단계 블럭": case "3단계 블럭":
$date = TimeUtil::now(); $date = TimeUtil::now();
$db = DB::db(); $db = DB::db();
$db->query('update general set block=3,killturn=24 where no IN %li',$genlist); $db->query('update general set block=3,killturn=24 where no IN %li', $genlist);
$uid = $db->queryFirstColumn('select owner from general where no IN %li', $genlist); $uid = $db->queryFirstColumn('select owner from general where no IN %li', $genlist);
RootDB::db()->query('update member set block_num=block_num+1,block_date=%s where id IN %ls', $date, $uid); RootDB::db()->query('update member set block_num=block_num+1,block_date=%s where id IN %ls', $date, $uid);
break; break;
case "무한삭턴": case "무한삭턴":
DB::db()->query('update general set killturn=8000 where no IN %li',$genlist); DB::db()->query('update general set killturn=8000 where no IN %li', $genlist);
break; break;
case "강제 사망": case "강제 사망":
$date = TimeUtil::now(true); $date = TimeUtil::now(true);
$db->update('general', [ $db->update('general', [
'killturn'=>0, 'killturn' => 0,
'turntime'=>$date, 'turntime' => $date,
], '`no` IN %li', $genlist); ], '`no` IN %li', $genlist);
$db->update('general_turn', [ $db->update('general_turn', [
'action'=>'휴식', 'action' => '휴식',
'arg'=>'{}', 'arg' => '{}',
'brief'=>'휴식' 'brief' => '휴식'
], 'general_id IN %li AND turn_idx = 0', $genlist); ], 'general_id IN %li AND turn_idx = 0', $genlist);
break; break;
case "메세지 전달": case "메세지 전달":
$date = TimeUtil::now(); $date = TimeUtil::now();
$src = MessageTarget::buildQuick($session->generalID); $src = MessageTarget::buildQuick($session->generalID);
for($i=0; $i < count($genlist); $i++) { for ($i = 0; $i < count($genlist); $i++) {
$msgObj = new Message( $msgObj = new Message(
Message::MSGTYPE_PRIVATE, Message::MSGTYPE_PRIVATE,
$src, $src,
@@ -73,7 +74,7 @@ switch($btn) {
new \DateTime('9999-12-31'), new \DateTime('9999-12-31'),
[] []
); );
if($msgObj){ if ($msgObj) {
$msgObj->send(true); $msgObj->send(true);
} }
} }
@@ -81,4 +82,3 @@ switch($btn) {
} }
header('location:_admin4.php'); header('location:_admin4.php');
+263 -202
View File
@@ -1,4 +1,5 @@
<?php <?php
namespace sammo; namespace sammo;
include "lib.php"; include "lib.php";
@@ -7,39 +8,22 @@ include "func.php";
$type = Util::getReq('type', 'int', 0); $type = Util::getReq('type', 'int', 0);
$type2 = Util::getReq('type2', 'int', 0); $type2 = Util::getReq('type2', 'int', 0);
if($type < 0 || $type > 17){ if ($type < 0 || $type > 17) {
$type = 0; $type = 0;
} }
if($type2 < 0 || $type2 > 6){ if ($type2 < 0 || $type2 > 6) {
$type2 = 0; $type2 = 0;
} }
//로그인 검사 //로그인 검사
$session = Session::requireGameLogin()->setReadOnly(); $session = Session::requireGameLogin()->setReadOnly();
if($session->userGrade < 5) { if ($session->userGrade < 5) {
?> die(requireAdminPermissionHTML());
<!DOCTYPE html>
<html>
<head>
<title>관리메뉴</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" />
<?=WebUtil::printCSS('../d_shared/common.css')?>
<?=WebUtil::printCSS('css/common.css')?>
</head>
<body>
관리자가 아닙니다.<br>
<?=banner()?>
</body>
</html>
<?php
exit();
} }
$db = DB::db(); $db = DB::db();
$connect=$db->get(); $connect = $db->get();
$sel = []; $sel = [];
$sel2 = []; $sel2 = [];
@@ -49,105 +33,111 @@ $sel2[$type2] = "selected";
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>일제정보</title> <title>일제정보</title>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" /> <meta name="viewport" content="width=1024" />
<?=WebUtil::printCSS('../d_shared/common.css')?> <?= WebUtil::printCSS('../d_shared/common.css') ?>
<?=WebUtil::printCSS('css/common.css')?> <?= WebUtil::printCSS('css/common.css') ?>
</head> </head>
<body> <body>
<table align=center width=1000 class='tb_layout bg0'> <table align=center width=1000 class='tb_layout bg0'>
<tr><td>일 제 정 보<br><?=closeButton()?></td></tr> <tr>
<tr><td> <td>일 제 정 보<br><?= closeButton() ?></td>
<form name=form1 method=post>정렬순서 : </tr>
<select name=type size=1> <tr>
<option <?=$sel[0]??''?> value=0>국력</option> <td>
<option <?=$sel[1]??''?> value=1>장수</option> <form name=form1 method=post>정렬순서 :
<option <?=$sel[2]??''?> value=2>기술</option> <select name=type size=1>
<option <?=$sel[3]??''?> value=3>국</option> <option <?= $sel[0] ?? '' ?> value=0>국</option>
<option <?=$sel[4]??''?> value=4>병량</option> <option <?= $sel[1] ?? '' ?> value=1>장수</option>
<option <?=$sel[5]??''?> value=5>평금</option> <option <?= $sel[2] ?? '' ?> value=2>기술</option>
<option <?=$sel[6]??''?> value=6>평쌀</option> <option <?= $sel[3] ?? '' ?> value=3>국고</option>
<option <?=$sel[7]??''?> value=7>평통</option> <option <?= $sel[4] ?? '' ?> value=4>병량</option>
<option <?=$sel[8]??''?> value=8>평</option> <option <?= $sel[5] ?? '' ?> value=5>평</option>
<option <?=$sel[9]??''?> value=9>평</option> <option <?= $sel[6] ?? '' ?> value=6>평</option>
<option <?=$sel[10]??''?> value=10>평Lv</option> <option <?= $sel[7] ?? '' ?> value=7>평통</option>
<option <?=$sel[11]??''?> value=11>접속률</option> <option <?= $sel[8] ?? '' ?> value=8>평무</option>
<option <?=$sel[12]??''?> value=12>단기접</option> <option <?= $sel[9] ?? '' ?> value=9>평지</option>
<option <?=$sel[13]??''?> value=13>보숙</option> <option <?= $sel[10] ?? '' ?> value=10>평Lv</option>
<option <?=$sel[14]??''?> value=14>궁숙</option> <option <?= $sel[11] ?? '' ?> value=11>접속률</option>
<option <?=$sel[15]??''?> value=15>기숙</option> <option <?= $sel[12] ?? '' ?> value=12>단기접</option>
<option <?=$sel[16]??''?> value=16>귀숙</option> <option <?= $sel[13] ?? '' ?> value=13>보숙</option>
<option <?=$sel[17]??''?> value=17>차숙</option> <option <?= $sel[14] ?? '' ?> value=14>궁숙</option>
</select> <option <?= $sel[15] ?? '' ?> value=15>기숙</option>
<select name=type2 size=1> <option <?= $sel[16] ?? '' ?> value=16>귀숙</option>
<option <?=$sel2[0]??''?> value=0>국력</option> <option <?= $sel[17] ?? '' ?> value=17>차숙</option>
<option <?=$sel2[1]??''?> value=1>국가별성향</option> </select>
<option <?=$sel2[2]??''?> value=2>국가성향</option> <select name=type2 size=1>
<option <?=$sel2[3]??''?> value=3>장수성격</option> <option <?= $sel2[0] ?? '' ?> value=0>국력</option>
<option <?=$sel2[4]??''?> value=4>장수특기</option> <option <?= $sel2[1] ?? '' ?> value=1>국가별성향</option>
<option <?=$sel2[5]??''?> value=5>병종수</option> <option <?= $sel2[2] ?? '' ?> value=2>국가성향</option>
<option <?=$sel2[6]??''?> value=6>기타</option> <option <?= $sel2[3] ?? '' ?> value=3>장수성격</option>
</select> <option <?= $sel2[4] ?? '' ?> value=4>장수특기</option>
<input type=submit value='정렬하기'> <option <?= $sel2[5] ?? '' ?> value=5>병종수</option>
</form> <option <?= $sel2[6] ?? '' ?> value=6>기타</option>
<form name=form2 method=post action=_admin5_submit.php> </select>
<select name=nation size=1 style=color:white;background-color:black>"; <input type=submit value='정렬하기'>
<option value=0>재야</option>"; </form>
<?php <form name=form2 method=post action=_admin5_submit.php>
$query = "select nation,name,color,scout,scoutmsg,gennum from nation order by power"; <select name=nation size=1 style=color:white;background-color:black>";
$result = MYDB_query($query, $connect) or Error("aaa_processing.php ".MYDB_error($connect),""); <option value=0>재야</option>";
$count = MYDB_num_rows($result); <?php
for($i=1; $i <= $count; $i++) { $query = "select nation,name,color,scout,scoutmsg,gennum from nation order by power";
$nation = MYDB_fetch_array($result); $result = MYDB_query($query, $connect) or Error("aaa_processing.php " . MYDB_error($connect), "");
$count = MYDB_num_rows($result);
for ($i = 1; $i <= $count; $i++) {
$nation = MYDB_fetch_array($result);
echo " echo "
<option value={$nation['nation']}>{$nation['name']}</option>"; <option value={$nation['nation']}>{$nation['name']}</option>";
} }
?> ?>
</select> </select>
<input type=submit name=btn value='국가변경'> <input type=submit name=btn value='국가변경'>
</form> </form>
</td></tr> </td>
</table> </tr>
</table>
<table align=center width=1600 class="tb_layout bg0"> <table align=center width=1600 class="tb_layout bg0">
<tr id=bg1> <tr id=bg1>
<td align=center>국명</td> <td align=center>국명</td>
<td align=center>접률</td> <td align=center>접률</td>
<td align=center>단접</td> <td align=center>단접</td>
<td align=center>국력</td> <td align=center>국력</td>
<td align=center>장수</td> <td align=center>장수</td>
<td align=center>속령</td> <td align=center>속령</td>
<td align=center>기술</td> <td align=center>기술</td>
<td align=center>전략</td> <td align=center>전략</td>
<td align=center>국고</td> <td align=center>국고</td>
<td align=center>병량</td> <td align=center>병량</td>
<td align=center>평금</td> <td align=center>평금</td>
<td align=center>평쌀</td> <td align=center>평쌀</td>
<td align=center>평통</td> <td align=center>평통</td>
<td align=center>평무</td> <td align=center>평무</td>
<td align=center>평지</td> <td align=center>평지</td>
<td align=center>평Lv</td> <td align=center>평Lv</td>
<td align=center>보숙</td> <td align=center>보숙</td>
<td align=center>궁숙</td> <td align=center>궁숙</td>
<td align=center>기숙</td> <td align=center>기숙</td>
<td align=center>귀숙</td> <td align=center>귀숙</td>
<td align=center>차숙</td> <td align=center>차숙</td>
<td align=center>총병</td> <td align=center>총병</td>
<td align=center>인구</td> <td align=center>인구</td>
<td align=center>인구율</td> <td align=center>인구율</td>
<td align=center>농업</td> <td align=center>농업</td>
<td align=center>상업</td> <td align=center>상업</td>
<td align=center>치안</td> <td align=center>치안</td>
<td align=center>성벽</td> <td align=center>성벽</td>
<td align=center>수비</td> <td align=center>수비</td>
<td align=center>국명</td> <td align=center>국명</td>
</tr> </tr>
<?php <?php
$query = " $query = "
SELECT SELECT
A.nation, A.nation,
A.name, A.name,
@@ -170,32 +160,68 @@ WHERE A.nation=B.nation
GROUP BY B.nation GROUP BY B.nation
"; ";
switch($type) { switch ($type) {
case 0: $query .= " order by power desc"; break; case 0:
case 1: $query .= " order by gennum desc"; break; $query .= " order by power desc";
case 2: $query .= " order by A.tech desc"; break; break;
case 3: $query .= " order by A.gold desc"; break; case 1:
case 4: $query .= " order by A.rice desc"; break; $query .= " order by gennum desc";
case 5: $query .= " order by avg(B.gold) desc"; break; break;
case 6: $query .= " order by avg(B.rice) desc"; break; case 2:
case 7: $query .= " order by avg(B.leadership) desc"; break; $query .= " order by A.tech desc";
case 8: $query .= " order by avg(B.strength) desc"; break; break;
case 9: $query .= " order by avg(B.intel) desc"; break; case 3:
case 10: $query .= " order by avg(B.explevel) desc"; break; $query .= " order by A.gold desc";
case 11: $query .= " order by avg(B.connect) desc"; break; break;
case 12: $query .= " order by avg(B.con) desc"; break; case 4:
case 13: $query .= " order by avg(B.dex1) desc"; break; $query .= " order by A.rice desc";
case 14: $query .= " order by avg(B.dex2) desc"; break; break;
case 15: $query .= " order by avg(B.dex3) desc"; break; case 5:
case 16: $query .= " order by avg(B.dex4) desc"; break; $query .= " order by avg(B.gold) desc";
case 17: $query .= " order by avg(B.dex5) desc"; break; break;
} case 6:
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); $query .= " order by avg(B.rice) desc";
$nationCount = MYDB_num_rows($result); break;
for($i=0; $i < $nationCount; $i++) { case 7:
$nation = MYDB_fetch_array($result); $query .= " order by avg(B.leadership) desc";
break;
case 8:
$query .= " order by avg(B.strength) desc";
break;
case 9:
$query .= " order by avg(B.intel) desc";
break;
case 10:
$query .= " order by avg(B.explevel) desc";
break;
case 11:
$query .= " order by avg(B.connect) desc";
break;
case 12:
$query .= " order by avg(B.con) desc";
break;
case 13:
$query .= " order by avg(B.dex1) desc";
break;
case 14:
$query .= " order by avg(B.dex2) desc";
break;
case 15:
$query .= " order by avg(B.dex3) desc";
break;
case 16:
$query .= " order by avg(B.dex4) desc";
break;
case 17:
$query .= " order by avg(B.dex5) desc";
break;
}
$result = MYDB_query($query, $connect) or Error(__LINE__ . MYDB_error($connect), "");
$nationCount = MYDB_num_rows($result);
for ($i = 0; $i < $nationCount; $i++) {
$nation = MYDB_fetch_array($result);
$query = "select COUNT(*) as cnt, $query = "select COUNT(*) as cnt,
ROUND(AVG(gold)) as avgg, ROUND(AVG(gold)) as avgg,
ROUND(AVG(rice)) as avgr, ROUND(AVG(rice)) as avgr,
SUM(leadership) as leadership, ROUND(AVG(leadership), 1) as avgl, SUM(leadership) as leadership, ROUND(AVG(leadership), 1) as avgl,
@@ -204,10 +230,10 @@ for($i=0; $i < $nationCount; $i++) {
ROUND(AVG(explevel), 1) as avge, ROUND(AVG(explevel), 1) as avge,
SUM(crew) as crew SUM(crew) as crew
from general where nation='{$nation['nation']}'"; from general where nation='{$nation['nation']}'";
$genResult = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); $genResult = MYDB_query($query, $connect) or Error(__LINE__ . MYDB_error($connect), "");
$gen = MYDB_fetch_array($genResult); $gen = MYDB_fetch_array($genResult);
$query = "select COUNT(*) as cnt, $query = "select COUNT(*) as cnt,
SUM(pop) as pop, SUM(pop_max) as pop_max, SUM(pop) as pop, SUM(pop_max) as pop_max,
ROUND(SUM(pop)/SUM(pop_max)*100, 2) as rate, ROUND(SUM(pop)/SUM(pop_max)*100, 2) as rate,
trust, trust,
@@ -217,18 +243,18 @@ for($i=0; $i < $nationCount; $i++) {
ROUND(SUM(wall)/SUM(wall_max)*100, 2) as wall, ROUND(SUM(wall)/SUM(wall_max)*100, 2) as wall,
ROUND(SUM(def)/SUM(def_max)*100, 2) as def ROUND(SUM(def)/SUM(def_max)*100, 2) as def
from city where nation='{$nation['nation']}'"; from city where nation='{$nation['nation']}'";
$cityResult = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); $cityResult = MYDB_query($query, $connect) or Error(__LINE__ . MYDB_error($connect), "");
$city = MYDB_fetch_array($cityResult); $city = MYDB_fetch_array($cityResult);
echo " echo "
<tr> <tr>
<td align=center style=background-color:{$nation['color']};color:".newColor($nation['color']).";>{$nation['name']}</td> <td align=center style=background-color:{$nation['color']};color:" . newColor($nation['color']) . ";>{$nation['name']}</td>
<td align=center>&nbsp;{$nation['connect']}&nbsp;</td> <td align=center>&nbsp;{$nation['connect']}&nbsp;</td>
<td align=center>&nbsp;{$nation['con']}&nbsp;</td> <td align=center>&nbsp;{$nation['con']}&nbsp;</td>
<td align=center>&nbsp;{$nation['power']}&nbsp;</td> <td align=center>&nbsp;{$nation['power']}&nbsp;</td>
<td align=center>&nbsp;{$gen['cnt']}&nbsp;</td> <td align=center>&nbsp;{$gen['cnt']}&nbsp;</td>
<td align=center>&nbsp;{$city['cnt']}&nbsp;</td> <td align=center>&nbsp;{$city['cnt']}&nbsp;</td>
<td align=right>&nbsp;".sprintf('%.1f',$nation['tech'])."&nbsp;</td> <td align=right>&nbsp;" . sprintf('%.1f', $nation['tech']) . "&nbsp;</td>
<td align=center>&nbsp;{$nation['strategic_cmd_limit']}&nbsp;</td> <td align=center>&nbsp;{$nation['strategic_cmd_limit']}&nbsp;</td>
<td align=center>&nbsp;{$nation['gold']}&nbsp;</td> <td align=center>&nbsp;{$nation['gold']}&nbsp;</td>
<td align=center>&nbsp;{$nation['rice']}&nbsp;</td> <td align=center>&nbsp;{$nation['rice']}&nbsp;</td>
@@ -245,77 +271,112 @@ for($i=0; $i < $nationCount; $i++) {
<td align=right>&nbsp;{$nation['dex5']}&nbsp;</td> <td align=right>&nbsp;{$nation['dex5']}&nbsp;</td>
<td align=right>&nbsp;{$gen['crew']}/{$gen['leadership']}00&nbsp;</td> <td align=right>&nbsp;{$gen['crew']}/{$gen['leadership']}00&nbsp;</td>
<td align=center>&nbsp;{$city['pop']}/{$city['pop_max']}&nbsp;</td> <td align=center>&nbsp;{$city['pop']}/{$city['pop_max']}&nbsp;</td>
<td align=center>&nbsp;".sprintf('%.1f',$city['pop']/Util::valueFit($city['pop_max'],1)*100)."%&nbsp;</td> <td align=center>&nbsp;" . sprintf('%.1f', $city['pop'] / Util::valueFit($city['pop_max'], 1) * 100) . "%&nbsp;</td>
<td align=center>&nbsp;{$city['agri']}%&nbsp;</td> <td align=center>&nbsp;{$city['agri']}%&nbsp;</td>
<td align=center>&nbsp;{$city['comm']}%&nbsp;</td> <td align=center>&nbsp;{$city['comm']}%&nbsp;</td>
<td align=center>&nbsp;{$city['secu']}%&nbsp;</td> <td align=center>&nbsp;{$city['secu']}%&nbsp;</td>
<td align=center>&nbsp;{$city['wall']}%&nbsp;</td> <td align=center>&nbsp;{$city['wall']}%&nbsp;</td>
<td align=center>&nbsp;{$city['def']}%&nbsp;</td> <td align=center>&nbsp;{$city['def']}%&nbsp;</td>
<td align=center style=background-color:{$nation['color']};color:".newColor($nation['color']).";>{$nation['name']}</td> <td align=center style=background-color:{$nation['color']};color:" . newColor($nation['color']) . ";>{$nation['name']}</td>
</tr> </tr>
"; ";
} }
?> ?>
</table> </table>
<table align=center width=1000 class='tb_layout bg0'> <table align=center width=1000 class='tb_layout bg0'>
<tr><td><?=getSabotageLogRecent(20)?></td></tr> <tr>
</table> <td><?= getSabotageLogRecent(20) ?></td>
</tr>
</table>
<table align=center width=1760 class="tb_layout bg0"> <table align=center width=1760 class="tb_layout bg0">
<tr id=bg1> <tr id=bg1>
<td width=30 align=center>년</td> <td width=30 align=center>년</td>
<td width=30 align=center>월</td> <td width=30 align=center>월</td>
<td width=50 align=center>국가수</td> <td width=50 align=center>국가수</td>
<td width=50 align=center>장수수</td> <td width=50 align=center>장수수</td>
<?php <?php
switch($type2) { switch ($type2) {
default: default:
case 0: echo "<td width=1600>국력(국력,장수수,도시수,인구/100,최대인구/100,국가자원/100,장수자원/100,능력치,숙련/1000,경험공헌/100)</td>"; break; case 0:
case 1: echo "<td width=1600>국가별성향</td>"; break; echo "<td width=1600>국력(국력,장수수,도시수,인구/100,최대인구/100,국가자원/100,장수자원/100,능력치,숙련/1000,경험공헌/100)</td>";
case 2: echo "<td width=1600>국가성향</td>"; break; break;
case 3: echo "<td width=1600>장수성격</td>"; break; case 1:
case 4: echo "<td width=1600>장수특기</td>"; break; echo "<td width=1600>국가별성향</td>";
case 5: echo "<td width=1600>병종수</td>"; break; break;
case 6: echo "<td width=1600>기타</td>"; break; case 2:
} echo "<td width=1600>국가성향</td>";
?> break;
</tr> case 3:
<?php echo "<td width=1600>장수성격</td>";
$query = "select * from statistic where month=1 or no=1"; break;
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); case 4:
$count = MYDB_num_rows($result); echo "<td width=1600>장수특기</td>";
for($i=0; $i < $count; $i++) { break;
$stat = MYDB_fetch_array($result); case 5:
echo "<td width=1600>병종수</td>";
break;
case 6:
echo "<td width=1600>기타</td>";
break;
}
?>
</tr>
<?php
$query = "select * from statistic where month=1 or no=1";
$result = MYDB_query($query, $connect) or Error(__LINE__ . MYDB_error($connect), "");
$count = MYDB_num_rows($result);
for ($i = 0; $i < $count; $i++) {
$stat = MYDB_fetch_array($result);
echo " echo "
<tr> <tr>
<td align=center>{$stat['year']}</td> <td align=center>{$stat['year']}</td>
<td align=center>{$stat['month']}</td> <td align=center>{$stat['month']}</td>
<td align=center>{$stat['nation_count']}</td> <td align=center>{$stat['nation_count']}</td>
<td align=center>{$stat['gen_count']}</td> <td align=center>{$stat['gen_count']}</td>
"; ";
switch($type2) { switch ($type2) {
default: default:
case 0: echo "<td>{$stat['power_hist']}</td>"; break; case 0:
case 1: echo "<td>{$stat['nation_name']}</td>"; break; echo "<td>{$stat['power_hist']}</td>";
case 2: echo "<td>{$stat['nation_hist']}</td>"; break; break;
case 3: echo "<td>{$stat['personal_hist']}</td>"; break; case 1:
case 4: echo "<td>{$stat['special_hist']}</td>"; break; echo "<td>{$stat['nation_name']}</td>";
case 5: echo "<td>{$stat['crewtype']}</td>"; break; break;
case 6: echo "<td>{$stat['etc']}</td>"; break; case 2:
} echo "<td>{$stat['nation_hist']}</td>";
break;
echo " case 3:
echo "<td>{$stat['personal_hist']}</td>";
break;
case 4:
echo "<td>{$stat['special_hist']}</td>";
break;
case 5:
echo "<td>{$stat['crewtype']}</td>";
break;
case 6:
echo "<td>{$stat['etc']}</td>";
break;
}
echo "
</tr> </tr>
"; ";
} }
?> ?>
</table> </table>
<table align=center width=1000 class='tb_layout bg0'> <table align=center width=1000 class='tb_layout bg0'>
<tr><td><?=closeButton()?></td></tr> <tr>
<tr><td><?=banner()?> </td></tr> <td><?= closeButton() ?></td>
</table> </tr>
<tr>
<td><?= banner() ?> </td>
</tr>
</table>
</body> </body>
</html>
</html>
+13 -14
View File
@@ -1,4 +1,5 @@
<?php <?php
namespace sammo; namespace sammo;
include "lib.php"; include "lib.php";
@@ -11,40 +12,38 @@ $nation = Util::getReq('nation', 'int');
$session = Session::requireGameLogin()->setReadOnly(); $session = Session::requireGameLogin()->setReadOnly();
$userID = Session::getUserID(); $userID = Session::getUserID();
if($session->userGrade < 5) { if ($session->userGrade < 5) {
header('location:_admin5.php'); header('location:_admin5.php');
die(); die();
} }
$db = DB::db(); $db = DB::db();
switch($btn) { switch ($btn) {
case "국가변경": case "국가변경":
$oldNation = $db->queryFirstField('SELECT nation FROM general WHERE owner=%i', $userID); $oldNation = $db->queryFirstField('SELECT nation FROM general WHERE owner=%i', $userID);
if($nation == 0) { if ($nation == 0) {
$db->update('general', [ $db->update('general', [
'nation'=>0, 'nation' => 0,
'officer_level'=>0, 'officer_level' => 0,
'officer_city'=>0 'officer_city' => 0
], 'owner=%i', $userID); ], 'owner=%i', $userID);
} else { } else {
$db->update('general', [ $db->update('general', [
'nation'=>$nation, 'nation' => $nation,
'officer_level'=>1, 'officer_level' => 1,
'officer_city'=>0 'officer_city' => 0
], 'owner=%i', $userID); ], 'owner=%i', $userID);
$db->update('nation', [ $db->update('nation', [
'gennum'=>$db->sqleval('gennum + 1') 'gennum' => $db->sqleval('gennum + 1')
], 'nation=%i', $oldNation); ], 'nation=%i', $oldNation);
} }
if($oldNation != 0){ if ($oldNation != 0) {
$db->update('nation', [ $db->update('nation', [
'gennum'=>$db->sqleval('gennum - 1') 'gennum' => $db->sqleval('gennum - 1')
], 'nation=%i', $oldNation); ], 'nation=%i', $oldNation);
} }
break; break;
} }
header('location:_admin5.php'); header('location:_admin5.php');
+84 -78
View File
@@ -1,110 +1,116 @@
<?php <?php
namespace sammo; namespace sammo;
include "lib.php"; include "lib.php";
include "func.php"; include "func.php";
$type = Util::getReq('type', 'int', 0); $type = Util::getReq('type', 'int', 0);
if($type < 0 || $type > 4){ if ($type < 0 || $type > 4) {
$type = 0; $type = 0;
} }
//로그인 검사 //로그인 검사
$session = Session::requireGameLogin()->setReadOnly(); $session = Session::requireGameLogin()->setReadOnly();
if($session->userGrade < 5) { if ($session->userGrade < 5) {
?> die(requireAdminPermissionHTML());
<!DOCTYPE html>
<html>
<head>
<title>관리메뉴</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" />
<?=WebUtil::printCSS('../d_shared/common.css')?>
<?=WebUtil::printCSS('css/common.css')?>
</head>
<body>
관리자가 아닙니다.<br>
<?=banner()?>
</body>
</html>
<?php
exit();
} }
$db = DB::db(); $db = DB::db();
$connect=$db->get(); $connect = $db->get();
$sel[$type] = "selected"; $sel[$type] = "selected";
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head>
<title>접속정보</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" />
<?=WebUtil::printCSS('../d_shared/common.css')?>
<?=WebUtil::printCSS('css/common.css')?>
</head>
<body>
<table align=center width=1000 class='tb_layout bg0'>
<tr><td>접 속 정 보<br><?=closeButton()?></td></tr>
<tr><td><form name=form1 method=post>정렬순서 :
<select name=type size=1>
<option <?=$sel[0]??''?> value=0>접속률</option>
<option <?=$sel[1]??''?> value=1>총갱신</option>
<option <?=$sel[2]??''?> value=2>갱신/턴</option>
<option <?=$sel[3]??''?> value=3>총로그인</option>
<option <?=$sel[4]??''?> value=4>갱신/로그인</option>
</select>
<input type=submit value='정렬하기'></form>
</td></tr>
</table>
<table align=center class='tb_layout bg0'>
<tr id=bg1>
<td align=center width=120>장수명</td>
<td align=center width=50>접속률</td>
<td align=center width=40>시작연령</td>
<td align=center width=40>연령</td>
<td align=center width=80>총갱신</td>
<td align=center width=80>갱신/턴</td>
<td align=center width=80>총로그인</td>
<td align=center width=100>갱신/로그인</td>
</tr>
<?php
switch($type) {
case 0: $query = "select name,connect,startage,age,refcnt,logcnt,refcnt/(age-startage+1)/12 as ref,refcnt/logcnt as log from general order by connect desc limit 0,30"; break;
case 1: $query = "select name,connect,startage,age,refcnt,logcnt,refcnt/(age-startage+1)/12 as ref,refcnt/logcnt as log from general order by refcnt desc limit 0,30"; break;
case 2: $query = "select name,connect,startage,age,refcnt,logcnt,refcnt/(age-startage+1)/12 as ref,refcnt/logcnt as log from general order by ref desc limit 0,30"; break;
case 3: $query = "select name,connect,startage,age,refcnt,logcnt,refcnt/(age-startage+1)/12 as ref,refcnt/logcnt as log from general order by logcnt desc limit 0,30"; break;
case 4: $query = "select name,connect,startage,age,refcnt,logcnt,refcnt/(age-startage+1)/12 as ref,refcnt/logcnt as log from general order by log desc limit 0,30"; break;
}
$genresult = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$gencount = MYDB_num_rows($genresult);
for($i=0; $i < $gencount; $i++) { <head>
$gen = MYDB_fetch_array($genresult); <title>접속정보</title>
echo " <meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" />
<?= WebUtil::printCSS('../d_shared/common.css') ?>
<?= WebUtil::printCSS('css/common.css') ?>
</head>
<body>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td>접 속 정 보<br><?= closeButton() ?></td>
</tr>
<tr>
<td>
<form name=form1 method=post>정렬순서 :
<select name=type size=1>
<option <?= $sel[0] ?? '' ?> value=0>접속률</option>
<option <?= $sel[1] ?? '' ?> value=1>총갱신</option>
<option <?= $sel[2] ?? '' ?> value=2>갱신/턴</option>
<option <?= $sel[3] ?? '' ?> value=3>총로그인</option>
<option <?= $sel[4] ?? '' ?> value=4>갱신/로그인</option>
</select>
<input type=submit value='정렬하기'></form>
</td>
</tr>
</table>
<table align=center class='tb_layout bg0'>
<tr id=bg1>
<td align=center width=120>장수명</td>
<td align=center width=50>접속률</td>
<td align=center width=40>시작연령</td>
<td align=center width=40>연령</td>
<td align=center width=80>총갱신</td>
<td align=center width=80>갱신/턴</td>
<td align=center width=80>총로그인</td>
<td align=center width=100>갱신/로그인</td>
</tr>
<?php
switch ($type) {
case 0:
$query = "select name,connect,startage,age,refcnt,logcnt,refcnt/(age-startage+1)/12 as ref,refcnt/logcnt as log from general order by connect desc limit 0,30";
break;
case 1:
$query = "select name,connect,startage,age,refcnt,logcnt,refcnt/(age-startage+1)/12 as ref,refcnt/logcnt as log from general order by refcnt desc limit 0,30";
break;
case 2:
$query = "select name,connect,startage,age,refcnt,logcnt,refcnt/(age-startage+1)/12 as ref,refcnt/logcnt as log from general order by ref desc limit 0,30";
break;
case 3:
$query = "select name,connect,startage,age,refcnt,logcnt,refcnt/(age-startage+1)/12 as ref,refcnt/logcnt as log from general order by logcnt desc limit 0,30";
break;
case 4:
$query = "select name,connect,startage,age,refcnt,logcnt,refcnt/(age-startage+1)/12 as ref,refcnt/logcnt as log from general order by log desc limit 0,30";
break;
}
$genresult = MYDB_query($query, $connect) or Error(__LINE__ . MYDB_error($connect), "");
$gencount = MYDB_num_rows($genresult);
for ($i = 0; $i < $gencount; $i++) {
$gen = MYDB_fetch_array($genresult);
echo "
<tr> <tr>
<td align=center>{$gen['name']}</td> <td align=center>{$gen['name']}</td>
<td align=center>{$gen['connect']}</td> <td align=center>{$gen['connect']}</td>
<td align=center>{$gen['startage']}</td> <td align=center>{$gen['startage']}</td>
<td align=center>{$gen['age']}</td> <td align=center>{$gen['age']}</td>
<td align=center>".round($gen['refcnt']/2, 1)."</td> <td align=center>" . round($gen['refcnt'] / 2, 1) . "</td>
<td align=center>".round($gen['ref']/2,1)."</td> <td align=center>" . round($gen['ref'] / 2, 1) . "</td>
<td align=center>{$gen['logcnt']}</td> <td align=center>{$gen['logcnt']}</td>
<td align=center>".round($gen['log']/2,1)."</td> <td align=center>" . round($gen['log'] / 2, 1) . "</td>
</tr>"; </tr>";
} }
?> ?>
</table> </table>
<table align=center width=1000 class='tb_layout bg0'> <table align=center width=1000 class='tb_layout bg0'>
<tr><td><?=closeButton()?></td></tr> <tr>
<tr><td><?=banner()?> </td></tr> <td><?= closeButton() ?></td>
</table> </tr>
<tr>
<td><?= banner() ?> </td>
</tr>
</table>
</body> </body>
</html>
</html>
+120 -114
View File
@@ -1,4 +1,5 @@
<?php <?php
namespace sammo; namespace sammo;
include "lib.php"; include "lib.php";
@@ -10,85 +11,66 @@ $reqQueryType = Util::getReq('query_type', 'string', null);
// $queryTypeText, $reqArgType(0=>None, 1=>AdditionalColumn, 2=>rankVal, 3=>aux), $comp // $queryTypeText, $reqArgType(0=>None, 1=>AdditionalColumn, 2=>rankVal, 3=>aux), $comp
$queryMap = [ $queryMap = [
'turntime' => ['최근턴', 0, function($lhs, $rhs){ 'turntime' => ['최근턴', 0, function ($lhs, $rhs) {
return -($lhs['turntime']<=>$rhs['turntime']); return - ($lhs['turntime'] <=> $rhs['turntime']);
}], }],
'recent_war' => ['최근전투', 1, function($lhs, $rhs){ 'recent_war' => ['최근전투', 1, function ($lhs, $rhs) {
return -($lhs['recent_war']<=>$rhs['recent_war']); return - ($lhs['recent_war'] <=> $rhs['recent_war']);
}], }],
'name' => ['장수명', 0, function($lhs, $rhs){ 'name' => ['장수명', 0, function ($lhs, $rhs) {
if($lhs['npc'] !== $rhs['npc']){ if ($lhs['npc'] !== $rhs['npc']) {
return $lhs['npc']<=>$rhs['npc']; return $lhs['npc'] <=> $rhs['npc'];
} }
return $lhs['name']<=>$rhs['name']; return $lhs['name'] <=> $rhs['name'];
}], }],
'warnum' => ['전투수', 2, function($lhs, $rhs){ 'warnum' => ['전투수', 2, function ($lhs, $rhs) {
return -($lhs['warnum']<=>$rhs['warnum']); return - ($lhs['warnum'] <=> $rhs['warnum']);
}] }]
]; ];
if($reqQueryType === null || !key_exists($reqQueryType, $queryMap)){ if ($reqQueryType === null || !key_exists($reqQueryType, $queryMap)) {
$reqQueryType = Util::array_first_key($queryMap); $reqQueryType = Util::array_first_key($queryMap);
} }
//로그인 검사 //로그인 검사
$session = Session::requireGameLogin()->setReadOnly(); $session = Session::requireGameLogin()->setReadOnly();
if($session->userGrade < 5) { if ($session->userGrade < 5) {
?> die(requireAdminPermissionHTML());
<!DOCTYPE html>
<html>
<head>
<title>관리메뉴</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" />
<?=WebUtil::printCSS('../d_shared/common.css')?>
<?=WebUtil::printCSS('css/common.css')?>
</head>
<body>
관리자가 아닙니다.<br>
<?=banner()?>
</body>
</html>
<?php
exit();
} }
$db = DB::db(); $db = DB::db();
if($btn == '정렬하기') { if ($btn == '정렬하기') {
$gen = 0; $gen = 0;
} }
[$queryTypeText, $reqArgType, $comp] = $queryMap[$reqQueryType]; [$queryTypeText, $reqArgType, $comp] = $queryMap[$reqQueryType];
if($reqArgType===0){ if ($reqArgType === 0) {
$generalBasicList = $db->query('SELECT no, name, nation, npc, turntime FROM general'); $generalBasicList = $db->query('SELECT no, name, nation, npc, turntime FROM general');
} } else if ($reqArgType === 1) {
else if($reqArgType===1){
$generalBasicList = $db->query('SELECT no, name, nation, npc, turntime, %b FROM general', $reqQueryType); $generalBasicList = $db->query('SELECT no, name, nation, npc, turntime, %b FROM general', $reqQueryType);
} } else if ($reqArgType === 2) {
else if($reqArgType===2){ $generalBasicList = $db->query(
$generalBasicList = $db->query('SELECT no, name, nation, npc, turntime, value as %b 'SELECT no, name, nation, npc, turntime, value as %b
FROM general LEFT JOIN rank_data FROM general LEFT JOIN rank_data
ON general.no = rank_data.general_id ON general.no = rank_data.general_id
WHERE rank_data.type = %s', WHERE rank_data.type = %s',
$reqQueryType, $reqQueryType $reqQueryType,
$reqQueryType
); );
} } else if ($reqArgType === 3) {
else if($reqArgType===3){ $generalBasicList = array_map(function ($arr) {
$generalBasicList = array_map(function($arr){
$arr['aux'] = Json::decode($arr['aux']); $arr['aux'] = Json::decode($arr['aux']);
return $arr; return $arr;
}, $db->query('SELECT no, name, nation, npc, turntime, aux FROM general')); }, $db->query('SELECT no, name, nation, npc, turntime, aux FROM general'));
} } else {
else{
throw new \sammo\MustNotBeReachedException(); throw new \sammo\MustNotBeReachedException();
} }
usort($generalBasicList, $comp); usort($generalBasicList, $comp);
if(!$gen){ if (!$gen) {
$gen = $generalBasicList[0]['no']; $gen = $generalBasicList[0]['no'];
} }
@@ -97,76 +79,100 @@ $generalObj = General::createGeneralObjFromDB($gen);
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>로그정보</title> <title>로그정보</title>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" /> <meta name="viewport" content="width=1024" />
<?=WebUtil::printCSS('../d_shared/common.css')?> <?= WebUtil::printCSS('../d_shared/common.css') ?>
<?=WebUtil::printCSS('css/common.css')?> <?= WebUtil::printCSS('css/common.css') ?>
</head> </head>
<body> <body>
<table align=center width=1000 class='tb_layout bg0'> <table align=center width=1000 class='tb_layout bg0'>
<tr><td>로 그 정 보<br><?=closeButton()?></td></tr> <tr>
<tr><td> <td>로 그 정 보<br><?= closeButton() ?></td>
<form name=form1 method=post> </tr>
정렬순서 : <tr>
<select name='query_type' size=1> <td>
<?php foreach($queryMap as $queryType => [$queryTypeText,]): ?> <form name=form1 method=post>
<option <?=$queryType==$reqQueryType?'selected':''?> value='<?=$queryType?>'><?=$queryTypeText?></option> 정렬순서 :
<?php endforeach; ?> <select name='query_type' size=1>
</select> <?php foreach ($queryMap as $queryType => [$queryTypeText,]) : ?>
<input type=submit name=btn value='정렬하기'> <option <?= $queryType == $reqQueryType ? 'selected' : '' ?> value='<?= $queryType ?>'><?= $queryTypeText ?></option>
대상장수 : <?php endforeach; ?>
<select name=gen size=1> </select>
<?php foreach($generalBasicList as $general): ?> <input type=submit name=btn value='정렬하기'>
<option <?=$gen==$general['no']?'selected':''?> value='<?=$general['no']?>'><?=$general['name']?> (<?=substr($general['turntime'], 14, 5)?>)</option> 대상장수 :
<?php endforeach; ?> <select name=gen size=1>
</select> <?php foreach ($generalBasicList as $general) : ?>
<input type=submit name=btn value='조회하기'> <option <?= $gen == $general['no'] ? 'selected' : '' ?> value='<?= $general['no'] ?>'><?= $general['name'] ?> (<?= substr($general['turntime'], 14, 5) ?>)</option>
</form> <?php endforeach; ?>
</td></tr> </select>
</table> <input type=submit name=btn value='조회하기'>
<table width=1000 align=center class='tb_layout bg0'> </form>
<tr> </td>
<td width=50% align=center id=bg1><font color=skyblue size=3>장 수 정 보</font></td> </tr>
<td width=50% align=center id=bg1><font color=orange size=3>-</font></td> </table>
</tr> <table width=1000 align=center class='tb_layout bg0'>
<tr> <tr>
<td valign=top> <td width=50% align=center id=bg1>
<?php generalInfo($generalObj); generalInfo2($generalObj); ?> <font color=skyblue size=3>장 수 정 보</font>
</td> </td>
<td valign=top>&nbsp; <td width=50% align=center id=bg1>
</td> <font color=orange size=3>-</font>
</tr> </td>
<tr> </tr>
<td align=center id=bg1><font color=skyblue size=3>개인 기록</font></td> <tr>
<td align=center id=bg1><font color=orange size=3>전투 기록</font></td> <td valign=top>
</tr> <?php generalInfo($generalObj);
<tr> generalInfo2($generalObj); ?>
<td valign=top> </td>
<?=formatHistoryToHTML(getGenLogRecent($gen, 24))?> <td valign=top>&nbsp;
</td> </td>
<td valign=top> </tr>
<?=formatHistoryToHTML(getBatLogRecent($gen, 24))?> <tr>
</td> <td align=center id=bg1>
</tr> <font color=skyblue size=3>개인 기록</font>
<tr> </td>
<td align=center id=bg1><font color=skyblue size=3>장수 열전</font></td> <td align=center id=bg1>
<td align=center id=bg1><font color=orange size=3>전투 결과</font></td> <font color=orange size=3>전투 기록</font>
</tr> </td>
<tr> </tr>
<td valign=top> <tr>
<?=formatHistoryToHTML(getGeneralHistoryAll($gen))?> <td valign=top>
</td> <?= formatHistoryToHTML(getGenLogRecent($gen, 24)) ?>
<td valign=top> </td>
<?=formatHistoryToHTML(getBatResRecent($gen, 24))?> <td valign=top>
</td> <?= formatHistoryToHTML(getBatLogRecent($gen, 24)) ?>
</tr> </td>
</table> </tr>
<table align=center width=1000 class='tb_layout bg0'> <tr>
<tr><td><?=closeButton()?></td></tr> <td align=center id=bg1>
<tr><td><?=banner()?> </td></tr> <font color=skyblue size=3>장수 열전</font>
</table> </td>
<td align=center id=bg1>
<font color=orange size=3>전투 결과</font>
</td>
</tr>
<tr>
<td valign=top>
<?= formatHistoryToHTML(getGeneralHistoryAll($gen)) ?>
</td>
<td valign=top>
<?= formatHistoryToHTML(getBatResRecent($gen, 24)) ?>
</td>
</tr>
</table>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td><?= closeButton() ?></td>
</tr>
<tr>
<td><?= banner() ?> </td>
</tr>
</table>
</body> </body>
</html>
</html>
+1 -18
View File
@@ -12,24 +12,7 @@ $type = 0;
$session = Session::requireGameLogin()->setReadOnly(); $session = Session::requireGameLogin()->setReadOnly();
if ($session->userGrade < 5) { if ($session->userGrade < 5) {
?> die(requireAdminPermissionHTML());
<!DOCTYPE html>
<html>
<head>
<title>관리메뉴</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" />
<?=WebUtil::printCSS('../d_shared/common.css')?>
<?=WebUtil::printCSS('css/common.css')?>
</head>
<body>
관리자가 아닙니다.<br>
<?=banner()?>
</body>
</html>
<?php
exit();
} }
$db = DB::db(); $db = DB::db();
+6 -5
View File
@@ -1,4 +1,5 @@
<?php <?php
namespace sammo; namespace sammo;
include "lib.php"; include "lib.php";
@@ -6,20 +7,20 @@ include "func.php";
//로그인 검사 //로그인 검사
$session = Session::requireGameLogin()->setReadOnly(); $session = Session::requireGameLogin()->setReadOnly();
if($session->userGrade < 5) { if ($session->userGrade < 5) {
die('권한 부족'); die('권한 부족');
} }
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
if(!$gameStor->isunited){ if (!$gameStor->isunited) {
die('아직 천통하지 않았습니다'); die('아직 천통하지 않았습니다');
} }
foreach($db->queryFirstColumn( foreach ($db->queryFirstColumn(
'SELECT no FROM general WHERE npc != 0 and age >= %i', 'SELECT no FROM general WHERE npc != 0 and age >= %i',
GameConst::$retirementYear GameConst::$retirementYear
) as $generalNo){ ) as $generalNo) {
CheckHall($generalNo); CheckHall($generalNo);
} }
+4 -3
View File
@@ -9,7 +9,8 @@ $commandType = Util::getReq('command', 'string');
$turnList = array_map('intval', explode('_', Util::getReq('turnList', 'string', '0'))); $turnList = array_map('intval', explode('_', Util::getReq('turnList', 'string', '0')));
$isChiefTurn = Util::getReq('is_chief', 'bool', false); $isChiefTurn = Util::getReq('is_chief', 'bool', false);
function die_redirect(){ function die_redirect()
{
global $isChiefTurn; global $isChiefTurn;
if(!$isChiefTurn){ if(!$isChiefTurn){
header('location:index.php', true, 303); header('location:index.php', true, 303);
@@ -59,9 +60,9 @@ if($commandObj->isArgValid()){
die_redirect(); die_redirect();
} }
/*if(!$commandObj->isReservable()){ if(!$commandObj->hasPermissionToReserve()){
die_redirect(); die_redirect();
}*/ }
$jsList = $commandObj->getJSFiles(); $jsList = $commandObj->getJSFiles();
$cssList = $commandObj->getCSSFiles(); $cssList = $commandObj->getCSSFiles();
+8 -6
View File
@@ -75,14 +75,16 @@ function getNationStaticInfo($nationID, $forceRefresh=false)
/** /**
* getNationStaticInfo() 함수의 국가 캐시를 초기화 * getNationStaticInfo() 함수의 국가 캐시를 초기화
*/ */
function refreshNationStaticInfo(){ function refreshNationStaticInfo()
{
getNationStaticInfo(null, true); getNationStaticInfo(null, true);
} }
/** /**
* getNationStaticInfo(-1) 의 단축형 * getNationStaticInfo(-1) 의 단축형
*/ */
function getAllNationStaticInfo(){ function getAllNationStaticInfo()
{
return getNationStaticInfo(-1); return getNationStaticInfo(-1);
} }
@@ -447,10 +449,10 @@ function printCommandTable(General $generalObj) {
} }
?> ?>
<option <option
class='commandBasic <?=$getCompensateClassName($commandObj->getCompensationStyle())?> <?=$commandObj->isReservable()?'':'commandImpossible'?>' class='commandBasic <?=$getCompensateClassName($commandObj->getCompensationStyle())?> <?=$commandObj->hasMinConditionMet()?'':'commandImpossible'?>'
value='<?=Util::getClassNameFromObj($commandObj)?>' value='<?=Util::getClassNameFromObj($commandObj)?>'
data-reqArg='<?=($commandObj::$reqArg)?'true':'false'?>' data-reqArg='<?=($commandObj::$reqArg)?'true':'false'?>'
><?=$commandObj->getCommandDetailTitle()?><?=$commandObj->isReservable()?'':'(불가)'?></option> ><?=$commandObj->getCommandDetailTitle()?><?=$commandObj->hasMinConditionMet()?'':'(불가)'?></option>
<?php <?php
} }
@@ -499,10 +501,10 @@ function chiefCommandTable(General $generalObj) {
} }
?> ?>
<option <option
class='commandBasic <?=$getCompensateClassName($commandObj->getCompensationStyle())?> <?=$commandObj->isReservable()?'':'commandImpossible'?>' class='commandBasic <?=$getCompensateClassName($commandObj->getCompensationStyle())?> <?=$commandObj->hasMinConditionMet()?'':'commandImpossible'?>'
value='<?=Util::getClassNameFromObj($commandObj)?>' value='<?=Util::getClassNameFromObj($commandObj)?>'
data-reqArg='<?=($commandObj::$reqArg)?'true':'false'?>' data-reqArg='<?=($commandObj::$reqArg)?'true':'false'?>'
><?=$commandObj->getCommandDetailTitle()?><?=$commandObj->isReservable()?'':'(불가)'?></option> ><?=$commandObj->getCommandDetailTitle()?><?=$commandObj->hasMinConditionMet()?'':'(불가)'?></option>
<?php <?php
} }
+6 -10
View File
@@ -328,11 +328,11 @@ function setGeneralCommand(int $generalID, array $rawTurnList, string $command,
]; ];
} }
if(!$commandObj->isReservable()){ if(!$commandObj->hasPermissionToReserve()){
return [ return [
'result'=>false, 'result'=>false,
'reason'=>'예약 불가능한 커맨드 :'.$commandObj->testReservable(), 'reason'=>'예약 불가능한 커맨드 :'.$commandObj->testPermissionToReserve(),
'test'=>'isReservable', 'test'=>'hasPermissionToReserve',
'target'=>'command' 'target'=>'command'
]; ];
} }
@@ -408,18 +408,14 @@ function setNationCommand(int $generalID, array $turnList, string $command, ?arr
]; ];
} }
if(!$commandObj->isReservable()){ if(!$commandObj->hasPermissionToReserve()){
return [ return [
'result'=>false, 'result'=>false,
'reason'=>'예약 불가능한 커맨드 :'.$commandObj->testReservable(), 'reason'=>'예약 불가능한 커맨드 :'.$commandObj->testPermissionToReserve(),
'test'=>'isReservable', 'test'=>'hasPermissionToReserve',
'target'=>'command' 'target'=>'command'
]; ];
} }
//TODO: Reservable은 '정말로 입력 불가'이고, '입력은 가능하지만 실행은 안될 것 같은' 군을 하나더 추가해야함
// Runnable은 Arg를 모두 받아서 처리해야 하는 것이고, Arg를 받지 않아도 안될 것 같지만 입력 자체는 가능할 것 같은 커맨드.
$brief = $commandObj->getBrief();
_setNationCommand($commandObj, $turnList); _setNationCommand($commandObj, $turnList);
return [ return [
+1 -1
View File
@@ -497,7 +497,7 @@ function checkWander() {
foreach(General::createGeneralObjListFromDB($wanderers) as $wanderer){ foreach(General::createGeneralObjListFromDB($wanderers) as $wanderer){
$wanderCmd = buildGeneralCommandClass('che_해산', $wanderer, $admin); $wanderCmd = buildGeneralCommandClass('che_해산', $wanderer, $admin);
if($wanderCmd->isRunnable()){ if($wanderCmd->hasFullConditionMet()){
$logger = $wanderer->getLogger(); $logger = $wanderer->getLogger();
$logger->pushGeneralActionLog('초반 제한후 방랑군은 자동 해산됩니다.', ActionLogger::PLAIN); $logger->pushGeneralActionLog('초반 제한후 방랑군은 자동 해산됩니다.', ActionLogger::PLAIN);
$wanderCmd->run(); $wanderCmd->run();
+2 -1
View File
@@ -1,7 +1,8 @@
<?php <?php
namespace sammo; namespace sammo;
function getMailboxList(){ function getMailboxList()
{
$generalNations = []; $generalNations = [];
+120 -82
View File
@@ -1,4 +1,5 @@
<?php <?php
namespace sammo; namespace sammo;
@@ -10,12 +11,42 @@ namespace sammo;
* TODO: side effect를 제거 * TODO: side effect를 제거
*/ */
/**
* 관리자 권한이 필요함을 출력.
* @return void
*/
function requireAdminPermissionHTML()
{
ob_start();
?>
<!DOCTYPE html>
<html>
function turnTable() { <head>
<title>관리메뉴</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" />
<?= WebUtil::printCSS('../d_shared/common.css') ?>
<?= WebUtil::printCSS('css/common.css') ?>
</head>
<body>
관리자가 아닙니다.<br>
<?= banner() ?>
</body>
</html>
<?php
return ob_get_clean();
}
function turnTable()
{
$turnList = []; $turnList = [];
$turnList[] = "<option selected value='0'>1턴</option>"; $turnList[] = "<option selected value='0'>1턴</option>";
foreach(Util::range(1, GameConst::$maxTurn) as $turnIdx){ foreach (Util::range(1, GameConst::$maxTurn) as $turnIdx) {
$turnText = $turnIdx + 1; $turnText = $turnIdx + 1;
$turnList[] = "<option value='{$turnIdx}'>{$turnText}턴</option>"; $turnList[] = "<option value='{$turnIdx}'>{$turnText}턴</option>";
} }
@@ -32,81 +63,86 @@ function turnTable() {
"; ";
} }
function chiefTurnTable() { function chiefTurnTable()
$turnList = []; {
$turnList[] = "<option selected value='0'>1턴</option>"; $turnList = [];
foreach(Util::range(1, GameConst::$maxChiefTurn) as $turnIdx){ $turnList[] = "<option selected value='0'>1턴</option>";
$turnText = $turnIdx + 1; foreach (Util::range(1, GameConst::$maxChiefTurn) as $turnIdx) {
$turnList[] = "<option value='{$turnIdx}'>{$turnText}턴</option>"; $turnText = $turnIdx + 1;
} $turnList[] = "<option value='{$turnIdx}'>{$turnText}턴</option>";
}
$turnText = join("\n", $turnList); $turnText = join("\n", $turnList);
return " return "
<select id='chiefTurnSelector' name=turn[] size=6 multiple> <select id='chiefTurnSelector' name=turn[] size=6 multiple>
{$turnText} {$turnText}
</select> </select>
"; ";
} }
function displayiActionObjInfo(?iAction $action){ function displayiActionObjInfo(?iAction $action)
if($action === null){ {
if ($action === null) {
$info = ''; $info = '';
$text = '-'; $text = '-';
} } else {
else{
$info = $action->getInfo(); $info = $action->getInfo();
$text = $action->getName(); $text = $action->getName();
} }
$templates = new \League\Plates\Engine(__DIR__.'/templates'); $templates = new \League\Plates\Engine(__DIR__ . '/templates');
return $templates->render('tooltip', [ return $templates->render('tooltip', [
'text'=>$text, 'text' => $text,
'info'=>$info, 'info' => $info,
]); ]);
} }
function displayCharInfo(string $type):string{ function displayCharInfo(string $type): string
{
$class = buildPersonalityClass($type); $class = buildPersonalityClass($type);
$info = $class->getInfo(); $info = $class->getInfo();
$text = $class->getName(); $text = $class->getName();
$templates = new \League\Plates\Engine(__DIR__.'/templates'); $templates = new \League\Plates\Engine(__DIR__ . '/templates');
return $templates->render('tooltip', [ return $templates->render('tooltip', [
'text'=>$text, 'text' => $text,
'info'=>$info, 'info' => $info,
]); ]);
} }
function displaySpecialWarInfo(?string $type):string{ function displaySpecialWarInfo(?string $type): string
{
$class = buildGeneralSpecialWarClass($type); $class = buildGeneralSpecialWarClass($type);
$info = $class->getInfo(); $info = $class->getInfo();
$name = $class->getName(); $name = $class->getName();
$templates = new \League\Plates\Engine(__DIR__.'/templates'); $templates = new \League\Plates\Engine(__DIR__ . '/templates');
return $templates->render('tooltip', [ return $templates->render('tooltip', [
'text'=>$name, 'text' => $name,
'info'=>$info, 'info' => $info,
]); ]);
} }
function displaySpecialDomesticInfo(?string $type):string{ function displaySpecialDomesticInfo(?string $type): string
{
$class = buildGeneralSpecialDomesticClass($type); $class = buildGeneralSpecialDomesticClass($type);
$info = $class->getInfo(); $info = $class->getInfo();
$name = $class->getName(); $name = $class->getName();
$templates = new \League\Plates\Engine(__DIR__.'/templates'); $templates = new \League\Plates\Engine(__DIR__ . '/templates');
return $templates->render('tooltip', [ return $templates->render('tooltip', [
'text'=>$name, 'text' => $name,
'info'=>$info, 'info' => $info,
]); ]);
} }
function allButton(bool $seizeNPCMode) { function allButton(bool $seizeNPCMode)
if($seizeNPCMode) { {
if ($seizeNPCMode) {
$site = "a_npcList.php"; $site = "a_npcList.php";
$call = "빙의일람"; $call = "빙의일람";
} else { } else {
@@ -114,13 +150,12 @@ function allButton(bool $seizeNPCMode) {
$call = "설문조사"; $call = "설문조사";
} }
if(\file_exists(__DIR__."/d_setting/templates/allButton.php")){ if (\file_exists(__DIR__ . "/d_setting/templates/allButton.php")) {
$templates = new \League\Plates\Engine(__DIR__.'/d_setting/templates'); $templates = new \League\Plates\Engine(__DIR__ . '/d_setting/templates');
} else {
$templates = new \League\Plates\Engine(__DIR__ . '/templates');
} }
else{
$templates = new \League\Plates\Engine(__DIR__.'/templates');
}
return $templates->render('allButton', [ return $templates->render('allButton', [
'call' => $call, 'call' => $call,
@@ -129,104 +164,107 @@ function allButton(bool $seizeNPCMode) {
} }
function commandButton() { function commandButton()
{
$session = Session::getInstance(); $session = Session::getInstance();
$userID = Session::getUserID(); $userID = Session::getUserID();
if(!$session->isGameLoggedIn()){ if (!$session->isGameLoggedIn()) {
return ''; return '';
} }
$db = DB::db(); $db = DB::db();
$me = $db->queryFirstRow("select no,nation,officer_level,belong,permission,penalty from general where owner=%i", $userID); $me = $db->queryFirstRow("select no,nation,officer_level,belong,permission,penalty from general where owner=%i", $userID);
$nation = $db->queryFirstRow("select nation,level,color,secretlimit from nation where nation=%i",$me['nation'])??[ $nation = $db->queryFirstRow("select nation,level,color,secretlimit from nation where nation=%i", $me['nation']) ?? [
'nation'=>0, 'nation' => 0,
'level'=>0, 'level' => 0,
'secretlimit'=>99, 'secretlimit' => 99,
'color'=>'#000000' 'color' => '#000000'
]; ];
$bgColor = Util::array_get($nation['color'])?:'#000000'; $bgColor = Util::array_get($nation['color']) ?: '#000000';
$fgColor = newColor($bgColor); $fgColor = newColor($bgColor);
$templates = new \League\Plates\Engine(__DIR__.'/templates'); $templates = new \League\Plates\Engine(__DIR__ . '/templates');
$showSecret = false; $showSecret = false;
$permission = checkSecretPermission($me); $permission = checkSecretPermission($me);
if($permission >= 1){ if ($permission >= 1) {
$showSecret = true; $showSecret = true;
} } else if ($me['officer_level'] == 0) {
else if($me['officer_level']== 0){
$showSecret = false; $showSecret = false;
} }
return $templates->render('commandButton', [ return $templates->render('commandButton', [
'bgColor'=>$bgColor, 'bgColor' => $bgColor,
'fgColor'=>$fgColor, 'fgColor' => $fgColor,
'meLevel'=>$me['officer_level'], 'meLevel' => $me['officer_level'],
'nationLevel'=>$nation['level'], 'nationLevel' => $nation['level'],
'showSecret'=>$showSecret, 'showSecret' => $showSecret,
'permission'=>$permission, 'permission' => $permission,
]); ]);
} }
function formatWounded(int $value, int $wound): string{ function formatWounded(int $value, int $wound): string
if($wound == 0){ {
if ($wound == 0) {
return "$value"; return "$value";
} }
$woundedValue = intdiv($value * (100 - $wound), 100); $woundedValue = intdiv($value * (100 - $wound), 100);
return "<font color=red>$woundedValue</font>"; return "<font color=red>$woundedValue</font>";
} }
function formatDefenceTrain(int $value): string{ function formatDefenceTrain(int $value): string
if($value === 999){ {
if ($value === 999) {
return "×"; return "×";
} } else if ($value >= 80) {
else if($value >= 80){
return "◎"; return "◎";
} } else {
else{
return "○"; return "○";
} }
} }
function formatLeadershipBonus(int $value): string{ function formatLeadershipBonus(int $value): string
if($value == 0){ {
if ($value == 0) {
return ''; return '';
} }
return "<font color=cyan>+{$value}</font>"; return "<font color=cyan>+{$value}</font>";
} }
function formatName(string $name, int $npc): string{ function formatName(string $name, int $npc): string
if($npc==1){ {
if ($npc == 1) {
$name = "<font color='skyblue'>$name</font>"; $name = "<font color='skyblue'>$name</font>";
} } else if ($npc > 1) {
else if($npc>1){
$name = "<font color='cyan'>$name</font>"; $name = "<font color='cyan'>$name</font>";
} }
return $name; return $name;
} }
function getMapHtml(?string $mapTheme=null){ function getMapHtml(?string $mapTheme = null)
$templates = new \League\Plates\Engine(__DIR__.'/templates'); {
$templates = new \League\Plates\Engine(__DIR__ . '/templates');
if($mapTheme === null){ if ($mapTheme === null) {
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
$mapTheme = $gameStor->map_theme??'che'; $mapTheme = $gameStor->map_theme ?? 'che';
} }
return $templates->render('map', [ return $templates->render('map', [
'mapTheme'=>$mapTheme 'mapTheme' => $mapTheme
]); ]);
} }
function getInvitationList(array $nationList){ function getInvitationList(array $nationList)
$templates = new \League\Plates\Engine(__DIR__.'/templates'); {
$templates = new \League\Plates\Engine(__DIR__ . '/templates');
foreach($nationList as &$nation){ foreach ($nationList as &$nation) {
$nation['textColor'] = newColor($nation['color']); $nation['textColor'] = newColor($nation['color']);
} }
return $templates->render('invitationList', [ return $templates->render('invitationList', [
'nationList'=>$nationList 'nationList' => $nationList
]); ]);
} }
+90 -78
View File
@@ -2,7 +2,8 @@
namespace sammo; namespace sammo;
class ActionLogger{ class ActionLogger
{
//TODO: global을 따로 뗴어내고, 장수 Logger를 상속해서 받는 형식으로. //TODO: global을 따로 뗴어내고, 장수 Logger를 상속해서 받는 형식으로.
protected $generalID; protected $generalID;
protected $nationID; protected $nationID;
@@ -10,7 +11,7 @@ class ActionLogger{
protected $year = null; protected $year = null;
protected $month = null; protected $month = null;
protected $generalHistoryLog = []; protected $generalHistoryLog = [];
protected $generalActionLog = []; protected $generalActionLog = [];
protected $generalBattleResultLog = []; protected $generalBattleResultLog = [];
@@ -37,7 +38,8 @@ class ActionLogger{
/** <R>★</>{$year}년 {$month}월: */ /** <R>★</>{$year}년 {$month}월: */
const NOTICE_YEAR_MONTH = 8; const NOTICE_YEAR_MONTH = 8;
public function __construct(int $generalID, int $nationID, int $year, int $month, bool $autoFlush = true){ public function __construct(int $generalID, int $nationID, int $year, int $month, bool $autoFlush = true)
{
$this->generalID = $generalID; $this->generalID = $generalID;
$this->nationID = $nationID; $this->nationID = $nationID;
$this->year = $year; $this->year = $year;
@@ -45,23 +47,25 @@ class ActionLogger{
$this->autoFlush = $autoFlush; $this->autoFlush = $autoFlush;
} }
public function __destruct(){ public function __destruct()
if($this->autoFlush){ {
if ($this->autoFlush) {
$this->flush(); $this->flush();
} }
} }
public function rollback(){ public function rollback()
{
$backup = [ $backup = [
'generalHistoryLog'=>$this->generalHistoryLog, 'generalHistoryLog' => $this->generalHistoryLog,
'generalActionLog'=>$this->generalActionLog, 'generalActionLog' => $this->generalActionLog,
'generalBattleResultLog'=>$this->generalBattleResultLog, 'generalBattleResultLog' => $this->generalBattleResultLog,
'generalBattleDetailLog'=>$this->generalBattleDetailLog, 'generalBattleDetailLog' => $this->generalBattleDetailLog,
'nationalHistoryLog'=>$this->nationalHistoryLog, 'nationalHistoryLog' => $this->nationalHistoryLog,
'globalHistoryLog'=>$this->globalHistoryLog, 'globalHistoryLog' => $this->globalHistoryLog,
'globalActionLog'=>$this->globalActionLog, 'globalActionLog' => $this->globalActionLog,
]; ];
$this->generalHistoryLog = []; $this->generalHistoryLog = [];
$this->generalActionLog = []; $this->generalActionLog = [];
$this->generalBattleResultLog = []; $this->generalBattleResultLog = [];
@@ -73,50 +77,52 @@ class ActionLogger{
return $backup; return $backup;
} }
public function flush(){ public function flush()
if($this->generalHistoryLog && $this->generalID){ {
if ($this->generalHistoryLog && $this->generalID) {
pushGeneralHistory($this->generalID, $this->generalHistoryLog, $this->year, $this->month); pushGeneralHistory($this->generalID, $this->generalHistoryLog, $this->year, $this->month);
$this->generalHistoryLog = []; $this->generalHistoryLog = [];
} }
if($this->generalActionLog && $this->generalID){ if ($this->generalActionLog && $this->generalID) {
pushGenLog($this->generalID, $this->generalActionLog, $this->year, $this->month); pushGenLog($this->generalID, $this->generalActionLog, $this->year, $this->month);
$this->generalActionLog = []; $this->generalActionLog = [];
} }
if($this->generalBattleResultLog && $this->generalID){ if ($this->generalBattleResultLog && $this->generalID) {
pushBatRes($this->generalID, $this->generalBattleResultLog, $this->year, $this->month); pushBatRes($this->generalID, $this->generalBattleResultLog, $this->year, $this->month);
$this->generalBattleResultLog = []; $this->generalBattleResultLog = [];
} }
if($this->generalBattleDetailLog && $this->generalID){ if ($this->generalBattleDetailLog && $this->generalID) {
pushBatLog($this->generalID, $this->generalBattleDetailLog, $this->year, $this->month); pushBatLog($this->generalID, $this->generalBattleDetailLog, $this->year, $this->month);
$this->generalBattleDetailLog = []; $this->generalBattleDetailLog = [];
} }
if($this->nationID && $this->nationalHistoryLog){ if ($this->nationID && $this->nationalHistoryLog) {
pushNationHistory($this->nationID, $this->nationalHistoryLog, $this->year, $this->month); pushNationHistory($this->nationID, $this->nationalHistoryLog, $this->year, $this->month);
$this->nationalHistoryLog = []; $this->nationalHistoryLog = [];
} }
if($this->globalHistoryLog){ if ($this->globalHistoryLog) {
pushWorldHistory($this->globalHistoryLog, $this->year, $this->month); pushWorldHistory($this->globalHistoryLog, $this->year, $this->month);
$this->globalHistoryLog = []; $this->globalHistoryLog = [];
} }
if($this->globalActionLog){ if ($this->globalActionLog) {
pushGeneralPublicRecord($this->globalActionLog, $this->year, $this->month); pushGeneralPublicRecord($this->globalActionLog, $this->year, $this->month);
$this->globalActionLog = []; $this->globalActionLog = [];
} }
} }
public function pushGeneralHistoryLog($text, int $formatType = self::YEAR_MONTH){ public function pushGeneralHistoryLog($text, int $formatType = self::YEAR_MONTH)
if(!$text){ {
if (!$text) {
return; return;
} }
if(is_array($text)){ if (is_array($text)) {
foreach($text as $textItem){ foreach ($text as $textItem) {
$this->pushGeneralHistoryLog($textItem); $this->pushGeneralHistoryLog($textItem);
} }
return; return;
@@ -126,12 +132,13 @@ class ActionLogger{
$this->generalHistoryLog[] = $text; $this->generalHistoryLog[] = $text;
} }
public function pushGeneralActionLog($text, int $formatType = self::MONTH){ public function pushGeneralActionLog($text, int $formatType = self::MONTH)
if(!$text){ {
if (!$text) {
return; return;
} }
if(is_array($text)){ if (is_array($text)) {
foreach($text as $textItem){ foreach ($text as $textItem) {
$this->pushGeneralActionLog($textItem); $this->pushGeneralActionLog($textItem);
} }
return; return;
@@ -141,12 +148,13 @@ class ActionLogger{
$this->generalActionLog[] = $text; $this->generalActionLog[] = $text;
} }
public function pushGeneralBattleResultLog($text, int $formatType = self::RAWTEXT){ public function pushGeneralBattleResultLog($text, int $formatType = self::RAWTEXT)
if(!$text){ {
if (!$text) {
return; return;
} }
if(is_array($text)){ if (is_array($text)) {
foreach($text as $textItem){ foreach ($text as $textItem) {
$this->pushGeneralBattleResultLog($textItem); $this->pushGeneralBattleResultLog($textItem);
} }
return; return;
@@ -156,12 +164,13 @@ class ActionLogger{
$this->generalBattleResultLog[] = $text; $this->generalBattleResultLog[] = $text;
} }
public function pushGeneralBattleDetailLog($text, int $formatType = self::PLAIN){ public function pushGeneralBattleDetailLog($text, int $formatType = self::PLAIN)
if(!$text){ {
if (!$text) {
return; return;
} }
if(is_array($text)){ if (is_array($text)) {
foreach($text as $textItem){ foreach ($text as $textItem) {
$this->pushGeneralBattleDetailLog($textItem); $this->pushGeneralBattleDetailLog($textItem);
} }
return; return;
@@ -171,12 +180,13 @@ class ActionLogger{
$this->generalBattleDetailLog[] = $text; $this->generalBattleDetailLog[] = $text;
} }
public function pushNationalHistoryLog($text, int $formatType = self::YEAR_MONTH){ public function pushNationalHistoryLog($text, int $formatType = self::YEAR_MONTH)
if(!$text){ {
if (!$text) {
return; return;
} }
if(is_array($text)){ if (is_array($text)) {
foreach($text as $textItem){ foreach ($text as $textItem) {
$this->pushNationalHistoryLog($textItem); $this->pushNationalHistoryLog($textItem);
} }
return; return;
@@ -186,12 +196,13 @@ class ActionLogger{
$this->nationalHistoryLog[] = $text; $this->nationalHistoryLog[] = $text;
} }
public function pushGlobalActionLog($text, int $formatType = self::MONTH){ public function pushGlobalActionLog($text, int $formatType = self::MONTH)
if(!$text){ {
if (!$text) {
return; return;
} }
if(is_array($text)){ if (is_array($text)) {
foreach($text as $textItem){ foreach ($text as $textItem) {
$this->pushGlobalActionLog($textItem); $this->pushGlobalActionLog($textItem);
} }
return; return;
@@ -201,12 +212,13 @@ class ActionLogger{
$this->globalActionLog[] = $text; $this->globalActionLog[] = $text;
} }
public function pushGlobalHistoryLog($text, int $formatType = self::YEAR_MONTH){ public function pushGlobalHistoryLog($text, int $formatType = self::YEAR_MONTH)
if(!$text){ {
if (!$text) {
return; return;
} }
if(is_array($text)){ if (is_array($text)) {
foreach($text as $textItem){ foreach ($text as $textItem) {
$this->pushGlobalHistoryLog($textItem); $this->pushGlobalHistoryLog($textItem);
} }
return; return;
@@ -216,55 +228,56 @@ class ActionLogger{
$this->globalHistoryLog[] = $text; $this->globalHistoryLog[] = $text;
} }
public function formatText(string $text, int $formatType):string{ public function formatText(string $text, int $formatType): string
if($formatType === self::RAWTEXT){ {
if ($formatType === self::RAWTEXT) {
return $text; return $text;
} }
if($formatType === self::PLAIN){ if ($formatType === self::PLAIN) {
return "<C>●</>{$text}"; return "<C>●</>{$text}";
} }
if($formatType === self::YEAR_MONTH){ if ($formatType === self::YEAR_MONTH) {
return "<C>●</>{$this->year}{$this->month}월:{$text}"; return "<C>●</>{$this->year}{$this->month}월:{$text}";
} }
if($formatType === self::YEAR){ if ($formatType === self::YEAR) {
return "<C>●</>{$this->year}년:{$text}"; return "<C>●</>{$this->year}년:{$text}";
} }
if($formatType === self::MONTH){ if ($formatType === self::MONTH) {
return "<C>●</>{$this->month}월:{$text}"; return "<C>●</>{$this->month}월:{$text}";
} }
if($formatType === self::EVENT_PLAIN){ if ($formatType === self::EVENT_PLAIN) {
return "<S>◆</>{$text}"; return "<S>◆</>{$text}";
} }
if($formatType === self::EVENT_YEAR_MONTH){ if ($formatType === self::EVENT_YEAR_MONTH) {
return "<S>◆</>{$this->year}{$this->month}월:{$text}"; return "<S>◆</>{$this->year}{$this->month}월:{$text}";
} }
if($formatType === self::NOTICE){ if ($formatType === self::NOTICE) {
return "<R>★</>{$text}"; return "<R>★</>{$text}";
} }
if($formatType === self::NOTICE_YEAR_MONTH){ if ($formatType === self::NOTICE_YEAR_MONTH) {
return "<R>★</>{$this->year}{$this->month}월:{$text}"; return "<R>★</>{$this->year}{$this->month}월:{$text}";
} }
return $text; return $text;
} }
public function pushBattleResultTemplate( public function pushBattleResultTemplate(
WarUnit $me, WarUnit $me,
WarUnit $oppose WarUnit $oppose
){ ) {
if($me instanceof WarUnitCity){ if ($me instanceof WarUnitCity) {
return; return;
} }
$templates = new \League\Plates\Engine(__DIR__.'/../templates'); $templates = new \League\Plates\Engine(__DIR__ . '/../templates');
$render_me = [ $render_me = [
'crewtype' => $me->getCrewTypeShortName(), 'crewtype' => $me->getCrewTypeShortName(),
@@ -280,24 +293,22 @@ class ActionLogger{
'killed_crew' => -$oppose->getDeadCurrentBattle() 'killed_crew' => -$oppose->getDeadCurrentBattle()
]; ];
if(!$me->isAttacker()){ if (!$me->isAttacker()) {
$warType = 'defense'; $warType = 'defense';
$warTypeStr = '←'; $warTypeStr = '←';
} } else if ($oppose instanceof WarUnitCity) {
else if($oppose instanceof WarUnitCity){
$warType = 'siege'; $warType = 'siege';
$warTypeStr = '→'; $warTypeStr = '→';
} } else {
else{
$warType = 'attack'; $warType = 'attack';
$warTypeStr = '→'; $warTypeStr = '→';
} }
$res = str_replace(["\r\n", "\r", "\n"], '', $templates->render('small_war_log',[ $res = str_replace(["\r\n", "\r", "\n"], '', $templates->render('small_war_log', [
'year'=>$this->year, 'year' => $this->year,
'month'=>$this->month, 'month' => $this->month,
'war_type'=>$warType, 'war_type' => $warType,
'war_type_str'=>$warTypeStr, 'war_type_str' => $warTypeStr,
'me' => $render_me, 'me' => $render_me,
'you' => $render_oppose, 'you' => $render_oppose,
])); ]));
@@ -307,12 +318,13 @@ class ActionLogger{
$this->pushGeneralActionLog($res, self::EVENT_YEAR_MONTH); $this->pushGeneralActionLog($res, self::EVENT_YEAR_MONTH);
} }
public function getYear():int{ public function getYear(): int
{
return $this->year; return $this->year;
} }
public function getMonth():int{ public function getMonth(): int
{
return $this->month; return $this->month;
} }
}
}
+140 -86
View File
@@ -5,7 +5,8 @@ use \sammo\{
Util, JosaUtil, DB, Util, JosaUtil, DB,
General, GameConst, General, GameConst,
ActionLogger, ActionLogger,
LastTurn LastTurn,
NotInheritedMethodException
}; };
use function \sammo\getNationStaticInfo; use function \sammo\getNationStaticInfo;
@@ -33,16 +34,19 @@ abstract class BaseCommand{
protected $destCity = null; protected $destCity = null;
protected $destNation = null; protected $destNation = null;
protected $runnable = null; protected $cachedPermissionToReserve = false;
protected $reservable = null; protected $cachedMinConditionMet = false;
protected $cachedFullConditionMet = false;
protected $isArgValid=false; protected $isArgValid=false;
protected $reasonNotRunnable = null; protected $reasonNotFullConditionMet = null;
protected $reasonNotReservable = null; protected $reasonNotMinConditionMet = null;
protected $reasonNoPermissionToReserve = null;
protected $runnableConstraints = null; protected $fullConditionConstraints = null;
protected $reservableConstraints = null; protected $minConditionConstraints = null;
protected $permissionConstraints = null;
protected $logger; protected $logger;
@@ -63,57 +67,48 @@ abstract class BaseCommand{
$this->logger = $generalObj->getLogger(); $this->logger = $generalObj->getLogger();
$this->env = $env; $this->env = $env;
$this->arg = $arg; $this->arg = $arg;
if (!$this->argTest()) {
return;
}
$this->isArgValid = true;
$this->init();
$this->init();
if ($this->argTest()) {
$this->isArgValid = true;
if(static::$reqArg){
$this->initWithArg();
}
}
else{
$this->isArgValid = false;
}
} }
protected function resetTestCache():void{ protected function resetTestCache():void{
$this->runnable = null; $this->cachedFullConditionMet = false;
$this->reservable = null; $this->cachedMinConditionMet = false;
$this->cachedPermissionToReserve = false;
$this->reasonNotRunnable = null; $this->reasonNotFullConditionMet = null;
$this->reasonNotReservable = null; $this->reasonNotMinConditionMet = null;
$this->reasonNoPermissionToReserve = null;
} }
protected function setCity(?array $args=null){ protected function setCity(){
$this->resetTestCache(); $this->resetTestCache();
$db = DB::db(); $db = DB::db();
if($args === null){
$this->city = $this->generalObj->getRawCity();
if($this->city){
return;
}
$this->city = $db->queryFirstRow('SELECT * FROM city WHERE city=%i', $this->generalObj->getVar('city'));
$this->generalObj->setRawCity($this->city);
return;
}
$this->city = $this->generalObj->getRawCity(); $this->city = $this->generalObj->getRawCity();
$hasArgs = true; if($this->city){
foreach($args as $arg){
if(!key_exists($arg, $this->city)){
$hasArgs = false;
break;
}
}
if($hasArgs){
return; return;
} }
$this->city = $db->queryFirstRow('SELECT * FROM city WHERE city=%i', $this->generalObj->getVar('city'));
$this->city = $db->queryFirstRow('SELECT %l FROM city WHERE city=%i', Util::formatListOfBackticks($args), $this->generalObj->getVar('city')); $this->generalObj->setRawCity($this->city);
if($this->generalObj->getRawCity() === null){ return;
$this->generalObj->setRawCity($this->city);
}
} }
protected function setNation(?array $args = null){ protected function setNation(?array $args = null){
$this->resetTestCache(); $this->resetTestCache();
if($args === null){ if($args === null){
$this->nation = $this->generalObj->getStaticNation(); if(!$this->nation){
$this->nation = $this->generalObj->getStaticNation();
}
return; return;
} }
@@ -143,7 +138,18 @@ abstract class BaseCommand{
'gennum'=>1 'gennum'=>1
]; ];
if($this->nation && $this->nation['nation'] === $nationID){
$allArgExists = true;
foreach($args as $arg){
if(!key_exists($arg, $this->nation)){
$allArgExists = false;
break;
}
}
if($allArgExists){
return;
}
}
$db = DB::db(); $db = DB::db();
$nation = $db->queryFirstRow('SELECT %l FROM nation WHERE nation=%i', Util::formatListOfBackticks($args), $nationID); $nation = $db->queryFirstRow('SELECT %l FROM nation WHERE nation=%i', Util::formatListOfBackticks($args), $nationID);
@@ -153,7 +159,14 @@ abstract class BaseCommand{
$nation[$arg] = $defaultValues[$arg]; $nation[$arg] = $defaultValues[$arg];
} }
} }
$this->nation = $nation;
if($this->nation){
//NOTE: 이 순서 맞다! https://www.php.net/manual/en/language.operators.array.php
$this->nation = $nation + $this->nation;
}
else{
$this->nation = $nation;
}
} }
protected function setDestGeneral(General $destGeneralObj){ protected function setDestGeneral(General $destGeneralObj){
@@ -161,19 +174,19 @@ abstract class BaseCommand{
$this->destGeneralObj = $destGeneralObj; $this->destGeneralObj = $destGeneralObj;
} }
protected function setDestCity(int $cityNo, ?array $args){ protected function setDestCity(int $cityNo, bool $onlyName=false){
$this->resetTestCache(); $this->resetTestCache();
$db = DB::db(); $db = DB::db();
if($args === []){ if($onlyName){
$cityObj = \sammo\CityConst::byID($cityNo); $cityObj = \sammo\CityConst::byID($cityNo);
$this->destCity = ['city'=>$cityNo, 'name'=>$cityObj->name]; $this->destCity = [
'city'=>$cityNo,
'name'=>$cityObj->name,
'region'=>$cityObj->region,
];
return; return;
} }
if($args === null){ $this->destCity = $db->queryFirstRow('SELECT * FROM city WHERE city=%i', $cityNo);
$this->destCity = $db->queryFirstRow('SELECT * FROM city WHERE city=%i', $cityNo);
return;
}
$this->destCity = $db->queryFirstRow('SELECT %l FROM city WHERE city=%i', Util::formatListOfBackticks($args), $cityNo);
} }
protected function setDestNation(int $nationID, ?array $args = null){ protected function setDestNation(int $nationID, ?array $args = null){
@@ -208,6 +221,11 @@ abstract class BaseCommand{
} }
abstract protected function init(); abstract protected function init();
protected function initWithArg(){
if(static::$reqArg){
throw new NotInheritedMethodException();
}
}
abstract protected function argTest():bool; abstract protected function argTest():bool;
public function getArg():?array{ public function getArg():?array{
@@ -253,13 +271,19 @@ abstract class BaseCommand{
return $this->logger; return $this->logger;
} }
public function testReservable():?string{ public function testPermissionToReserve():?string{
if($this->reservableConstraints === null){ if(!$this->isArgValid()){
$this->reasonNoPermissionToReserve = '인자가 올바르지 않습니다.';
$this->cachedPermissionToReserve = true;
return $this->reasonNoPermissionToReserve;
}
if($this->permissionConstraints === null){
return null; return null;
} }
if($this->reasonNotReservable){ if($this->reasonNoPermissionToReserve){
return $this->reasonNotReservable; return $this->reasonNoPermissionToReserve;
} }
$this->generalObj->unpackAux(); $this->generalObj->unpackAux();
@@ -274,27 +298,29 @@ abstract class BaseCommand{
'destNation'=>$this->destNation, 'destNation'=>$this->destNation,
]; ];
[$this->reasonConstraint, $this->reasonNotReservable] = Constraint::testAll($this->reservableConstraints??[], $constraintInput, $this->env); [$this->reasonConstraint, $this->reasonNoPermissionToReserve] = Constraint::testAll($this->permissionConstraints??[], $constraintInput, $this->env);
$this->reservable = $this->reasonNotReservable === null; $this->cachedPermissionToReserve = true;
return $this->reasonNotReservable; return $this->reasonNoPermissionToReserve;
} }
public function canDisplay():bool{ public function canDisplay():bool{
return true; return $this->hasPermissionToReserve();
} }
public function testRunnable():?string{ public function testMinConditionMet():?string{
if(!$this->isArgValid()){ if(!static::$reqArg){
$this->reasonNotReservable = '인자가 올바르지 않습니다.'; if($this->minConditionConstraints){
$this->reservable = false; throw new \LogicException('reqArg==false인데 minCondition이 설정됨');
return $this->reasonNotReservable; }
} return $this->testFullConditionMet();
if($this->runnableConstraints === null){
throw new \InvalidArgumentException('runnableConstraits가 제대로 설정되지 않았습니다');
} }
if($this->reasonNotRunnable){ if($this->minConditionConstraints === null){
return $this->reasonNotRunnable; throw new \InvalidArgumentException('minConditionConstraints가 제대로 설정되지 않았습니다');
}
if($this->cachedMinConditionMet){
return $this->reasonNotMinConditionMet;
} }
$this->generalObj->unpackAux(); $this->generalObj->unpackAux();
@@ -309,9 +335,42 @@ abstract class BaseCommand{
'destNation'=>$this->destNation, 'destNation'=>$this->destNation,
]; ];
[$this->reasonConstraint, $this->reasonNotRunnable] = Constraint::testAll($this->runnableConstraints??[], $constraintInput, $this->env); [$this->reasonConstraint, $this->reasonNotMinConditionMet] = Constraint::testAll($this->minConditionConstraints??[], $constraintInput, $this->env);
$this->runnable = $this->reasonNotRunnable === null; $this->cachedMinConditionMet = true;
return $this->reasonNotRunnable; return $this->reasonNotMinConditionMet;
}
public function testFullConditionMet():?string{
if(!$this->isArgValid()){
$this->reasonNotFullConditionMet = '인자가 올바르지 않습니다.';
$this->cachedFullConditionMet = true;
return $this->reasonNotFullConditionMet;
}
if($this->fullConditionConstraints === null){
throw new \InvalidArgumentException('fullConditionConstraints가 제대로 설정되지 않았습니다');
}
if($this->cachedFullConditionMet){
return $this->reasonNotFullConditionMet;
}
$this->generalObj->unpackAux();
$constraintInput = [
'general'=>$this->generalObj->getRaw(),
'city'=>$this->city,
'nation'=>$this->nation,
'cmd_arg'=>$this->arg,
'destGeneral'=>$this->destGeneralObj?$this->destGeneralObj->getRaw():null,
'destCity'=>$this->destCity,
'destNation'=>$this->destNation,
];
[$this->reasonConstraint, $this->reasonNotFullConditionMet] = Constraint::testAll($this->fullConditionConstraints??[], $constraintInput, $this->env);
$this->cachedFullConditionMet = true;
return $this->reasonNotFullConditionMet;
} }
@@ -350,30 +409,25 @@ abstract class BaseCommand{
return true; return true;
} }
public function isReservable():bool{ public function hasPermissionToReserve():bool{
if($this->reservable !== null){ return $this->testPermissionToReserve() === null;
return $this->reservable;
}
$this->reservable = $this->testReservable() === null;
return $this->reservable;
} }
public function isArgValid():bool{ public function isArgValid():bool{
return $this->isArgValid; return $this->isArgValid;
} }
public function isRunnable():bool { public function hasMinConditionMet():bool {
if($this->runnable !== null){ return $this->testMinConditionMet() === null;
return $this->runnable; }
}
public function hasFullConditionMet():bool {
return $this->testRunnable() === null; return $this->testFullConditionMet() === null;
} }
public function getFailString():string{ public function getFailString():string{
$commandName = $this->getName(); $commandName = $this->getName();
$failReason = $this->testRunnable(); $failReason = $this->testFullConditionMet();
if($failReason === null){ if($failReason === null){
throw new \RuntimeException('실행 가능한 커맨드에 대해 실패 이유를 수집'); throw new \RuntimeException('실행 가능한 커맨드에 대해 실패 이유를 수집');
} }
+3 -7
View File
@@ -48,11 +48,11 @@ class che_NPC능동 extends Command\GeneralCommand{
$this->setNation(); $this->setNation();
$this->reservableConstraints=[ $this->permissionConstraints=[
ConstraintHelper::MustBeNPC() ConstraintHelper::MustBeNPC()
]; ];
$this->runnableConstraints=[ $this->fullConditionConstraints=[
]; ];
@@ -70,12 +70,8 @@ class che_NPC능동 extends Command\GeneralCommand{
return 0; return 0;
} }
public function canDisplay():bool{
return false;
}
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
+66 -52
View File
@@ -1,17 +1,21 @@
<?php <?php
namespace sammo\Command\General; namespace sammo\Command\General;
use \sammo\{ use\sammo\{
DB, Util, JosaUtil, DB,
General, Util,
JosaUtil,
General,
ActionLogger, ActionLogger,
GameConst, GameUnitConst, GameConst,
GameUnitConst,
LastTurn, LastTurn,
Command Command
}; };
use function \sammo\{ use function\sammo\{
tryUniqueItemLottery, tryUniqueItemLottery,
printCitiesBasedOnDistance printCitiesBasedOnDistance
}; };
@@ -22,83 +26,95 @@ use sammo\CityConst;
class che_강행 extends Command\GeneralCommand{ class che_강행 extends Command\GeneralCommand
{
static protected $actionName = '강행'; static protected $actionName = '강행';
static public $reqArg = true; static public $reqArg = true;
protected function argTest():bool{ protected function argTest(): bool
if($this->arg === null){ {
if ($this->arg === null) {
return false; return false;
} }
if(!key_exists('destCityID', $this->arg)){ if (!key_exists('destCityID', $this->arg)) {
return false; return false;
} }
if(!key_exists($this->arg['destCityID'], CityConst::all())){ if (!key_exists($this->arg['destCityID'], CityConst::all())) {
return false; return false;
} }
$this->arg = [ $this->arg = [
'destCityID'=>$this->arg['destCityID'] 'destCityID' => $this->arg['destCityID']
]; ];
return true; return true;
} }
protected function init(){ protected function init()
{
$general = $this->generalObj;
$this->setCity(); $this->setCity();
$this->setNation(); $this->setNation();
$this->setDestCity($this->arg['destCityID'], []);
$this->minConditionConstraints = [];
}
protected function initWithArg()
{
$this->setDestCity($this->arg['destCityID'], true);
[$reqGold, $reqRice] = $this->getCost(); [$reqGold, $reqRice] = $this->getCost();
$this->runnableConstraints=[ $this->fullConditionConstraints = [
ConstraintHelper::NotSameDestCity(), ConstraintHelper::NotSameDestCity(),
ConstraintHelper::NearCity(3), ConstraintHelper::NearCity(3),
ConstraintHelper::ReqGeneralGold($reqGold), ConstraintHelper::ReqGeneralGold($reqGold),
ConstraintHelper::ReqGeneralRice($reqRice), ConstraintHelper::ReqGeneralRice($reqRice),
]; ];
} }
public function getCommandDetailTitle():string{ public function getCommandDetailTitle(): string
{
$name = $this->getName(); $name = $this->getName();
[$reqGold, $reqRice] = $this->getCost(); [$reqGold, $reqRice] = $this->getCost();
$title = "{$name}(통솔경험"; $title = "{$name}(통솔경험";
if($reqGold > 0){ if ($reqGold > 0) {
$title .= ", 자금{$reqGold}"; $title .= ", 자금{$reqGold}";
} }
if($reqRice > 0){ if ($reqRice > 0) {
$title .= ", 군량{$reqRice}"; $title .= ", 군량{$reqRice}";
} }
$title .= ', 병력,훈련,사기↓)'; $title .= ', 병력,훈련,사기↓)';
return $title; return $title;
} }
public function getCost():array{ public function getCost(): array
{
$env = $this->env; $env = $this->env;
return [$env['develcost'] * 5, 0]; return [$env['develcost'] * 5, 0];
} }
public function getPreReqTurn():int{ public function getPreReqTurn(): int
{
return 0; return 0;
} }
public function getPostReqTurn():int{ public function getPostReqTurn(): int
{
return 0; return 0;
} }
public function getBrief():string{ public function getBrief(): string
{
$commandName = $this->getName(); $commandName = $this->getName();
$destCityName = CityConst::byID($this->arg['destCityID'])->name; $destCityName = CityConst::byID($this->arg['destCityID'])->name;
$josaRo = JosaUtil::pick($destCityName, '로'); $josaRo = JosaUtil::pick($destCityName, '로');
return "{$destCityName}{$josaRo} {$commandName}"; return "{$destCityName}{$josaRo} {$commandName}";
} }
public function getFailString():string{ public function getFailString(): string
{
$commandName = $this->getName(); $commandName = $this->getName();
$failReason = $this->testRunnable(); $failReason = $this->testFullConditionMet();
if($failReason === null){ if ($failReason === null) {
throw new \RuntimeException('실행 가능한 커맨드에 대해 실패 이유를 수집'); throw new \RuntimeException('실행 가능한 커맨드에 대해 실패 이유를 수집');
} }
$destCityName = CityConst::byID($this->arg['destCityID'])->name; $destCityName = CityConst::byID($this->arg['destCityID'])->name;
@@ -106,8 +122,9 @@ class che_강행 extends Command\GeneralCommand{
return "{$failReason} <G><b>{$destCityName}</b></>{$josaRo} {$commandName} 실패."; return "{$failReason} <G><b>{$destCityName}</b></>{$josaRo} {$commandName} 실패.";
} }
public function run():bool{ public function run(): bool
if(!$this->isRunnable()){ {
if (!$this->hasFullConditionMet()) {
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -128,16 +145,16 @@ class che_강행 extends Command\GeneralCommand{
$exp = 100; $exp = 100;
$general->setVar('city', $destCityID); $general->setVar('city', $destCityID);
if($general->getVar('officer_level') == 12 && $this->nation['level'] == 0){ if ($general->getVar('officer_level') == 12 && $this->nation['level'] == 0) {
$generalList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND no!=%i', $general->getNationID(), $general->getID()); $generalList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND no!=%i', $general->getNationID(), $general->getID());
if($generalList){ if ($generalList) {
$db->update('general', [ $db->update('general', [
'city'=>$destCityID 'city' => $destCityID
], 'no IN %li and nation=%i', $generalList, $general->getNationID()); ], 'no IN %li and nation=%i', $generalList, $general->getNationID());
} }
foreach($generalList as $targetGeneralID){ foreach ($generalList as $targetGeneralID) {
$targetLogger = new ActionLogger($targetGeneralID, $general->getNationID(), $env['year'], $env['month']); $targetLogger = new ActionLogger($targetGeneralID, $general->getNationID(), $env['year'], $env['month']);
$targetLogger->pushGeneralActionLog("방랑군 세력이 <G><b>{$destCityName}</b></>{$josaRo} 강행했습니다.", ActionLogger::PLAIN); $targetLogger->pushGeneralActionLog("방랑군 세력이 <G><b>{$destCityName}</b></>{$josaRo} 강행했습니다.", ActionLogger::PLAIN);
$targetLogger->flush(); $targetLogger->flush();
@@ -153,7 +170,6 @@ class che_강행 extends Command\GeneralCommand{
$general->applyDB($db); $general->applyDB($db);
return true; return true;
} }
public function getJSFiles(): array public function getJSFiles(): array
@@ -170,19 +186,17 @@ class che_강행 extends Command\GeneralCommand{
ob_start(); ob_start();
?> ?>
<?=\sammo\getMapHtml()?><br> <?= \sammo\getMapHtml() ?><br>
선택된 도시로 강행합니다.<br> 선택된 도시로 강행합니다.<br>
최대 3칸내 도시로만 강행이 가능합니다.<br> 최대 3칸내 도시로만 강행이 가능합니다.<br>
목록을 선택하거나 도시를 클릭하세요.<br> 목록을 선택하거나 도시를 클릭하세요.<br>
<?=$currentCityName?> => <select class='formInput' name="destCityID" id="destCityID" size='1' style='color:white;background-color:black;'><br> <?= $currentCityName ?> => <select class='formInput' name="destCityID" id="destCityID" size='1' style='color:white;background-color:black;'><br>
<?=\sammo\optionsForCities()?><br> <?= \sammo\optionsForCities() ?><br>
</select> <input type=button id="commonSubmit" value="<?=$this->getName()?>"><br> </select> <input type=button id="commonSubmit" value="<?= $this->getName() ?>"><br>
<br> <br>
<br> <br>
<?=printCitiesBasedOnDistance($currentCityID, 3)?> <?= printCitiesBasedOnDistance($currentCityID, 3) ?>
<?php <?php
return ob_get_clean(); return ob_get_clean();
} }
}
}
+4 -3
View File
@@ -30,7 +30,8 @@ class che_거병 extends Command\GeneralCommand{
return true; return true;
} }
protected function init(){ protected function init()
{
$general = $this->generalObj; $general = $this->generalObj;
$env = $this->env; $env = $this->env;
@@ -40,7 +41,7 @@ class che_거병 extends Command\GeneralCommand{
$relYear = $env['year'] - $env['startyear']; $relYear = $env['year'] - $env['startyear'];
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::BeNeutral(), ConstraintHelper::BeNeutral(),
ConstraintHelper::BeOpeningPart($relYear+1), ConstraintHelper::BeOpeningPart($relYear+1),
ConstraintHelper::AllowJoinAction(), ConstraintHelper::AllowJoinAction(),
@@ -60,7 +61,7 @@ class che_거병 extends Command\GeneralCommand{
} }
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
+92 -73
View File
@@ -1,17 +1,21 @@
<?php <?php
namespace sammo\Command\General; namespace sammo\Command\General;
use \sammo\{ use\sammo\{
DB, Util, JosaUtil, DB,
General, Util,
JosaUtil,
General,
ActionLogger, ActionLogger,
GameConst, GameUnitConst, GameConst,
GameUnitConst,
LastTurn, LastTurn,
Command Command
}; };
use function \sammo\{ use function\sammo\{
tryUniqueItemLottery, tryUniqueItemLottery,
getAllNationStaticInfo getAllNationStaticInfo
}; };
@@ -25,69 +29,80 @@ use function sammo\GetNationColors;
use function sammo\newColor; use function sammo\newColor;
class che_건국 extends Command\GeneralCommand{ class che_건국 extends Command\GeneralCommand
{
static protected $actionName = '건국'; static protected $actionName = '건국';
static public $reqArg = true; static public $reqArg = true;
protected function argTest():bool{ protected function argTest(): bool
if($this->arg === null){ {
if ($this->arg === null) {
return false; return false;
} }
$nationName = $this->arg['nationName']??null; $nationName = $this->arg['nationName'] ?? null;
$nationType = $this->arg['nationType']??null; $nationType = $this->arg['nationType'] ?? null;
$colorType = $this->arg['colorType']??null; $colorType = $this->arg['colorType'] ?? null;
if($nationName === null || $nationType === null || $colorType === null){ if ($nationName === null || $nationType === null || $colorType === null) {
return false; return false;
} }
if(!is_string($nationName) || !is_string($nationType) || !is_int($colorType)){ if (!is_string($nationName) || !is_string($nationType) || !is_int($colorType)) {
return false; return false;
} }
if(mb_strwidth($nationName) > 18 || $nationName == ''){ if (mb_strwidth($nationName) > 18 || $nationName == '') {
return false; return false;
} }
if(!key_exists($colorType, GetNationColors())){ if (!key_exists($colorType, GetNationColors())) {
return false; return false;
} }
try{ try {
$nationTypeClass = buildNationTypeClass($nationType); $nationTypeClass = buildNationTypeClass($nationType);
} } catch (\InvalidArgumentException $e) {
catch(\InvalidArgumentException $e){
return false; return false;
} }
$this->arg = [ $this->arg = [
'nationName'=>$nationName, 'nationName' => $nationName,
'nationType'=>$nationType, 'nationType' => $nationType,
'colorType'=>$colorType 'colorType' => $colorType
]; ];
return true; return true;
} }
protected function init(){ protected function init()
{
$general = $this->generalObj;
$env = $this->env; $env = $this->env;
$nationName = $this->arg['nationName'];
$nationType = $this->arg['nationType'];
$colorType = $this->arg['colorType'];
$this->setCity(); $this->setCity();
$this->setNation(['gennum']); $this->setNation(['gennum']);
$relYear = $env['year'] - $env['startyear']; $relYear = $env['year'] - $env['startyear'];
$this->runnableConstraints=[ $this->minConditionConstraints = [
ConstraintHelper::BeOpeningPart($relYear + 1),
ConstraintHelper::ReqNationValue('level', '국가규모', '==', 0, '정식 국가가 아니어야합니다.')
];
}
protected function initWithArg()
{
$env = $this->env;
$relYear = $env['year'] - $env['startyear'];
$nationName = $this->arg['nationName'];
$nationType = $this->arg['nationType'];
$colorType = $this->arg['colorType'];
$this->fullConditionConstraints = [
ConstraintHelper::BeLord(), ConstraintHelper::BeLord(),
ConstraintHelper::WanderingNation(), ConstraintHelper::WanderingNation(),
ConstraintHelper::ReqNationValue('gennum', '수하 장수', '>=', 2), ConstraintHelper::ReqNationValue('gennum', '수하 장수', '>=', 2),
ConstraintHelper::BeOpeningPart($relYear+1), ConstraintHelper::BeOpeningPart($relYear + 1),
ConstraintHelper::CheckNationNameDuplicate($nationName), ConstraintHelper::CheckNationNameDuplicate($nationName),
ConstraintHelper::AllowJoinAction(), ConstraintHelper::AllowJoinAction(),
ConstraintHelper::ConstructableCity(), ConstraintHelper::ConstructableCity(),
@@ -101,20 +116,24 @@ class che_건국 extends Command\GeneralCommand{
return "{$nationName}{$josaUl} 건국"; return "{$nationName}{$josaUl} 건국";
} }
public function getCost():array{ public function getCost(): array
{
return [0, 0]; return [0, 0];
} }
public function getPreReqTurn():int{ public function getPreReqTurn(): int
{
return 0; return 0;
} }
public function getPostReqTurn():int{ public function getPostReqTurn(): int
{
return 0; return 0;
} }
public function run():bool{ public function run(): bool
if(!$this->isRunnable()){ {
if (!$this->hasFullConditionMet()) {
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -155,16 +174,16 @@ class che_건국 extends Command\GeneralCommand{
$general->addDedication($ded); $general->addDedication($ded);
$db->update('city', [ $db->update('city', [
'nation'=>$general->getNationID(), 'nation' => $general->getNationID(),
'conflict'=>'{}' 'conflict' => '{}'
], 'city=%i', $general->getCityID()); ], 'city=%i', $general->getCityID());
$db->update('nation', [ $db->update('nation', [
'name'=>$nationName, 'name' => $nationName,
'color'=>$colorType, 'color' => $colorType,
'level'=>1, 'level' => 1,
'type'=>$nationType, 'type' => $nationType,
'capital'=>$general->getCityID() 'capital' => $general->getCityID()
], 'nation=%i', $general->getNationID()); ], 'nation=%i', $general->getNationID());
refreshNationStaticInfo(); refreshNationStaticInfo();
@@ -180,7 +199,7 @@ class che_건국 extends Command\GeneralCommand{
public function getForm(): string public function getForm(): string
{ {
if(count(getAllNationStaticInfo()) >= $this->env['maxnation']){ if (count(getAllNationStaticInfo()) >= $this->env['maxnation']) {
return '더 이상 건국은 불가능합니다.'; return '더 이상 건국은 불가능합니다.';
} }
@@ -213,44 +232,44 @@ class che_건국 extends Command\GeneralCommand{
} }
} }
*/ */
ob_start(); ob_start();
?> ?>
현재 도시에서 나라를 세웁니다. 중, 소도시에서만 가능합니다.<br> 현재 도시에서 나라를 세웁니다. 중, 소도시에서만 가능합니다.<br>
<?php foreach(GameConst::$availableNationType as $nationType): <?php foreach (GameConst::$availableNationType as $nationType) :
$nationClass = buildNationTypeClass($nationType); $nationClass = buildNationTypeClass($nationType);
[$name, $pros, $cons] = [$nationClass->getName(), $nationClass::$pros, $nationClass::$cons]; [$name, $pros, $cons] = [$nationClass->getName(), $nationClass::$pros, $nationClass::$cons];
?> ?>
- <?=$name?> : <span style='color:cyan;'><?=$pros?></span> <span style='color:magenta;'><?=$cons?></span><br>
<?php endforeach; ?>
<br>
국명 : <input type='text' class='formInput' name="nationName" id="nationName" size='18' maxlength='18' style='color:white;background-color:black;'>
색깔 : <select class='formInput' name='colorType' id='colorType' size='1'>
<?php foreach(GetNationColors() as $idx=>$color): - <?= $name ?> : <span style='color:cyan;'><?= $pros ?></span> <span style='color:magenta;'><?= $cons ?></span><br>
/* <?php endforeach; ?>
<br>
국명 : <input type='text' class='formInput' name="nationName" id="nationName" size='18' maxlength='18' style='color:white;background-color:black;'>
색깔 : <select class='formInput' name='colorType' id='colorType' size='1'>
<?php foreach (GetNationColors() as $idx => $color) :
/*
if($colorUsed[$color] > 0){ if($colorUsed[$color] > 0){
continue; continue;
} }
*/ */
?> ?>
<option value="<?=$idx?>" style='background-color:<?=$color?>;color:<?=newColor($color)?>';>국가명</option> <option value="<?= $idx ?>" style='background-color:<?= $color ?>;color:<?= newColor($color) ?>' ;>국가명</option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
성향 : <select class='formInput' name='nationType' id='nationType' size='1'> 성향 : <select class='formInput' name='nationType' id='nationType' size='1'>
<?php foreach(GameConst::$availableNationType as $nationType): <?php foreach (GameConst::$availableNationType as $nationType) :
$nationTypeName = buildNationTypeClass($nationType)->getName(); $nationTypeName = buildNationTypeClass($nationType)->getName();
?> ?>
<option value='<?=$nationType?>' style=background-color:black;color:white;><?=$nationTypeName?></option> <option value='<?= $nationType ?>' style=background-color:black;color:white;><?= $nationTypeName ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
<input type=button id="commonSubmit" value="<?=$this->getName()?>"> <input type=button id="commonSubmit" value="<?= $this->getName() ?>">
<?php <?php
return ob_get_clean(); return ob_get_clean();
} }
} }
+4 -3
View File
@@ -28,11 +28,12 @@ class che_견문 extends Command\GeneralCommand{
return true; return true;
} }
protected function init(){ protected function init()
{
$general = $this->generalObj; $general = $this->generalObj;
$this->runnableConstraints=[ $this->fullConditionConstraints=[
]; ];
} }
@@ -55,7 +56,7 @@ class che_견문 extends Command\GeneralCommand{
} }
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
+17 -5
View File
@@ -56,24 +56,36 @@ class che_군량매매 extends Command\GeneralCommand{
return "군량 {$this->arg['amount']}{$buyRiceText}"; return "군량 {$this->arg['amount']}{$buyRiceText}";
} }
protected function init(){ protected function init()
{
$general = $this->generalObj; $general = $this->generalObj;
$this->setCity(); $this->setCity();
$this->setNation(); $this->setNation();
$this->minConditionConstraints=[
ConstraintHelper::ReqCityTrader($general->getVar('npc')),
ConstraintHelper::OccupiedCity(true),
ConstraintHelper::SuppliedCity(),
];
}
protected function initWithArg()
{
$general = $this->generalObj;
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::ReqCityTrader($general->getVar('npc')), ConstraintHelper::ReqCityTrader($general->getVar('npc')),
ConstraintHelper::OccupiedCity(true), ConstraintHelper::OccupiedCity(true),
ConstraintHelper::SuppliedCity(), ConstraintHelper::SuppliedCity(),
]; ];
if($this->arg['buyRice']){ if($this->arg['buyRice']){
$this->runnableConstraints[] = ConstraintHelper::ReqGeneralGold(1); $this->fullConditionConstraints[] = ConstraintHelper::ReqGeneralGold(1);
} }
else{ else{
$this->runnableConstraints[] = ConstraintHelper::ReqGeneralRice(1); $this->fullConditionConstraints[] = ConstraintHelper::ReqGeneralRice(1);
} }
} }
@@ -90,7 +102,7 @@ class che_군량매매 extends Command\GeneralCommand{
} }
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
+4 -3
View File
@@ -30,7 +30,8 @@ class che_귀환 extends Command\GeneralCommand{
return true; return true;
} }
protected function init(){ protected function init()
{
$general = $this->generalObj; $general = $this->generalObj;
@@ -39,7 +40,7 @@ class che_귀환 extends Command\GeneralCommand{
[$reqGold, $reqRice] = $this->getCost(); [$reqGold, $reqRice] = $this->getCost();
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
ConstraintHelper::NotWanderingNation(), ConstraintHelper::NotWanderingNation(),
ConstraintHelper::NotCapital(true), ConstraintHelper::NotCapital(true),
@@ -64,7 +65,7 @@ class che_귀환 extends Command\GeneralCommand{
} }
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -31,7 +31,8 @@ class che_기술연구 extends che_상업투자{
return true; return true;
} }
protected function init(){ protected function init()
{
$general = $this->generalObj; $general = $this->generalObj;
@@ -40,7 +41,7 @@ class che_기술연구 extends che_상업투자{
[$reqGold, $reqRice] = $this->getCost(); [$reqGold, $reqRice] = $this->getCost();
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
ConstraintHelper::NotWanderingNation(), ConstraintHelper::NotWanderingNation(),
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
@@ -53,7 +54,7 @@ class che_기술연구 extends che_상업투자{
} }
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
+4 -3
View File
@@ -28,7 +28,8 @@ class che_단련 extends Command\GeneralCommand{
return true; return true;
} }
protected function init(){ protected function init()
{
$general = $this->generalObj; $general = $this->generalObj;
@@ -37,7 +38,7 @@ class che_단련 extends Command\GeneralCommand{
[$reqGold, $reqRice] = $this->getCost(); [$reqGold, $reqRice] = $this->getCost();
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
ConstraintHelper::ReqGeneralCrew(), ConstraintHelper::ReqGeneralCrew(),
ConstraintHelper::ReqGeneralValue('train', '훈련', '>=', GameConst::$defaultTrainLow), ConstraintHelper::ReqGeneralValue('train', '훈련', '>=', GameConst::$defaultTrainLow),
@@ -77,7 +78,7 @@ class che_단련 extends Command\GeneralCommand{
} }
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
+25 -7
View File
@@ -53,21 +53,39 @@ class che_등용 extends Command\GeneralCommand{
return true; return true;
} }
protected function init(){ protected function init()
{
$general = $this->generalObj; $general = $this->generalObj;
$this->setCity(); $this->setCity();
$this->setNation(['gennum', 'scout']); $this->setNation(['gennum', 'scout']);
$relYear = $this->env['year'] - $this->env['startyear'];
$this->permissionConstraints=[
ConstraintHelper::ReqEnvValue('join_mode', '!=', 'onlyRandom', '랜덤 임관만 가능합니다'),
];
$this->minConditionConstraints=[
ConstraintHelper::ReqEnvValue('join_mode', '!=', 'onlyRandom', '랜덤 임관만 가능합니다'),
ConstraintHelper::NotBeNeutral(),
ConstraintHelper::NotOpeningPart($relYear),
ConstraintHelper::OccupiedCity(),
ConstraintHelper::SuppliedCity(),
];
}
protected function initWithArg()
{
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['nation'], 0); $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['nation'], 0);
$this->setDestGeneral($destGeneral); $this->setDestGeneral($destGeneral);
[$reqGold, $reqRice] = $this->getCost(); [$reqGold, $reqRice] = $this->getCost();
$relYear = $this->env['year'] - $this->env['startyear']; $relYear = $this->env['year'] - $this->env['startyear'];
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::ReqEnvValue('join_mode', '==', 'onlyRandom', '랜덤 임관만 가능합니다'), ConstraintHelper::ReqEnvValue('join_mode', '!=', 'onlyRandom', '랜덤 임관만 가능합니다'),
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
ConstraintHelper::NotOpeningPart($relYear), ConstraintHelper::NotOpeningPart($relYear),
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
@@ -77,9 +95,9 @@ class che_등용 extends Command\GeneralCommand{
ConstraintHelper::ReqGeneralGold($reqGold), ConstraintHelper::ReqGeneralGold($reqGold),
ConstraintHelper::ReqGeneralRice($reqRice), ConstraintHelper::ReqGeneralRice($reqRice),
]; ];
if($this->destGeneralObj->getVar('officer_level') == 12){ if($this->destGeneralObj->getVar('officer_level') == 12){
$this->runnableConstraints[] = ConstraintHelper::AlwaysFail('군주에게는 등용장을 보낼 수 없습니다.'); $this->fullConditionConstraints[] = ConstraintHelper::AlwaysFail('군주에게는 등용장을 보낼 수 없습니다.');
} }
} }
@@ -113,7 +131,7 @@ class che_등용 extends Command\GeneralCommand{
} }
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
+11 -7
View File
@@ -70,22 +70,26 @@ class che_등용수락 extends Command\GeneralCommand{
return true; return true;
} }
protected function init(){ protected function init()
{
$general = $this->generalObj; $general = $this->generalObj;
$this->setNation(['gennum', 'scout']); $this->setNation(['gennum', 'scout']);
$this->permissionConstraints = [
ConstraintHelper::AlwaysFail('예약 불가능 커맨드')
];
}
protected function initWithArg()
{
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['nation'], 0); $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['nation'], 0);
$this->setDestGeneral($destGeneral); $this->setDestGeneral($destGeneral);
$this->setDestNation($this->arg['destNationID'], ['gennum', 'scout']); $this->setDestNation($this->arg['destNationID'], ['gennum', 'scout']);
$relYear = $this->env['year'] - $this->env['startyear']; $relYear = $this->env['year'] - $this->env['startyear'];
$this->reservableConstraints = [ $this->fullConditionConstraints=[
ConstraintHelper::AlwaysFail('예약 불가능 커맨드')
];
$this->runnableConstraints=[
ConstraintHelper::ReqEnvValue('join_mode', '==', 'onlyRandom', '랜덤 임관만 가능합니다'), ConstraintHelper::ReqEnvValue('join_mode', '==', 'onlyRandom', '랜덤 임관만 가능합니다'),
ConstraintHelper::NotOpeningPart($relYear), ConstraintHelper::NotOpeningPart($relYear),
ConstraintHelper::ExistsDestNation(), ConstraintHelper::ExistsDestNation(),
@@ -109,7 +113,7 @@ class che_등용수락 extends Command\GeneralCommand{
} }
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -26,7 +26,6 @@ use sammo\MustNotBeReachedException;
class che_랜덤임관 extends Command\GeneralCommand{ class che_랜덤임관 extends Command\GeneralCommand{
static protected $actionName = '랜덤임관'; static protected $actionName = '랜덤임관';
static public $reqArg = false;
protected function argTest():bool{ protected function argTest():bool{
$this->arg = null; $this->arg = null;
@@ -61,7 +60,8 @@ class che_랜덤임관 extends Command\GeneralCommand{
return true;*/ return true;*/
} }
protected function init(){ protected function init()
{
$general = $this->generalObj; $general = $this->generalObj;
$env = $this->env; $env = $this->env;
@@ -71,14 +71,14 @@ class che_랜덤임관 extends Command\GeneralCommand{
$relYear = $env['year'] - $env['startyear']; $relYear = $env['year'] - $env['startyear'];
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::BeNeutral(), ConstraintHelper::BeNeutral(),
ConstraintHelper::AllowJoinAction(), ConstraintHelper::AllowJoinAction(),
]; ];
/* /*
if($this->arg['destNationIDList']??false){ if($this->arg['destNationIDList']??false){
$this->runnableConstraints[] = ConstraintHelper::ExistsAllowJoinNation($relYear, $this->arg['destNationIDList']); $this->fullConditionConstraints[] = ConstraintHelper::ExistsAllowJoinNation($relYear, $this->arg['destNationIDList']);
} }
*/ */
} }
@@ -96,7 +96,7 @@ class che_랜덤임관 extends Command\GeneralCommand{
} }
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -29,14 +29,15 @@ class che_모반시도 extends Command\GeneralCommand{
return true; return true;
} }
protected function init(){ protected function init()
{
$general = $this->generalObj; $general = $this->generalObj;
$this->setCity(); $this->setCity();
$this->setNation(); $this->setNation();
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
ConstraintHelper::BeChief(), ConstraintHelper::BeChief(),
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
@@ -59,7 +60,7 @@ class che_모반시도 extends Command\GeneralCommand{
} }
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -30,14 +30,15 @@ class che_물자조달 extends Command\GeneralCommand{
return true; return true;
} }
protected function init(){ protected function init()
{
$general = $this->generalObj; $general = $this->generalObj;
$this->setCity(); $this->setCity();
$this->setNation(); $this->setNation();
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
ConstraintHelper::NotWanderingNation(), ConstraintHelper::NotWanderingNation(),
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
@@ -63,7 +64,7 @@ class che_물자조달 extends Command\GeneralCommand{
} }
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
+2 -2
View File
@@ -40,7 +40,7 @@ class che_방랑 extends Command\GeneralCommand{
$relYear = $env['year'] - $env['startyear']; $relYear = $env['year'] - $env['startyear'];
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::BeLord(), ConstraintHelper::BeLord(),
ConstraintHelper::NotWanderingNation(), ConstraintHelper::NotWanderingNation(),
ConstraintHelper::NotOpeningPart($relYear), ConstraintHelper::NotOpeningPart($relYear),
@@ -63,7 +63,7 @@ class che_방랑 extends Command\GeneralCommand{
} }
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -36,7 +36,7 @@ class che_사기진작 extends Command\GeneralCommand{
[$reqGold, $reqRice] = $this->getCost(); [$reqGold, $reqRice] = $this->getCost();
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
ConstraintHelper::NotWanderingNation(), ConstraintHelper::NotWanderingNation(),
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
@@ -69,7 +69,7 @@ class che_사기진작 extends Command\GeneralCommand{
} }
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -45,7 +45,7 @@ class che_상업투자 extends Command\GeneralCommand{
[$reqGold, $reqRice] = $this->getCost(); [$reqGold, $reqRice] = $this->getCost();
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
ConstraintHelper::NotWanderingNation(), ConstraintHelper::NotWanderingNation(),
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
@@ -128,7 +128,7 @@ class che_상업투자 extends Command\GeneralCommand{
} }
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
+60 -42
View File
@@ -1,9 +1,13 @@
<?php <?php
namespace sammo\Command\General; namespace sammo\Command\General;
use \sammo\{ use\sammo\{
DB, Util, JosaUtil, DB,
General, DummyGeneral, Util,
JosaUtil,
General,
DummyGeneral,
ActionLogger, ActionLogger,
GameConst, GameConst,
LastTurn, LastTurn,
@@ -11,9 +15,9 @@ use \sammo\{
Command Command
}; };
use function \sammo\{ use function\sammo\{
getDomesticExpLevelBonus, getDomesticExpLevelBonus,
CriticalRatioDomestic, CriticalRatioDomestic,
CriticalScoreEx, CriticalScoreEx,
tryUniqueItemLottery tryUniqueItemLottery
}; };
@@ -22,45 +26,55 @@ use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
class che_선양 extends Command\GeneralCommand{ class che_선양 extends Command\GeneralCommand
{
static protected $actionName = '선양'; static protected $actionName = '선양';
static public $reqArg = true; static public $reqArg = true;
protected function argTest():bool{ protected function argTest(): bool
if($this->arg === null){ {
if ($this->arg === null) {
return false; return false;
} }
//NOTE: 사망 직전에 '선양' 턴을 넣을 수 있으므로, 존재하지 않는 장수여도 argTest에서 바로 탈락시키지 않음 //NOTE: 사망 직전에 '선양' 턴을 넣을 수 있으므로, 존재하지 않는 장수여도 argTest에서 바로 탈락시키지 않음
if(!key_exists('destGeneralID', $this->arg)){ if (!key_exists('destGeneralID', $this->arg)) {
return false; return false;
} }
$destGeneralID = $this->arg['destGeneralID']; $destGeneralID = $this->arg['destGeneralID'];
if(!is_int($destGeneralID)){ if (!is_int($destGeneralID)) {
return false; return false;
} }
if($destGeneralID <= 0){ if ($destGeneralID <= 0) {
return false; return false;
} }
if($destGeneralID == $this->generalObj->getID()){ if ($destGeneralID == $this->generalObj->getID()) {
return false; return false;
} }
$this->arg = [ $this->arg = [
'destGeneralID'=>$destGeneralID 'destGeneralID' => $destGeneralID
]; ];
return true; return true;
} }
protected function init(){ protected function init()
{
$general = $this->generalObj; $general = $this->generalObj;
$this->setNation(); $this->setNation();
$this->minConditionConstraints = [
ConstraintHelper::BeLord()
];
}
protected function initWithArg()
{
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['gold', 'nation'], 1); $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['gold', 'nation'], 1);
$this->setDestGeneral($destGeneral); $this->setDestGeneral($destGeneral);
$this->runnableConstraints=[ $this->fullConditionConstraints = [
ConstraintHelper::BeLord(), ConstraintHelper::BeLord(),
ConstraintHelper::ExistsDestGeneral(), ConstraintHelper::ExistsDestGeneral(),
ConstraintHelper::FriendlyDestGeneral(), ConstraintHelper::FriendlyDestGeneral(),
ConstraintHelper::DisallowDiplomacyStatus( ConstraintHelper::DisallowDiplomacyStatus(
@@ -70,15 +84,18 @@ class che_선양 extends Command\GeneralCommand{
]; ];
} }
public function getCost():array{ public function getCost(): array
{
return [0, 0]; return [0, 0];
} }
public function getPreReqTurn():int{ public function getPreReqTurn(): int
{
return 0; return 0;
} }
public function getPostReqTurn():int{ public function getPostReqTurn(): int
{
return 0; return 0;
} }
@@ -89,8 +106,9 @@ class che_선양 extends Command\GeneralCommand{
return "{$destGeneralName}】에게 {$name}"; return "{$destGeneralName}】에게 {$name}";
} }
public function run():bool{ public function run(): bool
if(!$this->isRunnable()){ {
if (!$this->hasFullConditionMet()) {
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -105,7 +123,7 @@ class che_선양 extends Command\GeneralCommand{
$destGeneralName = $destGeneral->getName(); $destGeneralName = $destGeneral->getName();
$nationName = $this->nation['name']; $nationName = $this->nation['name'];
$logger = $general->getLogger(); $logger = $general->getLogger();
$destLogger = $destGeneral->getLogger(); $destLogger = $destGeneral->getLogger();
@@ -138,26 +156,26 @@ class che_선양 extends Command\GeneralCommand{
//TODO: 암행부처럼 보여야... //TODO: 암행부처럼 보여야...
$db = DB::db(); $db = DB::db();
$destRawGenerals = $db->query('SELECT no,name,officer_level,npc FROM general WHERE nation != 0 AND nation = %i AND no != %i ORDER BY npc,binary(name)',$this->generalObj->getNationID(), $this->generalObj->getID()); $destRawGenerals = $db->query('SELECT no,name,officer_level,npc FROM general WHERE nation != 0 AND nation = %i AND no != %i ORDER BY npc,binary(name)', $this->generalObj->getNationID(), $this->generalObj->getID());
ob_start(); ob_start();
?> ?>
군주의 자리를 다른 장수에게 물려줍니다.<br> 군주의 자리를 다른 장수에게 물려줍니다.<br>
장수를 선택하세요.<br> 장수를 선택하세요.<br>
<select class='formInput' name="destGeneralID" id="destGeneralID" size='1' style='color:white;background-color:black;'> <select class='formInput' name="destGeneralID" id="destGeneralID" size='1' style='color:white;background-color:black;'>
<?php foreach($destRawGenerals as $destGeneral): <?php foreach ($destRawGenerals as $destGeneral) :
$color = \sammo\getNameColor($destGeneral['npc']); $color = \sammo\getNameColor($destGeneral['npc']);
if($color){ if ($color) {
$color = " style='color:{$color}'"; $color = " style='color:{$color}'";
} }
$name = $destGeneral['name']; $name = $destGeneral['name'];
if($destGeneral['officer_level'] >= 5){ if ($destGeneral['officer_level'] >= 5) {
$name = "*{$name}*"; $name = "*{$name}*";
} }
?> ?>
<option value='<?=$destGeneral['no']?>' <?=$color?>><?=$name?></option> <option value='<?= $destGeneral['no'] ?>' <?= $color ?>><?= $name ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> <input type=button id="commonSubmit" value="<?=$this->getName()?>"><br> </select> <input type=button id="commonSubmit" value="<?= $this->getName() ?>"><br>
<?php <?php
return ob_get_clean(); return ob_get_clean();
} }
} }
@@ -33,7 +33,7 @@ class che_소집해제 extends Command\GeneralCommand{
$this->setCity(); $this->setCity();
$this->setNation(); $this->setNation();
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::ReqGeneralCrew(), ConstraintHelper::ReqGeneralCrew(),
]; ];
@@ -58,7 +58,7 @@ class che_소집해제 extends Command\GeneralCommand{
} }
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
+81 -56
View File
@@ -1,18 +1,24 @@
<?php <?php
namespace sammo\Command\General; namespace sammo\Command\General;
use \sammo\{ use\sammo\{
DB, Util, JosaUtil, Session, KVStorage, DB,
General, Util,
JosaUtil,
Session,
KVStorage,
General,
ActionLogger, ActionLogger,
GameConst, GameUnitConst, GameConst,
GameUnitConst,
LastTurn, LastTurn,
Command, Command,
ServConfig ServConfig
}; };
use function \sammo\{ use function\sammo\{
getDexCall, getDexCall,
getTechCall, getTechCall,
tryUniqueItemLottery, tryUniqueItemLottery,
@@ -24,7 +30,8 @@ use \sammo\Constraint\ConstraintHelper;
class che_숙련전환 extends Command\GeneralCommand{ class che_숙련전환 extends Command\GeneralCommand
{
static protected $actionName = '숙련전환'; static protected $actionName = '숙련전환';
static public $reqArg = true; static public $reqArg = true;
@@ -36,103 +43,121 @@ class che_숙련전환 extends Command\GeneralCommand{
protected $destArmType; protected $destArmType;
/** @var string */ /** @var string */
protected $destArmTypeName; protected $destArmTypeName;
protected function argTest():bool{ protected function argTest(): bool
if($this->arg === null){ {
if ($this->arg === null) {
return false; return false;
} }
if(!key_exists('srcArmType', $this->arg)){ if (!key_exists('srcArmType', $this->arg)) {
return false; return false;
} }
if(!key_exists('destArmType', $this->arg)){ if (!key_exists('destArmType', $this->arg)) {
return false; return false;
} }
$srcArmType = $this->arg['srcArmType']; $srcArmType = $this->arg['srcArmType'];
$destArmType = $this->arg['destArmType']; $destArmType = $this->arg['destArmType'];
if(!is_int($srcArmType)){ if (!is_int($srcArmType)) {
return false; return false;
} }
if(!key_exists($srcArmType, GameUnitConst::allType())){ if (!key_exists($srcArmType, GameUnitConst::allType())) {
return false; return false;
} }
if(!is_int($destArmType)){ if (!is_int($destArmType)) {
return false; return false;
} }
if(!key_exists($destArmType, GameUnitConst::allType())){ if (!key_exists($destArmType, GameUnitConst::allType())) {
return false; return false;
} }
if($srcArmType === $destArmType){ if ($srcArmType === $destArmType) {
return false; return false;
} }
$this->arg = [ $this->arg = [
'srcArmType'=>$srcArmType, 'srcArmType' => $srcArmType,
'destArmType'=>$destArmType 'destArmType' => $destArmType
]; ];
return true; return true;
} }
protected function init(){ protected function init()
{
$general = $this->generalObj; $general = $this->generalObj;
$this->setCity(); $this->setCity();
$this->setNation(); $this->setNation();
[$reqGold, $reqRice] = $this->getCost();
$this->minConditionConstraints = [
ConstraintHelper::NotBeNeutral(),
ConstraintHelper::OccupiedCity(),
ConstraintHelper::ReqGeneralGold($reqGold),
ConstraintHelper::ReqGeneralRice($reqRice),
];
}
protected function initWithArg()
{
$this->srcArmType = $this->arg['srcArmType']; $this->srcArmType = $this->arg['srcArmType'];
$this->srcArmTypeName = GameUnitConst::allType()[$this->srcArmType]; $this->srcArmTypeName = GameUnitConst::allType()[$this->srcArmType];
$this->destArmType = $this->arg['destArmType']; $this->destArmType = $this->arg['destArmType'];
$this->destArmTypeName = GameUnitConst::allType()[$this->destArmType]; $this->destArmTypeName = GameUnitConst::allType()[$this->destArmType];
[$reqGold, $reqRice] = $this->getCost(); [$reqGold, $reqRice] = $this->getCost();
$this->runnableConstraints=[ $this->fullConditionConstraints = [
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
ConstraintHelper::ReqGeneralGold($reqGold), ConstraintHelper::ReqGeneralGold($reqGold),
ConstraintHelper::ReqGeneralRice($reqRice), ConstraintHelper::ReqGeneralRice($reqRice),
]; ];
} }
public function getBrief():string{ public function getBrief(): string
{
return "{$this->srcArmTypeName}】숙련을 【{$this->destArmTypeName}】숙련으로 전환"; return "{$this->srcArmTypeName}】숙련을 【{$this->destArmTypeName}】숙련으로 전환";
} }
public function getCommandDetailTitle():string{ public function getCommandDetailTitle(): string
{
$name = $this->getName(); $name = $this->getName();
[$reqGold, $reqRice] = $this->getCost(); [$reqGold, $reqRice] = $this->getCost();
$title = "{$name}(통솔경험"; $title = "{$name}(통솔경험";
if($reqGold > 0){ if ($reqGold > 0) {
$title .= ", 자금{$reqGold}"; $title .= ", 자금{$reqGold}";
} }
if($reqRice > 0){ if ($reqRice > 0) {
$title .= ", 군량{$reqRice}"; $title .= ", 군량{$reqRice}";
} }
$title .= ')'; $title .= ')';
return $title; return $title;
} }
public function getCost():array{ public function getCost(): array
{
$env = $this->env; $env = $this->env;
return [$env['develcost'], $env['develcost']]; return [$env['develcost'], $env['develcost']];
} }
public function getPreReqTurn():int{ public function getPreReqTurn(): int
{
return 0; return 0;
} }
public function getPostReqTurn():int{ public function getPostReqTurn(): int
{
return 0; return 0;
} }
public function run():bool{ public function run(): bool
if(!$this->isRunnable()){ {
if (!$this->hasFullConditionMet()) {
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -143,14 +168,14 @@ class che_숙련전환 extends Command\GeneralCommand{
$logger = $general->getLogger(); $logger = $general->getLogger();
$srcDex = $general->getVar('dex'.$this->srcArmType); $srcDex = $general->getVar('dex' . $this->srcArmType);
$cutDex = Util::toInt($srcDex * 0.3); $cutDex = Util::toInt($srcDex * 0.3);
$cutDexText = number_format($cutDex); $cutDexText = number_format($cutDex);
$addDex = Util::toInt($cutDex * 2 / 3); $addDex = Util::toInt($cutDex * 2 / 3);
$addDexText = number_format($addDex); $addDexText = number_format($addDex);
$general->increaseVar('dex'.$this->srcArmType, -$cutDex); $general->increaseVar('dex' . $this->srcArmType, -$cutDex);
$general->increaseVar('dex'.$this->destArmType, $addDex); $general->increaseVar('dex' . $this->destArmType, $addDex);
$josaUl = JosaUtil::pick($cutDex, '을'); $josaUl = JosaUtil::pick($cutDex, '을');
$josaRo = JosaUtil::pick($addDex, '로'); $josaRo = JosaUtil::pick($addDex, '로');
@@ -170,17 +195,17 @@ class che_숙련전환 extends Command\GeneralCommand{
return true; return true;
} }
public function getForm(): string public function getForm(): string
{ {
$db = DB::db(); $db = DB::db();
$general = $this->generalObj; $general = $this->generalObj;
$dexSrcTexts = []; $dexSrcTexts = [];
$dexDestTexts = []; $dexDestTexts = [];
foreach(GameUnitConst::allType() as $armType => $armName){ foreach (GameUnitConst::allType() as $armType => $armName) {
$dexVal = $general->getVar('dex'.$armType); $dexVal = $general->getVar('dex' . $armType);
$dexValText = number_format($dexVal); $dexValText = number_format($dexVal);
$cutDex = Util::toInt($dexVal * 0.3); $cutDex = Util::toInt($dexVal * 0.3);
$addDex = Util::toInt($cutDex * 2 / 3); $addDex = Util::toInt($cutDex * 2 / 3);
@@ -195,23 +220,23 @@ class che_숙련전환 extends Command\GeneralCommand{
ob_start(); ob_start();
?> ?>
본인의 특정 병종 숙련을 30% 줄이고, 줄어든 숙련 중 2/3(20%p)를 다른 병종 숙련으로 전환합니다.<br> 본인의 특정 병종 숙련을 30% 줄이고, 줄어든 숙련 중 2/3(20%p)를 다른 병종 숙련으로 전환합니다.<br>
<select class='formInput' name="srcArmType" id="srcArmType" size='1' style='color:white;background-color:black;'> <select class='formInput' name="srcArmType" id="srcArmType" size='1' style='color:white;background-color:black;'>
<?php foreach($dexSrcTexts as $armType=>$infoText): ?> <?php foreach ($dexSrcTexts as $armType => $infoText) : ?>
<option value="<?=$armType?>"><?=$infoText?></option> <option value="<?= $armType ?>"><?= $infoText ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
숙련을 숙련을
<select class='formInput' name="destArmType" id="destArmType" size='1' style='color:white;background-color:black;'> <select class='formInput' name="destArmType" id="destArmType" size='1' style='color:white;background-color:black;'>
<?php foreach($dexDestTexts as $armType=>$infoText): ?> <?php foreach ($dexDestTexts as $armType => $infoText) : ?>
<option value="<?=$armType?>"><?=$infoText?></option> <option value="<?= $armType ?>"><?= $infoText ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
숙련으로 <input type=button id="commonSubmit" value="<?=$this->getName()?>"><br> 숙련으로 <input type=button id="commonSubmit" value="<?= $this->getName() ?>"><br>
<?php <?php
return ob_get_clean(); return ob_get_clean();
} }
} }
+2 -2
View File
@@ -34,7 +34,7 @@ class che_요양 extends Command\GeneralCommand{
$this->setNation(); $this->setNation();
$this->runnableConstraints=[ $this->fullConditionConstraints=[
]; ];
} }
@@ -52,7 +52,7 @@ class che_요양 extends Command\GeneralCommand{
} }
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
+69 -44
View File
@@ -1,17 +1,21 @@
<?php <?php
namespace sammo\Command\General; namespace sammo\Command\General;
use \sammo\{ use\sammo\{
DB, Util, JosaUtil, DB,
General, Util,
JosaUtil,
General,
ActionLogger, ActionLogger,
GameConst, GameUnitConst, GameConst,
GameUnitConst,
LastTurn, LastTurn,
Command Command
}; };
use function \sammo\{ use function\sammo\{
tryUniqueItemLottery, tryUniqueItemLottery,
printCitiesBasedOnDistance printCitiesBasedOnDistance
}; };
@@ -22,83 +26,103 @@ use sammo\CityConst;
class che_이동 extends Command\GeneralCommand{ class che_이동 extends Command\GeneralCommand
{
static protected $actionName = '이동'; static protected $actionName = '이동';
static public $reqArg = true; static public $reqArg = true;
protected function argTest():bool{ protected function argTest(): bool
if($this->arg === null){ {
if ($this->arg === null) {
return false; return false;
} }
if(!key_exists('destCityID', $this->arg)){ if (!key_exists('destCityID', $this->arg)) {
return false; return false;
} }
if(!key_exists($this->arg['destCityID'], CityConst::all())){ if (!key_exists($this->arg['destCityID'], CityConst::all())) {
return false; return false;
} }
$this->arg = [ $this->arg = [
'destCityID'=>$this->arg['destCityID'] 'destCityID' => $this->arg['destCityID']
]; ];
return true; return true;
} }
protected function init(){ protected function init()
{
$general = $this->generalObj; $general = $this->generalObj;
$this->setCity(); $this->setCity();
$this->setNation(); $this->setNation();
$this->setDestCity($this->arg['destCityID'], []);
[$reqGold, $reqRice] = $this->getCost(); [$reqGold, $reqRice] = $this->getCost();
$this->runnableConstraints=[ $this->minConditionConstraints = [
ConstraintHelper::NotSameDestCity(), ConstraintHelper::ReqGeneralGold($reqGold),
ConstraintHelper::ReqGeneralRice($reqRice),
];
}
protected function initWithArg()
{
$this->setDestCity($this->arg['destCityID'], true);
[$reqGold, $reqRice] = $this->getCost();
$this->fullConditionConstraints = [
ConstraintHelper::NotSameDestCity(),
ConstraintHelper::NearCity(1), ConstraintHelper::NearCity(1),
ConstraintHelper::ReqGeneralGold($reqGold), ConstraintHelper::ReqGeneralGold($reqGold),
ConstraintHelper::ReqGeneralRice($reqRice), ConstraintHelper::ReqGeneralRice($reqRice),
]; ];
} }
public function getCommandDetailTitle():string{ public function getCommandDetailTitle(): string
{
$name = $this->getName(); $name = $this->getName();
[$reqGold, $reqRice] = $this->getCost(); [$reqGold, $reqRice] = $this->getCost();
$title = "{$name}(통솔경험"; $title = "{$name}(통솔경험";
if($reqGold > 0){ if ($reqGold > 0) {
$title .= ", 자금{$reqGold}"; $title .= ", 자금{$reqGold}";
} }
if($reqRice > 0){ if ($reqRice > 0) {
$title .= ", 군량{$reqRice}"; $title .= ", 군량{$reqRice}";
} }
$title .= ', 사기↓)'; $title .= ', 사기↓)';
return $title; return $title;
} }
public function getCost():array{ public function getCost(): array
{
$env = $this->env; $env = $this->env;
return [$env['develcost'], 0]; return [$env['develcost'], 0];
} }
public function getPreReqTurn():int{ public function getPreReqTurn(): int
{
return 0; return 0;
} }
public function getPostReqTurn():int{ public function getPostReqTurn(): int
{
return 0; return 0;
} }
public function getBrief():string{ public function getBrief(): string
{
$commandName = $this->getName(); $commandName = $this->getName();
$destCityName = CityConst::byID($this->arg['destCityID'])->name; $destCityName = CityConst::byID($this->arg['destCityID'])->name;
$josaRo = JosaUtil::pick($destCityName, '로'); $josaRo = JosaUtil::pick($destCityName, '로');
return "{$destCityName}{$josaRo} {$commandName}"; return "{$destCityName}{$josaRo} {$commandName}";
} }
public function getFailString():string{ public function getFailString(): string
{
$commandName = $this->getName(); $commandName = $this->getName();
$failReason = $this->testRunnable(); $failReason = $this->testFullConditionMet();
if($failReason === null){ if ($failReason === null) {
throw new \RuntimeException('실행 가능한 커맨드에 대해 실패 이유를 수집'); throw new \RuntimeException('실행 가능한 커맨드에 대해 실패 이유를 수집');
} }
$destCityName = CityConst::byID($this->arg['destCityID'])->name; $destCityName = CityConst::byID($this->arg['destCityID'])->name;
@@ -106,8 +130,9 @@ class che_이동 extends Command\GeneralCommand{
return "{$failReason} <G><b>{$destCityName}</b></>{$josaRo} {$commandName} 실패."; return "{$failReason} <G><b>{$destCityName}</b></>{$josaRo} {$commandName} 실패.";
} }
public function run():bool{ public function run(): bool
if(!$this->isRunnable()){ {
if (!$this->hasFullConditionMet()) {
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -129,14 +154,14 @@ class che_이동 extends Command\GeneralCommand{
$general->setVar('city', $destCityID); $general->setVar('city', $destCityID);
if($general->getVar('officer_level') == 12 && $this->nation['level'] == 0){ if ($general->getVar('officer_level') == 12 && $this->nation['level'] == 0) {
$generalList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND no!=%i', $general->getNationID(), $general->getID()); $generalList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND no!=%i', $general->getNationID(), $general->getID());
if($generalList){ if ($generalList) {
$db->update('general', [ $db->update('general', [
'city'=>$destCityID 'city' => $destCityID
], 'no IN %li', $generalList); ], 'no IN %li', $generalList);
} }
foreach($generalList as $targetGeneralID){ foreach ($generalList as $targetGeneralID) {
$targetLogger = new ActionLogger($targetGeneralID, $general->getNationID(), $env['year'], $env['month']); $targetLogger = new ActionLogger($targetGeneralID, $general->getNationID(), $env['year'], $env['month']);
$targetLogger->pushGeneralActionLog("방랑군 세력이 <G><b>{$destCityName}</b></>{$josaRo} 이동했습니다.", ActionLogger::PLAIN); $targetLogger->pushGeneralActionLog("방랑군 세력이 <G><b>{$destCityName}</b></>{$josaRo} 이동했습니다.", ActionLogger::PLAIN);
$targetLogger->flush(); $targetLogger->flush();
@@ -168,17 +193,17 @@ class che_이동 extends Command\GeneralCommand{
ob_start(); ob_start();
?> ?>
<?=\sammo\getMapHtml()?><br> <?= \sammo\getMapHtml() ?><br>
선택된 도시로 이동합니다.<br> 선택된 도시로 이동합니다.<br>
인접 도시로만 이동이 가능합니다.<br> 인접 도시로만 이동이 가능합니다.<br>
목록을 선택하거나 도시를 클릭하세요.<br> 목록을 선택하거나 도시를 클릭하세요.<br>
<?=$currentCityName?> => <select class='formInput' name="destCityID" id="destCityID" size='1' style='color:white;background-color:black;'><br> <?= $currentCityName ?> => <select class='formInput' name="destCityID" id="destCityID" size='1' style='color:white;background-color:black;'><br>
<?=\sammo\optionsForCities()?><br> <?= \sammo\optionsForCities() ?><br>
</select> <input type=button id="commonSubmit" value="<?=$this->getName()?>"><br> </select> <input type=button id="commonSubmit" value="<?= $this->getName() ?>"><br>
<br> <br>
<br> <br>
<?=printCitiesBasedOnDistance($currentCityID, 1)?> <?= printCitiesBasedOnDistance($currentCityID, 1) ?>
<?php <?php
return ob_get_clean(); return ob_get_clean();
} }
} }
@@ -40,7 +40,7 @@ class che_인재탐색 extends Command\GeneralCommand{
[$reqGold, $reqRice] = $this->getCost(); [$reqGold, $reqRice] = $this->getCost();
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
ConstraintHelper::NotWanderingNation(), ConstraintHelper::NotWanderingNation(),
ConstraintHelper::ReqGeneralGold($reqGold), ConstraintHelper::ReqGeneralGold($reqGold),
@@ -51,7 +51,7 @@ class che_인재탐색 extends Command\GeneralCommand{
if($this->nation['nation'] != 0 && $relYear < 3 && $this->nation['gennum'] >= GameConst::$initialNationGenLimit){ if($this->nation['nation'] != 0 && $relYear < 3 && $this->nation['gennum'] >= GameConst::$initialNationGenLimit){
$nationName = $this->nation['name']; $nationName = $this->nation['name'];
$josaUn = JosaUtil::pick($nationName, '은'); $josaUn = JosaUtil::pick($nationName, '은');
$this->runnableConstraints[] = ConstraintHelper::AlwaysFail("현재 <D>{$nationName}</>{$josaUn} 탐색이 제한되고 있습니다."); $this->fullConditionConstraints[] = ConstraintHelper::AlwaysFail("현재 <D>{$nationName}</>{$josaUn} 탐색이 제한되고 있습니다.");
} }
} }
@@ -84,7 +84,7 @@ class che_인재탐색 extends Command\GeneralCommand{
} }
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
+19 -12
View File
@@ -82,6 +82,22 @@ class che_임관 extends Command\GeneralCommand{
$this->setCity(); $this->setCity();
$this->setNation(); $this->setNation();
$relYear = $env['year'] - $env['startyear'];
$this->permissionConstraints=[
ConstraintHelper::ReqEnvValue('join_mode', '!=', 'onlyRandom', '랜덤 임관만 가능합니다')
];
$this->minConditionConstraints=[
ConstraintHelper::ReqEnvValue('join_mode', '!=', 'onlyRandom', '랜덤 임관만 가능합니다'),
ConstraintHelper::BeNeutral(),
ConstraintHelper::AllowJoinAction()
];
}
protected function initWithArg()
{
$destGeneralID = $this->arg['destGeneralID']??null; $destGeneralID = $this->arg['destGeneralID']??null;
$destNationID = $this->arg['destNationID']??null; $destNationID = $this->arg['destNationID']??null;
if($destGeneralID !== null){ if($destGeneralID !== null){
@@ -92,13 +108,9 @@ class che_임관 extends Command\GeneralCommand{
$this->setDestNation($destNationID, ['gennum', 'scout']); $this->setDestNation($destNationID, ['gennum', 'scout']);
} }
$env = $this->env;
$relYear = $env['year'] - $env['startyear']; $relYear = $env['year'] - $env['startyear'];
$this->fullConditionConstraints=[
$this->reservableConstraints=[
ConstraintHelper::ReqEnvValue('join_mode', '!=', 'onlyRandom', '랜덤 임관만 가능합니다')
];
$this->runnableConstraints=[
ConstraintHelper::ReqEnvValue('join_mode', '!=', 'onlyRandom', '랜덤 임관만 가능합니다'), ConstraintHelper::ReqEnvValue('join_mode', '!=', 'onlyRandom', '랜덤 임관만 가능합니다'),
ConstraintHelper::BeNeutral(), ConstraintHelper::BeNeutral(),
ConstraintHelper::ExistsDestNation(), ConstraintHelper::ExistsDestNation(),
@@ -107,11 +119,6 @@ class che_임관 extends Command\GeneralCommand{
]; ];
} }
public function canDisplay(): bool
{
return ($this->env['join_mode']??'') != 'onlyRandom';
}
public function getCost():array{ public function getCost():array{
return [0, 0]; return [0, 0];
} }
@@ -132,7 +139,7 @@ class che_임관 extends Command\GeneralCommand{
} }
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
+15 -7
View File
@@ -63,14 +63,23 @@ class che_장비매매 extends Command\GeneralCommand{
$this->setCity(); $this->setCity();
$this->setNation(); $this->setNation();
$this->minConditionConstraints=[
ConstraintHelper::ReqCityTrader($general->getVar('npc')),
];
}
protected function initWithArg()
{
$general = $this->generalObj;
$itemType = $this->arg['itemType']; $itemType = $this->arg['itemType'];
$itemTypeName = static::$itemMap[$itemType]; $itemTypeName = static::$itemMap[$itemType];
$itemCode = $this->arg['itemCode']; $itemCode = $this->arg['itemCode'];
$itemClass = buildItemClass($itemCode); $itemClass = buildItemClass($itemCode);
[$reqGold, $reqRice] = $this->getCost(); [$reqGold, $reqRice] = $this->getCost();
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::ReqCityTrader($general->getVar('npc')), ConstraintHelper::ReqCityTrader($general->getVar('npc')),
ConstraintHelper::ReqCityCapacity('secu', '치안 수치', $itemClass->getReqSecu()), ConstraintHelper::ReqCityCapacity('secu', '치안 수치', $itemClass->getReqSecu()),
ConstraintHelper::ReqGeneralGold($reqGold), ConstraintHelper::ReqGeneralGold($reqGold),
@@ -78,15 +87,14 @@ class che_장비매매 extends Command\GeneralCommand{
]; ];
if($itemCode === 'None'){ if($itemCode === 'None'){
$this->runnableConstraints[] = ConstraintHelper::ReqGeneralValue($itemType, $itemTypeName, '!=', 'None'); $this->fullConditionConstraints[] = ConstraintHelper::ReqGeneralValue($itemType, $itemTypeName, '!=', 'None');
} }
else if($itemCode == $general->getVar($itemType)){ else if($itemCode == $general->getVar($itemType)){
$this->runnableConstraints[] = ConstraintHelper::AlwaysFail('이미 가지고 있습니다.'); $this->fullConditionConstraints[] = ConstraintHelper::AlwaysFail('이미 가지고 있습니다.');
} }
else if($itemType != 'item' && !buildItemClass($general->getVar($itemType))->isBuyable()){ else if($itemType != 'item' && !buildItemClass($general->getVar($itemType))->isBuyable()){
$this->runnableConstraints[] = ConstraintHelper::AlwaysFail('이미 진귀한 것을 가지고 있습니다.'); $this->fullConditionConstraints[] = ConstraintHelper::AlwaysFail('이미 진귀한 것을 가지고 있습니다.');
} }
} }
public function getCost():array{ public function getCost():array{
@@ -128,7 +136,7 @@ class che_장비매매 extends Command\GeneralCommand{
} }
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -37,7 +37,7 @@ class che_전투태세 extends Command\GeneralCommand{
[$reqGold, $reqRice] = $this->getCost(); [$reqGold, $reqRice] = $this->getCost();
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
ConstraintHelper::NotWanderingNation(), ConstraintHelper::NotWanderingNation(),
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
@@ -65,7 +65,7 @@ class che_전투태세 extends Command\GeneralCommand{
} }
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -44,7 +44,7 @@ class che_정착장려 extends Command\GeneralCommand{
[$reqGold, $reqRice] = $this->getCost(); [$reqGold, $reqRice] = $this->getCost();
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
ConstraintHelper::NotWanderingNation(), ConstraintHelper::NotWanderingNation(),
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
@@ -118,7 +118,7 @@ class che_정착장려 extends Command\GeneralCommand{
} }
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -44,7 +44,7 @@ class che_주민선정 extends Command\GeneralCommand{
[$reqGold, $reqRice] = $this->getCost(); [$reqGold, $reqRice] = $this->getCost();
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
ConstraintHelper::NotWanderingNation(), ConstraintHelper::NotWanderingNation(),
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
@@ -119,7 +119,7 @@ class che_주민선정 extends Command\GeneralCommand{
} }
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
+89 -70
View File
@@ -1,9 +1,13 @@
<?php <?php
namespace sammo\Command\General; namespace sammo\Command\General;
use \sammo\{ use\sammo\{
DB, Util, JosaUtil, DB,
General, DummyGeneral, Util,
JosaUtil,
General,
DummyGeneral,
ActionLogger, ActionLogger,
GameConst, GameConst,
LastTurn, LastTurn,
@@ -11,9 +15,9 @@ use \sammo\{
Command Command
}; };
use function \sammo\{ use function\sammo\{
getDomesticExpLevelBonus, getDomesticExpLevelBonus,
CriticalRatioDomestic, CriticalRatioDomestic,
CriticalScoreEx, CriticalScoreEx,
tryUniqueItemLottery tryUniqueItemLottery
}; };
@@ -22,108 +26,123 @@ use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
class che_증여 extends Command\GeneralCommand{ class che_증여 extends Command\GeneralCommand
{
static protected $actionName = '증여'; static protected $actionName = '증여';
static public $reqArg = true; static public $reqArg = true;
protected function argTest():bool{ protected function argTest(): bool
if($this->arg === null){ {
if ($this->arg === null) {
return false; return false;
} }
//NOTE: 사망 직전에 '증여' 턴을 넣을 수 있으므로, 존재하지 않는 장수여도 argTest에서 바로 탈락시키지 않음 //NOTE: 사망 직전에 '증여' 턴을 넣을 수 있으므로, 존재하지 않는 장수여도 argTest에서 바로 탈락시키지 않음
if(!key_exists('isGold', $this->arg)){ if (!key_exists('isGold', $this->arg)) {
return false; return false;
} }
if(!key_exists('amount', $this->arg)){ if (!key_exists('amount', $this->arg)) {
return false; return false;
} }
if(!key_exists('destGeneralID', $this->arg)){ if (!key_exists('destGeneralID', $this->arg)) {
return false; return false;
} }
$isGold = $this->arg['isGold']; $isGold = $this->arg['isGold'];
$amount = $this->arg['amount']; $amount = $this->arg['amount'];
$destGeneralID = $this->arg['destGeneralID']; $destGeneralID = $this->arg['destGeneralID'];
if(!is_numeric($amount)){ if (!is_numeric($amount)) {
return false; return false;
} }
$amount = Util::round($amount, -2); $amount = Util::round($amount, -2);
$amount = Util::valueFit($amount, 100, GameConst::$maxResourceActionAmount); $amount = Util::valueFit($amount, 100, GameConst::$maxResourceActionAmount);
if($amount <= 0){ if ($amount <= 0) {
return false; return false;
} }
if(!is_bool($isGold)){ if (!is_bool($isGold)) {
return false; return false;
} }
if(!is_int($destGeneralID)){ if (!is_int($destGeneralID)) {
return false; return false;
} }
if($destGeneralID <= 0){ if ($destGeneralID <= 0) {
return false; return false;
} }
if($destGeneralID == $this->generalObj->getID()){ if ($destGeneralID == $this->generalObj->getID()) {
return false; return false;
} }
$this->arg = [ $this->arg = [
'isGold'=>$isGold, 'isGold' => $isGold,
'amount'=>$amount, 'amount' => $amount,
'destGeneralID'=>$destGeneralID 'destGeneralID' => $destGeneralID
]; ];
return true; return true;
} }
protected function init(){ protected function init()
{
$general = $this->generalObj; $general = $this->generalObj;
$this->setCity(); $this->setCity();
$this->setNation(); $this->setNation();
$this->minConditionConstraints = [
ConstraintHelper::NotBeNeutral(),
ConstraintHelper::OccupiedCity(),
ConstraintHelper::SuppliedCity(),
];
}
protected function initWithArg()
{
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['gold', 'rice', 'nation'], 1); $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['gold', 'rice', 'nation'], 1);
$this->setDestGeneral($destGeneral); $this->setDestGeneral($destGeneral);
$this->runnableConstraints=[ $this->fullConditionConstraints = [
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
ConstraintHelper::SuppliedCity(), ConstraintHelper::SuppliedCity(),
ConstraintHelper::ExistsDestGeneral(), ConstraintHelper::ExistsDestGeneral(),
ConstraintHelper::FriendlyDestGeneral() ConstraintHelper::FriendlyDestGeneral()
]; ];
if($this->arg['isGold']){ if ($this->arg['isGold']) {
$this->runnableConstraints[] = ConstraintHelper::ReqGeneralGold(GameConst::$generalMinimumGold); $this->fullConditionConstraints[] = ConstraintHelper::ReqGeneralGold(GameConst::$generalMinimumGold);
} else {
$this->fullConditionConstraints[] = ConstraintHelper::ReqGeneralRice(GameConst::$generalMinimumRice);
} }
else{
$this->runnableConstraints[] = ConstraintHelper::ReqGeneralRice(GameConst::$generalMinimumRice);
}
} }
public function getCommandDetailTitle():string{ public function getCommandDetailTitle(): string
{
$name = $this->getName(); $name = $this->getName();
return "{$name}(통솔경험)"; return "{$name}(통솔경험)";
} }
public function getCost():array{ public function getCost(): array
{
return [0, 0]; return [0, 0];
} }
public function getPreReqTurn():int{ public function getPreReqTurn(): int
{
return 0; return 0;
} }
public function getPostReqTurn():int{ public function getPostReqTurn(): int
{
return 0; return 0;
} }
public function getBrief(): string public function getBrief(): string
{ {
$destGeneralName = $this->destGeneralObj->getName(); $destGeneralName = $this->destGeneralObj->getName();
$resText = $this->arg['isGold']?'금':'쌀'; $resText = $this->arg['isGold'] ? '금' : '쌀';
$name = $this->getName(); $name = $this->getName();
return "{$destGeneralName}】에게 {$resText} {$this->arg['amount']}{$name}"; return "{$destGeneralName}】에게 {$resText} {$this->arg['amount']}{$name}";
} }
public function run():bool{ public function run(): bool
if(!$this->isRunnable()){ {
if (!$this->hasFullConditionMet()) {
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -134,13 +153,13 @@ class che_증여 extends Command\GeneralCommand{
$isGold = $this->arg['isGold']; $isGold = $this->arg['isGold'];
$amount = $this->arg['amount']; $amount = $this->arg['amount'];
$resKey = $isGold?'gold':'rice'; $resKey = $isGold ? 'gold' : 'rice';
$resName = $isGold?'금':'쌀'; $resName = $isGold ? '금' : '쌀';
$destGeneral = $this->destGeneralObj; $destGeneral = $this->destGeneralObj;
$amount = Util::valueFit($amount, 0, $general->getVar($resKey) - ($isGold?GameConst::$generalMinimumGold:GameConst::$generalMinimumRice)); $amount = Util::valueFit($amount, 0, $general->getVar($resKey) - ($isGold ? GameConst::$generalMinimumGold : GameConst::$generalMinimumRice));
$amountText = number_format($amount, 0); $amountText = number_format($amount, 0);
$logger = $general->getLogger(); $logger = $general->getLogger();
$destGeneral->increaseVarWithLimit($resKey, $amount); $destGeneral->increaseVarWithLimit($resKey, $amount);
@@ -169,35 +188,35 @@ class che_증여 extends Command\GeneralCommand{
//TODO: 암행부처럼 보여야... //TODO: 암행부처럼 보여야...
$db = DB::db(); $db = DB::db();
$destRawGenerals = $db->query('SELECT no,name,officer_level,npc,gold,rice FROM general WHERE nation != 0 AND nation = %i AND no != %i ORDER BY npc,binary(name)',$this->generalObj->getNationID(), $this->generalObj->getID()); $destRawGenerals = $db->query('SELECT no,name,officer_level,npc,gold,rice FROM general WHERE nation != 0 AND nation = %i AND no != %i ORDER BY npc,binary(name)', $this->generalObj->getNationID(), $this->generalObj->getID());
ob_start(); ob_start();
?> ?>
자신의 자금이나 군량을 다른 장수에게 증여합니다.<br> 자신의 자금이나 군량을 다른 장수에게 증여합니다.<br>
장수를 선택하세요.<br> 장수를 선택하세요.<br>
<select class='formInput' name="destGeneralID" id="destGeneralID" size='1' style='color:white;background-color:black;'> <select class='formInput' name="destGeneralID" id="destGeneralID" size='1' style='color:white;background-color:black;'>
<?php foreach($destRawGenerals as $destGeneral): <?php foreach ($destRawGenerals as $destGeneral) :
$color = \sammo\getNameColor($destGeneral['npc']); $color = \sammo\getNameColor($destGeneral['npc']);
if($color){ if ($color) {
$color = " style='color:{$color}'"; $color = " style='color:{$color}'";
} }
$name = $destGeneral['name']; $name = $destGeneral['name'];
if($destGeneral['officer_level'] >= 5){ if ($destGeneral['officer_level'] >= 5) {
$name = "*{$name}*"; $name = "*{$name}*";
} }
?> ?>
<option value='<?=$destGeneral['no']?>' <?=$color?>><?=$name?>(금:<?=$destGeneral['gold']?>, 쌀:<?=$destGeneral['rice']?>)</option> <option value='<?= $destGeneral['no'] ?>' <?= $color ?>><?= $name ?>(금:<?= $destGeneral['gold'] ?>, 쌀:<?= $destGeneral['rice'] ?>)</option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
<select class='formInput' name="isGold" id="isGold" size='1' style='color:white;background-color:black;'> <select class='formInput' name="isGold" id="isGold" size='1' style='color:white;background-color:black;'>
<option value="true">금</option> <option value="true">금</option>
<option value="false">쌀</option> <option value="false">쌀</option>
</select> </select>
<select class='formInput' name="amount" id="amount" size='1' style='color:white;background-color:black;'> <select class='formInput' name="amount" id="amount" size='1' style='color:white;background-color:black;'>
<?php foreach(GameConst::$resourceActionAmountGuide as $amount): ?> <?php foreach (GameConst::$resourceActionAmountGuide as $amount) : ?>
<option value='<?=$amount?>'><?=$amount?></option> <option value='<?= $amount ?>'><?= $amount ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> <input type=button id="commonSubmit" value="<?=$this->getName()?>"><br> </select> <input type=button id="commonSubmit" value="<?= $this->getName() ?>"><br>
<?php <?php
return ob_get_clean(); return ob_get_clean();
} }
} }
+2 -2
View File
@@ -38,7 +38,7 @@ class che_집합 extends Command\GeneralCommand{
[$reqGold, $reqRice] = $this->getCost(); [$reqGold, $reqRice] = $this->getCost();
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
ConstraintHelper::SuppliedCity(), ConstraintHelper::SuppliedCity(),
@@ -65,7 +65,7 @@ class che_집합 extends Command\GeneralCommand{
} }
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
+178 -167
View File
@@ -1,18 +1,24 @@
<?php <?php
namespace sammo\Command\General; namespace sammo\Command\General;
use \sammo\{ use\sammo\{
DB, Util, JosaUtil, Session, KVStorage, DB,
General, Util,
JosaUtil,
Session,
KVStorage,
General,
ActionLogger, ActionLogger,
GameConst, GameUnitConst, GameConst,
GameUnitConst,
LastTurn, LastTurn,
Command, Command,
ServConfig ServConfig
}; };
use function \sammo\{ use function\sammo\{
getTechCall, getTechCall,
tryUniqueItemLottery, tryUniqueItemLottery,
getTechAbil getTechAbil
@@ -23,7 +29,8 @@ use \sammo\Constraint\ConstraintHelper;
class che_징병 extends Command\GeneralCommand{ class che_징병 extends Command\GeneralCommand
{
static protected $actionName = '징병'; static protected $actionName = '징병';
static protected $costOffset = 1; static protected $costOffset = 1;
static public $reqArg = true; static public $reqArg = true;
@@ -37,7 +44,7 @@ class che_징병 extends Command\GeneralCommand{
protected $reqCrewType; protected $reqCrewType;
/** @var \sammo\GameUnitDetail */ /** @var \sammo\GameUnitDetail */
protected $currCrewType; protected $currCrewType;
static protected $isInitStatic = false; static protected $isInitStatic = false;
protected static function initStatic() protected static function initStatic()
{ {
@@ -45,52 +52,64 @@ class che_징병 extends Command\GeneralCommand{
static::$defaultAtmos = GameConst::$defaultAtmosLow; static::$defaultAtmos = GameConst::$defaultAtmosLow;
} }
protected function argTest():bool{ protected function argTest(): bool
if($this->arg === null){ {
if ($this->arg === null) {
return false; return false;
} }
if(!key_exists('crewType', $this->arg)){ if (!key_exists('crewType', $this->arg)) {
return false; return false;
} }
if(!key_exists('amount', $this->arg)){ if (!key_exists('amount', $this->arg)) {
return false; return false;
} }
$crewType = $this->arg['crewType']; $crewType = $this->arg['crewType'];
$amount = $this->arg['amount']; $amount = $this->arg['amount'];
if(!is_int($crewType)){ if (!is_int($crewType)) {
return false; return false;
} }
if(!is_numeric($amount)){ if (!is_numeric($amount)) {
return false; return false;
} }
$amount = (int)$amount; $amount = (int) $amount;
if(GameUnitConst::byID($crewType) === null){ if (GameUnitConst::byID($crewType) === null) {
return false; return false;
} }
if($amount < 0){ if ($amount < 0) {
return false; return false;
} }
$this->arg = [ $this->arg = [
'crewType'=>$crewType, 'crewType' => $crewType,
'amount'=>$amount 'amount' => $amount
]; ];
return true; return true;
} }
protected function init(){ protected function init()
$general = $this->generalObj; {
$this->setCity(); $this->setCity();
$this->setNation(['tech']); $this->setNation(['tech']);
$this->minConditionConstraints = [
ConstraintHelper::NotBeNeutral(),
ConstraintHelper::OccupiedCity(),
ConstraintHelper::ReqCityCapacity('pop', '주민', GameConst::$minAvailableRecruitPop + 100),
ConstraintHelper::ReqCityTrust(20),
];
}
protected function initWithArg()
{
$general = $this->generalObj;
$leadership = $general->getLeadership(false); $leadership = $general->getLeadership(false);
$currCrewType = $general->getCrewTypeObj(); $currCrewType = $general->getCrewTypeObj();
$maxCrew = $leadership * 100; $maxCrew = $leadership * 100;
$reqCrewType = GameUnitConst::byID($this->arg['crewType']); $reqCrewType = GameUnitConst::byID($this->arg['crewType']);
if($reqCrewType->id == $currCrewType->id){ if ($reqCrewType->id == $currCrewType->id) {
$maxCrew -= $general->getVar('crew'); $maxCrew -= $general->getVar('crew');
} }
$this->maxCrew = Util::valueFit($this->arg['amount'], 100, $maxCrew); $this->maxCrew = Util::valueFit($this->arg['amount'], 100, $maxCrew);
@@ -100,9 +119,9 @@ class che_징병 extends Command\GeneralCommand{
$this->currCrewType = $currCrewType; $this->currCrewType = $currCrewType;
[$reqGold, $reqRice] = $this->getCost(); [$reqGold, $reqRice] = $this->getCost();
$this->runnableConstraints=[ $this->fullConditionConstraints = [
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
ConstraintHelper::ReqCityCapacity('pop', '주민', GameConst::$minAvailableRecruitPop + $reqCrew), ConstraintHelper::ReqCityCapacity('pop', '주민', GameConst::$minAvailableRecruitPop + $reqCrew),
ConstraintHelper::ReqCityTrust(20), ConstraintHelper::ReqCityTrust(20),
@@ -111,26 +130,28 @@ class che_징병 extends Command\GeneralCommand{
ConstraintHelper::ReqGeneralCrewMargin($reqCrewType->id), ConstraintHelper::ReqGeneralCrewMargin($reqCrewType->id),
ConstraintHelper::AvailableRecruitCrewType($reqCrewType->id) ConstraintHelper::AvailableRecruitCrewType($reqCrewType->id)
]; ];
} }
public function getBrief():string{ public function getBrief(): string
{
$crewTypeName = $this->reqCrewType->name; $crewTypeName = $this->reqCrewType->name;
$amount = $this->reqCrew; $amount = $this->reqCrew;
$commandName = static::getName(); $commandName = static::getName();
return "{$crewTypeName}{$amount}{$commandName}"; return "{$crewTypeName}{$amount}{$commandName}";
} }
public function getCommandDetailTitle():string{ public function getCommandDetailTitle(): string
{
return "{$this->getName()}(통솔경험)"; return "{$this->getName()}(통솔경험)";
} }
public function getCost():array{ public function getCost(): array
if(!$this->isArgValid){ {
if (!$this->isArgValid) {
return [0, 0]; return [0, 0];
} }
$reqGold = $this->reqCrewType->costWithTech($this->nation['tech'], $this->maxCrew); $reqGold = $this->reqCrewType->costWithTech($this->nation['tech'], $this->maxCrew);
$reqGold = $this->generalObj->onCalcDomestic('징병', 'cost', $reqGold, ['armType'=>$this->reqCrewType->armType]); $reqGold = $this->generalObj->onCalcDomestic('징병', 'cost', $reqGold, ['armType' => $this->reqCrewType->armType]);
$reqGold *= static::$costOffset; $reqGold *= static::$costOffset;
$reqRice = $this->maxCrew / 100; $reqRice = $this->maxCrew / 100;
@@ -138,17 +159,20 @@ class che_징병 extends Command\GeneralCommand{
$reqRice = Util::round($reqRice); $reqRice = Util::round($reqRice);
return [$reqGold, $reqRice]; return [$reqGold, $reqRice];
} }
public function getPreReqTurn():int{ public function getPreReqTurn(): int
{
return 0; return 0;
} }
public function getPostReqTurn():int{ public function getPostReqTurn(): int
{
return 0; return 0;
} }
public function run():bool{ public function run(): bool
if(!$this->isRunnable()){ {
if (!$this->hasFullConditionMet()) {
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -168,7 +192,7 @@ class che_징병 extends Command\GeneralCommand{
$logger = $general->getLogger(); $logger = $general->getLogger();
if($reqCrewType->id == $currCrewType->id && $currCrew > 0){ if ($reqCrewType->id == $currCrewType->id && $currCrew > 0) {
$logger->pushGeneralActionLog("{$crewTypeName} <C>{$reqCrewText}</>명을 추가{$this->getName()}했습니다. <1>$date</>"); $logger->pushGeneralActionLog("{$crewTypeName} <C>{$reqCrewText}</>명을 추가{$this->getName()}했습니다. <1>$date</>");
$train = ($currCrew * $general->getVar('train') + $reqCrew * static::$defaultTrain) / ($currCrew + $reqCrew); $train = ($currCrew * $general->getVar('train') + $reqCrew * static::$defaultTrain) / ($currCrew + $reqCrew);
$atmos = ($currCrew * $general->getVar('atmos') + $reqCrew * static::$defaultAtmos) / ($currCrew + $reqCrew); $atmos = ($currCrew * $general->getVar('atmos') + $reqCrew * static::$defaultAtmos) / ($currCrew + $reqCrew);
@@ -176,8 +200,7 @@ class che_징병 extends Command\GeneralCommand{
$general->increaseVar('crew', $reqCrew); $general->increaseVar('crew', $reqCrew);
$general->setVar('train', $train); $general->setVar('train', $train);
$general->setVar('atmos', $atmos); $general->setVar('atmos', $atmos);
} } else {
else{
$logger->pushGeneralActionLog("{$crewTypeName} <C>{$reqCrewText}</>명을 {$this->getName()}했습니다. <1>$date</>"); $logger->pushGeneralActionLog("{$crewTypeName} <C>{$reqCrewText}</>명을 {$this->getName()}했습니다. <1>$date</>");
$general->setVar('crewtype', $reqCrewType->id); $general->setVar('crewtype', $reqCrewType->id);
$general->setVar('crew', $reqCrew); $general->setVar('crew', $reqCrew);
@@ -188,10 +211,10 @@ class che_징병 extends Command\GeneralCommand{
$newTrust = Util::valueFit($this->city['trust'] - ($reqCrew / $this->city['pop']) / static::$costOffset * 100, 0); $newTrust = Util::valueFit($this->city['trust'] - ($reqCrew / $this->city['pop']) / static::$costOffset * 100, 0);
$db->update('city', [ $db->update('city', [
'trust'=>$newTrust, 'trust' => $newTrust,
'pop'=>$this->city['pop'] - $reqCrew 'pop' => $this->city['pop'] - $reqCrew
], 'city=%i', $general->getCityID()); ], 'city=%i', $general->getCityID());
$exp = Util::round($reqCrew / 100); $exp = Util::round($reqCrew / 100);
$ded = Util::round($reqCrew / 100); $ded = Util::round($reqCrew / 100);
@@ -219,7 +242,7 @@ class che_징병 extends Command\GeneralCommand{
'js/recruitCrewForm.js' 'js/recruitCrewForm.js'
]; ];
} }
public function getForm(): string public function getForm(): string
{ {
$db = DB::db(); $db = DB::db();
@@ -227,74 +250,72 @@ class che_징병 extends Command\GeneralCommand{
$general = $this->generalObj; $general = $this->generalObj;
[$nationLevel, $tech] = $db->queryFirstList('SELECT level,tech FROM nation WHERE nation=%i', $general->getNationID()); [$nationLevel, $tech] = $db->queryFirstList('SELECT level,tech FROM nation WHERE nation=%i', $general->getNationID());
if(!$nationLevel){ if (!$nationLevel) {
$nationLevel = 0; $nationLevel = 0;
} }
if(!$tech){ if (!$tech) {
$tech = 0; $tech = 0;
} }
$ownCities = []; $ownCities = [];
$ownRegions = []; $ownRegions = [];
$year = $this->env['year']; $year = $this->env['year'];
$startyear = $this->env['startyear']; $startyear = $this->env['startyear'];
$relativeYear = $year - $startyear; $relativeYear = $year - $startyear;
foreach(DB::db()->query('SELECT city, region from city where nation = %i', $general->getNationID()) as $city){ foreach (DB::db()->query('SELECT city, region from city where nation = %i', $general->getNationID()) as $city) {
$ownCities[$city['city']] = 1; $ownCities[$city['city']] = 1;
$ownRegions[$city['region']] = 1; $ownRegions[$city['region']] = 1;
} }
$leadership = $general->getLeadership(); $leadership = $general->getLeadership();
$fullLeadership = $general->getLeadership(false); $fullLeadership = $general->getLeadership(false);
$abil = getTechAbil($tech); $abil = getTechAbil($tech);
$armTypes = []; $armTypes = [];
foreach(GameUnitConst::allType() as $armType => $armName){ foreach (GameUnitConst::allType() as $armType => $armName) {
$armTypeCrews = []; $armTypeCrews = [];
foreach(GameUnitConst::byType($armType) as $unit){ foreach (GameUnitConst::byType($armType) as $unit) {
$crewObj = new \stdClass; $crewObj = new \stdClass;
$crewObj->showDefault = 'true'; $crewObj->showDefault = 'true';
$crewObj->id = $unit->id; $crewObj->id = $unit->id;
if($unit->reqTech == 0){ if ($unit->reqTech == 0) {
$crewObj->bgcolor = 'green'; $crewObj->bgcolor = 'green';
} } else {
else{
$crewObj->bgcolor = 'limegreen'; $crewObj->bgcolor = 'limegreen';
} }
if(!$unit->isValid($ownCities, $ownRegions, $relativeYear, $tech)){ if (!$unit->isValid($ownCities, $ownRegions, $relativeYear, $tech)) {
$crewObj->showDefault = 'false'; $crewObj->showDefault = 'false';
$crewObj->bgcolor = 'red'; $crewObj->bgcolor = 'red';
} }
$crewObj->baseRice = $general->onCalcDomestic($this->getName(), 'rice', $unit->riceWithTech($tech), ['armType'=>$unit->armType]); $crewObj->baseRice = $general->onCalcDomestic($this->getName(), 'rice', $unit->riceWithTech($tech), ['armType' => $unit->armType]);
$crewObj->baseCost = $general->onCalcDomestic($this->getName(), 'cost', $unit->costWithTech($tech), ['armType'=>$unit->armType]); $crewObj->baseCost = $general->onCalcDomestic($this->getName(), 'cost', $unit->costWithTech($tech), ['armType' => $unit->armType]);
$crewObj->name = $unit->name; $crewObj->name = $unit->name;
$crewObj->attack = $unit->attack + $abil; $crewObj->attack = $unit->attack + $abil;
$crewObj->defence = $unit->defence + $abil; $crewObj->defence = $unit->defence + $abil;
$crewObj->speed = $unit->speed; $crewObj->speed = $unit->speed;
$crewObj->avoid = $unit->avoid; $crewObj->avoid = $unit->avoid;
if($this->env['show_img_level'] < 2) { if ($this->env['show_img_level'] < 2) {
$crewObj->img = ServConfig::$sharedIconPath."/default.jpg"; $crewObj->img = ServConfig::$sharedIconPath . "/default.jpg";
} else {
$crewObj->img = ServConfig::$gameImagePath . "/crewtype" . $unit->id . ".png";
} }
else{
$crewObj->img = ServConfig::$gameImagePath."/crewtype".$unit->id.".png";
}
$crewObj->baseRiceShort = round($crewObj->baseRice, 1); $crewObj->baseRiceShort = round($crewObj->baseRice, 1);
$crewObj->baseCostShort = round($crewObj->baseCost, 1); $crewObj->baseCostShort = round($crewObj->baseCost, 1);
$crewObj->info = join('<br>', $unit->info); $crewObj->info = join('<br>', $unit->info);
$armTypeCrews[] = $crewObj; $armTypeCrews[] = $crewObj;
} }
$armTypes[] = [$armName, $armTypeCrews]; $armTypes[] = [$armName, $armTypeCrews];
@@ -310,100 +331,90 @@ class che_징병 extends Command\GeneralCommand{
ob_start(); ob_start();
?> ?>
<font size=2>병사를 모집합니다. <font size=2>병사를 모집합니다.
<?php if($commandName=='징병'): ?> <?php if ($commandName == '징병') : ?>
훈련과 사기치는 낮지만 가격이 저렴합니다.<br> 훈련과 사기치는 낮지만 가격이 저렴합니다.<br>
<?php else: ?> <?php else : ?>
훈련과 사기치는 높지만 자금이 많이 듭니다. 훈련과 사기치는 높지만 자금이 많이 듭니다.
<?php endif; ?> <?php endif; ?>
가능한 수보다 많게 입력하면 가능한 최대 병사를 모집합니다.<br> 가능한 수보다 많게 입력하면 가능한 최대 병사를 모집합니다.<br>
이미 병사가 있는 경우 추가<?=$commandName?>되며, 병종이 다를경우는 기존의 병사는 소집해제됩니다.<br> 이미 병사가 있는 경우 추가<?= $commandName ?>되며, 병종이 다를경우는 기존의 병사는 소집해제됩니다.<br>
현재 <?=$commandName?> 가능한 병종은 <font color=green>녹색</font>으로 표시되며,<br> 현재 <?= $commandName ?> 가능한 병종은 <font color=green>녹색</font>으로 표시되며,<br>
현재 <?=$commandName?> 가능한 특수병종은 <font color=limegreen>초록색</font>으로 표시됩니다.<br> 현재 <?= $commandName ?> 가능한 특수병종은 <font color=limegreen>초록색</font>으로 표시됩니다.<br>
<table class='tb_layout' style='margin:auto;'> <table class='tb_layout' style='margin:auto;'>
<thead> <thead>
<tr><td colspan=11><div style='float:right'><input type='checkbox' id="show_unavailable_troops">불가능한 병종 표시</input></div> <tr>
<?php if($commandName=='모병'): ?> <td colspan=11>
<div style='text-align:center;'>모병은 가격 2배의 자금이 소요됩니다.</div> <div style='float:right'><input type='checkbox' id="show_unavailable_troops">불가능한 병종 표시</input></div>
<?php endif; ?> <?php if ($commandName == '모병') : ?>
</td></tr> <div style='text-align:center;'>모병은 가격 2배의 자금이 소요됩니다.</div>
<tr> <?php endif; ?>
<td colspan=11 align=center class='bg2'> </td>
현재 기술력 : <?=$techLevelText?> </tr>
현재 통솔 : <?=$leadership?><?=($leadership!=$fullLeadership)?"({$fullLeadership})":''?> <tr>
현재 병종 : <?=$crewTypeObj->name?> <td colspan=11 align=center class='bg2'>
현재 병사 : <?=$crew?> 현재 기술력 : <?= $techLevelText ?>
현재 자금 : <?=$gold?> 현재 통솔 : <?= $leadership ?><?= ($leadership != $fullLeadership) ? "({$fullLeadership})" : '' ?>
</td> 현재 병종 : <?= $crewTypeObj->name ?>
</tr> 현재 병사 : <?= $crew ?>
<tr> 현재 자금 : <?= $gold ?>
<td width=64 align=center class='bg1'>사진</td> </td>
<td width=64 align=center class='bg1'>병종</td> </tr>
<td width=40 align=center class='bg1'>공격</td> <tr>
<td width=40 align=center class='bg1'>방어</td> <td width=64 align=center class='bg1'>사진</td>
<td width=40 align=center class='bg1'>기동</td> <td width=64 align=center class='bg1'>병종</td>
<td width=40 align=center class='bg1'>회피</td> <td width=40 align=center class='bg1'>공격</td>
<td width=40 align=center class='bg1'>가격</td> <td width=40 align=center class='bg1'>방어</td>
<td width=40 align=center class='bg1'>군량</td> <td width=40 align=center class='bg1'>기동</td>
<td width=180 align=center class='bg1'>병사수</td> <td width=40 align=center class='bg1'>회피</td>
<td width=50 align=center class='bg1'>행동</td> <td width=40 align=center class='bg1'>가격</td>
<td width=300 align=center class='bg1'>특징</td> <td width=40 align=center class='bg1'>군량</td>
</tr> <td width=180 align=center class='bg1'>병사수</td>
</thead> <td width=50 align=center class='bg1'>행동</td>
<tbody> <td width=300 align=center class='bg1'>특징</td>
<?php foreach($armTypes as [$armName,$armTypeCrews]): ?> </tr>
<tr><td colspan=11><?=$armName?> 계열</td></tr> </thead>
<?php foreach($armTypeCrews as $crewObj): ?> <tbody>
<tr <?php foreach ($armTypes as [$armName, $armTypeCrews]) : ?>
id="crewType<?=$crewObj->id?>" <tr>
class="show_default_<?=$crewObj->showDefault?>" <td colspan=11><?= $armName ?> 계열</td>
style='height:64px;background-color:<?=$crewObj->bgcolor?>' </tr>
data-rice="<?=$crewObj->baseRice?>" <?php foreach ($armTypeCrews as $crewObj) : ?>
data-cost="<?=$crewObj->baseCost?>" <tr id="crewType<?= $crewObj->id ?>" class="show_default_<?= $crewObj->showDefault ?>" style='height:64px;background-color:<?= $crewObj->bgcolor ?>' data-rice="<?= $crewObj->baseRice ?>" data-cost="<?= $crewObj->baseCost ?>">
> <td style='background:#222222 no-repeat center url("<?= $crewObj->img ?>");background-size:64px'></td>
<td style='background:#222222 no-repeat center url("<?=$crewObj->img?>");background-size:64px'></td> <td style='text-align:center;vertical-align:middle;'><?= $crewObj->name ?></td>
<td style='text-align:center;vertical-align:middle;'><?=$crewObj->name?></td> <td style='text-align:center;vertical-align:middle;'><?= $crewObj->attack ?></td>
<td style='text-align:center;vertical-align:middle;'><?=$crewObj->attack?></td> <td style='text-align:center;vertical-align:middle;'><?= $crewObj->defence ?></td>
<td style='text-align:center;vertical-align:middle;'><?=$crewObj->defence?></td> <td style='text-align:center;vertical-align:middle;'><?= $crewObj->speed ?></td>
<td style='text-align:center;vertical-align:middle;'><?=$crewObj->speed?></td> <td style='text-align:center;vertical-align:middle;'><?= $crewObj->avoid ?></td>
<td style='text-align:center;vertical-align:middle;'><?=$crewObj->avoid?></td> <td style='text-align:center;vertical-align:middle;'><?= $crewObj->baseCostShort ?></td>
<td style='text-align:center;vertical-align:middle;'><?=$crewObj->baseCostShort?></td> <td style='text-align:center;vertical-align:middle;'><?= $crewObj->baseRiceShort ?></td>
<td style='text-align:center;vertical-align:middle;'><?=$crewObj->baseRiceShort?></td> <td style='text-align:center;vertical-align:middle;' class='input_form' data-crewtype='<?= $crewObj->id ?>'>
<td style='text-align:center;vertical-align:middle;' class='input_form' data-crewtype='<?=$crewObj->id?>'> <input type=button value='절반' class='btn_half'><input type=button value='채우기' class='btn_fill'><input type=button value='가득' class='btn_full'><br>
<input type=button value='절반' class='btn_half' <input type=text data-crewtype='<?= $crewObj->id ?>' class=form_double name=double maxlength=3 size=3 style=text-align:right;color:white;background-color:black>00명
><input type=button value='채우기' class='btn_fill' <input type=text class=form_cost name=cost maxlength=5 size=5 readonly style=text-align:right;color:white;background-color:black>원
><input type=button value='가득' class='btn_full'
><br> </td>
<input type=text data-crewtype='<?=$crewObj->id?>' class=form_double name=double maxlength=3 size=3 <td style='position:relative;height:64px;'><input type=submit value='<?= $commandName ?>' class='submit_btn' style='width:100%;height:44px;margin:10px 0;display:block;position: absolute;left:0;top:0;'></td>
style=text-align:right;color:white;background-color:black <td><?= $crewObj->info ?></td>
>00명 </tr>
<input type=text class=form_cost name=cost maxlength=5 size=5 readonly <?php endforeach; ?>
style=text-align:right;color:white;background-color:black>원 <?php endforeach; ?>
</tbody>
</td> </table>
<td style='position:relative;height:64px;'><input <input type='hidden' id='amount' value='1'>
type=submit value='<?=$commandName?>' class='submit_btn' <input type='hidden' id='crewType' value='<?= $crewTypeObj->id ?>'>
style='width:100%;height:44px;margin:10px 0;display:block;position: absolute;left:0;top:0;' <script>
></td> window.currentTech = <?= $tech ?>;
<td><?=$crewObj->info?></td> window.leadership = <?= $leadership ?>;
</tr> window.fullLeadership = <?= $fullLeadership ?>;
<?php endforeach; ?> window.currentCrewType = <?= $crewTypeObj->id ?>;
<?php endforeach; ?> window.currentCrew = <?= $crew ?>;
</tbody> window.currentGold = <?= $gold ?>;
</table> window.is모병 = <?= ($this->getName() == '모병') ? 'true' : 'false' ?>;
<input type='hidden' id='amount' value='1'> </script>
<input type='hidden' id='crewType' value='<?=$crewTypeObj->id?>'> <?php
<script>
window.currentTech = <?=$tech?>;
window.leadership = <?=$leadership?>;
window.fullLeadership = <?=$fullLeadership?>;
window.currentCrewType = <?=$crewTypeObj->id?>;
window.currentCrew = <?=$crew?>;
window.currentGold = <?=$gold?>;
window.is모병 = <?=($this->getName()=='모병')?'true':'false'?>;
</script>
<?php
return ob_get_clean(); return ob_get_clean();
} }
} }
+80 -63
View File
@@ -1,17 +1,21 @@
<?php <?php
namespace sammo\Command\General; namespace sammo\Command\General;
use \sammo\{ use\sammo\{
DB, Util, JosaUtil, DB,
General, Util,
JosaUtil,
General,
ActionLogger, ActionLogger,
GameConst, GameUnitConst, GameConst,
GameUnitConst,
LastTurn, LastTurn,
Command Command
}; };
use function \sammo\{ use function\sammo\{
tryUniqueItemLottery, tryUniqueItemLottery,
searchDistance, searchDistance,
printCitiesBasedOnDistance printCitiesBasedOnDistance
@@ -23,89 +27,111 @@ use sammo\CityConst;
class che_첩보 extends Command\GeneralCommand{ class che_첩보 extends Command\GeneralCommand
{
static protected $actionName = '첩보'; static protected $actionName = '첩보';
static public $reqArg = true; static public $reqArg = true;
protected function argTest():bool{ protected function argTest(): bool
if($this->arg === null){ {
if ($this->arg === null) {
return false; return false;
} }
if(!key_exists('destCityID', $this->arg)){ if (!key_exists('destCityID', $this->arg)) {
return false; return false;
} }
if(!key_exists($this->arg['destCityID'], CityConst::all())){ if (!key_exists($this->arg['destCityID'], CityConst::all())) {
return false; return false;
} }
$this->arg = [ $this->arg = [
'destCityID'=>$this->arg['destCityID'] 'destCityID' => $this->arg['destCityID']
]; ];
return true; return true;
} }
protected function init(){ protected function init()
{
$general = $this->generalObj; $general = $this->generalObj;
$this->setCity(); $this->setCity();
$this->setNation(['tech']); $this->setNation(['tech']);
$this->setDestCity($this->arg['destCityID'], null);
$this->setDestNation($this->destCity['nation'], ['tech']);
[$reqGold, $reqRice] = $this->getCost(); [$reqGold, $reqRice] = $this->getCost();
$this->runnableConstraints=[ $this->minConditionConstraints = [
ConstraintHelper::NotOccupiedDestCity(), ConstraintHelper::NotOccupiedDestCity(),
ConstraintHelper::ReqGeneralGold($reqGold), ConstraintHelper::ReqGeneralGold($reqGold),
ConstraintHelper::ReqGeneralRice($reqRice), ConstraintHelper::ReqGeneralRice($reqRice),
]; ];
} }
public function getBrief():string{ protected function initWithArg()
{
$this->setDestCity($this->arg['destCityID']);
$this->setDestNation($this->destCity['nation'], ['tech']);
[$reqGold, $reqRice] = $this->getCost();
$this->fullConditionConstraints = [
ConstraintHelper::NotOccupiedDestCity(),
ConstraintHelper::ReqGeneralGold($reqGold),
ConstraintHelper::ReqGeneralRice($reqRice),
];
}
public function getBrief(): string
{
$cityName = $this->destCity['name']; $cityName = $this->destCity['name'];
return "{$cityName}】에 {$this->getName()} 실행"; return "{$cityName}】에 {$this->getName()} 실행";
} }
public function getCommandDetailTitle():string{ public function getCommandDetailTitle(): string
{
$name = $this->getName(); $name = $this->getName();
[$reqGold, $reqRice] = $this->getCost(); [$reqGold, $reqRice] = $this->getCost();
$title = "{$name}(통솔경험"; $title = "{$name}(통솔경험";
if($reqGold > 0){ if ($reqGold > 0) {
$title .= ", 자금{$reqGold}"; $title .= ", 자금{$reqGold}";
} }
if($reqRice > 0){ if ($reqRice > 0) {
$title .= ", 군량{$reqRice}"; $title .= ", 군량{$reqRice}";
} }
$title .= ')'; $title .= ')';
return $title; return $title;
} }
public function getCost():array{ public function getCost(): array
{
$env = $this->env; $env = $this->env;
return [$env['develcost'], $env['develcost']]; return [$env['develcost'], $env['develcost']];
} }
public function getPreReqTurn():int{ public function getPreReqTurn(): int
{
return 0; return 0;
} }
public function getPostReqTurn():int{ public function getPostReqTurn(): int
{
return 0; return 0;
} }
public function getFailString():string{ public function getFailString(): string
{
$commandName = $this->getName(); $commandName = $this->getName();
$failReason = $this->testRunnable(); $failReason = $this->testFullConditionMet();
if($failReason === null){ if ($failReason === null) {
throw new \RuntimeException('실행 가능한 커맨드에 대해 실패 이유를 수집'); throw new \RuntimeException('실행 가능한 커맨드에 대해 실패 이유를 수집');
} }
$destCityName = CityConst::byID($this->arg['destCityID'])->name; $destCityName = CityConst::byID($this->arg['destCityID'])->name;
return "{$failReason} <G><b>{$destCityName}</b></>에 {$commandName} 실패."; return "{$failReason} <G><b>{$destCityName}</b></>에 {$commandName} 실패.";
} }
public function run():bool{ public function run(): bool
if(!$this->isRunnable()){ {
if (!$this->hasFullConditionMet()) {
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -124,13 +150,13 @@ class che_첩보 extends Command\GeneralCommand{
$logger = $general->getLogger(); $logger = $general->getLogger();
$dist = searchDistance($general->getCityID(), 2, false)[$destCityID]??3; $dist = searchDistance($general->getCityID(), 2, false)[$destCityID] ?? 3;
$destCityGeneralList = $db->query('SELECT crew, crewtype FROM general WHERE city = %i AND nation = %i', $destCityID, $destNationID); $destCityGeneralList = $db->query('SELECT crew, crewtype FROM general WHERE city = %i AND nation = %i', $destCityID, $destNationID);
$totalCrew = Util::arraySum($destCityGeneralList, 'crew'); $totalCrew = Util::arraySum($destCityGeneralList, 'crew');
$totalGenCnt = count($destCityGeneralList); $totalGenCnt = count($destCityGeneralList);
$byCrewType = Util::arrayGroupBy($destCityGeneralList, 'crewtype'); $byCrewType = Util::arrayGroupBy($destCityGeneralList, 'crewtype');
$popText = number_format($destCity['pop']); $popText = number_format($destCity['pop']);
$trustText = number_format($destCity['trust'], 1); $trustText = number_format($destCity['trust'], 1);
$agriText = number_format($destCity['agri']); $agriText = number_format($destCity['agri']);
@@ -143,50 +169,43 @@ class che_첩보 extends Command\GeneralCommand{
$cityDevel = "【<M>첩보</>】농업:{$agriText}, 상업:{$commText}, 치안:{$secuText}, 수비:{$defText}, 성벽:{$wallText}"; $cityDevel = "【<M>첩보</>】농업:{$agriText}, 상업:{$commText}, 치안:{$secuText}, 수비:{$defText}, 성벽:{$wallText}";
$logger->pushGeneralActionLog("누군가가 <G><b>{$destCityName}</b></>{$josaUl} 살피는 것 같습니다."); $logger->pushGeneralActionLog("누군가가 <G><b>{$destCityName}</b></>{$josaUl} 살피는 것 같습니다.");
if($dist < 1){ if ($dist < 1) {
$logger->pushGeneralActionLog("<G><b>{$destCityName}</b></>의 정보를 많이 얻었습니다. <1>$date</>"); $logger->pushGeneralActionLog("<G><b>{$destCityName}</b></>의 정보를 많이 얻었습니다. <1>$date</>");
$logger->pushGeneralActionLog($cityBrief, ActionLogger::RAWTEXT); $logger->pushGeneralActionLog($cityBrief, ActionLogger::RAWTEXT);
$logger->pushGeneralActionLog($cityDevel, ActionLogger::RAWTEXT); $logger->pushGeneralActionLog($cityDevel, ActionLogger::RAWTEXT);
$logger->pushGeneralActionLog('【<S>병종</>】 '. join(' ', Util::mapWithKey(function($crewType, $value){ $logger->pushGeneralActionLog('【<S>병종</>】 ' . join(' ', Util::mapWithKey(function ($crewType, $value) {
$crewTypeText = mb_substr(GameUnitConst::byID($crewType)->name, 0, 2); $crewTypeText = mb_substr(GameUnitConst::byID($crewType)->name, 0, 2);
$cnt = count($value); $cnt = count($value);
return "{$crewTypeText}:{$cnt}"; return "{$crewTypeText}:{$cnt}";
}, $destCityGeneralList)), ActionLogger::RAWTEXT); }, $destCityGeneralList)), ActionLogger::RAWTEXT);
if($this->destNation['nation'] && $general->getNationID()){ if ($this->destNation['nation'] && $general->getNationID()) {
$techDiff = floor($this->destNation['tech']) - floor($this->nation['tech']); $techDiff = floor($this->destNation['tech']) - floor($this->nation['tech']);
if($techDiff >= 1000){ if ($techDiff >= 1000) {
$techText = '<M>↑</>압도'; $techText = '<M>↑</>압도';
} } else if ($techDiff >= 250) {
else if($techDiff >= 250){
$techText = '<Y>▲</>우위'; $techText = '<Y>▲</>우위';
} } else if ($techDiff >= -250) {
else if($techDiff >= -250){
$techText = '<W>↕</>대등'; $techText = '<W>↕</>대등';
} } else if ($techDiff >= -1000) {
else if($techDiff >= -1000){
$techText = '<G>▼</>열위'; $techText = '<G>▼</>열위';
} } else {
else{
$techText = '<C>↓</>미미'; $techText = '<C>↓</>미미';
} }
$logger->pushGeneralActionLog("【<span class='ev_notice'>{$this->destNation['name']}</span>】아국대비기술:{$techText}"); $logger->pushGeneralActionLog("【<span class='ev_notice'>{$this->destNation['name']}</span>】아국대비기술:{$techText}");
} }
} else if ($dist == 2) {
}
else if($dist == 2){
$logger->pushGeneralActionLog("<G><b>{$destCityName}</b></>의 정보를 어느 정도 얻었습니다. <1>$date</>"); $logger->pushGeneralActionLog("<G><b>{$destCityName}</b></>의 정보를 어느 정도 얻었습니다. <1>$date</>");
$logger->pushGeneralActionLog($cityBrief, ActionLogger::RAWTEXT); $logger->pushGeneralActionLog($cityBrief, ActionLogger::RAWTEXT);
$logger->pushGeneralActionLog($cityDevel, ActionLogger::RAWTEXT); $logger->pushGeneralActionLog($cityDevel, ActionLogger::RAWTEXT);
} } else {
else{
$logger->pushGeneralActionLog("<G><b>{$destCityName}</b></>의 소문만 들을 수 있었습니다. <1>$date</>"); $logger->pushGeneralActionLog("<G><b>{$destCityName}</b></>의 소문만 들을 수 있었습니다. <1>$date</>");
$logger->pushGeneralActionLog($cityBrief, ActionLogger::RAWTEXT); $logger->pushGeneralActionLog($cityBrief, ActionLogger::RAWTEXT);
} }
$exp = Util::randRangeInt(1, 100); $exp = Util::randRangeInt(1, 100);
$ded = Util::randRangeInt(1, 70); $ded = Util::randRangeInt(1, 70);
[$reqGold, $reqRice] = $this->getCost(); [$reqGold, $reqRice] = $this->getCost();
$general->increaseVarWithLimit('gold', -$reqGold, 0); $general->increaseVarWithLimit('gold', -$reqGold, 0);
$general->increaseVarWithLimit('rice', -$reqRice, 0); $general->increaseVarWithLimit('rice', -$reqRice, 0);
@@ -212,19 +231,17 @@ class che_첩보 extends Command\GeneralCommand{
$currentCityID = $this->generalObj->getCityID(); $currentCityID = $this->generalObj->getCityID();
ob_start(); ob_start();
?> ?>
<?=\sammo\getMapHtml()?><br> <?= \sammo\getMapHtml() ?><br>
선택된 도시에 첩보를 실행합니다.<br> 선택된 도시에 첩보를 실행합니다.<br>
인접도시일 경우 많은 정보를 얻을 수 있습니다.<br> 인접도시일 경우 많은 정보를 얻을 수 있습니다.<br>
목록을 선택하거나 도시를 클릭하세요.<br> 목록을 선택하거나 도시를 클릭하세요.<br>
<select class='formInput' name="destCityID" id="destCityID" size='1' style='color:white;background-color:black;'><br> <select class='formInput' name="destCityID" id="destCityID" size='1' style='color:white;background-color:black;'><br>
<?=\sammo\optionsForCities()?><br> <?= \sammo\optionsForCities() ?><br>
</select> <input type=button id="commonSubmit" value="<?=$this->getName()?>"><br> </select> <input type=button id="commonSubmit" value="<?= $this->getName() ?>"><br>
<br> <br>
<br> <br>
<?=printCitiesBasedOnDistance($currentCityID, 3)?> <?= printCitiesBasedOnDistance($currentCityID, 3) ?>
<?php <?php
return ob_get_clean(); return ob_get_clean();
} }
}
}
+91 -63
View File
@@ -1,17 +1,21 @@
<?php <?php
namespace sammo\Command\General; namespace sammo\Command\General;
use \sammo\{ use\sammo\{
DB, Util, JosaUtil, DB,
General, Util,
JosaUtil,
General,
ActionLogger, ActionLogger,
GameConst, GameUnitConst, GameConst,
GameUnitConst,
LastTurn, LastTurn,
Command Command
}; };
use function \sammo\{ use function\sammo\{
tryUniqueItemLottery, tryUniqueItemLottery,
processWar processWar
}; };
@@ -22,38 +26,58 @@ use sammo\CityConst;
class che_출병 extends Command\GeneralCommand{ class che_출병 extends Command\GeneralCommand
{
static protected $actionName = '출병'; static protected $actionName = '출병';
static public $reqArg = true; static public $reqArg = true;
protected function argTest():bool{ protected function argTest(): bool
if($this->arg === null){ {
if ($this->arg === null) {
return false; return false;
} }
if(!key_exists('destCityID', $this->arg)){ if (!key_exists('destCityID', $this->arg)) {
return false; return false;
} }
if(!key_exists($this->arg['destCityID'], CityConst::all())){ if (!key_exists($this->arg['destCityID'], CityConst::all())) {
return false; return false;
} }
$this->arg = [ $this->arg = [
'destCityID'=>$this->arg['destCityID'] 'destCityID' => $this->arg['destCityID']
]; ];
return true; return true;
} }
protected function init(){ protected function init()
{
$general = $this->generalObj; $general = $this->generalObj;
$this->setCity(); $this->setCity();
$this->setNation(['war', 'gennum', 'tech', 'gold', 'rice', 'color', 'type', 'level', 'capital']); $this->setNation(['war', 'gennum', 'tech', 'gold', 'rice', 'color', 'type', 'level', 'capital']);
$this->setDestCity($this->arg['destCityID'], null);
[$reqGold, $reqRice] = $this->getCost(); [$reqGold, $reqRice] = $this->getCost();
$relYear = $this->env['year'] - $this->env['startyear']; $relYear = $this->env['year'] - $this->env['startyear'];
$this->minConditionConstraints = [
ConstraintHelper::NotOpeningPart($relYear+1),
ConstraintHelper::NotBeNeutral(),
ConstraintHelper::OccupiedCity(),
ConstraintHelper::ReqGeneralCrew(),
ConstraintHelper::ReqGeneralRice($reqRice),
];
$this->runnableConstraints=[ }
protected function initWithArg()
{
$this->setDestCity($this->arg['destCityID']);
[$reqGold, $reqRice] = $this->getCost();
$relYear = $this->env['year'] - $this->env['startyear'];
$this->fullConditionConstraints = [
ConstraintHelper::NotOpeningPart($relYear), ConstraintHelper::NotOpeningPart($relYear),
ConstraintHelper::NotSameDestCity(), ConstraintHelper::NotSameDestCity(),
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
@@ -65,36 +89,42 @@ class che_출병 extends Command\GeneralCommand{
]; ];
} }
public function getCommandDetailTitle():string{ public function getCommandDetailTitle(): string
{
$name = $this->getName(); $name = $this->getName();
//[$reqGold, $reqRice] = $this->getCost(); //[$reqGold, $reqRice] = $this->getCost();
return "{$name}(통솔경험, 병종숙련, 군량↓)"; return "{$name}(통솔경험, 병종숙련, 군량↓)";
} }
public function getCost():array{ public function getCost(): array
return [0, Util::round($this->generalObj->getVar('crew')/100)]; {
return [0, Util::round($this->generalObj->getVar('crew') / 100)];
} }
public function getPreReqTurn():int{ public function getPreReqTurn(): int
{
return 0; return 0;
} }
public function getPostReqTurn():int{ public function getPostReqTurn(): int
{
return 0; return 0;
} }
public function getBrief():string{ public function getBrief(): string
{
$commandName = $this->getName(); $commandName = $this->getName();
$destCityName = CityConst::byID($this->arg['destCityID'])->name; $destCityName = CityConst::byID($this->arg['destCityID'])->name;
$josaRo = JosaUtil::pick($destCityName, '로'); $josaRo = JosaUtil::pick($destCityName, '로');
return "{$destCityName}{$josaRo} {$commandName}"; return "{$destCityName}{$josaRo} {$commandName}";
} }
public function getFailString():string{ public function getFailString(): string
{
$commandName = $this->getName(); $commandName = $this->getName();
$failReason = $this->testRunnable(); $failReason = $this->testFullConditionMet();
if($failReason === null){ if ($failReason === null) {
throw new \RuntimeException('실행 가능한 커맨드에 대해 실패 이유를 수집'); throw new \RuntimeException('실행 가능한 커맨드에 대해 실패 이유를 수집');
} }
$destCityName = CityConst::byID($this->arg['destCityID'])->name; $destCityName = CityConst::byID($this->arg['destCityID'])->name;
@@ -102,8 +132,9 @@ class che_출병 extends Command\GeneralCommand{
return "{$failReason} <G><b>{$destCityName}</b></>{$josaRo} {$commandName} 실패."; return "{$failReason} <G><b>{$destCityName}</b></>{$josaRo} {$commandName} 실패.";
} }
public function run():bool{ public function run(): bool
if(!$this->isRunnable()){ {
if (!$this->hasFullConditionMet()) {
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -117,10 +148,10 @@ class che_출병 extends Command\GeneralCommand{
$attackerCityID = $general->getCityID(); $attackerCityID = $general->getCityID();
$finalTargetCityID = $this->destCity['city']; $finalTargetCityID = $this->destCity['city'];
$finalTargetCityName = $this->destCity['name']; $finalTargetCityName = $this->destCity['name'];
$logger = $general->getLogger(); $logger = $general->getLogger();
@@ -136,62 +167,61 @@ class che_출병 extends Command\GeneralCommand{
do { do {
//1: 최단 거리 도시 중 공격 대상이 있는가 확인 //1: 최단 거리 도시 중 공격 대상이 있는가 확인
//2: 최단 거리 + 1 도시 중 공격 대상이 있는가 확인 //2: 최단 거리 + 1 도시 중 공격 대상이 있는가 확인
foreach($distanceList as $dist => $distCitiesInfo){ foreach ($distanceList as $dist => $distCitiesInfo) {
if($dist > $minDist + 1){ if ($dist > $minDist + 1) {
break; break;
} }
$currDist = $dist; $currDist = $dist;
foreach($distCitiesInfo as [$distCityID, $distCityNation]){ foreach ($distCitiesInfo as [$distCityID, $distCityNation]) {
if($distCityNation !== $attackerNationID){ if ($distCityNation !== $attackerNationID) {
$candidateCities[] = $distCityID; $candidateCities[] = $distCityID;
} }
} }
if($candidateCities){ if ($candidateCities) {
break 2; break 2;
} }
} }
//3: 최단 거리 도시 중 아군 도시 선택 //3: 최단 거리 도시 중 아군 도시 선택
foreach($distanceList[$minDist] as [$distCityID, $distCityNation]){ foreach ($distanceList[$minDist] as [$distCityID, $distCityNation]) {
if($distCityNation === $attackerNationID){ if ($distCityNation === $attackerNationID) {
$candidateCities[] = $distCityID; $candidateCities[] = $distCityID;
} }
} }
}while(false); } while (false);
$defenderCityID = (int)Util::choiceRandom($candidateCities); $defenderCityID = (int) Util::choiceRandom($candidateCities);
$defenderCityName = $this->destCity['name']; $defenderCityName = $this->destCity['name'];
$this->setDestCity($defenderCityID, null); $this->setDestCity($defenderCityID);
$josaRo = JosaUtil::pick($defenderCityName, '로'); $josaRo = JosaUtil::pick($defenderCityName, '로');
if($attackerNationID == $defenderNationID){ if ($attackerNationID == $defenderNationID) {
$logger->pushGeneralActionLog("본국입니다. <G><b>{$defenderCityName}</b></>{$josaRo} 으로 이동합니다. <1>$date</>"); $logger->pushGeneralActionLog("본국입니다. <G><b>{$defenderCityName}</b></>{$josaRo} 으로 이동합니다. <1>$date</>");
$this->alternative = new che_이동($general, $this->env, ['destCityID'=>$defenderCityID]); $this->alternative = new che_이동($general, $this->env, ['destCityID' => $defenderCityID]);
return false; return false;
} }
if($finalTargetCityID !== $defenderCityID){ if ($finalTargetCityID !== $defenderCityID) {
$josaRo = JosaUtil::pick($finalTargetCityName, '로'); $josaRo = JosaUtil::pick($finalTargetCityName, '로');
$josaUl = JosaUtil::pick($defenderCityName, '을'); $josaUl = JosaUtil::pick($defenderCityName, '을');
if($minDist == $currDist){ if ($minDist == $currDist) {
$logger->pushGeneralActionLog("<G><b>{$finalTargetCityName}</b></>{$josaRo} 가기 위해 <G><b>{$defenderCityName}</b></>{$josaUl} 거쳐야 합니다. <1>$date</>"); $logger->pushGeneralActionLog("<G><b>{$finalTargetCityName}</b></>{$josaRo} 가기 위해 <G><b>{$defenderCityName}</b></>{$josaUl} 거쳐야 합니다. <1>$date</>");
} } else {
else{
$logger->pushGeneralActionLog("<G><b>{$finalTargetCityName}</b></>{$josaRo} 가는 도중 <G><b>{$defenderCityName}</b></>{$josaUl} 거치기로 합니다. <1>$date</>"); $logger->pushGeneralActionLog("<G><b>{$finalTargetCityName}</b></>{$josaRo} 가는 도중 <G><b>{$defenderCityName}</b></>{$josaUl} 거치기로 합니다. <1>$date</>");
} }
} }
$db->update('city', [ $db->update('city', [
'state'=>43, 'state' => 43,
'term'=>3 'term' => 3
], 'city=%i', $defenderCityID); ], 'city=%i', $defenderCityID);
$this->destCity['state'] = 43; $this->destCity['state'] = 43;
$this->destCity['term'] = 3; $this->destCity['term'] = 3;
$general->addDex($general->getCrewTypeObj(), $general->getVar('crew')/100); $general->addDex($general->getCrewTypeObj(), $general->getVar('crew') / 100);
$general->setResultTurn(new LastTurn(static::getName(), $this->arg)); $general->setResultTurn(new LastTurn(static::getName(), $this->arg));
$general->applyDB($db); $general->applyDB($db);
@@ -200,7 +230,7 @@ class che_출병 extends Command\GeneralCommand{
tryUniqueItemLottery($general); tryUniqueItemLottery($general);
$general->applyDB($db); $general->applyDB($db);
return true; return true;
} }
@@ -216,17 +246,15 @@ class che_출병 extends Command\GeneralCommand{
$srcCityName = \sammo\CityConst::byID($this->generalObj->getCityID())->name; $srcCityName = \sammo\CityConst::byID($this->generalObj->getCityID())->name;
ob_start(); ob_start();
?> ?>
<?=\sammo\getMapHtml()?><br> <?= \sammo\getMapHtml() ?><br>
선택된 도시를 향해 침공을 합니다.<br> 선택된 도시를 향해 침공을 합니다.<br>
침공 경로에 적군의 도시가 있다면 전투를 벌입니다.<br> 침공 경로에 적군의 도시가 있다면 전투를 벌입니다.<br>
목록을 선택하거나 도시를 클릭하세요.<br> 목록을 선택하거나 도시를 클릭하세요.<br>
<?=$srcCityName?> =><select class='formInput' name="destCityID" id="destCityID" size='1' style='color:white;background-color:black;'> <?= $srcCityName ?> =><select class='formInput' name="destCityID" id="destCityID" size='1' style='color:white;background-color:black;'>
<?=\sammo\optionsForCities()?><br> <?= \sammo\optionsForCities() ?><br>
</select> <input type=button id="commonSubmit" value="<?=$this->getName()?>"><br> </select> <input type=button id="commonSubmit" value="<?= $this->getName() ?>"><br>
<br> <br>
<?php <?php
return ob_get_clean(); return ob_get_clean();
} }
}
}
+2 -2
View File
@@ -38,7 +38,7 @@ class che_하야 extends Command\GeneralCommand{
$relYear = $env['year'] - $env['startyear']; $relYear = $env['year'] - $env['startyear'];
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
ConstraintHelper::NotOpeningPart($relYear), ConstraintHelper::NotOpeningPart($relYear),
ConstraintHelper::NotLord(), ConstraintHelper::NotLord(),
@@ -58,7 +58,7 @@ class che_하야 extends Command\GeneralCommand{
} }
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
+2 -2
View File
@@ -40,7 +40,7 @@ class che_해산 extends Command\GeneralCommand{
$this->setCity(); $this->setCity();
$this->setNation(['gennum']); $this->setNation(['gennum']);
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::BeLord(), ConstraintHelper::BeLord(),
ConstraintHelper::WanderingNation(), ConstraintHelper::WanderingNation(),
]; ];
@@ -59,7 +59,7 @@ class che_해산 extends Command\GeneralCommand{
} }
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
+65 -47
View File
@@ -1,9 +1,12 @@
<?php <?php
namespace sammo\Command\General; namespace sammo\Command\General;
use \sammo\{ use\sammo\{
DB, Util, JosaUtil, DB,
General, Util,
JosaUtil,
General,
ActionLogger, ActionLogger,
GameConst, GameConst,
LastTurn, LastTurn,
@@ -11,9 +14,9 @@ use \sammo\{
Command Command
}; };
use function \sammo\{ use function\sammo\{
getDomesticExpLevelBonus, getDomesticExpLevelBonus,
CriticalRatioDomestic, CriticalRatioDomestic,
CriticalScoreEx, CriticalScoreEx,
tryUniqueItemLottery tryUniqueItemLottery
}; };
@@ -22,84 +25,99 @@ use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
class che_헌납 extends Command\GeneralCommand{ class che_헌납 extends Command\GeneralCommand
{
static protected $actionName = '헌납'; static protected $actionName = '헌납';
static public $reqArg = true; static public $reqArg = true;
protected function argTest():bool{ protected function argTest(): bool
if($this->arg === null){ {
if ($this->arg === null) {
return false; return false;
} }
if(!key_exists('isGold', $this->arg)){ if (!key_exists('isGold', $this->arg)) {
return false; return false;
} }
if(!key_exists('amount', $this->arg)){ if (!key_exists('amount', $this->arg)) {
return false; return false;
} }
$isGold = $this->arg['isGold']; $isGold = $this->arg['isGold'];
$amount = $this->arg['amount']; $amount = $this->arg['amount'];
if(!is_numeric($amount)){ if (!is_numeric($amount)) {
return false; return false;
} }
$amount = Util::round($amount, -2); $amount = Util::round($amount, -2);
$amount = Util::valueFit($amount, 100, GameConst::$maxResourceActionAmount); $amount = Util::valueFit($amount, 100, GameConst::$maxResourceActionAmount);
if(!is_bool($isGold)){ if (!is_bool($isGold)) {
return false; return false;
} }
$this->arg = [ $this->arg = [
'isGold'=>$isGold, 'isGold' => $isGold,
'amount'=>$amount 'amount' => $amount
]; ];
return true; return true;
} }
protected function init(){ protected function init()
{
$general = $this->generalObj; $general = $this->generalObj;
$this->setCity(); $this->setCity();
$this->setNation(); $this->setNation();
$this->runnableConstraints=[ $this->minConditionConstraints = [
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
ConstraintHelper::SuppliedCity(), ConstraintHelper::SuppliedCity(),
]; ];
if($this->arg['isGold']){ }
$this->runnableConstraints[] = ConstraintHelper::ReqGeneralGold(GameConst::$generalMinimumGold);
}
else{
$this->runnableConstraints[] = ConstraintHelper::ReqGeneralRice(GameConst::$generalMinimumRice);
}
protected function initWithArg()
{
$this->fullConditionConstraints = [
ConstraintHelper::NotBeNeutral(),
ConstraintHelper::OccupiedCity(),
ConstraintHelper::SuppliedCity(),
];
if ($this->arg['isGold']) {
$this->fullConditionConstraints[] = ConstraintHelper::ReqGeneralGold(GameConst::$generalMinimumGold);
} else {
$this->fullConditionConstraints[] = ConstraintHelper::ReqGeneralRice(GameConst::$generalMinimumRice);
}
} }
public function getBrief(): string public function getBrief(): string
{ {
$resText = $this->arg['isGold']?'금':'쌀'; $resText = $this->arg['isGold'] ? '금' : '쌀';
$name = $this->getName(); $name = $this->getName();
return "{$resText} {$this->arg['amount']}{$name}"; return "{$resText} {$this->arg['amount']}{$name}";
} }
public function getCommandDetailTitle():string{ public function getCommandDetailTitle(): string
{
$name = $this->getName(); $name = $this->getName();
return "{$name}(통솔경험)"; return "{$name}(통솔경험)";
} }
public function getCost():array{ public function getCost(): array
{
return [0, 0]; return [0, 0];
} }
public function getPreReqTurn():int{ public function getPreReqTurn(): int
{
return 0; return 0;
} }
public function getPostReqTurn():int{ public function getPostReqTurn(): int
{
return 0; return 0;
} }
public function run():bool{ public function run(): bool
if(!$this->isRunnable()){ {
if (!$this->hasFullConditionMet()) {
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -110,16 +128,16 @@ class che_헌납 extends Command\GeneralCommand{
$isGold = $this->arg['isGold']; $isGold = $this->arg['isGold'];
$amount = $this->arg['amount']; $amount = $this->arg['amount'];
$resKey = $isGold?'gold':'rice'; $resKey = $isGold ? 'gold' : 'rice';
$resName = $isGold?'금':'쌀'; $resName = $isGold ? '금' : '쌀';
$amount = Util::valueFit($amount, 0, $general->getVar($resKey)); $amount = Util::valueFit($amount, 0, $general->getVar($resKey));
$amountText = number_format($amount, 0); $amountText = number_format($amount, 0);
$logger = $general->getLogger(); $logger = $general->getLogger();
$db->update('nation', [ $db->update('nation', [
$resKey=>$db->sqleval('%b + %i', $resKey, $amount) $resKey => $db->sqleval('%b + %i', $resKey, $amount)
], 'nation=%i', $general->getNationID()); ], 'nation=%i', $general->getNationID());
$general->increaseVarWithLimit($resKey, -$amount, 0); $general->increaseVarWithLimit($resKey, -$amount, 0);
@@ -144,17 +162,17 @@ class che_헌납 extends Command\GeneralCommand{
{ {
ob_start(); ob_start();
?> ?>
자신의 자금이나 군량을 국가 재산으로 헌납합니다.<br> 자신의 자금이나 군량을 국가 재산으로 헌납합니다.<br>
<select id='isGold' name="isGold" size=1 style=color:white;background-color:black> <select id='isGold' name="isGold" size=1 style=color:white;background-color:black>
<option value='true'>금</option> <option value='true'>금</option>
<option value='false'>쌀</option> <option value='false'>쌀</option>
</select> </select>
<select name=amount id='amount' size=1 style=text-align:right;color:white;background-color:black> <select name=amount id='amount' size=1 style=text-align:right;color:white;background-color:black>
<?php foreach(GameConst::$resourceActionAmountGuide as $amount): ?> <?php foreach (GameConst::$resourceActionAmountGuide as $amount) : ?>
<option value='<?=$amount?>'><?=$amount?></option> <option value='<?= $amount ?>'><?= $amount ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> <input type=button id="commonSubmit" value="<?=$this->getName()?>"><br> </select> <input type=button id="commonSubmit" value="<?= $this->getName() ?>"><br>
<?php <?php
return ob_get_clean(); return ob_get_clean();
} }
} }
+101 -76
View File
@@ -1,17 +1,21 @@
<?php <?php
namespace sammo\Command\General; namespace sammo\Command\General;
use \sammo\{ use\sammo\{
DB, Util, JosaUtil, DB,
General, Util,
JosaUtil,
General,
ActionLogger, ActionLogger,
GameConst, GameUnitConst, GameConst,
GameUnitConst,
LastTurn, LastTurn,
Command Command
}; };
use function \sammo\{ use function\sammo\{
searchDistance, searchDistance,
printCitiesBasedOnDistance printCitiesBasedOnDistance
}; };
@@ -22,44 +26,44 @@ use sammo\CityConst;
class che_화계 extends Command\GeneralCommand{ class che_화계 extends Command\GeneralCommand
{
static protected $actionName = '화계'; static protected $actionName = '화계';
static public $reqArg = true; static public $reqArg = true;
static protected $statType = 'intel'; static protected $statType = 'intel';
static protected $injuryGeneral = true; static protected $injuryGeneral = true;
protected function argTest():bool{ protected function argTest(): bool
if($this->arg === null){ {
if ($this->arg === null) {
return false; return false;
} }
if(!key_exists('destCityID', $this->arg)){ if (!key_exists('destCityID', $this->arg)) {
return false; return false;
} }
if(!key_exists($this->arg['destCityID'], CityConst::all())){ if (!key_exists($this->arg['destCityID'], CityConst::all())) {
return false; return false;
} }
$this->arg = [ $this->arg = [
'destCityID'=>$this->arg['destCityID'] 'destCityID' => $this->arg['destCityID']
]; ];
return true; return true;
} }
protected function calcSabotageAttackProb():float{ protected function calcSabotageAttackProb(): float
{
$statType = static::$statType; $statType = static::$statType;
$general = $this->generalObj; $general = $this->generalObj;
$nation = $this->nation; $nation = $this->nation;
if($statType === 'leadership'){ if ($statType === 'leadership') {
$genScore = $general->getLeadership(); $genScore = $general->getLeadership();
} } else if ($statType === 'strength') {
else if($statType === 'strength'){
$genScore = $general->getStrength(); $genScore = $general->getStrength();
} } else if ($statType === 'intel') {
else if($statType === 'intel'){
$genScore = $general->getIntel(); $genScore = $general->getIntel();
} } else {
else{
throw new \sammo\MustNotBeReachedException(); throw new \sammo\MustNotBeReachedException();
} }
@@ -68,29 +72,27 @@ class che_화계 extends Command\GeneralCommand{
return $prob; return $prob;
} }
protected function calcSabotageDefenceProb(array $destCityGeneralList):float{ protected function calcSabotageDefenceProb(array $destCityGeneralList): float
{
$statType = static::$statType; $statType = static::$statType;
$destCity = $this->destCity; $destCity = $this->destCity;
$destNation = $this->destNation; $destNation = $this->destNation;
$destNationID = $destNation['nation']; $destNationID = $destNation['nation'];
$maxGenScore = 0; $maxGenScore = 0;
foreach($destCityGeneralList as $destGeneral){ foreach ($destCityGeneralList as $destGeneral) {
/** @var General $destGeneral */ /** @var General $destGeneral */
if($destGeneral->getNationID() != $destNationID){ if ($destGeneral->getNationID() != $destNationID) {
continue; continue;
} }
if($statType === 'leadership'){ if ($statType === 'leadership') {
$genScore = $destGeneral->getLeadership(); $genScore = $destGeneral->getLeadership();
} } else if ($statType === 'strength') {
else if($statType === 'strength'){
$genScore = $destGeneral->getStrength(); $genScore = $destGeneral->getStrength();
} } else if ($statType === 'intel') {
else if($statType === 'intel'){
$genScore = $destGeneral->getIntel(); $genScore = $destGeneral->getIntel();
} } else {
else{
throw new \sammo\MustNotBeReachedException(); throw new \sammo\MustNotBeReachedException();
} }
$maxGenScore = max($maxGenScore, $genScore); $maxGenScore = max($maxGenScore, $genScore);
@@ -103,17 +105,35 @@ class che_화계 extends Command\GeneralCommand{
return $prob; return $prob;
} }
protected function init(){ protected function init()
{
$general = $this->generalObj; $general = $this->generalObj;
$this->setCity(); $this->setCity();
$this->setDestCity($this->arg['destCityID'], null); //xxx: 이대로라면 메인 페이지 갱신시마다 DB query를 하게 된다.
[$reqGold, $reqRice] = $this->getCost();
$this->minConditionConstraints = [
ConstraintHelper::NotBeNeutral(),
ConstraintHelper::OccupiedCity(),
ConstraintHelper::SuppliedCity(),
ConstraintHelper::ReqGeneralGold($reqGold),
ConstraintHelper::ReqGeneralRice($reqRice),
];
}
protected function initWithArg()
{
$this->setDestCity($this->arg['destCityID']);
$this->setDestNation($this->destCity['nation']); $this->setDestNation($this->destCity['nation']);
[$reqGold, $reqRice] = $this->getCost(); [$reqGold, $reqRice] = $this->getCost();
$this->runnableConstraints=[ $this->fullConditionConstraints = [
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
ConstraintHelper::SuppliedCity(), ConstraintHelper::SuppliedCity(),
@@ -128,58 +148,65 @@ class che_화계 extends Command\GeneralCommand{
]; ];
} }
public function getCommandDetailTitle():string{ public function getCommandDetailTitle(): string
{
$name = $this->getName(); $name = $this->getName();
$statTypeBase = [ $statTypeBase = [
'leadership'=>'통솔경험', 'leadership' => '통솔경험',
'strength'=>'무력경험', 'strength' => '무력경험',
'intel'=>'지력경험', 'intel' => '지력경험',
]; ];
$statType = $statTypeBase[static::$statType]; $statType = $statTypeBase[static::$statType];
[$reqGold, $reqRice] = $this->getCost(); [$reqGold, $reqRice] = $this->getCost();
$title = "{$name}({$statType}"; $title = "{$name}({$statType}";
if($reqGold > 0){ if ($reqGold > 0) {
$title .= ", 자금{$reqGold}"; $title .= ", 자금{$reqGold}";
} }
if($reqRice > 0){ if ($reqRice > 0) {
$title .= ", 군량{$reqRice}"; $title .= ", 군량{$reqRice}";
} }
$title .= ')'; $title .= ')';
return $title; return $title;
} }
public function getCost():array{ public function getCost(): array
{
$env = $this->env; $env = $this->env;
$cost = $env['develcost'] * 5; $cost = $env['develcost'] * 5;
return [$cost, $cost]; return [$cost, $cost];
} }
public function getPreReqTurn():int{ public function getPreReqTurn(): int
{
return 0; return 0;
} }
public function getPostReqTurn():int{ public function getPostReqTurn(): int
{
return 0; return 0;
} }
public function getBrief():string{ public function getBrief(): string
{
$commandName = $this->getName(); $commandName = $this->getName();
$destCityName = CityConst::byID($this->arg['destCityID'])->name; $destCityName = CityConst::byID($this->arg['destCityID'])->name;
return "{$destCityName}】에 {$commandName}실행"; return "{$destCityName}】에 {$commandName}실행";
} }
public function getFailString():string{ public function getFailString(): string
{
$commandName = $this->getName(); $commandName = $this->getName();
$failReason = $this->testRunnable(); $failReason = $this->testFullConditionMet();
if($failReason === null){ if ($failReason === null) {
throw new \RuntimeException('실행 가능한 커맨드에 대해 실패 이유를 수집'); throw new \RuntimeException('실행 가능한 커맨드에 대해 실패 이유를 수집');
} }
$destCityName = CityConst::byID($this->arg['destCityID'])->name; $destCityName = CityConst::byID($this->arg['destCityID'])->name;
return "{$failReason} <G><b>{$destCityName}</b></>에 {$commandName} 실패."; return "{$failReason} <G><b>{$destCityName}</b></>에 {$commandName} 실패.";
} }
protected function affectDestCity(int $injuryCount){ protected function affectDestCity(int $injuryCount)
{
$general = $this->generalObj; $general = $this->generalObj;
$date = $general->getTurnTime($general::TURNTIME_HM); $date = $general->getTurnTime($general::TURNTIME_HM);
@@ -198,9 +225,9 @@ class che_화계 extends Command\GeneralCommand{
$destCity['comm'] -= $commAmount; $destCity['comm'] -= $commAmount;
DB::db()->update('city', [ DB::db()->update('city', [
'state'=>32, 'state' => 32,
'agri'=>$destCity['agri'], 'agri' => $destCity['agri'],
'comm'=>$destCity['comm'] 'comm' => $destCity['comm']
], 'city=%i', $destCityID); ], 'city=%i', $destCityID);
$agriAmountText = number_format($agriAmount); $agriAmountText = number_format($agriAmount);
@@ -217,8 +244,9 @@ class che_화계 extends Command\GeneralCommand{
); );
} }
public function run():bool{ public function run(): bool
if(!$this->isRunnable()){ {
if (!$this->hasFullConditionMet()) {
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -239,13 +267,13 @@ class che_화계 extends Command\GeneralCommand{
$logger = $general->getLogger(); $logger = $general->getLogger();
$dist = searchDistance($general->getCityID(), 5, false)[$destCityID]??99; $dist = searchDistance($general->getCityID(), 5, false)[$destCityID] ?? 99;
$destCityGeneralList = []; $destCityGeneralList = [];
$cityGeneralID = $db->queryFirstColumn('SELECT no FROM general WHERE city = %i AND nation = %i', $destCityID, $destNationID); $cityGeneralID = $db->queryFirstColumn('SELECT no FROM general WHERE city = %i AND nation = %i', $destCityID, $destNationID);
$destCityGeneralList = General::createGeneralObjListFromDB($cityGeneralID, ['name', 'city', 'nation', 'officer_level', 'leadership', 'horse', 'strength', 'weapon', 'intel', 'book', 'item', 'last_turn', 'injury', 'special', 'special2', 'injury', 'crew', 'atmos', 'train'], 2); $destCityGeneralList = General::createGeneralObjListFromDB($cityGeneralID, ['name', 'city', 'nation', 'officer_level', 'leadership', 'horse', 'strength', 'weapon', 'intel', 'book', 'item', 'last_turn', 'injury', 'special', 'special2', 'injury', 'crew', 'atmos', 'train'], 2);
foreach($destCityGeneralList as &$destCityGeneral){ foreach ($destCityGeneralList as &$destCityGeneral) {
$destCityGeneral->setRawCity($this->destCity); $destCityGeneral->setRawCity($this->destCity);
unset($destCityGeneral); unset($destCityGeneral);
} }
@@ -255,7 +283,7 @@ class che_화계 extends Command\GeneralCommand{
$prob = GameConst::$sabotageDefaultProb + $this->calcSabotageAttackProb() - $this->calcSabotageDefenceProb($destCityGeneralList); $prob = GameConst::$sabotageDefaultProb + $this->calcSabotageAttackProb() - $this->calcSabotageDefenceProb($destCityGeneralList);
$prob /= $dist; $prob /= $dist;
if(!Util::randBool($prob)){ if (!Util::randBool($prob)) {
$josaYi = JosaUtil::pick($commandName, '이'); $josaYi = JosaUtil::pick($commandName, '이');
$logger->pushGeneralActionLog("<G><b>{$destCityName}</b></>에 {$commandName}{$josaYi} 실패했습니다. <1>$date</>"); $logger->pushGeneralActionLog("<G><b>{$destCityName}</b></>에 {$commandName}{$josaYi} 실패했습니다. <1>$date</>");
@@ -267,7 +295,7 @@ class che_화계 extends Command\GeneralCommand{
$general->increaseVarWithLimit('rice', -$reqRice, 0); $general->increaseVarWithLimit('rice', -$reqRice, 0);
$general->addExperience($exp); $general->addExperience($exp);
$general->addDedication($ded); $general->addDedication($ded);
$general->increaseVar($statType.'_exp', 1); $general->increaseVar($statType . '_exp', 1);
$general->setResultTurn(new LastTurn(static::getName(), $this->arg)); $general->setResultTurn(new LastTurn(static::getName(), $this->arg));
$general->checkStatChange(); $general->checkStatChange();
@@ -275,17 +303,16 @@ class che_화계 extends Command\GeneralCommand{
return false; return false;
} }
if(static::$injuryGeneral){ if (static::$injuryGeneral) {
$injuryCount = \sammo\SabotageInjury($destCityGeneralList, '계략'); $injuryCount = \sammo\SabotageInjury($destCityGeneralList, '계략');
} } else {
else{
$injuryCount = 0; $injuryCount = 0;
} }
$this->affectDestCity($injuryCount); $this->affectDestCity($injuryCount);
$itemObj = $general->getItem(); $itemObj = $general->getItem();
if($itemObj->isConsumableNow('GeneralCommand', '계략') && $itemObj->isConsumableNow('GeneralCommand', '계략')){ if ($itemObj->isConsumableNow('GeneralCommand', '계략') && $itemObj->isConsumableNow('GeneralCommand', '계략')) {
$itemName = $itemObj->getName(); $itemName = $itemObj->getName();
$itemRawName = $itemObj->getRawName(); $itemRawName = $itemObj->getRawName();
$josaUl = JosaUtil::pick($itemRawName, '을'); $josaUl = JosaUtil::pick($itemRawName, '을');
@@ -295,13 +322,13 @@ class che_화계 extends Command\GeneralCommand{
$exp = Util::randRangeInt(201, 300); $exp = Util::randRangeInt(201, 300);
$ded = Util::randRangeInt(141, 210); $ded = Util::randRangeInt(141, 210);
[$reqGold, $reqRice] = $this->getCost(); [$reqGold, $reqRice] = $this->getCost();
$general->increaseVarWithLimit('gold', -$reqGold, 0); $general->increaseVarWithLimit('gold', -$reqGold, 0);
$general->increaseVarWithLimit('rice', -$reqRice, 0); $general->increaseVarWithLimit('rice', -$reqRice, 0);
$general->addExperience($exp); $general->addExperience($exp);
$general->addDedication($ded); $general->addDedication($ded);
$general->increaseVar($statType.'_exp', 1); $general->increaseVar($statType . '_exp', 1);
$general->increaseRankVar('firenum', 1); $general->increaseRankVar('firenum', 1);
$general->setResultTurn(new LastTurn(static::getName(), $this->arg)); $general->setResultTurn(new LastTurn(static::getName(), $this->arg));
$general->checkStatChange(); $general->checkStatChange();
@@ -325,18 +352,16 @@ class che_화계 extends Command\GeneralCommand{
ob_start(); ob_start();
?> ?>
<?=\sammo\getMapHtml()?><br> <?= \sammo\getMapHtml() ?><br>
선택된 도시에 <?=$commandName?><?=$josaUl?> 실행합니다.<br> 선택된 도시에 <?= $commandName ?><?= $josaUl ?> 실행합니다.<br>
목록을 선택하거나 도시를 클릭하세요.<br> 목록을 선택하거나 도시를 클릭하세요.<br>
<select class='formInput' name="destCityID" id="destCityID" size='1' style='color:white;background-color:black;'><br> <select class='formInput' name="destCityID" id="destCityID" size='1' style='color:white;background-color:black;'><br>
<?=\sammo\optionsForCities()?><br> <?= \sammo\optionsForCities() ?><br>
</select> <input type=button id="commonSubmit" value="<?=$this->getName()?>"><br> </select> <input type=button id="commonSubmit" value="<?= $this->getName() ?>"><br>
<br> <br>
<br> <br>
<?=printCitiesBasedOnDistance($currentCityID, 2)?> <?= printCitiesBasedOnDistance($currentCityID, 2) ?>
<?php <?php
return ob_get_clean(); return ob_get_clean();
} }
}
}
+2 -2
View File
@@ -35,7 +35,7 @@ class che_훈련 extends Command\GeneralCommand{
$this->setCity(); $this->setCity();
$this->setNation(); $this->setNation();
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
ConstraintHelper::NotWanderingNation(), ConstraintHelper::NotWanderingNation(),
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
@@ -73,7 +73,7 @@ class che_훈련 extends Command\GeneralCommand{
} }
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
+4 -2
View File
@@ -14,8 +14,10 @@ class 휴식 extends Command\GeneralCommand{
return true; return true;
} }
protected function init(){ protected function init()
$this->runnableConstraints=[]; {
$this->minConditionConstraints=[];
$this->fullConditionConstraints=[];
} }
public function getCost():array{ public function getCost():array{
+5 -6
View File
@@ -29,7 +29,6 @@ use sammo\Event\Action;
class che_감축 extends Command\NationCommand{ class che_감축 extends Command\NationCommand{
static protected $actionName = '감축'; static protected $actionName = '감축';
static public $reqArg = false;
protected function argTest():bool{ protected function argTest():bool{
$this->arg = []; $this->arg = [];
@@ -43,10 +42,10 @@ class che_감축 extends Command\NationCommand{
$env = $this->env; $env = $this->env;
if($general->getNationID()===0){ if($general->getNationID()===0){
$this->reservableConstraints=[ $this->permissionConstraints=[
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
]; ];
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
]; ];
return; return;
@@ -54,13 +53,13 @@ class che_감축 extends Command\NationCommand{
$this->setCity(); $this->setCity();
$this->setNation(['gold', 'rice', 'capset', 'capital']); $this->setNation(['gold', 'rice', 'capset', 'capital']);
$this->setDestCity($this->nation['capital'], null); $this->setDestCity($this->nation['capital']);
[$reqGold, $reqRice] = $this->getCost(); [$reqGold, $reqRice] = $this->getCost();
$origCityLevel = CityConst::byID($this->nation['capital'])->level; $origCityLevel = CityConst::byID($this->nation['capital'])->level;
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
ConstraintHelper::BeChief(), ConstraintHelper::BeChief(),
ConstraintHelper::SuppliedCity(), ConstraintHelper::SuppliedCity(),
@@ -136,7 +135,7 @@ class che_감축 extends Command\NationCommand{
} }
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
+76 -55
View File
@@ -1,20 +1,25 @@
<?php <?php
namespace sammo\Command\Nation; namespace sammo\Command\Nation;
use \sammo\{ use\sammo\{
DB, Util, JosaUtil, DB,
General, DummyGeneral, Util,
JosaUtil,
General,
DummyGeneral,
ActionLogger, ActionLogger,
GameConst, GameConst,
LastTurn, LastTurn,
GameUnitConst, GameUnitConst,
Command, Command,
Message, MessageTarget Message,
MessageTarget
}; };
use function \sammo\{ use function\sammo\{
getDomesticExpLevelBonus, getDomesticExpLevelBonus,
CriticalRatioDomestic, CriticalRatioDomestic,
CriticalScoreEx, CriticalScoreEx,
getAllNationStaticInfo, getAllNationStaticInfo,
getNationStaticInfo, getNationStaticInfo,
@@ -24,34 +29,37 @@ use function \sammo\{
use \sammo\Constraint\Constraint; use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
class che_급습 extends Command\NationCommand{ class che_급습 extends Command\NationCommand
{
static protected $actionName = '급습'; static protected $actionName = '급습';
static public $reqArg = true; static public $reqArg = true;
protected function argTest():bool{ protected function argTest(): bool
if($this->arg === null){ {
if ($this->arg === null) {
return false; return false;
} }
//NOTE: 멸망 직전에 턴을 넣을 수 있으므로, 존재하지 않는 국가여도 argTest에서 바로 탈락시키지 않음 //NOTE: 멸망 직전에 턴을 넣을 수 있으므로, 존재하지 않는 국가여도 argTest에서 바로 탈락시키지 않음
if(!key_exists('destNationID', $this->arg)){ if (!key_exists('destNationID', $this->arg)) {
return false; return false;
} }
$destNationID = $this->arg['destNationID']; $destNationID = $this->arg['destNationID'];
if(!is_int($destNationID)){ if (!is_int($destNationID)) {
return false; return false;
} }
if($destNationID < 1){ if ($destNationID < 1) {
return false; return false;
} }
$this->arg = [ $this->arg = [
'destNationID'=>$destNationID 'destNationID' => $destNationID
]; ];
return true; return true;
} }
protected function init(){ protected function init()
{
$general = $this->generalObj; $general = $this->generalObj;
$env = $this->env; $env = $this->env;
@@ -59,54 +67,71 @@ class che_급습 extends Command\NationCommand{
$this->setCity(); $this->setCity();
$this->setNation(['strategic_cmd_limit']); $this->setNation(['strategic_cmd_limit']);
$this->minConditionConstraints = [
ConstraintHelper::OccupiedCity(),
ConstraintHelper::BeChief(),
ConstraintHelper::AvailableStrategicCommand(),
];
}
protected function initWithArg()
{
$this->setDestNation($this->arg['destNationID'], null); $this->setDestNation($this->arg['destNationID'], null);
$this->runnableConstraints=[ $this->fullConditionConstraints = [
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
ConstraintHelper::BeChief(), ConstraintHelper::BeChief(),
ConstraintHelper::ExistsDestNation(), ConstraintHelper::ExistsDestNation(),
ConstraintHelper::AllowDiplomacyWithTerm( ConstraintHelper::AllowDiplomacyWithTerm(
1, 12, 1,
12,
'선포 12개월 이상인 상대국에만 가능합니다.' '선포 12개월 이상인 상대국에만 가능합니다.'
), ),
ConstraintHelper::AvailableStrategicCommand(), ConstraintHelper::AvailableStrategicCommand(),
]; ];
} }
public function getCommandDetailTitle():string{ public function getCommandDetailTitle(): string
{
$name = $this->getName(); $name = $this->getName();
$reqTurn = $this->getPreReqTurn()+1; $reqTurn = $this->getPreReqTurn() + 1;
$postReqTurn = $this->getPostReqTurn(); $postReqTurn = $this->getPostReqTurn();
return "{$name}/{$reqTurn}턴(전략$postReqTurn)"; return "{$name}/{$reqTurn}턴(전략$postReqTurn)";
} }
public function getCost():array{ public function getCost(): array
{
return [0, 0]; return [0, 0];
} }
public function getPreReqTurn():int{ public function getPreReqTurn(): int
{
return 0; return 0;
} }
public function getPostReqTurn():int{ public function getPostReqTurn(): int
{
$genCount = Util::valueFit($this->nation['gennum'], GameConst::$initialNationGenLimit); $genCount = Util::valueFit($this->nation['gennum'], GameConst::$initialNationGenLimit);
$nextTerm = Util::round(sqrt($genCount*16)*10); $nextTerm = Util::round(sqrt($genCount * 16) * 10);
$nextTerm = $this->generalObj->onCalcStrategic($this->getName(), 'delay', $nextTerm); $nextTerm = $this->generalObj->onCalcStrategic($this->getName(), 'delay', $nextTerm);
return $nextTerm; return $nextTerm;
} }
public function getBrief():string{ public function getBrief(): string
{
$commandName = $this->getName(); $commandName = $this->getName();
$destNationName = getNationStaticInfo($this->arg['destNationID'])['name']; $destNationName = getNationStaticInfo($this->arg['destNationID'])['name'];
return "{$destNationName}】에 {$commandName}"; return "{$destNationName}】에 {$commandName}";
} }
public function run():bool{ public function run(): bool
if(!$this->isRunnable()){ {
if (!$this->hasFullConditionMet()) {
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -144,7 +169,7 @@ class che_급습 extends Command\NationCommand{
$broadcastMessage = "<Y>{$generalName}</>{$josaYi} <G><b>{$destNationName}</b></>에 <M>{$commandName}</>{$josaUl} 발동하였습니다."; $broadcastMessage = "<Y>{$generalName}</>{$josaYi} <G><b>{$destNationName}</b></>에 <M>{$commandName}</>{$josaUl} 발동하였습니다.";
$nationGeneralList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND no != %i', $nationID, $generalID); $nationGeneralList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND no != %i', $nationID, $generalID);
foreach($nationGeneralList as $nationGeneralID){ foreach ($nationGeneralList as $nationGeneralID) {
$nationGeneralLogger = new ActionLogger($nationGeneralID, $nationID, $year, $month); $nationGeneralLogger = new ActionLogger($nationGeneralID, $nationID, $year, $month);
$nationGeneralLogger->pushGeneralActionLog($broadcastMessage, ActionLogger::PLAIN); $nationGeneralLogger->pushGeneralActionLog($broadcastMessage, ActionLogger::PLAIN);
$nationGeneralLogger->flush(); $nationGeneralLogger->flush();
@@ -155,7 +180,7 @@ class che_급습 extends Command\NationCommand{
$broadcastMessage = "아국에 <M>{$commandName}</>{$josaYiCommand} 발동되었습니다."; $broadcastMessage = "아국에 <M>{$commandName}</>{$josaYiCommand} 발동되었습니다.";
$destNationGeneralList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND no != %i', $nationID, $generalID); $destNationGeneralList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND no != %i', $nationID, $generalID);
foreach($destNationGeneralList as $destNationGeneralID){ foreach ($destNationGeneralList as $destNationGeneralID) {
$destNationGeneralLogger = new ActionLogger($destNationGeneralID, $destNationID, $year, $month); $destNationGeneralLogger = new ActionLogger($destNationGeneralID, $destNationID, $year, $month);
$destNationGeneralLogger->pushGeneralActionLog($broadcastMessage, ActionLogger::PLAIN); $destNationGeneralLogger->pushGeneralActionLog($broadcastMessage, ActionLogger::PLAIN);
$destNationGeneralLogger->flush(); $destNationGeneralLogger->flush();
@@ -166,12 +191,12 @@ class che_급습 extends Command\NationCommand{
$destNationLogger->flush(); $destNationLogger->flush();
$logger->pushNationalHistoryLog("<Y>{$generalName}</>{$josaYi} <D><b>{$destNationName}</b></>에 <M>{$commandName}</>{$josaUl} 발동"); $logger->pushNationalHistoryLog("<Y>{$generalName}</>{$josaYi} <D><b>{$destNationName}</b></>에 <M>{$commandName}</>{$josaUl} 발동");
$db->update('nation', [ $db->update('nation', [
'strategic_cmd_limit' => $this->getPostReqTurn() 'strategic_cmd_limit' => $this->getPostReqTurn()
], 'nation=%i', $nationID); ], 'nation=%i', $nationID);
$db->update('diplomacy', [ $db->update('diplomacy', [
'term'=>$db->sqleval('`term` - %i', 3), 'term' => $db->sqleval('`term` - %i', 3),
], '(me = %i AND you = %i) OR (you = %i AND me = %i)', $nationID, $destNationID, $nationID, $destNationID); ], '(me = %i AND you = %i) OR (you = %i AND me = %i)', $nationID, $destNationID, $nationID, $destNationID);
$general->applyDB($db); $general->applyDB($db);
@@ -192,39 +217,35 @@ class che_급습 extends Command\NationCommand{
$nationID = $generalObj->getNationID(); $nationID = $generalObj->getNationID();
$nationList = []; $nationList = [];
$testTurn = new LastTurn($this->getName(), null, $this->getPreReqTurn()); $testTurn = new LastTurn($this->getName(), null, $this->getPreReqTurn());
foreach(getAllNationStaticInfo() as $destNation){ foreach (getAllNationStaticInfo() as $destNation) {
if($destNation['nation'] == $nationID){ if ($destNation['nation'] == $nationID) {
continue; continue;
} }
$testTurn->setArg(['destNationID'=>$destNation['nation']]); $testTurn->setArg(['destNationID' => $destNation['nation']]);
$testCommand = new static($generalObj, $this->env, $testTurn, ['destNationID'=>$destNation['nation']]); $testCommand = new static($generalObj, $this->env, $testTurn, ['destNationID' => $destNation['nation']]);
if($testCommand->isRunnable()){ if ($testCommand->hasFullConditionMet()) {
$destNation['availableCommand'] = true; $destNation['availableCommand'] = true;
} } else {
else{
$destNation['availableCommand'] = false; $destNation['availableCommand'] = false;
} }
$nationList[] = $destNation; $nationList[] = $destNation;
} }
ob_start(); ob_start();
?> ?>
<?=\sammo\getMapHtml()?><br> <?= \sammo\getMapHtml() ?><br>
선택된 국가에 급습을 발동합니다.<br> 선택된 국가에 급습을 발동합니다.<br>
선포, 전쟁중인 상대국에만 가능합니다.<br> 선포, 전쟁중인 상대국에만 가능합니다.<br>
상대 국가를 목록에서 선택하세요.<br> 상대 국가를 목록에서 선택하세요.<br>
배경색은 현재 급습 불가능 국가는 <font color=red>붉은색</font>으로 표시됩니다.<br> 배경색은 현재 급습 불가능 국가는 <font color=red>붉은색</font>으로 표시됩니다.<br>
<select class='formInput' name="destNationID" id="destNationID" size='1' style='color:white;background-color:black;'> <select class='formInput' name="destNationID" id="destNationID" size='1' style='color:white;background-color:black;'>
<?php foreach($nationList as $nation): ?> <?php foreach ($nationList as $nation) : ?>
<option <option value='<?= $nation['nation'] ?>' style='color:<?= $nation['color'] ?>;<?= $nation['availableCommand'] ? '' : 'background-color:red;' ?>'>【<?= $nation['name'] ?> 】</option>
value='<?=$nation['nation']?>' <?php endforeach; ?>
style='color:<?=$nation['color']?>;<?=$nation['availableCommand']?'':'background-color:red;'?>' <input type=button id="commonSubmit" value="<?= $this->getName() ?>">
>【<?=$nation['name']?> 】</option> <?php
<?php endforeach; ?>
<input type=button id="commonSubmit" value="<?=$this->getName()?>">
<?php
return ob_get_clean(); return ob_get_clean();
} }
} }
+96 -70
View File
@@ -1,9 +1,13 @@
<?php <?php
namespace sammo\Command\Nation; namespace sammo\Command\Nation;
use \sammo\{ use\sammo\{
DB, Util, JosaUtil, DB,
General, DummyGeneral, Util,
JosaUtil,
General,
DummyGeneral,
ActionLogger, ActionLogger,
GameConst, GameConst,
LastTurn, LastTurn,
@@ -13,9 +17,9 @@ use \sammo\{
Message Message
}; };
use function \sammo\{ use function\sammo\{
getDomesticExpLevelBonus, getDomesticExpLevelBonus,
CriticalRatioDomestic, CriticalRatioDomestic,
CriticalScoreEx, CriticalScoreEx,
GetImageURL GetImageURL
}; };
@@ -23,56 +27,59 @@ use function \sammo\{
use \sammo\Constraint\Constraint; use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
class che_몰수 extends Command\NationCommand{ class che_몰수 extends Command\NationCommand
{
static protected $actionName = '몰수'; static protected $actionName = '몰수';
static public $reqArg = true; static public $reqArg = true;
protected function argTest():bool{ protected function argTest(): bool
if($this->arg === null){ {
if ($this->arg === null) {
return false; return false;
} }
//NOTE: 사망 직전에 턴을 넣을 수 있으므로, 존재하지 않는 장수여도 argTest에서 바로 탈락시키지 않음 //NOTE: 사망 직전에 턴을 넣을 수 있으므로, 존재하지 않는 장수여도 argTest에서 바로 탈락시키지 않음
if(!key_exists('isGold', $this->arg)){ if (!key_exists('isGold', $this->arg)) {
return false; return false;
} }
if(!key_exists('amount', $this->arg)){ if (!key_exists('amount', $this->arg)) {
return false; return false;
} }
if(!key_exists('destGeneralID', $this->arg)){ if (!key_exists('destGeneralID', $this->arg)) {
return false; return false;
} }
$isGold = $this->arg['isGold']; $isGold = $this->arg['isGold'];
$amount = $this->arg['amount']; $amount = $this->arg['amount'];
$destGeneralID = $this->arg['destGeneralID']; $destGeneralID = $this->arg['destGeneralID'];
if(!is_numeric($amount)){ if (!is_numeric($amount)) {
return false; return false;
} }
$amount = Util::round($amount, -2); $amount = Util::round($amount, -2);
$amount = Util::valueFit($amount, 100, GameConst::$maxResourceActionAmount); $amount = Util::valueFit($amount, 100, GameConst::$maxResourceActionAmount);
if($amount <= 0){ if ($amount <= 0) {
return false; return false;
} }
if(!is_bool($isGold)){ if (!is_bool($isGold)) {
return false; return false;
} }
if(!is_int($destGeneralID)){ if (!is_int($destGeneralID)) {
return false; return false;
} }
if($destGeneralID <= 0){ if ($destGeneralID <= 0) {
return false; return false;
} }
if($destGeneralID == $this->generalObj->getID()){ if ($destGeneralID == $this->generalObj->getID()) {
return false; return false;
} }
$this->arg = [ $this->arg = [
'isGold'=>$isGold, 'isGold' => $isGold,
'amount'=>$amount, 'amount' => $amount,
'destGeneralID'=>$destGeneralID 'destGeneralID' => $destGeneralID
]; ];
return true; return true;
} }
protected function init(){ protected function init()
{
$general = $this->generalObj; $general = $this->generalObj;
$env = $this->env; $env = $this->env;
@@ -80,13 +87,27 @@ class che_몰수 extends Command\NationCommand{
$this->setCity(); $this->setCity();
$this->setNation(['gold', 'rice']); $this->setNation(['gold', 'rice']);
$relYear = $env['year'] - $env['startyear'];
$this->minConditionConstraints = [
ConstraintHelper::NotBeNeutral(),
ConstraintHelper::OccupiedCity(),
ConstraintHelper::BeChief(),
ConstraintHelper::NotOpeningPart($relYear),
ConstraintHelper::SuppliedCity(),
];
}
protected function initWithArg()
{
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['gold', 'rice', 'npc', 'nation', 'imgsvr', 'picture'], 1); $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['gold', 'rice', 'npc', 'nation', 'imgsvr', 'picture'], 1);
$this->setDestGeneral($destGeneral); $this->setDestGeneral($destGeneral);
$env = $this->env;
$relYear = $env['year'] - $env['startyear']; $relYear = $env['year'] - $env['startyear'];
$this->runnableConstraints=[ $this->fullConditionConstraints = [
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
ConstraintHelper::BeChief(), ConstraintHelper::BeChief(),
ConstraintHelper::NotOpeningPart($relYear), ConstraintHelper::NotOpeningPart($relYear),
@@ -95,32 +116,37 @@ class che_몰수 extends Command\NationCommand{
ConstraintHelper::FriendlyDestGeneral() ConstraintHelper::FriendlyDestGeneral()
]; ];
} }
public function getCost():array{ public function getCost(): array
{
return [0, 0]; return [0, 0];
} }
public function getPreReqTurn():int{ public function getPreReqTurn(): int
{
return 0; return 0;
} }
public function getPostReqTurn():int{ public function getPostReqTurn(): int
{
return 0; return 0;
} }
public function getBrief():string{ public function getBrief(): string
{
$isGold = $this->arg['isGold']; $isGold = $this->arg['isGold'];
$amount = $this->arg['amount']; $amount = $this->arg['amount'];
$amountText = number_format($amount, 0); $amountText = number_format($amount, 0);
$resName = $isGold?'금':'쌀'; $resName = $isGold ? '금' : '쌀';
$destGeneral = $this->destGeneralObj; $destGeneral = $this->destGeneralObj;
$commandName = $this->getName(); $commandName = $this->getName();
return "{$destGeneral->getName()}{$resName} $amountText {$commandName}"; return "{$destGeneral->getName()}{$resName} $amountText {$commandName}";
} }
public function run():bool{ public function run(): bool
if(!$this->isRunnable()){ {
if (!$this->hasFullConditionMet()) {
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -134,10 +160,10 @@ class che_몰수 extends Command\NationCommand{
$isGold = $this->arg['isGold']; $isGold = $this->arg['isGold'];
$amount = $this->arg['amount']; $amount = $this->arg['amount'];
$resKey = $isGold?'gold':'rice'; $resKey = $isGold ? 'gold' : 'rice';
$resName = $isGold?'금':'쌀'; $resName = $isGold ? '금' : '쌀';
$destGeneral = $this->destGeneralObj; $destGeneral = $this->destGeneralObj;
$amount = Util::valueFit( $amount = Util::valueFit(
$amount, $amount,
0, 0,
@@ -145,17 +171,17 @@ class che_몰수 extends Command\NationCommand{
); );
$amountText = number_format($amount, 0); $amountText = number_format($amount, 0);
if($destGeneral->getVar('npc') >= 2 && Util::randBool(0.01)){ if ($destGeneral->getVar('npc') >= 2 && Util::randBool(0.01)) {
$npcTexts = [ $npcTexts = [
'몰수를 하다니... 이것이 윗사람이 할 짓이란 말입니까...', '몰수를 하다니... 이것이 윗사람이 할 짓이란 말입니까...',
'사유재산까지 몰수해가면서 이 나라가 잘 될거라 믿습니까? 정말 이해할 수가 없군요...', '사유재산까지 몰수해가면서 이 나라가 잘 될거라 믿습니까? 정말 이해할 수가 없군요...',
'내 돈 내놔라! 내 돈! 몰수가 왠 말이냐!', '내 돈 내놔라! 내 돈! 몰수가 왠 말이냐!',
'몰수해간 내 자금... 언젠가 몰래 다시 빼내올 것이다...', '몰수해간 내 자금... 언젠가 몰래 다시 빼내올 것이다...',
'몰수로 인한 사기 저하는 몰수로 얻은 물자보다 더 손해란걸 모른단 말인가!' '몰수로 인한 사기 저하는 몰수로 얻은 물자보다 더 손해란걸 모른단 말인가!'
]; ];
$text = Util::choiceRandom($npcTexts); $text = Util::choiceRandom($npcTexts);
$src = new MessageTarget( $src = new MessageTarget(
$destGeneral->getID(), $destGeneral->getID(),
$destGeneral->getName(), $destGeneral->getName(),
$nationID, $nationID,
$nation['name'], $nation['name'],
@@ -163,7 +189,7 @@ class che_몰수 extends Command\NationCommand{
GetImageURL($destGeneral->getVar('imgsvr'), $destGeneral->getVar('picture')) GetImageURL($destGeneral->getVar('imgsvr'), $destGeneral->getVar('picture'))
); );
$msg = new Message( $msg = new Message(
Message::MSGTYPE_PUBLIC, Message::MSGTYPE_PUBLIC,
$src, $src,
$src, $src,
$text, $text,
@@ -173,12 +199,12 @@ class che_몰수 extends Command\NationCommand{
); );
$msg->send(); $msg->send();
} }
$logger = $general->getLogger(); $logger = $general->getLogger();
$destGeneral->increaseVarWithLimit($resKey, -$amount, 0); $destGeneral->increaseVarWithLimit($resKey, -$amount, 0);
$db->update('nation', [ $db->update('nation', [
$resKey=>$db->sqleval('%b + %i', $resKey, $amount) $resKey => $db->sqleval('%b + %i', $resKey, $amount)
], 'nation=%i', $nationID); ], 'nation=%i', $nationID);
$destGeneral->getLogger()->pushGeneralActionLog("{$resName} {$amountText}을 몰수 당했습니다.", ActionLogger::PLAIN); $destGeneral->getLogger()->pushGeneralActionLog("{$resName} {$amountText}을 몰수 당했습니다.", ActionLogger::PLAIN);
@@ -196,48 +222,48 @@ class che_몰수 extends Command\NationCommand{
//TODO: 암행부처럼 보여야... //TODO: 암행부처럼 보여야...
$db = DB::db(); $db = DB::db();
$destRawGenerals = $db->query('SELECT no,name,officer_level,npc,gold,rice FROM general WHERE nation = %i AND no != %i ORDER BY npc,binary(name)',$this->generalObj->getNationID(), $this->generalObj->getID()); $destRawGenerals = $db->query('SELECT no,name,officer_level,npc,gold,rice FROM general WHERE nation = %i AND no != %i ORDER BY npc,binary(name)', $this->generalObj->getNationID(), $this->generalObj->getID());
$destGeneralList = []; $destGeneralList = [];
foreach($destRawGenerals as $destGeneral){ foreach ($destRawGenerals as $destGeneral) {
$nameColor = \sammo\getNameColor($destGeneral['npc']); $nameColor = \sammo\getNameColor($destGeneral['npc']);
if($nameColor){ if ($nameColor) {
$nameColor = " style='color:{$nameColor}'"; $nameColor = " style='color:{$nameColor}'";
} }
$name = $destGeneral['name']; $name = $destGeneral['name'];
if($destGeneral['officer_level'] >= 5){ if ($destGeneral['officer_level'] >= 5) {
$name = "*{$name}*"; $name = "*{$name}*";
} }
$destGeneralList[] = [ $destGeneralList[] = [
'no'=>$destGeneral['no'], 'no' => $destGeneral['no'],
'color'=>$nameColor, 'color' => $nameColor,
'name'=>$name, 'name' => $name,
'gold'=>$destGeneral['gold'], 'gold' => $destGeneral['gold'],
'rice'=>$destGeneral['rice'] 'rice' => $destGeneral['rice']
]; ];
} }
ob_start(); ob_start();
?> ?>
장수의 자금이나 군량을 몰수합니다.<br> 장수의 자금이나 군량을 몰수합니다.<br>
몰수한것은 국가재산으로 귀속됩니다.<br> 몰수한것은 국가재산으로 귀속됩니다.<br>
<select class='formInput' name="destGeneralID" id="destGeneralID" size='1' style='color:white;background-color:black;'> <select class='formInput' name="destGeneralID" id="destGeneralID" size='1' style='color:white;background-color:black;'>
<?php foreach($destGeneralList as $destGeneral): ?> <?php foreach ($destGeneralList as $destGeneral) : ?>
<option value='<?=$destGeneral['no']?>' <?=$destGeneral['color']?>><?=$destGeneral['name']?>(금:<?=$destGeneral['gold']?>, 쌀:<?=$destGeneral['rice']?>)</option> <option value='<?= $destGeneral['no'] ?>' <?= $destGeneral['color'] ?>><?= $destGeneral['name'] ?>(금:<?= $destGeneral['gold'] ?>, 쌀:<?= $destGeneral['rice'] ?>)</option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
<select class='formInput' name="isGold" id="isGold" size='1' style='color:white;background-color:black;'> <select class='formInput' name="isGold" id="isGold" size='1' style='color:white;background-color:black;'>
<option value="true">금</option> <option value="true">금</option>
<option value="false">쌀</option> <option value="false">쌀</option>
</select> </select>
</select> </select>
<select class='formInput' name="amount" id="amount" size='1' style='color:white;background-color:black;'> <select class='formInput' name="amount" id="amount" size='1' style='color:white;background-color:black;'>
<?php foreach(GameConst::$resourceActionAmountGuide as $amount): ?> <?php foreach (GameConst::$resourceActionAmountGuide as $amount) : ?>
<option value='<?=$amount?>'><?=$amount?></option> <option value='<?= $amount ?>'><?= $amount ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> <input type=button id="commonSubmit" value="<?=$this->getName()?>"><br> </select> <input type=button id="commonSubmit" value="<?= $this->getName() ?>"><br>
<br> <br>
<?php <?php
return ob_get_clean(); return ob_get_clean();
} }
} }
+14 -4
View File
@@ -80,6 +80,16 @@ class che_물자원조 extends Command\NationCommand{
$this->setCity(); $this->setCity();
$this->setNation(['gold', 'rice', 'surlimit']); $this->setNation(['gold', 'rice', 'surlimit']);
$this->minConditionConstraints=[
ConstraintHelper::OccupiedCity(),
ConstraintHelper::BeChief(),
ConstraintHelper::SuppliedCity(),
ConstraintHelper::ReqNationValue('surlimit', '외교제한', '==', 0, '외교제한중입니다.'),
];
}
protected function initWithArg()
{
$destNationID = $this->arg['destNationID']; $destNationID = $this->arg['destNationID'];
$this->setDestNation($destNationID, ['gold', 'rice', 'surlimit']); $this->setDestNation($destNationID, ['gold', 'rice', 'surlimit']);
@@ -87,13 +97,13 @@ class che_물자원조 extends Command\NationCommand{
$limit = $this->nation['level'] * GameConst::$coefAidAmount; $limit = $this->nation['level'] * GameConst::$coefAidAmount;
if($goldAmount > $limit || $riceAmount > $limit){ if($goldAmount > $limit || $riceAmount > $limit){
$this->runnableConstraints[ $this->fullConditionConstraints[
ConstraintHelper::AlwaysFail('작위 제한량 이상은 보낼 수 없습니다.') ConstraintHelper::AlwaysFail('작위 제한량 이상은 보낼 수 없습니다.')
]; ];
return; return;
} }
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::ExistsDestNation(), ConstraintHelper::ExistsDestNation(),
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
ConstraintHelper::BeChief(), ConstraintHelper::BeChief(),
@@ -128,7 +138,7 @@ class che_물자원조 extends Command\NationCommand{
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
+15 -5
View File
@@ -59,13 +59,23 @@ class che_발령 extends Command\NationCommand{
$this->setCity(); $this->setCity();
$this->setNation(); $this->setNation();
$this->minConditionConstraints=[
ConstraintHelper::BeChief(),
ConstraintHelper::NotBeNeutral(),
ConstraintHelper::OccupiedCity(),
ConstraintHelper::SuppliedCity(),
];
}
$this->setDestCity($this->arg['destCityID'], null); protected function initWithArg()
{
$this->setDestCity($this->arg['destCityID']);
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], null, 1); $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], null, 1);
$this->setDestGeneral($destGeneral); $this->setDestGeneral($destGeneral);
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::BeChief(), ConstraintHelper::BeChief(),
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
@@ -79,7 +89,7 @@ class che_발령 extends Command\NationCommand{
public function getFailString():string{ public function getFailString():string{
$commandName = $this->getName(); $commandName = $this->getName();
$failReason = $this->testRunnable(); $failReason = $this->testFullConditionMet();
if($failReason === null){ if($failReason === null){
throw new \RuntimeException('실행 가능한 커맨드에 대해 실패 이유를 수집'); throw new \RuntimeException('실행 가능한 커맨드에 대해 실패 이유를 수집');
} }
@@ -109,7 +119,7 @@ class che_발령 extends Command\NationCommand{
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
+14 -4
View File
@@ -56,10 +56,20 @@ class che_백성동원 extends Command\NationCommand{
$this->setCity(); $this->setCity();
$this->setNation(['strategic_cmd_limit']); $this->setNation(['strategic_cmd_limit']);
$this->setDestCity($this->arg['destCityID'], null);
$this->setDestNation($this->destCity['nation']);
$this->runnableConstraints=[ $this->minConditionConstraints=[
ConstraintHelper::OccupiedCity(),
ConstraintHelper::BeChief(),
ConstraintHelper::AvailableStrategicCommand()
];
}
protected function initWithArg()
{
$this->setDestCity($this->arg['destCityID']);
$this->setDestNation($this->destCity['nation']);
$this->fullConditionConstraints=[
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
ConstraintHelper::BeChief(), ConstraintHelper::BeChief(),
ConstraintHelper::AllowDiplomacyStatus($this->generalObj->getNationID(), [ ConstraintHelper::AllowDiplomacyStatus($this->generalObj->getNationID(), [
@@ -101,7 +111,7 @@ class che_백성동원 extends Command\NationCommand{
} }
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -1,9 +1,13 @@
<?php <?php
namespace sammo\Command\Nation; namespace sammo\Command\Nation;
use \sammo\{ use\sammo\{
DB, Util, JosaUtil, DB,
General, DummyGeneral, Util,
JosaUtil,
General,
DummyGeneral,
ActionLogger, ActionLogger,
GameConst, GameConst,
LastTurn, LastTurn,
@@ -14,9 +18,9 @@ use \sammo\{
Message, Message,
}; };
use function \sammo\{ use function\sammo\{
getDomesticExpLevelBonus, getDomesticExpLevelBonus,
CriticalRatioDomestic, CriticalRatioDomestic,
CriticalScoreEx, CriticalScoreEx,
getAllNationStaticInfo, getAllNationStaticInfo,
getNationStaticInfo, getNationStaticInfo,
@@ -26,75 +30,85 @@ use function \sammo\{
use \sammo\Constraint\Constraint; use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
class che_불가침수락 extends Command\NationCommand{ class che_불가침수락 extends Command\NationCommand
{
static protected $actionName = '불가침 수락'; static protected $actionName = '불가침 수락';
static public $reqArg = true; static public $reqArg = true;
protected function argTest():bool{ protected function argTest(): bool
if($this->arg === null){ {
if ($this->arg === null) {
return false; return false;
} }
if(!key_exists('destNationID', $this->arg)){ if (!key_exists('destNationID', $this->arg)) {
return false; return false;
} }
$destNationID = $this->arg['destNationID']; $destNationID = $this->arg['destNationID'];
if(!is_int($destNationID)){ if (!is_int($destNationID)) {
return false; return false;
} }
if($destNationID < 1){ if ($destNationID < 1) {
return false; return false;
} }
if(!key_exists('destGeneralID', $this->arg)){ if (!key_exists('destGeneralID', $this->arg)) {
return false; return false;
} }
$destGeneralID = $this->arg['destGeneralID']; $destGeneralID = $this->arg['destGeneralID'];
if(!is_int($destGeneralID)){ if (!is_int($destGeneralID)) {
return false; return false;
} }
if($destGeneralID <= 0){ if ($destGeneralID <= 0) {
return false; return false;
} }
if($destGeneralID == $this->generalObj->getID()){ if ($destGeneralID == $this->generalObj->getID()) {
return false; return false;
} }
if(!key_exists('year', $this->arg) || !key_exists('month', $this->arg) ){ if (!key_exists('year', $this->arg) || !key_exists('month', $this->arg)) {
return false; return false;
} }
$year = $this->arg['year']; $year = $this->arg['year'];
$month = $this->arg['month']; $month = $this->arg['month'];
if(!is_int($year) || !is_int($month)){ if (!is_int($year) || !is_int($month)) {
return false; return false;
} }
if($month < 1 || 12 < $month){ if ($month < 1 || 12 < $month) {
return false; return false;
} }
if($year < $this->env['startyear']){ if ($year < $this->env['startyear']) {
return false; return false;
} }
$this->arg = [ $this->arg = [
'destNationID'=>$destNationID, 'destNationID' => $destNationID,
'destGeneralID'=>$destGeneralID, 'destGeneralID' => $destGeneralID,
'year'=>$year, 'year' => $year,
'month'=>$month, 'month' => $month,
]; ];
return true; return true;
} }
protected function init(){ protected function init()
{
$general = $this->generalObj; $general = $this->generalObj;
$env = $this->env;
$relYear = $env['year'] - $env['startyear'];
$this->setCity(); $this->setCity();
$this->setNation(); $this->setNation();
$this->permissionConstraints = [
ConstraintHelper::AlwaysFail('예약 불가능 커맨드')
];
}
protected function initWithArg()
{
$env = $this->env;
$relYear = $env['year'] - $env['startyear'];
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], [], 1); $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], [], 1);
$this->setDestGeneral($destGeneral); $this->setDestGeneral($destGeneral);
$this->setDestNation($this->arg['destNationID']); $this->setDestNation($this->arg['destNationID']);
@@ -104,24 +118,20 @@ class che_불가침수락 extends Command\NationCommand{
$month = $this->arg['month']; $month = $this->arg['month'];
$currentMonth = $env['year'] * 12 + $env['month'] - 1; $currentMonth = $env['year'] * 12 + $env['month'] - 1;
$reqMonth = $year *12 + $month - 1; $reqMonth = $year * 12 + $month - 1;
$nationID = $this->nation['nation']; $nationID = $this->nation['nation'];
$this->reservableConstraints = [
ConstraintHelper::AlwaysFail('예약 불가능 커맨드')
];
if ($reqMonth <= $currentMonth) { if ($reqMonth <= $currentMonth) {
$this->runnableConstraints = [ $this->fullConditionConstraints = [
ConstraintHelper::AlwaysFail('이미 기한이 지났습니다.') ConstraintHelper::AlwaysFail('이미 기한이 지났습니다.')
]; ];
return; return;
} }
$this->runnableConstraints=[ $this->fullConditionConstraints = [
ConstraintHelper::BeChief(), ConstraintHelper::BeChief(),
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
ConstraintHelper::SuppliedCity(), ConstraintHelper::SuppliedCity(),
ConstraintHelper::ExistsDestNation(), ConstraintHelper::ExistsDestNation(),
@@ -136,22 +146,25 @@ class che_불가침수락 extends Command\NationCommand{
6 => '아국과 외교 진행중입니다.', 6 => '아국과 외교 진행중입니다.',
]), ]),
]; ];
} }
public function getCost():array{ public function getCost(): array
{
return [0, 0]; return [0, 0];
} }
public function getPreReqTurn():int{ public function getPreReqTurn(): int
{
return 0; return 0;
} }
public function getPostReqTurn():int{ public function getPostReqTurn(): int
{
return 0; return 0;
} }
public function getBrief():string{ public function getBrief(): string
{
$commandName = $this->getName(); $commandName = $this->getName();
$destNationName = getNationStaticInfo($this->arg['destNationID'])['name']; $destNationName = getNationStaticInfo($this->arg['destNationID'])['name'];
$year = $this->arg['year']; $year = $this->arg['year'];
@@ -159,8 +172,9 @@ class che_불가침수락 extends Command\NationCommand{
return "{$year}{$month}월까지 불가침 합의"; return "{$year}{$month}월까지 불가침 합의";
} }
public function run():bool{ public function run(): bool
if(!$this->isRunnable()){ {
if (!$this->hasFullConditionMet()) {
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -182,17 +196,22 @@ class che_불가침수락 extends Command\NationCommand{
$logger = $general->getLogger(); $logger = $general->getLogger();
$destLogger = $this->destGeneralObj->getLogger(); $destLogger = $this->destGeneralObj->getLogger();
$currentMonth = $env['year'] * 12 + $env['month'] - 1;
$reqMonth = $year *12 + $month - 1;
$db->update('diplomacy',[ $currentMonth = $env['year'] * 12 + $env['month'] - 1;
'state'=>7, $reqMonth = $year * 12 + $month - 1;
'term'=>$reqMonth - $currentMonth
], $db->update(
'(me=%i AND you=%i) OR (you=%i AND me=%i)', 'diplomacy',
$nationID, $destNationID, [
$nationID, $destNationID); 'state' => 7,
'term' => $reqMonth - $currentMonth
],
'(me=%i AND you=%i) OR (you=%i AND me=%i)',
$nationID,
$destNationID,
$nationID,
$destNationID
);
$josaWa = JosaUtil::pick($destNationName, '와'); $josaWa = JosaUtil::pick($destNationName, '와');
$logger->pushGeneralActionLog("<D><b>{$destNationName}</b></>{$josaWa} <C>$year</>년 <C>{$month}</>월까지 불가침에 성공했습니다.", ActionLogger::PLAIN); $logger->pushGeneralActionLog("<D><b>{$destNationName}</b></>{$josaWa} <C>$year</>년 <C>{$month}</>월까지 불가침에 성공했습니다.", ActionLogger::PLAIN);
@@ -208,4 +227,4 @@ class che_불가침수락 extends Command\NationCommand{
return true; return true;
} }
} }
@@ -1,9 +1,13 @@
<?php <?php
namespace sammo\Command\Nation; namespace sammo\Command\Nation;
use \sammo\{ use\sammo\{
DB, Util, JosaUtil, DB,
General, DummyGeneral, Util,
JosaUtil,
General,
DummyGeneral,
ActionLogger, ActionLogger,
GameConst, GameConst,
LastTurn, LastTurn,
@@ -14,9 +18,9 @@ use \sammo\{
Message, Message,
}; };
use function \sammo\{ use function\sammo\{
getDomesticExpLevelBonus, getDomesticExpLevelBonus,
CriticalRatioDomestic, CriticalRatioDomestic,
CriticalScoreEx, CriticalScoreEx,
getAllNationStaticInfo, getAllNationStaticInfo,
getNationStaticInfo, getNationStaticInfo,
@@ -26,85 +30,98 @@ use function \sammo\{
use \sammo\Constraint\Constraint; use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
class che_불가침제의 extends Command\NationCommand{ class che_불가침제의 extends Command\NationCommand
{
static protected $actionName = '불가침 제의'; static protected $actionName = '불가침 제의';
static public $reqArg = true; static public $reqArg = true;
protected function argTest():bool{ protected function argTest(): bool
if($this->arg === null){ {
if ($this->arg === null) {
return false; return false;
} }
//NOTE: 멸망 직전에 턴을 넣을 수 있으므로, 존재하지 않는 국가여도 argTest에서 바로 탈락시키지 않음 //NOTE: 멸망 직전에 턴을 넣을 수 있으므로, 존재하지 않는 국가여도 argTest에서 바로 탈락시키지 않음
if(!key_exists('destNationID', $this->arg)){ if (!key_exists('destNationID', $this->arg)) {
return false; return false;
} }
$destNationID = $this->arg['destNationID']; $destNationID = $this->arg['destNationID'];
if(!is_int($destNationID)){ if (!is_int($destNationID)) {
return false; return false;
} }
if($destNationID < 1){ if ($destNationID < 1) {
return false; return false;
} }
if(!key_exists('year', $this->arg) || !key_exists('month', $this->arg) ){ if (!key_exists('year', $this->arg) || !key_exists('month', $this->arg)) {
return false; return false;
} }
$year = $this->arg['year']; $year = $this->arg['year'];
$month = $this->arg['month']; $month = $this->arg['month'];
if(!is_int($year) || !is_int($month)){ if (!is_int($year) || !is_int($month)) {
return false; return false;
} }
if($month < 1 || 12 < $month){ if ($month < 1 || 12 < $month) {
return false; return false;
} }
if($year < $this->env['startyear']){ if ($year < $this->env['startyear']) {
return false; return false;
} }
$this->arg = [ $this->arg = [
'destNationID'=>$destNationID, 'destNationID' => $destNationID,
'year'=>$year, 'year' => $year,
'month'=>$month, 'month' => $month,
]; ];
return true; return true;
} }
protected function init(){ protected function init()
{
$general = $this->generalObj; $general = $this->generalObj;
$env = $this->env;
$relYear = $env['year'] - $env['startyear'];
$this->setCity(); $this->setCity();
$this->setNation(); $this->setNation();
$this->minConditionConstraints = [
ConstraintHelper::BeChief(),
ConstraintHelper::NotBeNeutral(),
];
}
protected function initWithArg()
{
$this->setDestNation($this->arg['destNationID'], null); $this->setDestNation($this->arg['destNationID'], null);
//NOTE: 개월에서 기한으로 바뀜 //NOTE: 개월에서 기한으로 바뀜
$year = $this->arg['year']; $year = $this->arg['year'];
$month = $this->arg['month']; $month = $this->arg['month'];
$env = $this->env;
$relYear = $env['year'] - $env['startyear'];
$currentMonth = $env['year'] * 12 + $env['month'] - 1; $currentMonth = $env['year'] * 12 + $env['month'] - 1;
$reqMonth = $year *12 + $month - 1; $reqMonth = $year * 12 + $month - 1;
$nationID = $this->nation['nation']; $nationID = $this->nation['nation'];
if ($reqMonth < $currentMonth + 12) { if ($reqMonth < $currentMonth + 12) {
$this->reservableConstraints = [ $this->permissionConstraints = [
ConstraintHelper::AlwaysFail('기한은 1년 이상이어야 합니다.') ConstraintHelper::AlwaysFail('기한은 1년 이상이어야 합니다.')
]; ];
$this->runnableConstraints = [ $this->fullConditionConstraints = [
ConstraintHelper::AlwaysFail('기한은 1년 이상이어야 합니다.') ConstraintHelper::AlwaysFail('기한은 1년 이상이어야 합니다.')
]; ];
return; return;
} }
$this->runnableConstraints=[ $this->fullConditionConstraints = [
ConstraintHelper::BeChief(), ConstraintHelper::BeChief(),
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
ConstraintHelper::ExistsDestNation(), ConstraintHelper::ExistsDestNation(),
ConstraintHelper::DisallowDiplomacyBetweenStatus([ ConstraintHelper::DisallowDiplomacyBetweenStatus([
0 => '아국과 이미 교전중입니다.', 0 => '아국과 이미 교전중입니다.',
@@ -115,22 +132,25 @@ class che_불가침제의 extends Command\NationCommand{
6 => '아국과 외교 진행중입니다.', 6 => '아국과 외교 진행중입니다.',
]), ]),
]; ];
} }
public function getCost():array{ public function getCost(): array
{
return [0, 0]; return [0, 0];
} }
public function getPreReqTurn():int{ public function getPreReqTurn(): int
{
return 0; return 0;
} }
public function getPostReqTurn():int{ public function getPostReqTurn(): int
{
return 0; return 0;
} }
public function getBrief():string{ public function getBrief(): string
{
$commandName = $this->getName(); $commandName = $this->getName();
$destNationName = getNationStaticInfo($this->arg['destNationID'])['name']; $destNationName = getNationStaticInfo($this->arg['destNationID'])['name'];
$year = $this->arg['year']; $year = $this->arg['year'];
@@ -139,8 +159,9 @@ class che_불가침제의 extends Command\NationCommand{
} }
public function run():bool{ public function run(): bool
if(!$this->isRunnable()){ {
if (!$this->hasFullConditionMet()) {
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -169,7 +190,7 @@ class che_불가침제의 extends Command\NationCommand{
// 상대에게 발송 // 상대에게 발송
$src = new MessageTarget( $src = new MessageTarget(
$general->getID(), $general->getID(),
$general->getName(), $general->getName(),
$nationID, $nationID,
$nationName, $nationName,
@@ -186,7 +207,7 @@ class che_불가침제의 extends Command\NationCommand{
$now = new \DateTime($date); $now = new \DateTime($date);
$validUntil = new \DateTime($date); $validUntil = new \DateTime($date);
$validMinutes = max(30, $env['turnterm']*3); $validMinutes = max(30, $env['turnterm'] * 3);
$validUntil->add(new \DateInterval("PT{$validMinutes}M")); $validUntil->add(new \DateInterval("PT{$validMinutes}M"));
$josaWa = JosaUtil::pick($nationName, '와'); $josaWa = JosaUtil::pick($nationName, '와');
@@ -199,9 +220,9 @@ class che_불가침제의 extends Command\NationCommand{
$now, $now,
$validUntil, $validUntil,
[ [
'action'=>DiplomaticMessage::TYPE_NO_AGGRESSION, 'action' => DiplomaticMessage::TYPE_NO_AGGRESSION,
'year'=>$year, 'year' => $year,
'month'=>$month, 'month' => $month,
] ]
); );
$msg->send(); $msg->send();
@@ -224,7 +245,7 @@ class che_불가침제의 extends Command\NationCommand{
{ {
$generalObj = $this->generalObj; $generalObj = $this->generalObj;
$nationID = $generalObj->getNationID(); $nationID = $generalObj->getNationID();
$db = DB::db(); $db = DB::db();
$currYear = $this->env['year']; $currYear = $this->env['year'];
@@ -235,57 +256,52 @@ class che_불가침제의 extends Command\NationCommand{
); );
$nationList = []; $nationList = [];
foreach(getAllNationStaticInfo() as $destNation){ foreach (getAllNationStaticInfo() as $destNation) {
if($destNation['nation'] == $nationID){ if ($destNation['nation'] == $nationID) {
continue; continue;
} }
$testCommand = new static($generalObj, $this->env, $this->getLastTurn(), [ $testCommand = new static($generalObj, $this->env, $this->getLastTurn(), [
'destNationID'=>$destNation['nation'], 'destNationID' => $destNation['nation'],
'year'=>$currYear+1, 'year' => $currYear + 1,
'month'=>12 'month' => 12
]); ]);
if(!$testCommand->isRunnable()){ if (!$testCommand->hasFullConditionMet()) {
$destNation['cssBgColor'] = 'background-color:red;'; $destNation['cssBgColor'] = 'background-color:red;';
} } else if ($diplomacyStatus[$destNation['nation']]['state'] == 7) {
else if($diplomacyStatus[$destNation['nation']]['state'] == 7){
$destNation['cssBgColor'] = 'background-color:blue;'; $destNation['cssBgColor'] = 'background-color:blue;';
} } else {
else{
$destNation['cssBgColor'] = ''; $destNation['cssBgColor'] = '';
} }
$nationList[] = $destNation; $nationList[] = $destNation;
} }
ob_start(); ob_start();
?> ?>
<?=\sammo\getMapHtml()?><br> <?= \sammo\getMapHtml() ?><br>
타국에게 불가침을 제의합니다.<br> 타국에게 불가침을 제의합니다.<br>
제의할 국가를 목록에서 선택하세요.<br> 제의할 국가를 목록에서 선택하세요.<br>
불가침 기한 다음 달부터 선포 가능합니다.<br> 불가침 기한 다음 달부터 선포 가능합니다.<br>
배경색은 현재 제의가 불가능한 국가는 <font color=red>붉은색</font>, 현재 불가침중인 국가는 <font color=blue>푸른색</font>으로 표시됩니다.<br> 배경색은 현재 제의가 불가능한 국가는 <font color=red>붉은색</font>, 현재 불가침중인 국가는 <font color=blue>푸른색</font>으로 표시됩니다.<br>
<br> <br>
<select class='formInput' name="destNationID" id="destNationID" size='1' style='color:white;background-color:black;'> <select class='formInput' name="destNationID" id="destNationID" size='1' style='color:white;background-color:black;'>
<?php foreach($nationList as $nation): ?> <?php foreach ($nationList as $nation) : ?>
<option <option value='<?= $nation['nation'] ?>' style='color:<?= $nation['color'] ?>;<?= $nation['cssBgColor'] ?>'>【<?= $nation['name'] ?> 】</option>
value='<?=$nation['nation']?>' <?php endforeach; ?>
style='color:<?=$nation['color']?>;<?=$nation['cssBgColor']?>' </select>에게
>【<?=$nation['name']?> 】</option> <select class='formInput' name="year" id="year" size='1' style='color:white;background-color:black;'>
<?php endforeach; ?> <?php foreach (Util::range($currYear + 1, $currYear + 20 + 1) as $formYear) : ?>
</select>에게 <option value='<?= $formYear ?>'><?= $formYear ?></option>
<select class='formInput' name="year" id="year" size='1' style='color:white;background-color:black;'> <?php endforeach; ?>
<?php foreach(Util::range($currYear+1, $currYear+20+1) as $formYear): ?> </select>년
<option value='<?=$formYear?>'><?=$formYear?></option> <select class='formInput' name="month" id="month" size='1' style='color:white;background-color:black;'>
<?php endforeach; ?> <?php foreach (Util::range(1, 12 + 1) as $formMonth) : ?>
</select>년 <option value='<?= $formMonth ?>'><?= $formMonth ?></option>
<select class='formInput' name="month" id="month" size='1' style='color:white;background-color:black;'> <?php endforeach; ?>
<?php foreach(Util::range(1, 12+1) as $formMonth): ?> </select>월까지
<option value='<?=$formMonth?>'><?=$formMonth?></option> <input type=button id="commonSubmit" value="<?= $this->getName() ?>">
<?php endforeach; ?>
</select>월까지
<input type=button id="commonSubmit" value="<?=$this->getName()?>">
<?php <?php
return ob_get_clean(); return ob_get_clean();
} }
} }
@@ -1,9 +1,13 @@
<?php <?php
namespace sammo\Command\Nation; namespace sammo\Command\Nation;
use \sammo\{ use\sammo\{
DB, Util, JosaUtil, DB,
General, DummyGeneral, Util,
JosaUtil,
General,
DummyGeneral,
ActionLogger, ActionLogger,
GameConst, GameConst,
LastTurn, LastTurn,
@@ -14,9 +18,9 @@ use \sammo\{
Message, Message,
}; };
use function \sammo\{ use function\sammo\{
getDomesticExpLevelBonus, getDomesticExpLevelBonus,
CriticalRatioDomestic, CriticalRatioDomestic,
CriticalScoreEx, CriticalScoreEx,
getAllNationStaticInfo, getAllNationStaticInfo,
getNationStaticInfo, getNationStaticInfo,
@@ -26,69 +30,69 @@ use function \sammo\{
use \sammo\Constraint\Constraint; use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
class che_불가침파기수락 extends Command\NationCommand{ class che_불가침파기수락 extends Command\NationCommand
{
static protected $actionName = '불가침 파기 수락'; static protected $actionName = '불가침 파기 수락';
static public $reqArg = true; static public $reqArg = true;
protected function argTest():bool{ protected function argTest(): bool
if($this->arg === null){ {
if ($this->arg === null) {
return false; return false;
} }
if(!key_exists('destNationID', $this->arg)){ if (!key_exists('destNationID', $this->arg)) {
return false; return false;
} }
$destNationID = $this->arg['destNationID']; $destNationID = $this->arg['destNationID'];
if(!is_int($destNationID)){ if (!is_int($destNationID)) {
return false; return false;
} }
if($destNationID < 1){ if ($destNationID < 1) {
return false; return false;
} }
if(!key_exists('destGeneralID', $this->arg)){ if (!key_exists('destGeneralID', $this->arg)) {
return false; return false;
} }
$destGeneralID = $this->arg['destGeneralID']; $destGeneralID = $this->arg['destGeneralID'];
if(!is_int($destGeneralID)){ if (!is_int($destGeneralID)) {
return false; return false;
} }
if($destGeneralID <= 0){ if ($destGeneralID <= 0) {
return false; return false;
} }
if($destGeneralID == $this->generalObj->getID()){ if ($destGeneralID == $this->generalObj->getID()) {
return false; return false;
} }
$this->arg = [ $this->arg = [
'destNationID'=>$destNationID, 'destNationID' => $destNationID,
'destGeneralID'=>$destGeneralID, 'destGeneralID' => $destGeneralID,
]; ];
return true; return true;
} }
protected function init(){ protected function init()
$general = $this->generalObj; {
$env = $this->env;
$relYear = $env['year'] - $env['startyear'];
$this->setCity(); $this->setCity();
$this->setNation(); $this->setNation();
$this->permissionConstraints = [
ConstraintHelper::AlwaysFail('예약 불가능 커맨드')
];
}
protected function initWithArg()
{
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], [], 1); $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], [], 1);
$this->setDestGeneral($destGeneral); $this->setDestGeneral($destGeneral);
$this->setDestNation($this->arg['destNationID']); $this->setDestNation($this->arg['destNationID']);
$nationID = $this->nation['nation'];
$this->reservableConstraints = [ $this->fullConditionConstraints = [
ConstraintHelper::AlwaysFail('예약 불가능 커맨드')
];
$this->runnableConstraints=[
ConstraintHelper::BeChief(), ConstraintHelper::BeChief(),
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
ConstraintHelper::ExistsDestNation(), ConstraintHelper::ExistsDestNation(),
ConstraintHelper::ExistsDestGeneral(), ConstraintHelper::ExistsDestGeneral(),
ConstraintHelper::ReqDestNationValue('nation', '소속', '==', $this->destGeneralObj->getNationID(), '제의 장수가 국가 소속이 아닙니다'), ConstraintHelper::ReqDestNationValue('nation', '소속', '==', $this->destGeneralObj->getNationID(), '제의 장수가 국가 소속이 아닙니다'),
@@ -97,29 +101,33 @@ class che_불가침파기수락 extends Command\NationCommand{
'불가침 중인 상대국에게만 가능합니다.' '불가침 중인 상대국에게만 가능합니다.'
), ),
]; ];
} }
public function getCost():array{ public function getCost(): array
{
return [0, 0]; return [0, 0];
} }
public function getPreReqTurn():int{ public function getPreReqTurn(): int
{
return 0; return 0;
} }
public function getPostReqTurn():int{ public function getPostReqTurn(): int
{
return 0; return 0;
} }
public function getBrief():string{ public function getBrief(): string
{
$commandName = $this->getName(); $commandName = $this->getName();
$destNationName = getNationStaticInfo($this->arg['destNationID'])['name']; $destNationName = getNationStaticInfo($this->arg['destNationID'])['name'];
return "{$destNationName}국과 불가침 파기 합의"; return "{$destNationName}국과 불가침 파기 합의";
} }
public function run():bool{ public function run(): bool
if(!$this->isRunnable()){ {
if (!$this->hasFullConditionMet()) {
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -140,13 +148,18 @@ class che_불가침파기수락 extends Command\NationCommand{
$logger = $general->getLogger(); $logger = $general->getLogger();
$destLogger = $this->destGeneralObj->getLogger(); $destLogger = $this->destGeneralObj->getLogger();
$db->update('diplomacy',[ $db->update(
'state'=>2, 'diplomacy',
'term'=>0 [
], 'state' => 2,
'(me=%i AND you=%i) OR (you=%i AND me=%i)', 'term' => 0
$nationID, $destNationID, ],
$nationID, $destNationID); '(me=%i AND you=%i) OR (you=%i AND me=%i)',
$nationID,
$destNationID,
$nationID,
$destNationID
);
$josaYiGeneral = JosaUtil::pick($generalName, '이'); $josaYiGeneral = JosaUtil::pick($generalName, '이');
$josaYiNation = JosaUtil::pick($nationName, '이'); $josaYiNation = JosaUtil::pick($nationName, '이');
@@ -168,4 +181,4 @@ class che_불가침파기수락 extends Command\NationCommand{
return true; return true;
} }
} }
@@ -60,9 +60,21 @@ class che_불가침파기제의 extends Command\NationCommand{
$this->setCity(); $this->setCity();
$this->setNation(); $this->setNation();
$this->minConditionConstraints=[
ConstraintHelper::BeChief(),
ConstraintHelper::NotBeNeutral(),
ConstraintHelper::OccupiedCity(),
ConstraintHelper::SuppliedCity(),
];
}
protected function initWithArg()
{
$this->setDestNation($this->arg['destNationID'], null); $this->setDestNation($this->arg['destNationID'], null);
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::BeChief(), ConstraintHelper::BeChief(),
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
@@ -96,7 +108,7 @@ class che_불가침파기제의 extends Command\NationCommand{
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
+77 -61
View File
@@ -1,20 +1,25 @@
<?php <?php
namespace sammo\Command\Nation; namespace sammo\Command\Nation;
use \sammo\{ use\sammo\{
DB, Util, JosaUtil, DB,
General, DummyGeneral, Util,
JosaUtil,
General,
DummyGeneral,
ActionLogger, ActionLogger,
GameConst, GameConst,
LastTurn, LastTurn,
GameUnitConst, GameUnitConst,
Command, Command,
Message, MessageTarget Message,
MessageTarget
}; };
use function \sammo\{ use function\sammo\{
getDomesticExpLevelBonus, getDomesticExpLevelBonus,
CriticalRatioDomestic, CriticalRatioDomestic,
CriticalScoreEx, CriticalScoreEx,
getAllNationStaticInfo, getAllNationStaticInfo,
getNationStaticInfo, getNationStaticInfo,
@@ -24,56 +29,67 @@ use function \sammo\{
use \sammo\Constraint\Constraint; use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
class che_선전포고 extends Command\NationCommand{ class che_선전포고 extends Command\NationCommand
{
static protected $actionName = '선전포고'; static protected $actionName = '선전포고';
static public $reqArg = true; static public $reqArg = true;
protected function argTest():bool{ protected function argTest(): bool
if($this->arg === null){ {
if ($this->arg === null) {
return false; return false;
} }
//NOTE: 멸망 직전에 턴을 넣을 수 있으므로, 존재하지 않는 국가여도 argTest에서 바로 탈락시키지 않음 //NOTE: 멸망 직전에 턴을 넣을 수 있으므로, 존재하지 않는 국가여도 argTest에서 바로 탈락시키지 않음
if(!key_exists('destNationID', $this->arg)){ if (!key_exists('destNationID', $this->arg)) {
return false; return false;
} }
$destNationID = $this->arg['destNationID']; $destNationID = $this->arg['destNationID'];
if(!is_int($destNationID)){ if (!is_int($destNationID)) {
return false; return false;
} }
if($destNationID < 1){ if ($destNationID < 1) {
return false; return false;
} }
$this->arg = [ $this->arg = [
'destNationID'=>$destNationID 'destNationID' => $destNationID
]; ];
return true; return true;
} }
protected function init(){ protected function init()
{
$general = $this->generalObj; $general = $this->generalObj;
$env = $this->env; $env = $this->env;
$relYear = $env['year'] - $env['startyear'];
$this->setCity(); $this->setCity();
$this->setNation(); $this->setNation();
$this->setDestNation($this->arg['destNationID'], null); $startYear = $this->env['startyear'];
$this->minConditionConstraints = [
if($relYear < 3 - 2){
$this->runnableConstraints = [
ConstraintHelper::AlwaysFail('초반제한 해제 2년전부터 가능합니다.')
];
return;
}
$this->runnableConstraints=[
ConstraintHelper::BeChief(), ConstraintHelper::BeChief(),
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
ConstraintHelper::SuppliedCity(), ConstraintHelper::SuppliedCity(),
ConstraintHelper::ReqEnvValue('year', '>=', $startYear + 1, '초반제한 해제 2년전부터 가능합니다.'),
];
}
protected function initWithArg()
{
$startYear = $this->env['startyear'];
$this->setDestNation($this->arg['destNationID'], null);
$this->fullConditionConstraints = [
ConstraintHelper::BeChief(),
ConstraintHelper::NotBeNeutral(),
ConstraintHelper::OccupiedCity(),
ConstraintHelper::SuppliedCity(),
ConstraintHelper::ReqEnvValue('year', '>=', $startYear + 1, '초반제한 해제 2년전부터 가능합니다.'),
ConstraintHelper::ExistsDestNation(), ConstraintHelper::ExistsDestNation(),
ConstraintHelper::NearNation(), ConstraintHelper::NearNation(),
ConstraintHelper::DisallowDiplomacyBetweenStatus([ ConstraintHelper::DisallowDiplomacyBetweenStatus([
@@ -86,30 +102,34 @@ class che_선전포고 extends Command\NationCommand{
5 => '상대국이 외교 진행중입니다.' 5 => '상대국이 외교 진행중입니다.'
]), ]),
]; ];
} }
public function getCost():array{ public function getCost(): array
{
return [0, 0]; return [0, 0];
} }
public function getPreReqTurn():int{ public function getPreReqTurn(): int
{
return 0; return 0;
} }
public function getPostReqTurn():int{ public function getPostReqTurn(): int
{
return 0; return 0;
} }
public function getBrief():string{ public function getBrief(): string
{
$commandName = $this->getName(); $commandName = $this->getName();
$destNationName = getNationStaticInfo($this->arg['destNationID'])['name']; $destNationName = getNationStaticInfo($this->arg['destNationID'])['name'];
return "{$destNationName}】에 {$commandName}"; return "{$destNationName}】에 {$commandName}";
} }
public function run():bool{ public function run(): bool
if(!$this->isRunnable()){ {
if (!$this->hasFullConditionMet()) {
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -143,15 +163,15 @@ class che_선전포고 extends Command\NationCommand{
$logger->pushGlobalHistoryLog("<R><b>【선포】</b></><D><b>{$nationName}</b></>{$josaYiNation} <D><b>{$destNationName}</b></>에 선전 포고 하였습니다."); $logger->pushGlobalHistoryLog("<R><b>【선포】</b></><D><b>{$nationName}</b></>{$josaYiNation} <D><b>{$destNationName}</b></>에 선전 포고 하였습니다.");
$db->update('diplomacy', [ $db->update('diplomacy', [
'state'=>1, 'state' => 1,
'term'=>24 'term' => 24
], '(me=%i AND you=%i) OR (me=%i AND you=%i)', $nationID, $destNationID, $destNationID, $nationID); ], '(me=%i AND you=%i) OR (me=%i AND you=%i)', $nationID, $destNationID, $destNationID, $nationID);
//국메로 저장 //국메로 저장
$text = "【외교】{$env['year']}{$env['month']}월:{$nationName}에서 {$destNationName}에 선전포고"; $text = "【외교】{$env['year']}{$env['month']}월:{$nationName}에서 {$destNationName}에 선전포고";
$src = new MessageTarget( $src = new MessageTarget(
$general->getID(), $general->getID(),
$general->getName(), $general->getName(),
$nationID, $nationID,
$nationName, $nationName,
@@ -166,7 +186,7 @@ class che_선전포고 extends Command\NationCommand{
$destNation['color'] $destNation['color']
); );
$msg = new Message( $msg = new Message(
Message::MSGTYPE_NATIONAL, Message::MSGTYPE_NATIONAL,
$src, $src,
$dest, $dest,
$text, $text,
@@ -197,40 +217,36 @@ class che_선전포고 extends Command\NationCommand{
$startYear = $this->env['startyear']; $startYear = $this->env['startyear'];
$availableYear = $startYear + 1; $availableYear = $startYear + 1;
$nationList = []; $nationList = [];
foreach(getAllNationStaticInfo() as $destNation){ foreach (getAllNationStaticInfo() as $destNation) {
if($destNation['nation'] == $nationID){ if ($destNation['nation'] == $nationID) {
continue; continue;
} }
$testCommand = new static($generalObj, $this->env, $this->getLastTurn(), ['destNationID'=>$destNation['nation']]); $testCommand = new static($generalObj, $this->env, $this->getLastTurn(), ['destNationID' => $destNation['nation']]);
if($testCommand->isRunnable()){ if ($testCommand->hasFullConditionMet()) {
$destNation['availableWar'] = true; $destNation['availableWar'] = true;
} } else {
else{
$destNation['availableWar'] = false; $destNation['availableWar'] = false;
} }
$nationList[] = $destNation; $nationList[] = $destNation;
} }
ob_start(); ob_start();
?> ?>
<?=\sammo\getMapHtml()?><br> <?= \sammo\getMapHtml() ?><br>
타국에게 선전 포고합니다.<br> 타국에게 선전 포고합니다.<br>
선전 포고할 국가를 목록에서 선택하세요.<br> 선전 포고할 국가를 목록에서 선택하세요.<br>
고립되지 않은 아국 도시에서 인접한 국가에 선포 가능합니다.<br> 고립되지 않은 아국 도시에서 인접한 국가에 선포 가능합니다.<br>
초반제한 해제 2년전부터 선포가 가능합니다. (<?=$availableYear?>년 1월부터 가능)<br> 초반제한 해제 2년전부터 선포가 가능합니다. (<?= $availableYear ?>년 1월부터 가능)<br>
현재 선포가 불가능한 국가는 배경색이 <font color=red>붉은색</font>으로 표시됩니다.<br> 현재 선포가 불가능한 국가는 배경색이 <font color=red>붉은색</font>으로 표시됩니다.<br>
<select class='formInput' name="destNationID" id="destNationID" size='1' style='color:white;background-color:black;'> <select class='formInput' name="destNationID" id="destNationID" size='1' style='color:white;background-color:black;'>
<?php foreach($nationList as $nation): ?> <?php foreach ($nationList as $nation) : ?>
<option <option value='<?= $nation['nation'] ?>' style='color:<?= $nation['color'] ?>;<?= $nation['availableWar'] ? '' : 'background-color:red;' ?>'>【<?= $nation['name'] ?> 】</option>
value='<?=$nation['nation']?>' <?php endforeach; ?>
style='color:<?=$nation['color']?>;<?=$nation['availableWar']?'':'background-color:red;'?>' </select>
>【<?=$nation['name']?> 】</option> <input type=button id="commonSubmit" value="<?= $this->getName() ?>">
<?php endforeach; ?>
</select>
<input type=button id="commonSubmit" value="<?=$this->getName()?>">
<?php <?php
return ob_get_clean(); return ob_get_clean();
} }
} }
+13 -3
View File
@@ -56,10 +56,20 @@ class che_수몰 extends Command\NationCommand{
$this->setCity(); $this->setCity();
$this->setNation(['strategic_cmd_limit']); $this->setNation(['strategic_cmd_limit']);
$this->setDestCity($this->arg['destCityID'], null);
$this->minConditionConstraints=[
ConstraintHelper::OccupiedCity(),
ConstraintHelper::BeChief(),
ConstraintHelper::AvailableStrategicCommand(),
];
}
protected function initWithArg()
{
$this->setDestCity($this->arg['destCityID']);
$this->setDestNation($this->destCity['nation']); $this->setDestNation($this->destCity['nation']);
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
ConstraintHelper::BeChief(), ConstraintHelper::BeChief(),
ConstraintHelper::NotNeutralDestCity(), ConstraintHelper::NotNeutralDestCity(),
@@ -101,7 +111,7 @@ class che_수몰 extends Command\NationCommand{
} }
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -25,7 +25,6 @@ use \sammo\Constraint\ConstraintHelper;
class che_의병모집 extends Command\NationCommand{ class che_의병모집 extends Command\NationCommand{
static protected $actionName = '의병모집'; static protected $actionName = '의병모집';
static public $reqArg = false;
protected function argTest():bool{ protected function argTest():bool{
$this->arg = null; $this->arg = null;
@@ -41,7 +40,7 @@ class che_의병모집 extends Command\NationCommand{
$env = $this->env; $env = $this->env;
$relYear = $env['year'] - $env['startyear']; $relYear = $env['year'] - $env['startyear'];
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::BeChief(), ConstraintHelper::BeChief(),
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
@@ -75,7 +74,7 @@ class che_의병모집 extends Command\NationCommand{
} }
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
+73 -55
View File
@@ -1,20 +1,25 @@
<?php <?php
namespace sammo\Command\Nation; namespace sammo\Command\Nation;
use \sammo\{ use\sammo\{
DB, Util, JosaUtil, DB,
General, DummyGeneral, Util,
JosaUtil,
General,
DummyGeneral,
ActionLogger, ActionLogger,
GameConst, GameConst,
LastTurn, LastTurn,
GameUnitConst, GameUnitConst,
Command, Command,
Message, MessageTarget Message,
MessageTarget
}; };
use function \sammo\{ use function\sammo\{
getDomesticExpLevelBonus, getDomesticExpLevelBonus,
CriticalRatioDomestic, CriticalRatioDomestic,
CriticalScoreEx, CriticalScoreEx,
getAllNationStaticInfo, getAllNationStaticInfo,
getNationStaticInfo, getNationStaticInfo,
@@ -24,34 +29,37 @@ use function \sammo\{
use \sammo\Constraint\Constraint; use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
class che_이호경식 extends Command\NationCommand{ class che_이호경식 extends Command\NationCommand
{
static protected $actionName = '이호경식'; static protected $actionName = '이호경식';
static public $reqArg = true; static public $reqArg = true;
protected function argTest():bool{ protected function argTest(): bool
if($this->arg === null){ {
if ($this->arg === null) {
return false; return false;
} }
//NOTE: 멸망 직전에 턴을 넣을 수 있으므로, 존재하지 않는 국가여도 argTest에서 바로 탈락시키지 않음 //NOTE: 멸망 직전에 턴을 넣을 수 있으므로, 존재하지 않는 국가여도 argTest에서 바로 탈락시키지 않음
if(!key_exists('destNationID', $this->arg)){ if (!key_exists('destNationID', $this->arg)) {
return false; return false;
} }
$destNationID = $this->arg['destNationID']; $destNationID = $this->arg['destNationID'];
if(!is_int($destNationID)){ if (!is_int($destNationID)) {
return false; return false;
} }
if($destNationID < 1){ if ($destNationID < 1) {
return false; return false;
} }
$this->arg = [ $this->arg = [
'destNationID'=>$destNationID 'destNationID' => $destNationID
]; ];
return true; return true;
} }
protected function init(){ protected function init()
{
$general = $this->generalObj; $general = $this->generalObj;
$env = $this->env; $env = $this->env;
@@ -59,9 +67,18 @@ class che_이호경식 extends Command\NationCommand{
$this->setCity(); $this->setCity();
$this->setNation(['strategic_cmd_limit']); $this->setNation(['strategic_cmd_limit']);
$this->minConditionConstraints = [
ConstraintHelper::OccupiedCity(),
ConstraintHelper::BeChief(),
ConstraintHelper::AvailableStrategicCommand(),
];
}
protected function initWithArg()
{
$this->setDestNation($this->arg['destNationID'], null); $this->setDestNation($this->arg['destNationID'], null);
$this->runnableConstraints=[ $this->fullConditionConstraints = [
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
ConstraintHelper::BeChief(), ConstraintHelper::BeChief(),
ConstraintHelper::ExistsDestNation(), ConstraintHelper::ExistsDestNation(),
@@ -71,42 +88,47 @@ class che_이호경식 extends Command\NationCommand{
), ),
ConstraintHelper::AvailableStrategicCommand(), ConstraintHelper::AvailableStrategicCommand(),
]; ];
} }
public function getCommandDetailTitle():string{ public function getCommandDetailTitle(): string
{
$name = $this->getName(); $name = $this->getName();
$reqTurn = $this->getPreReqTurn()+1; $reqTurn = $this->getPreReqTurn() + 1;
$postReqTurn = $this->getPostReqTurn(); $postReqTurn = $this->getPostReqTurn();
return "{$name}/{$reqTurn}턴(전략$postReqTurn)"; return "{$name}/{$reqTurn}턴(전략$postReqTurn)";
} }
public function getCost():array{ public function getCost(): array
{
return [0, 0]; return [0, 0];
} }
public function getPreReqTurn():int{ public function getPreReqTurn(): int
{
return 0; return 0;
} }
public function getPostReqTurn():int{ public function getPostReqTurn(): int
{
$genCount = Util::valueFit($this->nation['gennum'], GameConst::$initialNationGenLimit); $genCount = Util::valueFit($this->nation['gennum'], GameConst::$initialNationGenLimit);
$nextTerm = Util::round(sqrt($genCount*16)*10); $nextTerm = Util::round(sqrt($genCount * 16) * 10);
$nextTerm = $this->generalObj->onCalcStrategic($this->getName(), 'delay', $nextTerm); $nextTerm = $this->generalObj->onCalcStrategic($this->getName(), 'delay', $nextTerm);
return $nextTerm; return $nextTerm;
} }
public function getBrief():string{ public function getBrief(): string
{
$commandName = $this->getName(); $commandName = $this->getName();
$destNationName = getNationStaticInfo($this->arg['destNationID'])['name']; $destNationName = getNationStaticInfo($this->arg['destNationID'])['name'];
return "{$destNationName}】에 {$commandName}"; return "{$destNationName}】에 {$commandName}";
} }
public function run():bool{ public function run(): bool
if(!$this->isRunnable()){ {
if (!$this->hasFullConditionMet()) {
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -144,7 +166,7 @@ class che_이호경식 extends Command\NationCommand{
$broadcastMessage = "<Y>{$generalName}</>{$josaYi} <G><b>{$destNationName}</b></>에 <M>{$commandName}</>{$josaUl} 발동하였습니다."; $broadcastMessage = "<Y>{$generalName}</>{$josaYi} <G><b>{$destNationName}</b></>에 <M>{$commandName}</>{$josaUl} 발동하였습니다.";
$nationGeneralList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND no != %i', $nationID, $generalID); $nationGeneralList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND no != %i', $nationID, $generalID);
foreach($nationGeneralList as $nationGeneralID){ foreach ($nationGeneralList as $nationGeneralID) {
$nationGeneralLogger = new ActionLogger($nationGeneralID, $nationID, $year, $month); $nationGeneralLogger = new ActionLogger($nationGeneralID, $nationID, $year, $month);
$nationGeneralLogger->pushGeneralActionLog($broadcastMessage, ActionLogger::PLAIN); $nationGeneralLogger->pushGeneralActionLog($broadcastMessage, ActionLogger::PLAIN);
$nationGeneralLogger->flush(); $nationGeneralLogger->flush();
@@ -155,7 +177,7 @@ class che_이호경식 extends Command\NationCommand{
$broadcastMessage = "아국에 <M>{$commandName}</>{$josaYiCommand} 발동되었습니다."; $broadcastMessage = "아국에 <M>{$commandName}</>{$josaYiCommand} 발동되었습니다.";
$destNationGeneralList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND no != %i', $nationID, $generalID); $destNationGeneralList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND no != %i', $nationID, $generalID);
foreach($destNationGeneralList as $destNationGeneralID){ foreach ($destNationGeneralList as $destNationGeneralID) {
$destNationGeneralLogger = new ActionLogger($destNationGeneralID, $destNationID, $year, $month); $destNationGeneralLogger = new ActionLogger($destNationGeneralID, $destNationID, $year, $month);
$destNationGeneralLogger->pushGeneralActionLog($broadcastMessage, ActionLogger::PLAIN); $destNationGeneralLogger->pushGeneralActionLog($broadcastMessage, ActionLogger::PLAIN);
$destNationGeneralLogger->flush(); $destNationGeneralLogger->flush();
@@ -166,13 +188,13 @@ class che_이호경식 extends Command\NationCommand{
$destNationLogger->flush(); $destNationLogger->flush();
$logger->pushNationalHistoryLog("<Y>{$generalName}</>{$josaYi} <D><b>{$destNationName}</b></>에 <M>{$commandName}</>{$josaUl} 발동"); $logger->pushNationalHistoryLog("<Y>{$generalName}</>{$josaYi} <D><b>{$destNationName}</b></>에 <M>{$commandName}</>{$josaUl} 발동");
$db->update('nation', [ $db->update('nation', [
'strategic_cmd_limit' => $this->getPostReqTurn() 'strategic_cmd_limit' => $this->getPostReqTurn()
], 'nation=%i', $nationID); ], 'nation=%i', $nationID);
$db->update('diplomacy', [ $db->update('diplomacy', [
'term'=>$db->sqleval('IF(`state`=0, %i, `term`+ %i)', 3, 3), 'term' => $db->sqleval('IF(`state`=0, %i, `term`+ %i)', 3, 3),
'state'=>1, 'state' => 1,
], '(me = %i AND you = %i) OR (you = %i AND me = %i)', $nationID, $destNationID, $nationID, $destNationID); ], '(me = %i AND you = %i) OR (you = %i AND me = %i)', $nationID, $destNationID, $nationID, $destNationID);
$general->applyDB($db); $general->applyDB($db);
@@ -193,39 +215,35 @@ class che_이호경식 extends Command\NationCommand{
$nationID = $generalObj->getNationID(); $nationID = $generalObj->getNationID();
$nationList = []; $nationList = [];
$testTurn = new LastTurn($this->getName(), null, $this->getPreReqTurn()); $testTurn = new LastTurn($this->getName(), null, $this->getPreReqTurn());
foreach(getAllNationStaticInfo() as $destNation){ foreach (getAllNationStaticInfo() as $destNation) {
if($destNation['nation'] == $nationID){ if ($destNation['nation'] == $nationID) {
continue; continue;
} }
$testTurn->setArg(['destNationID'=>$destNation['nation']]); $testTurn->setArg(['destNationID' => $destNation['nation']]);
$testCommand = new static($generalObj, $this->env, $testTurn, ['destNationID'=>$destNation['nation']]); $testCommand = new static($generalObj, $this->env, $testTurn, ['destNationID' => $destNation['nation']]);
if($testCommand->isRunnable()){ if ($testCommand->hasFullConditionMet()) {
$destNation['availableCommand'] = true; $destNation['availableCommand'] = true;
} } else {
else{
$destNation['availableCommand'] = false; $destNation['availableCommand'] = false;
} }
$nationList[] = $destNation; $nationList[] = $destNation;
} }
ob_start(); ob_start();
?> ?>
<?=\sammo\getMapHtml()?><br> <?= \sammo\getMapHtml() ?><br>
선택된 국가에 이호경식을 발동합니다.<br> 선택된 국가에 이호경식을 발동합니다.<br>
선포, 전쟁중인 상대국에만 가능합니다.<br> 선포, 전쟁중인 상대국에만 가능합니다.<br>
상대 국가를 목록에서 선택하세요.<br> 상대 국가를 목록에서 선택하세요.<br>
배경색은 현재 이호경식 불가능 국가는 <font color=red>붉은색</font>으로 표시됩니다.<br> 배경색은 현재 이호경식 불가능 국가는 <font color=red>붉은색</font>으로 표시됩니다.<br>
<select class='formInput' name="destNationID" id="destNationID" size='1' style='color:white;background-color:black;'> <select class='formInput' name="destNationID" id="destNationID" size='1' style='color:white;background-color:black;'>
<?php foreach($nationList as $nation): ?> <?php foreach ($nationList as $nation) : ?>
<option <option value='<?= $nation['nation'] ?>' style='color:<?= $nation['color'] ?>;<?= $nation['availableCommand'] ? '' : 'background-color:red;' ?>'>【<?= $nation['name'] ?> 】</option>
value='<?=$nation['nation']?>' <?php endforeach; ?>
style='color:<?=$nation['color']?>;<?=$nation['availableCommand']?'':'background-color:red;'?>' <input type=button id="commonSubmit" value="<?= $this->getName() ?>">
>【<?=$nation['name']?> 】</option> <?php
<?php endforeach; ?>
<input type=button id="commonSubmit" value="<?=$this->getName()?>">
<?php
return ob_get_clean(); return ob_get_clean();
} }
} }
+62 -42
View File
@@ -1,9 +1,13 @@
<?php <?php
namespace sammo\Command\Nation; namespace sammo\Command\Nation;
use \sammo\{ use\sammo\{
DB, Util, JosaUtil, DB,
General, DummyGeneral, Util,
JosaUtil,
General,
DummyGeneral,
ActionLogger, ActionLogger,
GameConst, GameConst,
LastTurn, LastTurn,
@@ -14,9 +18,9 @@ use \sammo\{
Message, Message,
}; };
use function \sammo\{ use function\sammo\{
getDomesticExpLevelBonus, getDomesticExpLevelBonus,
CriticalRatioDomestic, CriticalRatioDomestic,
CriticalScoreEx, CriticalScoreEx,
getAllNationStaticInfo, getAllNationStaticInfo,
getNationStaticInfo, getNationStaticInfo,
@@ -26,48 +30,51 @@ use function \sammo\{
use \sammo\Constraint\Constraint; use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
class che_종전수락 extends Command\NationCommand{ class che_종전수락 extends Command\NationCommand
{
static protected $actionName = '종전 수락'; static protected $actionName = '종전 수락';
static public $reqArg = true; static public $reqArg = true;
protected function argTest():bool{ protected function argTest(): bool
if($this->arg === null){ {
if ($this->arg === null) {
return false; return false;
} }
if(!key_exists('destNationID', $this->arg)){ if (!key_exists('destNationID', $this->arg)) {
return false; return false;
} }
$destNationID = $this->arg['destNationID']; $destNationID = $this->arg['destNationID'];
if(!is_int($destNationID)){ if (!is_int($destNationID)) {
return false; return false;
} }
if($destNationID < 1){ if ($destNationID < 1) {
return false; return false;
} }
if(!key_exists('destGeneralID', $this->arg)){ if (!key_exists('destGeneralID', $this->arg)) {
return false; return false;
} }
$destGeneralID = $this->arg['destGeneralID']; $destGeneralID = $this->arg['destGeneralID'];
if(!is_int($destGeneralID)){ if (!is_int($destGeneralID)) {
return false; return false;
} }
if($destGeneralID <= 0){ if ($destGeneralID <= 0) {
return false; return false;
} }
if($destGeneralID == $this->generalObj->getID()){ if ($destGeneralID == $this->generalObj->getID()) {
return false; return false;
} }
$this->arg = [ $this->arg = [
'destNationID'=>$destNationID, 'destNationID' => $destNationID,
'destGeneralID'=>$destGeneralID, 'destGeneralID' => $destGeneralID,
]; ];
return true; return true;
} }
protected function init(){ protected function init()
{
$general = $this->generalObj; $general = $this->generalObj;
$env = $this->env; $env = $this->env;
@@ -76,19 +83,23 @@ class che_종전수락 extends Command\NationCommand{
$this->setCity(); $this->setCity();
$this->setNation(); $this->setNation();
$nationID = $this->nation['nation'];
$this->permissionConstraints = [
ConstraintHelper::AlwaysFail('예약 불가능 커맨드')
];
}
protected function initWithArg()
{
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], [], 1); $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], [], 1);
$this->setDestGeneral($destGeneral); $this->setDestGeneral($destGeneral);
$this->setDestNation($this->arg['destNationID']); $this->setDestNation($this->arg['destNationID']);
$nationID = $this->nation['nation']; $this->fullConditionConstraints = [
$this->reservableConstraints = [
ConstraintHelper::AlwaysFail('예약 불가능 커맨드')
];
$this->runnableConstraints=[
ConstraintHelper::BeChief(), ConstraintHelper::BeChief(),
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
ConstraintHelper::ExistsDestNation(), ConstraintHelper::ExistsDestNation(),
ConstraintHelper::ExistsDestGeneral(), ConstraintHelper::ExistsDestGeneral(),
ConstraintHelper::ReqDestNationValue('nation', '소속', '==', $this->destGeneralObj->getNationID(), '제의 장수가 국가 소속이 아닙니다'), ConstraintHelper::ReqDestNationValue('nation', '소속', '==', $this->destGeneralObj->getNationID(), '제의 장수가 국가 소속이 아닙니다'),
@@ -97,29 +108,33 @@ class che_종전수락 extends Command\NationCommand{
'상대국과 선포, 전쟁중이지 않습니다.' '상대국과 선포, 전쟁중이지 않습니다.'
), ),
]; ];
} }
public function getCost():array{ public function getCost(): array
{
return [0, 0]; return [0, 0];
} }
public function getPreReqTurn():int{ public function getPreReqTurn(): int
{
return 0; return 0;
} }
public function getPostReqTurn():int{ public function getPostReqTurn(): int
{
return 0; return 0;
} }
public function getBrief():string{ public function getBrief(): string
{
$commandName = $this->getName(); $commandName = $this->getName();
$destNationName = getNationStaticInfo($this->arg['destNationID'])['name']; $destNationName = getNationStaticInfo($this->arg['destNationID'])['name'];
return "{$destNationName}국과 종전 합의"; return "{$destNationName}국과 종전 합의";
} }
public function run():bool{ public function run(): bool
if(!$this->isRunnable()){ {
if (!$this->hasFullConditionMet()) {
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -140,13 +155,18 @@ class che_종전수락 extends Command\NationCommand{
$logger = $general->getLogger(); $logger = $general->getLogger();
$destLogger = $this->destGeneralObj->getLogger(); $destLogger = $this->destGeneralObj->getLogger();
$db->update('diplomacy',[ $db->update(
'state'=>2, 'diplomacy',
'term'=>0 [
], 'state' => 2,
'(me=%i AND you=%i) OR (you=%i AND me=%i)', 'term' => 0
$nationID, $destNationID, ],
$nationID, $destNationID); '(me=%i AND you=%i) OR (you=%i AND me=%i)',
$nationID,
$destNationID,
$nationID,
$destNationID
);
$josaYiGeneral = JosaUtil::pick($generalName, '이'); $josaYiGeneral = JosaUtil::pick($generalName, '이');
$josaYiNation = JosaUtil::pick($nationName, '이'); $josaYiNation = JosaUtil::pick($nationName, '이');
@@ -168,4 +188,4 @@ class che_종전수락 extends Command\NationCommand{
return true; return true;
} }
} }
+13 -3
View File
@@ -60,9 +60,20 @@ class che_종전제의 extends Command\NationCommand{
$this->setCity(); $this->setCity();
$this->setNation(); $this->setNation();
$this->minConditionConstraints=[
ConstraintHelper::BeChief(),
ConstraintHelper::NotBeNeutral(),
ConstraintHelper::OccupiedCity(),
ConstraintHelper::SuppliedCity(),
];
}
protected function initWithArg()
{
$this->setDestNation($this->arg['destNationID'], null); $this->setDestNation($this->arg['destNationID'], null);
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::BeChief(), ConstraintHelper::BeChief(),
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
@@ -73,7 +84,6 @@ class che_종전제의 extends Command\NationCommand{
'선포, 전쟁중인 상대국에게만 가능합니다.' '선포, 전쟁중인 상대국에게만 가능합니다.'
), ),
]; ];
} }
public function getCost():array{ public function getCost():array{
@@ -96,7 +106,7 @@ class che_종전제의 extends Command\NationCommand{
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
+5 -6
View File
@@ -28,7 +28,6 @@ use sammo\Event\Action;
class che_증축 extends Command\NationCommand{ class che_증축 extends Command\NationCommand{
static protected $actionName = '증축'; static protected $actionName = '증축';
static public $reqArg = false;
protected function argTest():bool{ protected function argTest():bool{
$this->arg = []; $this->arg = [];
@@ -42,10 +41,10 @@ class che_증축 extends Command\NationCommand{
$env = $this->env; $env = $this->env;
if($general->getNationID()===0){ if($general->getNationID()===0){
$this->reservableConstraints=[ $this->permissionConstraints=[
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
]; ];
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
]; ];
return; return;
@@ -53,11 +52,11 @@ class che_증축 extends Command\NationCommand{
$this->setCity(); $this->setCity();
$this->setNation(['gold', 'rice', 'capset', 'capital']); $this->setNation(['gold', 'rice', 'capset', 'capital']);
$this->setDestCity($this->nation['capital'], null); $this->setDestCity($this->nation['capital']);
[$reqGold, $reqRice] = $this->getCost(); [$reqGold, $reqRice] = $this->getCost();
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
ConstraintHelper::BeChief(), ConstraintHelper::BeChief(),
ConstraintHelper::SuppliedCity(), ConstraintHelper::SuppliedCity(),
@@ -135,7 +134,7 @@ class che_증축 extends Command\NationCommand{
} }
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
+76 -53
View File
@@ -1,9 +1,13 @@
<?php <?php
namespace sammo\Command\Nation; namespace sammo\Command\Nation;
use \sammo\{ use\sammo\{
DB, Util, JosaUtil, DB,
General, DummyGeneral, Util,
JosaUtil,
General,
DummyGeneral,
ActionLogger, ActionLogger,
GameConst, GameConst,
LastTurn, LastTurn,
@@ -14,110 +18,127 @@ use \sammo\{
CityConst CityConst
}; };
use function \sammo\{ use function\sammo\{
getDomesticExpLevelBonus, getDomesticExpLevelBonus,
CriticalRatioDomestic, CriticalRatioDomestic,
CriticalScoreEx, CriticalScoreEx,
GetImageURL, GetImageURL,
getNationStaticInfo getNationStaticInfo
}; };
use \sammo\Constraint\Constraint; use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
use sammo\Event\Action; use sammo\Event\Action;
class che_천도 extends Command\NationCommand{ class che_천도 extends Command\NationCommand
{
static protected $actionName = '천도'; static protected $actionName = '천도';
static public $reqArg = true; static public $reqArg = true;
private $cachedDist = null; private $cachedDist = null;
protected function argTest():bool{ protected function argTest(): bool
if($this->arg === null){ {
if ($this->arg === null) {
return false; return false;
} }
if(!key_exists('destCityID', $this->arg)){ if (!key_exists('destCityID', $this->arg)) {
return false; return false;
} }
if(CityConst::byID($this->arg['destCityID']) === null){ if (CityConst::byID($this->arg['destCityID']) === null) {
return false; return false;
} }
$destCityID = $this->arg['destCityID']; $destCityID = $this->arg['destCityID'];
$this->arg = [ $this->arg = [
'destCityID'=>$destCityID, 'destCityID' => $destCityID,
]; ];
return true; return true;
} }
protected function init(){ protected function init()
{
$general = $this->generalObj; $general = $this->generalObj;
$env = $this->env; $env = $this->env;
$this->setCity(); $this->setCity();
$this->setNation(['capset', 'gold', 'rice', 'capital']); $this->setNation(['capset', 'gold', 'rice', 'capital']);
$this->setDestCity($this->arg['destCityID'], null);
$this->minConditionConstraints = [
ConstraintHelper::OccupiedCity(),
ConstraintHelper::BeChief(),
ConstraintHelper::SuppliedCity(),
];
}
protected function initWithArg()
{
$this->setDestCity($this->arg['destCityID']);
[$reqGold, $reqRice] = $this->getCost(); [$reqGold, $reqRice] = $this->getCost();
if($this->getDistance() === null){ if ($this->getDistance() === null) {
$this->runnableConstraints[ $this->fullConditionConstraints[ConstraintHelper::AlwaysFail('천도 대상으로 도달할 방법이 없습니다.')];
ConstraintHelper::AlwaysFail('천도 대상으로 도달할 방법이 없습니다.')
];
return; return;
} }
$this->runnableConstraints=[ $this->fullConditionConstraints = [
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
ConstraintHelper::OccupiedDestCity(), ConstraintHelper::OccupiedDestCity(),
ConstraintHelper::BeChief(), ConstraintHelper::BeChief(),
ConstraintHelper::SuppliedCity(), ConstraintHelper::SuppliedCity(),
ConstraintHelper::SuppliedDestCity(), ConstraintHelper::SuppliedDestCity(),
ConstraintHelper::ReqNationValue('capital', '수도', '!=', $this->destCity['city'], '이미 수도입니다.'), ConstraintHelper::ReqNationValue('capital', '수도', '!=', $this->destCity['city'], '이미 수도입니다.'),
ConstraintHelper::ReqNationGold(GameConst::$basegold+$reqGold), ConstraintHelper::ReqNationGold(GameConst::$basegold + $reqGold),
ConstraintHelper::ReqNationRice(GameConst::$baserice+$reqRice), ConstraintHelper::ReqNationRice(GameConst::$baserice + $reqRice),
]; ];
} }
public function getCommandDetailTitle():string{ public function getCommandDetailTitle(): string
{
$name = $this->getName(); $name = $this->getName();
$amount = number_format($this->env['develcost'] * 5); $amount = number_format($this->env['develcost'] * 5);
return "{$name}/1+거리×2턴(금쌀 {$amount}×2^거리)"; return "{$name}/1+거리×2턴(금쌀 {$amount}×2^거리)";
} }
public function getCost():array{ public function getCost(): array
{
$amount = $this->env['develcost'] * 5; $amount = $this->env['develcost'] * 5;
$amount *= 2**$this->getDistance()??50; $amount *= 2 ** $this->getDistance() ?? 50;
return [$amount, $amount]; return [$amount, $amount];
} }
private function getDistance():?int{ private function getDistance(): ?int
if($this->cachedDist !== null){ {
if ($this->cachedDist !== null) {
return $this->cachedDist; return $this->cachedDist;
} }
$srcCityID = $this->nation['capital']; $srcCityID = $this->nation['capital'];
$destCityID = $this->arg['destCityID']; $destCityID = $this->arg['destCityID'];
$nationID = $this->nation['nation']; $nationID = $this->nation['nation'];
$distance = \sammo\calcCityDistance($srcCityID, $destCityID, [$nationID])??50; $distance = \sammo\calcCityDistance($srcCityID, $destCityID, [$nationID]) ?? 50;
$this->cachedDist = $distance; $this->cachedDist = $distance;
return $distance; return $distance;
} }
public function getPreReqTurn():int{ public function getPreReqTurn(): int
return $this->getDistance()*2; {
return $this->getDistance() * 2;
} }
public function getPostReqTurn():int{ public function getPostReqTurn(): int
{
return 0; return 0;
} }
public function addTermStack():bool{ public function addTermStack(): bool
{
$lastTurn = $this->getLastTurn(); $lastTurn = $this->getLastTurn();
$commandName = $this->getName(); $commandName = $this->getName();
@@ -126,7 +147,7 @@ class che_천도 extends Command\NationCommand{
$nationID = $general->getNationID(); $nationID = $general->getNationID();
$nationStor->setValue("last천도Trial_{$nationID}", [$general->getVar('officer_level'), $general->getTurnTime()]); $nationStor->setValue("last천도Trial_{$nationID}", [$general->getVar('officer_level'), $general->getTurnTime()]);
if($lastTurn->getCommand() != $commandName || $lastTurn->getArg() !== $this->arg){ if ($lastTurn->getCommand() != $commandName || $lastTurn->getArg() !== $this->arg) {
$this->setResultTurn(new LastTurn( $this->setResultTurn(new LastTurn(
$commandName, $commandName,
$this->arg, $this->arg,
@@ -136,7 +157,7 @@ class che_천도 extends Command\NationCommand{
return false; return false;
} }
if($lastTurn->getSeq() < $this->nation['capset']){ if ($lastTurn->getSeq() < $this->nation['capset']) {
//NOTE: 최근에 천도, 증축이 일어났으면 리셋됨 //NOTE: 최근에 천도, 증축이 일어났으면 리셋됨
$this->setResultTurn(new LastTurn( $this->setResultTurn(new LastTurn(
$commandName, $commandName,
@@ -147,7 +168,7 @@ class che_천도 extends Command\NationCommand{
return false; return false;
} }
if($lastTurn->getTerm() < $this->getPreReqTurn()){ if ($lastTurn->getTerm() < $this->getPreReqTurn()) {
$this->setResultTurn(new LastTurn( $this->setResultTurn(new LastTurn(
$commandName, $commandName,
$this->arg, $this->arg,
@@ -160,15 +181,17 @@ class che_천도 extends Command\NationCommand{
return true; return true;
} }
public function getBrief():string{ public function getBrief(): string
{
$commandName = $this->getName(); $commandName = $this->getName();
$destCityName = CityConst::byID($this->arg['destCityID'])->name; $destCityName = CityConst::byID($this->arg['destCityID'])->name;
$josaRo = JosaUtil::pick($destCityName, '로'); $josaRo = JosaUtil::pick($destCityName, '로');
return "{$destCityName}{$josaRo} {$commandName}"; return "{$destCityName}{$josaRo} {$commandName}";
} }
public function run():bool{ public function run(): bool
if(!$this->isRunnable()){ {
if (!$this->hasFullConditionMet()) {
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -192,7 +215,7 @@ class che_천도 extends Command\NationCommand{
$josaRo = JosaUtil::pick($destCityName, '로'); $josaRo = JosaUtil::pick($destCityName, '로');
$logger = $general->getLogger(); $logger = $general->getLogger();
$general->addExperience(5 * ($this->getPreReqTurn() + 1)); $general->addExperience(5 * ($this->getPreReqTurn() + 1));
$general->addDedication(5 * ($this->getPreReqTurn() + 1)); $general->addDedication(5 * ($this->getPreReqTurn() + 1));
@@ -204,7 +227,7 @@ class che_천도 extends Command\NationCommand{
'capital' => $destCityID, 'capital' => $destCityID,
'capset' => $db->sqleval('capset + 1'), 'capset' => $db->sqleval('capset + 1'),
], 'nation=%i', $nationID); ], 'nation=%i', $nationID);
$logger->pushGeneralActionLog("<G><b>{$destCityName}</b></>{$josaRo} 천도했습니다. <1>$date</>"); $logger->pushGeneralActionLog("<G><b>{$destCityName}</b></>{$josaRo} 천도했습니다. <1>$date</>");
$logger->pushGeneralHistoryLog("<G><b>{$destCityName}</b></>{$josaRo} <M>천도</>명령"); $logger->pushGeneralHistoryLog("<G><b>{$destCityName}</b></>{$josaRo} <M>천도</>명령");
$logger->pushNationalHistoryLog("<Y>{$generalName}</>{$josaYi} <G><b>{$destCityName}</b></>{$josaRo} <M>천도</> 명령"); $logger->pushNationalHistoryLog("<Y>{$generalName}</>{$josaYi} <G><b>{$destCityName}</b></>{$josaRo} <M>천도</> 명령");
@@ -228,15 +251,15 @@ class che_천도 extends Command\NationCommand{
{ {
ob_start(); ob_start();
?> ?>
<?=\sammo\getMapHtml()?><br> <?= \sammo\getMapHtml() ?><br>
선택된 도시로 천도합니다.<br> 선택된 도시로 천도합니다.<br>
현재 수도에서 연결된 도시만 가능하며, 1+2×거리만큼의 턴이 필요합니다.<br> 현재 수도에서 연결된 도시만 가능하며, 1+2×거리만큼의 턴이 필요합니다.<br>
목록을 선택하거나 도시를 클릭하세요.<br> 목록을 선택하거나 도시를 클릭하세요.<br>
<select class='formInput' name="destCityID" id="destCityID" size='1' style='color:white;background-color:black;'> <select class='formInput' name="destCityID" id="destCityID" size='1' style='color:white;background-color:black;'>
<?=\sammo\optionsForCities()?><br> <?= \sammo\optionsForCities() ?><br>
</select> <input type=button id="commonSubmit" value="<?=$this->getName()?>"><br> </select> <input type=button id="commonSubmit" value="<?= $this->getName() ?>"><br>
<br> <br>
<?php <?php
return ob_get_clean(); return ob_get_clean();
} }
} }
+14 -3
View File
@@ -58,9 +58,20 @@ class che_초토화 extends Command\NationCommand{
$this->setCity(); $this->setCity();
$this->setNation(['surlimit', 'gold', 'rice', 'capital']); $this->setNation(['surlimit', 'gold', 'rice', 'capital']);
$this->setDestCity($this->arg['destCityID'], null);
$this->runnableConstraints=[ $this->minConditionConstraints=[
ConstraintHelper::OccupiedCity(),
ConstraintHelper::BeChief(),
ConstraintHelper::SuppliedCity(),
ConstraintHelper::ReqNationValue('surlimit', '제한 턴', '==', 0, '외교제한 턴이 남아있습니다.'),
];
}
protected function initWithArg()
{
$this->setDestCity($this->arg['destCityID']);
$this->fullConditionConstraints=[
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
ConstraintHelper::OccupiedDestCity(), ConstraintHelper::OccupiedDestCity(),
ConstraintHelper::BeChief(), ConstraintHelper::BeChief(),
@@ -102,7 +113,7 @@ class che_초토화 extends Command\NationCommand{
} }
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
+95 -74
View File
@@ -1,9 +1,13 @@
<?php <?php
namespace sammo\Command\Nation; namespace sammo\Command\Nation;
use \sammo\{ use\sammo\{
DB, Util, JosaUtil, DB,
General, DummyGeneral, Util,
JosaUtil,
General,
DummyGeneral,
ActionLogger, ActionLogger,
GameConst, GameConst,
LastTurn, LastTurn,
@@ -11,114 +15,131 @@ use \sammo\{
Command Command
}; };
use function \sammo\{ use function\sammo\{
getDomesticExpLevelBonus, getDomesticExpLevelBonus,
CriticalRatioDomestic, CriticalRatioDomestic,
CriticalScoreEx CriticalScoreEx
}; };
use \sammo\Constraint\Constraint; use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
class che_포상 extends Command\NationCommand{ class che_포상 extends Command\NationCommand
{
static protected $actionName = '포상'; static protected $actionName = '포상';
static public $reqArg = true; static public $reqArg = true;
protected function argTest():bool{ protected function argTest(): bool
if($this->arg === null){ {
if ($this->arg === null) {
return false; return false;
} }
//NOTE: 사망 직전에 '포상' 턴을 넣을 수 있으므로, 존재하지 않는 장수여도 argTest에서 바로 탈락시키지 않음 //NOTE: 사망 직전에 '포상' 턴을 넣을 수 있으므로, 존재하지 않는 장수여도 argTest에서 바로 탈락시키지 않음
if(!key_exists('isGold', $this->arg)){ if (!key_exists('isGold', $this->arg)) {
return false; return false;
} }
if(!key_exists('amount', $this->arg)){ if (!key_exists('amount', $this->arg)) {
return false; return false;
} }
if(!key_exists('destGeneralID', $this->arg)){ if (!key_exists('destGeneralID', $this->arg)) {
return false; return false;
} }
$isGold = $this->arg['isGold']; $isGold = $this->arg['isGold'];
$amount = $this->arg['amount']; $amount = $this->arg['amount'];
$destGeneralID = $this->arg['destGeneralID']; $destGeneralID = $this->arg['destGeneralID'];
if(!is_numeric($amount)){ if (!is_numeric($amount)) {
return false; return false;
} }
$amount = Util::round($amount, -2); $amount = Util::round($amount, -2);
$amount = Util::valueFit($amount, 100, GameConst::$maxResourceActionAmount); $amount = Util::valueFit($amount, 100, GameConst::$maxResourceActionAmount);
if($amount <= 0){ if ($amount <= 0) {
return false; return false;
} }
if(!is_bool($isGold)){ if (!is_bool($isGold)) {
return false; return false;
} }
if(!is_int($destGeneralID)){ if (!is_int($destGeneralID)) {
return false; return false;
} }
if($destGeneralID <= 0){ if ($destGeneralID <= 0) {
return false; return false;
} }
if($destGeneralID == $this->generalObj->getID()){ if ($destGeneralID == $this->generalObj->getID()) {
return false; return false;
} }
$this->arg = [ $this->arg = [
'isGold'=>$isGold, 'isGold' => $isGold,
'amount'=>$amount, 'amount' => $amount,
'destGeneralID'=>$destGeneralID 'destGeneralID' => $destGeneralID
]; ];
return true; return true;
} }
protected function init(){ protected function init()
{
$general = $this->generalObj; $general = $this->generalObj;
$this->setCity(); $this->setCity();
$this->setNation(['gold', 'rice']); $this->setNation(['gold', 'rice']);
$this->minConditionConstraints = [
ConstraintHelper::NotBeNeutral(),
ConstraintHelper::OccupiedCity(),
ConstraintHelper::BeChief(),
ConstraintHelper::SuppliedCity(),
];
}
protected function initWithArg()
{
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['gold', 'rice', 'nation'], 1); $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['gold', 'rice', 'nation'], 1);
$this->setDestGeneral($destGeneral); $this->setDestGeneral($destGeneral);
$this->runnableConstraints=[ $this->fullConditionConstraints = [
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
ConstraintHelper::BeChief(), ConstraintHelper::BeChief(),
ConstraintHelper::SuppliedCity(), ConstraintHelper::SuppliedCity(),
ConstraintHelper::ExistsDestGeneral(), ConstraintHelper::ExistsDestGeneral(),
ConstraintHelper::FriendlyDestGeneral() ConstraintHelper::FriendlyDestGeneral()
]; ];
if($this->arg['isGold']){ if ($this->arg['isGold']) {
$this->runnableConstraints[] = ConstraintHelper::ReqNationGold(1+GameConst::$basegold); $this->fullConditionConstraints[] = ConstraintHelper::ReqNationGold(1 + GameConst::$basegold);
} } else {
else{ $this->fullConditionConstraints[] = ConstraintHelper::ReqNationRice(1 + GameConst::$baserice);
$this->runnableConstraints[] = ConstraintHelper::ReqNationRice(1+GameConst::$baserice);
} }
} }
public function getCost():array{ public function getCost(): array
{
return [0, 0]; return [0, 0];
} }
public function getPreReqTurn():int{ public function getPreReqTurn(): int
{
return 0; return 0;
} }
public function getPostReqTurn():int{ public function getPostReqTurn(): int
{
return 0; return 0;
} }
public function getBrief():string{ public function getBrief(): string
{
$isGold = $this->arg['isGold']; $isGold = $this->arg['isGold'];
$amount = $this->arg['amount']; $amount = $this->arg['amount'];
$amountText = number_format($amount, 0); $amountText = number_format($amount, 0);
$resName = $isGold?'금':'쌀'; $resName = $isGold ? '금' : '쌀';
$destGeneral = $this->destGeneralObj; $destGeneral = $this->destGeneralObj;
$commandName = $this->getName(); $commandName = $this->getName();
return "{$destGeneral->getName()}{$resName} $amountText {$commandName}"; return "{$destGeneral->getName()}{$resName} $amountText {$commandName}";
} }
public function run():bool{ public function run(): bool
if(!$this->isRunnable()){ {
if (!$this->hasFullConditionMet()) {
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -132,22 +153,22 @@ class che_포상 extends Command\NationCommand{
$isGold = $this->arg['isGold']; $isGold = $this->arg['isGold'];
$amount = $this->arg['amount']; $amount = $this->arg['amount'];
$resKey = $isGold?'gold':'rice'; $resKey = $isGold ? 'gold' : 'rice';
$resName = $isGold?'금':'쌀'; $resName = $isGold ? '금' : '쌀';
$destGeneral = $this->destGeneralObj; $destGeneral = $this->destGeneralObj;
$amount = Util::valueFit( $amount = Util::valueFit(
$amount, $amount,
0, 0,
$nation[$resKey] - ($isGold?GameConst::$basegold:GameConst::$baserice) $nation[$resKey] - ($isGold ? GameConst::$basegold : GameConst::$baserice)
); );
$amountText = number_format($amount, 0); $amountText = number_format($amount, 0);
$logger = $general->getLogger(); $logger = $general->getLogger();
$destGeneral->increaseVar($resKey, $amount); $destGeneral->increaseVar($resKey, $amount);
$db->update('nation', [ $db->update('nation', [
$resKey=>$db->sqleval('%b - %i', $resKey, $amount) $resKey => $db->sqleval('%b - %i', $resKey, $amount)
], 'nation=%i', $nationID); ], 'nation=%i', $nationID);
$destGeneral->getLogger()->pushGeneralActionLog("{$resName} <C>{$amountText}</>을 포상으로 받았습니다.", ActionLogger::PLAIN); $destGeneral->getLogger()->pushGeneralActionLog("{$resName} <C>{$amountText}</>을 포상으로 받았습니다.", ActionLogger::PLAIN);
@@ -160,53 +181,53 @@ class che_포상 extends Command\NationCommand{
return true; return true;
} }
public function getForm(): string public function getForm(): string
{ {
//TODO: 암행부처럼 보여야... //TODO: 암행부처럼 보여야...
$db = DB::db(); $db = DB::db();
$destRawGenerals = $db->query('SELECT no,name,officer_level,npc,gold,rice FROM general WHERE nation = %i AND no != %i ORDER BY npc,binary(name)',$this->generalObj->getNationID(), $this->generalObj->getID()); $destRawGenerals = $db->query('SELECT no,name,officer_level,npc,gold,rice FROM general WHERE nation = %i AND no != %i ORDER BY npc,binary(name)', $this->generalObj->getNationID(), $this->generalObj->getID());
$destGeneralList = []; $destGeneralList = [];
foreach($destRawGenerals as $destGeneral){ foreach ($destRawGenerals as $destGeneral) {
$nameColor = \sammo\getNameColor($destGeneral['npc']); $nameColor = \sammo\getNameColor($destGeneral['npc']);
if($nameColor){ if ($nameColor) {
$nameColor = " style='color:{$nameColor}'"; $nameColor = " style='color:{$nameColor}'";
} }
$name = $destGeneral['name']; $name = $destGeneral['name'];
if($destGeneral['officer_level'] >= 5){ if ($destGeneral['officer_level'] >= 5) {
$name = "*{$name}*"; $name = "*{$name}*";
} }
$destGeneralList[] = [ $destGeneralList[] = [
'no'=>$destGeneral['no'], 'no' => $destGeneral['no'],
'color'=>$nameColor, 'color' => $nameColor,
'name'=>$name, 'name' => $name,
'gold'=>$destGeneral['gold'], 'gold' => $destGeneral['gold'],
'rice'=>$destGeneral['rice'] 'rice' => $destGeneral['rice']
]; ];
} }
ob_start(); ob_start();
?> ?>
국고로 장수에게 자금이나 군량을 지급합니다.<br> 국고로 장수에게 자금이나 군량을 지급합니다.<br>
<select class='formInput' name="destGeneralID" id="destGeneralID" size='1' style='color:white;background-color:black;'> <select class='formInput' name="destGeneralID" id="destGeneralID" size='1' style='color:white;background-color:black;'>
<?php foreach($destGeneralList as $destGeneral): ?> <?php foreach ($destGeneralList as $destGeneral) : ?>
<option value='<?=$destGeneral['no']?>' <?=$destGeneral['color']?>><?=$destGeneral['name']?>(금:<?=$destGeneral['gold']?>, 쌀:<?=$destGeneral['rice']?>)</option> <option value='<?= $destGeneral['no'] ?>' <?= $destGeneral['color'] ?>><?= $destGeneral['name'] ?>(금:<?= $destGeneral['gold'] ?>, 쌀:<?= $destGeneral['rice'] ?>)</option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
<select class='formInput' name="isGold" id="isGold" size='1' style='color:white;background-color:black;'> <select class='formInput' name="isGold" id="isGold" size='1' style='color:white;background-color:black;'>
<option value="true">금</option> <option value="true">금</option>
<option value="false">쌀</option> <option value="false">쌀</option>
</select> </select>
</select> </select>
<select class='formInput' name="amount" id="amount" size='1' style='color:white;background-color:black;'> <select class='formInput' name="amount" id="amount" size='1' style='color:white;background-color:black;'>
<?php foreach(GameConst::$resourceActionAmountGuide as $amount): ?> <?php foreach (GameConst::$resourceActionAmountGuide as $amount) : ?>
<option value='<?=$amount?>'><?=$amount?></option> <option value='<?= $amount ?>'><?= $amount ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> <input type=button id="commonSubmit" value="<?=$this->getName()?>"><br> </select> <input type=button id="commonSubmit" value="<?= $this->getName() ?>"><br>
<br> <br>
<?php <?php
return ob_get_clean(); return ob_get_clean();
} }
} }
+12 -4
View File
@@ -60,9 +60,18 @@ class che_피장파장 extends Command\NationCommand{
$this->setCity(); $this->setCity();
$this->setNation(['strategic_cmd_limit']); $this->setNation(['strategic_cmd_limit']);
$this->minConditionConstraints=[
ConstraintHelper::OccupiedCity(),
ConstraintHelper::BeChief(),
ConstraintHelper::AvailableStrategicCommand(),
];
}
protected function initWithArg()
{
$this->setDestNation($this->arg['destNationID'], null); $this->setDestNation($this->arg['destNationID'], null);
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
ConstraintHelper::BeChief(), ConstraintHelper::BeChief(),
ConstraintHelper::ExistsDestNation(), ConstraintHelper::ExistsDestNation(),
@@ -72,7 +81,6 @@ class che_피장파장 extends Command\NationCommand{
), ),
ConstraintHelper::AvailableStrategicCommand(), ConstraintHelper::AvailableStrategicCommand(),
]; ];
} }
public function getCommandDetailTitle():string{ public function getCommandDetailTitle():string{
@@ -107,7 +115,7 @@ class che_피장파장 extends Command\NationCommand{
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -200,7 +208,7 @@ class che_피장파장 extends Command\NationCommand{
$testTurn->setArg(['destNationID'=>$destNation['nation']]); $testTurn->setArg(['destNationID'=>$destNation['nation']]);
$testCommand = new static($generalObj, $this->env, $testTurn, ['destNationID'=>$destNation['nation']]); $testCommand = new static($generalObj, $this->env, $testTurn, ['destNationID'=>$destNation['nation']]);
if($testCommand->isRunnable()){ if($testCommand->hasFullConditionMet()){
$destNation['availableCommand'] = true; $destNation['availableCommand'] = true;
} }
else{ else{
@@ -26,7 +26,6 @@ use sammo\Event\Action;
class che_필사즉생 extends Command\NationCommand{ class che_필사즉생 extends Command\NationCommand{
static protected $actionName = '필사즉생'; static protected $actionName = '필사즉생';
static public $reqArg = false;
protected function argTest():bool{ protected function argTest():bool{
$this->arg = []; $this->arg = [];
@@ -42,7 +41,7 @@ class che_필사즉생 extends Command\NationCommand{
$this->setCity(); $this->setCity();
$this->setNation(['strategic_cmd_limit']); $this->setNation(['strategic_cmd_limit']);
$this->runnableConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
ConstraintHelper::BeChief(), ConstraintHelper::BeChief(),
ConstraintHelper::AllowDiplomacyStatus($this->generalObj->getNationID(), [ ConstraintHelper::AllowDiplomacyStatus($this->generalObj->getNationID(), [
@@ -77,7 +76,7 @@ class che_필사즉생 extends Command\NationCommand{
} }
public function run():bool{ public function run():bool{
if(!$this->isRunnable()){ if(!$this->hasFullConditionMet()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
+66 -42
View File
@@ -1,9 +1,13 @@
<?php <?php
namespace sammo\Command\Nation; namespace sammo\Command\Nation;
use \sammo\{ use\sammo\{
DB, Util, JosaUtil, DB,
General, DummyGeneral, Util,
JosaUtil,
General,
DummyGeneral,
ActionLogger, ActionLogger,
GameConst, GameConst,
LastTurn, LastTurn,
@@ -14,52 +18,65 @@ use \sammo\{
CityConst CityConst
}; };
use function \sammo\{ use function\sammo\{
getDomesticExpLevelBonus, getDomesticExpLevelBonus,
CriticalRatioDomestic, CriticalRatioDomestic,
CriticalScoreEx, CriticalScoreEx,
GetImageURL, GetImageURL,
getNationStaticInfo getNationStaticInfo
}; };
use \sammo\Constraint\Constraint; use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
use sammo\Event\Action; use sammo\Event\Action;
class che_허보 extends Command\NationCommand{ class che_허보 extends Command\NationCommand
{
static protected $actionName = '허보'; static protected $actionName = '허보';
static public $reqArg = true; static public $reqArg = true;
protected function argTest():bool{ protected function argTest(): bool
if($this->arg === null){ {
if ($this->arg === null) {
return false; return false;
} }
if(!key_exists('destCityID', $this->arg)){ if (!key_exists('destCityID', $this->arg)) {
return false; return false;
} }
if(CityConst::byID($this->arg['destCityID']) === null){ if (CityConst::byID($this->arg['destCityID']) === null) {
return false; return false;
} }
$destCityID = $this->arg['destCityID']; $destCityID = $this->arg['destCityID'];
$this->arg = [ $this->arg = [
'destCityID'=>$destCityID, 'destCityID' => $destCityID,
]; ];
return true; return true;
} }
protected function init(){ protected function init()
{
$general = $this->generalObj; $general = $this->generalObj;
$env = $this->env; $env = $this->env;
$this->setCity(); $this->setCity();
$this->setNation(['strategic_cmd_limit']); $this->setNation(['strategic_cmd_limit']);
$this->setDestCity($this->arg['destCityID'], null);
$this->setDestNation($this->destCity['nation']);
$this->runnableConstraints=[ $this->minConditionConstraints = [
ConstraintHelper::OccupiedCity(),
ConstraintHelper::BeChief(),
ConstraintHelper::AvailableStrategicCommand(),
];
}
protected function initWithArg()
{
$this->setDestCity($this->arg['destCityID']);
$this->setDestNation($this->destCity['nation']);
$this->fullConditionConstraints = [
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
ConstraintHelper::BeChief(), ConstraintHelper::BeChief(),
ConstraintHelper::NotNeutralDestCity(), ConstraintHelper::NotNeutralDestCity(),
@@ -72,38 +89,44 @@ class che_허보 extends Command\NationCommand{
]; ];
} }
public function getCommandDetailTitle():string{ public function getCommandDetailTitle(): string
{
$name = $this->getName(); $name = $this->getName();
$reqTurn = $this->getPreReqTurn()+1; $reqTurn = $this->getPreReqTurn() + 1;
$postReqTurn = $this->getPostReqTurn(); $postReqTurn = $this->getPostReqTurn();
return "{$name}/{$reqTurn}턴(전략$postReqTurn)"; return "{$name}/{$reqTurn}턴(전략$postReqTurn)";
} }
public function getCost():array{ public function getCost(): array
{
return [0, 0]; return [0, 0];
} }
public function getPreReqTurn():int{ public function getPreReqTurn(): int
{
return 1; return 1;
} }
public function getPostReqTurn():int{ public function getPostReqTurn(): int
{
$genCount = Util::valueFit($this->nation['gennum'], GameConst::$initialNationGenLimit); $genCount = Util::valueFit($this->nation['gennum'], GameConst::$initialNationGenLimit);
$nextTerm = Util::round(sqrt($genCount*4)*10); $nextTerm = Util::round(sqrt($genCount * 4) * 10);
$nextTerm = $this->generalObj->onCalcStrategic($this->getName(), 'delay', $nextTerm); $nextTerm = $this->generalObj->onCalcStrategic($this->getName(), 'delay', $nextTerm);
return $nextTerm; return $nextTerm;
} }
public function getBrief():string{ public function getBrief(): string
{
$commandName = $this->getName(); $commandName = $this->getName();
$destCityName = CityConst::byID($this->arg['destCityID'])->name; $destCityName = CityConst::byID($this->arg['destCityID'])->name;
return "{$destCityName}】에 {$commandName}"; return "{$destCityName}】에 {$commandName}";
} }
public function run():bool{ public function run(): bool
if(!$this->isRunnable()){ {
if (!$this->hasFullConditionMet()) {
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -123,7 +146,7 @@ class che_허보 extends Command\NationCommand{
$destNationID = $destCity['nation']; $destNationID = $destCity['nation'];
$destNationName = getNationStaticInfo($destNationID)['name']; $destNationName = getNationStaticInfo($destNationID)['name'];
$nationID = $general->getNationID(); $nationID = $general->getNationID();
$nationName = $this->nation['name']; $nationName = $this->nation['name'];
@@ -138,7 +161,7 @@ class che_허보 extends Command\NationCommand{
$broadcastMessage = "<Y>{$generalName}</>{$josaYi} <G><b>{$destCityName}</b></>에 <M>허보</>를 발동하였습니다."; $broadcastMessage = "<Y>{$generalName}</>{$josaYi} <G><b>{$destCityName}</b></>에 <M>허보</>를 발동하였습니다.";
$targetGeneralList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND no != %i', $nationID, $generalID); $targetGeneralList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND no != %i', $nationID, $generalID);
foreach($targetGeneralList as $targetGeneralID){ foreach ($targetGeneralList as $targetGeneralID) {
$targetLogger = new ActionLogger($targetGeneralID, $nationID, $year, $month); $targetLogger = new ActionLogger($targetGeneralID, $nationID, $year, $month);
$targetLogger->pushGeneralActionLog($broadcastMessage, ActionLogger::PLAIN); $targetLogger->pushGeneralActionLog($broadcastMessage, ActionLogger::PLAIN);
$targetLogger->flush(); $targetLogger->flush();
@@ -148,12 +171,12 @@ class che_허보 extends Command\NationCommand{
$destNationCityList = $db->queryFirstColumn('SELECT city FROM city WHERE nation = %i AND supply = 1', $destNationID); $destNationCityList = $db->queryFirstColumn('SELECT city FROM city WHERE nation = %i AND supply = 1', $destNationID);
$targetGeneralList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND city=%i', $destNationID, $destCityID); $targetGeneralList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND city=%i', $destNationID, $destCityID);
foreach(General::createGeneralObjListFromDB($targetGeneralList) as $targetGeneralID => $targetGeneral){ foreach (General::createGeneralObjListFromDB($targetGeneralList) as $targetGeneralID => $targetGeneral) {
$targetLogger = $targetGeneral->getLogger(); $targetLogger = $targetGeneral->getLogger();
$targetLogger->pushGeneralActionLog($destBroadcastMessage, ActionLogger::PLAIN); $targetLogger->pushGeneralActionLog($destBroadcastMessage, ActionLogger::PLAIN);
$moveCityID = Util::choiceRandom($destNationCityList); $moveCityID = Util::choiceRandom($destNationCityList);
if($moveCityID == $destCityID){ if ($moveCityID == $destCityID) {
//현재도시면 다시 랜덤 추첨 //현재도시면 다시 랜덤 추첨
$moveCityID = Util::choiceRandom($destNationCityList); $moveCityID = Util::choiceRandom($destNationCityList);
} }
@@ -164,7 +187,8 @@ class che_허보 extends Command\NationCommand{
$destNationLogger = new ActionLogger(0, $destNationID, $year, $month); $destNationLogger = new ActionLogger(0, $destNationID, $year, $month);
$destNationLogger->pushNationalHistoryLog( $destNationLogger->pushNationalHistoryLog(
"<D><b>{$nationName}</b></>의 <Y>{$generalName}</>{$josaYi} 아국의 <G><b>{$destCityName}</b></>에 <M>허보</>를 발동", ActionLogger::PLAIN "<D><b>{$nationName}</b></>의 <Y>{$generalName}</>{$josaYi} 아국의 <G><b>{$destCityName}</b></>에 <M>허보</>를 발동",
ActionLogger::PLAIN
); );
$destNationLogger->flush(); $destNationLogger->flush();
@@ -173,7 +197,7 @@ class che_허보 extends Command\NationCommand{
'def' => $db->sqleval('def * 0.2'), 'def' => $db->sqleval('def * 0.2'),
'wall' => $db->sqleval('wall * 0.2'), 'wall' => $db->sqleval('wall * 0.2'),
], 'city=%i', $destCityID); ], 'city=%i', $destCityID);
$josaYiNation = JosaUtil::pick($nationName, '이'); $josaYiNation = JosaUtil::pick($nationName, '이');
$logger->pushGeneralHistoryLog("<G><b>{$destCityName}</b></>에 <M>허보</>를 발동"); $logger->pushGeneralHistoryLog("<G><b>{$destCityName}</b></>에 <M>허보</>를 발동");
@@ -202,15 +226,15 @@ class che_허보 extends Command\NationCommand{
{ {
ob_start(); ob_start();
?> ?>
<?=\sammo\getMapHtml()?><br> <?= \sammo\getMapHtml() ?><br>
선택된 도시에 허보를 발동합니다.<br> 선택된 도시에 허보를 발동합니다.<br>
전쟁중인 상대국 도시만 가능합니다.<br> 전쟁중인 상대국 도시만 가능합니다.<br>
목록을 선택하거나 도시를 클릭하세요.<br> 목록을 선택하거나 도시를 클릭하세요.<br>
<select class='formInput' name="destCityID" id="destCityID" size='1' style='color:white;background-color:black;'> <select class='formInput' name="destCityID" id="destCityID" size='1' style='color:white;background-color:black;'>
<?=\sammo\optionsForCities()?><br> <?= \sammo\optionsForCities() ?><br>
</select> <input type=button id="commonSubmit" value="<?=$this->getName()?>"><br> </select> <input type=button id="commonSubmit" value="<?= $this->getName() ?>"><br>
<br> <br>
<?php <?php
return ob_get_clean(); return ob_get_clean();
} }
} }
+1 -1
View File
@@ -15,7 +15,7 @@ class 휴식 extends Command\NationCommand{
protected function init(){ protected function init(){
//아무것도 하지 않음 //아무것도 하지 않음
$this->runnableConstraints=[]; $this->fullConditionConstraints=[];
} }
+3 -3
View File
@@ -88,7 +88,7 @@ class DiplomaticMessage extends Message{
$this->diplomacyDetail = $commandObj->getBrief(); $this->diplomacyDetail = $commandObj->getBrief();
if(!$commandObj->isRunnable()){ if(!$commandObj->hasFullConditionMet()){
return [self::DECLINED, $commandObj->getFailString()]; return [self::DECLINED, $commandObj->getFailString()];
} }
@@ -109,7 +109,7 @@ class DiplomaticMessage extends Message{
$this->diplomacyDetail = $commandObj->getBrief(); $this->diplomacyDetail = $commandObj->getBrief();
if(!$commandObj->isRunnable()){ if(!$commandObj->hasFullConditionMet()){
return [self::DECLINED, $commandObj->getFailString()]; return [self::DECLINED, $commandObj->getFailString()];
} }
@@ -130,7 +130,7 @@ class DiplomaticMessage extends Message{
$this->diplomacyDetail = $commandObj->getBrief(); $this->diplomacyDetail = $commandObj->getBrief();
if(!$commandObj->isRunnable()){ if(!$commandObj->hasFullConditionMet()){
return [self::DECLINED, $commandObj->getFailString()]; return [self::DECLINED, $commandObj->getFailString()];
} }
+62 -62
View File
@@ -344,7 +344,7 @@ class GeneralAI
} }
$cmd = buildNationCommandClass('che_발령', $this->general, $this->env, $lastTurn, Util::choiceRandom($troopCandidate)); $cmd = buildNationCommandClass('che_발령', $this->general, $this->env, $lastTurn, Util::choiceRandom($troopCandidate));
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
@@ -433,7 +433,7 @@ class GeneralAI
'destCityID'=>Util::choiceRandom($cityCandidates)['city'] 'destCityID'=>Util::choiceRandom($cityCandidates)['city']
]); ]);
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
@@ -544,7 +544,7 @@ class GeneralAI
'destCityID'=>Util::choiceRandom($cityCandidates)['city'] 'destCityID'=>Util::choiceRandom($cityCandidates)['city']
]); ]);
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
@@ -615,7 +615,7 @@ class GeneralAI
'destCityID'=>Util::choiceRandom($cityCandidates)['city'] 'destCityID'=>Util::choiceRandom($cityCandidates)['city']
]); ]);
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
@@ -666,7 +666,7 @@ class GeneralAI
return null; return null;
} }
$cmd = buildNationCommandClass('che_발령', $this->general, $this->env, $lastTurn, Util::choiceRandom($args)); $cmd = buildNationCommandClass('che_발령', $this->general, $this->env, $lastTurn, Util::choiceRandom($args));
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
return null; return null;
@@ -722,7 +722,7 @@ class GeneralAI
'destCityID'=>Util::choiceRandomUsingWeight($cityCandidates) 'destCityID'=>Util::choiceRandomUsingWeight($cityCandidates)
]); ]);
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
@@ -794,7 +794,7 @@ class GeneralAI
'destCityID'=>$destCity['city'] 'destCityID'=>$destCity['city']
]); ]);
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
@@ -869,7 +869,7 @@ class GeneralAI
'destCityID'=>Util::choiceRandom($cityCandidates)['city'] 'destCityID'=>Util::choiceRandom($cityCandidates)['city']
]); ]);
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
@@ -899,7 +899,7 @@ class GeneralAI
return null; return null;
} }
$cmd = buildNationCommandClass('che_발령', $this->general, $this->env, $lastTurn, Util::choiceRandom($args)); $cmd = buildNationCommandClass('che_발령', $this->general, $this->env, $lastTurn, Util::choiceRandom($args));
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
return null; return null;
@@ -955,7 +955,7 @@ class GeneralAI
'destCityID'=>Util::choiceRandomUsingWeight($cityCandidates) 'destCityID'=>Util::choiceRandomUsingWeight($cityCandidates)
]); ]);
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
@@ -1023,7 +1023,7 @@ class GeneralAI
'destCityID'=>$destCity['city'] 'destCityID'=>$destCity['city']
]); ]);
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
@@ -1101,7 +1101,7 @@ class GeneralAI
'che_포상', $this->general, $this->env, $lastTurn, 'che_포상', $this->general, $this->env, $lastTurn,
Util::choiceRandomUsingWeightPair($candidateArgs) Util::choiceRandomUsingWeightPair($candidateArgs)
); );
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
@@ -1203,7 +1203,7 @@ class GeneralAI
'che_포상', $this->general, $this->env, $lastTurn, 'che_포상', $this->general, $this->env, $lastTurn,
Util::choiceRandomUsingWeightPair($candidateArgs) Util::choiceRandomUsingWeightPair($candidateArgs)
); );
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
@@ -1287,7 +1287,7 @@ class GeneralAI
'che_포상', $this->general, $this->env, $lastTurn, 'che_포상', $this->general, $this->env, $lastTurn,
Util::choiceRandomUsingWeightPair($candidateArgs) Util::choiceRandomUsingWeightPair($candidateArgs)
); );
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
@@ -1398,7 +1398,7 @@ class GeneralAI
'che_포상', $this->general, $this->env, $lastTurn, 'che_포상', $this->general, $this->env, $lastTurn,
Util::choiceRandomUsingWeightPair($candidateArgs) Util::choiceRandomUsingWeightPair($candidateArgs)
); );
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
@@ -1528,7 +1528,7 @@ class GeneralAI
'che_몰수', $this->general, $this->env, $lastTurn, 'che_몰수', $this->general, $this->env, $lastTurn,
Util::choiceRandomUsingWeightPair($candidateArgs) Util::choiceRandomUsingWeightPair($candidateArgs)
); );
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
@@ -1635,7 +1635,7 @@ class GeneralAI
$cmd = buildNationCommandClass('che_선전포고', $this->general, $this->env, $lastTurn, [ $cmd = buildNationCommandClass('che_선전포고', $this->general, $this->env, $lastTurn, [
'destNationID' => Util::choiceRandomUsingWeight($nations) 'destNationID' => Util::choiceRandomUsingWeight($nations)
]); ]);
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
@@ -1654,7 +1654,7 @@ class GeneralAI
//천도를 한턴 넣었다면 계속 넣는다. //천도를 한턴 넣었다면 계속 넣는다.
if($lastTurn->getCommand() === '천도' && $lastTurn->getArg()['destCityID'] != $this->nation['capital']){ if($lastTurn->getCommand() === '천도' && $lastTurn->getArg()['destCityID'] != $this->nation['capital']){
$cmd = buildNationCommandClass('che_천도', $this->general, $this->env, $lastTurn, $lastTurn->getArg()); $cmd = buildNationCommandClass('che_천도', $this->general, $this->env, $lastTurn, $lastTurn->getArg());
if($cmd->isRunnable()){ if($cmd->hasFullConditionMet()){
$nationStor->setValue("last천도Trial_{$this->nation['nation']}", [$general->getVar('officer_level'), $general->getTurnTime()]); $nationStor->setValue("last천도Trial_{$this->nation['nation']}", [$general->getVar('officer_level'), $general->getTurnTime()]);
return $cmd; return $cmd;
} }
@@ -1771,7 +1771,7 @@ class GeneralAI
'destCityID'=>$targetCityID 'destCityID'=>$targetCityID
]); ]);
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
@@ -1802,13 +1802,13 @@ class GeneralAI
if ($genType & self::t통솔장) { if ($genType & self::t통솔장) {
if ($develRate['trust'] < 0.95) { if ($develRate['trust'] < 0.95) {
$cmd = buildGeneralCommandClass('che_주민선정', $general, $env); $cmd = buildGeneralCommandClass('che_주민선정', $general, $env);
if($cmd->isRunnable()){ if($cmd->hasFullConditionMet()){
$cmdList[] = [$cmd, $leadership / Util::valueFit($develRate['trust']-0.2, 0.001) * 2]; $cmdList[] = [$cmd, $leadership / Util::valueFit($develRate['trust']-0.2, 0.001) * 2];
} }
} }
if ($develRate['pop'] < 0.8) { if ($develRate['pop'] < 0.8) {
$cmd = buildGeneralCommandClass('che_정착장려', $general, $env); $cmd = buildGeneralCommandClass('che_정착장려', $general, $env);
if($cmd->isRunnable()){ if($cmd->hasFullConditionMet()){
$cmdList[] = [$cmd, $leadership / Util::valueFit($develRate['pop'], 0.001)]; $cmdList[] = [$cmd, $leadership / Util::valueFit($develRate['pop'], 0.001)];
} }
} }
@@ -1817,19 +1817,19 @@ class GeneralAI
if($genType & self::t무장){ if($genType & self::t무장){
if($develRate['def'] < 1){ if($develRate['def'] < 1){
$cmd = buildGeneralCommandClass('che_수비강화', $general, $env); $cmd = buildGeneralCommandClass('che_수비강화', $general, $env);
if($cmd->isRunnable()){ if($cmd->hasFullConditionMet()){
$cmdList[] = [$cmd, $strength / Util::valueFit($develRate['def'], 0.001)]; $cmdList[] = [$cmd, $strength / Util::valueFit($develRate['def'], 0.001)];
} }
} }
if($develRate['wall'] < 1){ if($develRate['wall'] < 1){
$cmd = buildGeneralCommandClass('che_성벽보수', $general, $env); $cmd = buildGeneralCommandClass('che_성벽보수', $general, $env);
if($cmd->isRunnable()){ if($cmd->hasFullConditionMet()){
$cmdList[] = [$cmd, $strength / Util::valueFit($develRate['wall'], 0.001)]; $cmdList[] = [$cmd, $strength / Util::valueFit($develRate['wall'], 0.001)];
} }
} }
if($develRate['secu'] < 0.9){ if($develRate['secu'] < 0.9){
$cmd = buildGeneralCommandClass('che_치안강화', $general, $env); $cmd = buildGeneralCommandClass('che_치안강화', $general, $env);
if($cmd->isRunnable()){ if($cmd->hasFullConditionMet()){
$cmdList[] = [$cmd, $strength / Util::valueFit($develRate['comm'] / 0.8, 0.001, 1)]; $cmdList[] = [$cmd, $strength / Util::valueFit($develRate['comm'] / 0.8, 0.001, 1)];
} }
} }
@@ -1838,7 +1838,7 @@ class GeneralAI
if($genType & self::t지장){ if($genType & self::t지장){
if (!TechLimit($env['startyear'], $env['year'], $nation['tech'])) { if (!TechLimit($env['startyear'], $env['year'], $nation['tech'])) {
$cmd = buildGeneralCommandClass('che_기술연구', $general, $env); $cmd = buildGeneralCommandClass('che_기술연구', $general, $env);
if ($cmd->isRunnable()) { if ($cmd->hasFullConditionMet()) {
$nextTech = $nation['tech'] % 1000 + 1; $nextTech = $nation['tech'] % 1000 + 1;
if (!TechLimit($env['startyear'], $env['year'], $nation['tech'] + 1000)) { if (!TechLimit($env['startyear'], $env['year'], $nation['tech'] + 1000)) {
//한등급 이상 뒤쳐져 있다면, 조금 더 열심히 하자. //한등급 이상 뒤쳐져 있다면, 조금 더 열심히 하자.
@@ -1850,13 +1850,13 @@ class GeneralAI
} }
if ($develRate['agri'] < 1) { if ($develRate['agri'] < 1) {
$cmd = buildGeneralCommandClass('che_농지개간', $general, $env); $cmd = buildGeneralCommandClass('che_농지개간', $general, $env);
if ($cmd->isRunnable()) { if ($cmd->hasFullConditionMet()) {
$cmdList[] = [$cmd, ($isSpringSummer?1.2:0.8) * $intel / Util::valueFit($develRate['agri'], 0.001, 1)]; $cmdList[] = [$cmd, ($isSpringSummer?1.2:0.8) * $intel / Util::valueFit($develRate['agri'], 0.001, 1)];
} }
} }
if ($develRate['comm'] < 1) { if ($develRate['comm'] < 1) {
$cmd = buildGeneralCommandClass('che_상업투자', $general, $env); $cmd = buildGeneralCommandClass('che_상업투자', $general, $env);
if ($cmd->isRunnable()) { if ($cmd->hasFullConditionMet()) {
$cmdList[] = [$cmd, ($isSpringSummer?0.8:1.2) * $intel / Util::valueFit($develRate['comm'], 0.001, 1)]; $cmdList[] = [$cmd, ($isSpringSummer?0.8:1.2) * $intel / Util::valueFit($develRate['comm'], 0.001, 1)];
} }
} }
@@ -1887,14 +1887,14 @@ class GeneralAI
if($city['trust'] < 70 && Util::randBool($leadership / GameConst::$chiefStatMin)){ if($city['trust'] < 70 && Util::randBool($leadership / GameConst::$chiefStatMin)){
$cmd = buildGeneralCommandClass('che_주민선정', $general, $env); $cmd = buildGeneralCommandClass('che_주민선정', $general, $env);
if($cmd->isRunnable()){ if($cmd->hasFullConditionMet()){
return $cmd; return $cmd;
} }
} }
if($city['pop'] < $this->nationPolicy->minNPCRecruitCityPopulation && Util::randBool($leadership / GameConst::$chiefStatMin / 2)){ if($city['pop'] < $this->nationPolicy->minNPCRecruitCityPopulation && Util::randBool($leadership / GameConst::$chiefStatMin / 2)){
$cmd = buildGeneralCommandClass('che_정착장려', $general, $env); $cmd = buildGeneralCommandClass('che_정착장려', $general, $env);
if($cmd->isRunnable()){ if($cmd->hasFullConditionMet()){
return $cmd; return $cmd;
} }
} }
@@ -1927,13 +1927,13 @@ class GeneralAI
if ($genType & self::t통솔장) { if ($genType & self::t통솔장) {
if ($develRate['trust'] < 0.95) { if ($develRate['trust'] < 0.95) {
$cmd = buildGeneralCommandClass('che_주민선정', $general, $env); $cmd = buildGeneralCommandClass('che_주민선정', $general, $env);
if($cmd->isRunnable()){ if($cmd->hasFullConditionMet()){
$cmdList[] = [$cmd, $leadership / Util::valueFit($develRate['trust']-0.2, 0.001) * 2]; $cmdList[] = [$cmd, $leadership / Util::valueFit($develRate['trust']-0.2, 0.001) * 2];
} }
} }
if ($develRate['pop'] < 0.8) { if ($develRate['pop'] < 0.8) {
$cmd = buildGeneralCommandClass('che_정착장려', $general, $env); $cmd = buildGeneralCommandClass('che_정착장려', $general, $env);
if($cmd->isRunnable()){ if($cmd->hasFullConditionMet()){
if (in_array($city['front'], [1, 3])) { if (in_array($city['front'], [1, 3])) {
$cmdList[] = [$cmd, $leadership / Util::valueFit($develRate['pop'], 0.001)]; $cmdList[] = [$cmd, $leadership / Util::valueFit($develRate['pop'], 0.001)];
} }
@@ -1947,19 +1947,19 @@ class GeneralAI
if($genType & self::t무장){ if($genType & self::t무장){
if($develRate['def'] < 0.5){ if($develRate['def'] < 0.5){
$cmd = buildGeneralCommandClass('che_수비강화', $general, $env); $cmd = buildGeneralCommandClass('che_수비강화', $general, $env);
if($cmd->isRunnable()){ if($cmd->hasFullConditionMet()){
$cmdList[] = [$cmd, $strength / Util::valueFit($develRate['def'], 0.001) / 2]; $cmdList[] = [$cmd, $strength / Util::valueFit($develRate['def'], 0.001) / 2];
} }
} }
if($develRate['wall'] < 0.5){ if($develRate['wall'] < 0.5){
$cmd = buildGeneralCommandClass('che_성벽보수', $general, $env); $cmd = buildGeneralCommandClass('che_성벽보수', $general, $env);
if($cmd->isRunnable()){ if($cmd->hasFullConditionMet()){
$cmdList[] = [$cmd, $strength / Util::valueFit($develRate['wall'], 0.001) / 2]; $cmdList[] = [$cmd, $strength / Util::valueFit($develRate['wall'], 0.001) / 2];
} }
} }
if($develRate['secu'] < 0.5){ if($develRate['secu'] < 0.5){
$cmd = buildGeneralCommandClass('che_치안강화', $general, $env); $cmd = buildGeneralCommandClass('che_치안강화', $general, $env);
if($cmd->isRunnable()){ if($cmd->hasFullConditionMet()){
$cmdList[] = [$cmd, $strength / Util::valueFit($develRate['secu'] / 0.8, 0.001, 1) / 4]; $cmdList[] = [$cmd, $strength / Util::valueFit($develRate['secu'] / 0.8, 0.001, 1) / 4];
} }
} }
@@ -1968,7 +1968,7 @@ class GeneralAI
if($genType & self::t지장){ if($genType & self::t지장){
if (!TechLimit($env['startyear'], $env['year'], $nation['tech'])) { if (!TechLimit($env['startyear'], $env['year'], $nation['tech'])) {
$cmd = buildGeneralCommandClass('che_기술연구', $general, $env); $cmd = buildGeneralCommandClass('che_기술연구', $general, $env);
if ($cmd->isRunnable()) { if ($cmd->hasFullConditionMet()) {
$nextTech = $nation['tech'] % 1000 + 1; $nextTech = $nation['tech'] % 1000 + 1;
if (!TechLimit($env['startyear'], $env['year'], $nation['tech'] + 1000)) { if (!TechLimit($env['startyear'], $env['year'], $nation['tech'] + 1000)) {
//한등급 이상 뒤쳐져 있다면, 조금 더 열심히 하자. 전쟁중이면 더더욱 //한등급 이상 뒤쳐져 있다면, 조금 더 열심히 하자. 전쟁중이면 더더욱
@@ -1980,7 +1980,7 @@ class GeneralAI
} }
if ($develRate['agri'] < 0.5) { if ($develRate['agri'] < 0.5) {
$cmd = buildGeneralCommandClass('che_농지개간', $general, $env); $cmd = buildGeneralCommandClass('che_농지개간', $general, $env);
if ($cmd->isRunnable()) { if ($cmd->hasFullConditionMet()) {
if (in_array($city['front'], [1, 3])) { if (in_array($city['front'], [1, 3])) {
$cmdList[] = [$cmd, ($isSpringSummer?1.2:0.8) * $intel / 4 / Util::valueFit($develRate['agri'], 0.001, 1)]; $cmdList[] = [$cmd, ($isSpringSummer?1.2:0.8) * $intel / 4 / Util::valueFit($develRate['agri'], 0.001, 1)];
} }
@@ -1991,7 +1991,7 @@ class GeneralAI
} }
if ($develRate['comm'] < 0.5) { if ($develRate['comm'] < 0.5) {
$cmd = buildGeneralCommandClass('che_상업투자', $general, $env); $cmd = buildGeneralCommandClass('che_상업투자', $general, $env);
if ($cmd->isRunnable()) { if ($cmd->hasFullConditionMet()) {
if (in_array($city['front'], [1, 3])) { if (in_array($city['front'], [1, 3])) {
$cmdList[] = [$cmd, ($isSpringSummer?0.8:1.2) * $intel / 4 / Util::valueFit($develRate['comm'], 0.001, 1)]; $cmdList[] = [$cmd, ($isSpringSummer?0.8:1.2) * $intel / 4 / Util::valueFit($develRate['comm'], 0.001, 1)];
} }
@@ -2055,7 +2055,7 @@ class GeneralAI
'amount' => Util::valueFit(Util::toInt($general->getVar('gold') - $avgAmount), 100, GameConst::$maxResourceActionAmount) 'amount' => Util::valueFit(Util::toInt($general->getVar('gold') - $avgAmount), 100, GameConst::$maxResourceActionAmount)
] ]
); );
if($cmd->isRunnable()){ if($cmd->hasFullConditionMet()){
return $cmd; return $cmd;
} }
} }
@@ -2067,7 +2067,7 @@ class GeneralAI
'amount' => Util::valueFit(Util::toInt($general->getVar('rice') - $avgAmount), 100, GameConst::$maxResourceActionAmount) 'amount' => Util::valueFit(Util::toInt($general->getVar('rice') - $avgAmount), 100, GameConst::$maxResourceActionAmount)
] ]
); );
if($cmd->isRunnable()){ if($cmd->hasFullConditionMet()){
return $cmd; return $cmd;
} }
} }
@@ -2081,7 +2081,7 @@ class GeneralAI
'amount' => Util::valueFit(Util::toInt($general->getVar('gold') - $avgAmount), 100, GameConst::$maxResourceActionAmount) 'amount' => Util::valueFit(Util::toInt($general->getVar('gold') - $avgAmount), 100, GameConst::$maxResourceActionAmount)
] ]
); );
if($cmd->isRunnable()){ if($cmd->hasFullConditionMet()){
return $cmd; return $cmd;
} }
} }
@@ -2093,7 +2093,7 @@ class GeneralAI
'amount' => Util::valueFit(Util::toInt($general->getVar('rice') - $avgAmount), 100, GameConst::$maxResourceActionAmount) 'amount' => Util::valueFit(Util::toInt($general->getVar('rice') - $avgAmount), 100, GameConst::$maxResourceActionAmount)
] ]
); );
if($cmd->isRunnable()){ if($cmd->hasFullConditionMet()){
return $cmd; return $cmd;
} }
} }
@@ -2250,7 +2250,7 @@ class GeneralAI
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
return $cmd; return $cmd;
@@ -2269,14 +2269,14 @@ class GeneralAI
if($train < $this->nationPolicy->properWarTrainAtmos){ if($train < $this->nationPolicy->properWarTrainAtmos){
$cmd = buildGeneralCommandClass('che_훈련', $general, $this->env); $cmd = buildGeneralCommandClass('che_훈련', $general, $this->env);
if($cmd->isRunnable()){ if($cmd->hasFullConditionMet()){
$cmdList[] = [$cmd, GameConst::$maxTrainByCommand / Util::valueFit($train, 1)]; $cmdList[] = [$cmd, GameConst::$maxTrainByCommand / Util::valueFit($train, 1)];
} }
} }
if($atmos < $this->nationPolicy->properWarTrainAtmos){ if($atmos < $this->nationPolicy->properWarTrainAtmos){
$cmd = buildGeneralCommandClass('che_사기진작', $general, $this->env); $cmd = buildGeneralCommandClass('che_사기진작', $general, $this->env);
if($cmd->isRunnable()){ if($cmd->hasFullConditionMet()){
$cmdList[] = [$cmd, GameConst::$maxAtmosByCommand / Util::valueFit($atmos, 1)]; $cmdList[] = [$cmd, GameConst::$maxAtmosByCommand / Util::valueFit($atmos, 1)];
} }
} }
@@ -2302,7 +2302,7 @@ class GeneralAI
return null; return null;
} }
$cmd = buildGeneralCommandClass('che_소집해제', $this->general, $this->env); $cmd = buildGeneralCommandClass('che_소집해제', $this->general, $this->env);
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
return $cmd; return $cmd;
@@ -2369,7 +2369,7 @@ class GeneralAI
} }
$cmd = buildGeneralCommandClass('che_출병', $general, $this->env, ['destCityID' => Util::choiceRandom($attackableCities)]); $cmd = buildGeneralCommandClass('che_출병', $general, $this->env, ['destCityID' => Util::choiceRandom($attackableCities)]);
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
@@ -2441,7 +2441,7 @@ class GeneralAI
} }
$cmd = buildGeneralCommandClass('che_헌납', $general, $this->env, Util::choiceRandomUsingWeightPair($args)); $cmd = buildGeneralCommandClass('che_헌납', $general, $this->env, Util::choiceRandomUsingWeightPair($args));
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
return $cmd; return $cmd;
@@ -2518,7 +2518,7 @@ class GeneralAI
]); ]);
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
@@ -2565,7 +2565,7 @@ class GeneralAI
]); ]);
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
@@ -2634,7 +2634,7 @@ class GeneralAI
'optionText' => '순간이동', 'optionText' => '순간이동',
'destCityID' => Util::choiceRandomUsingWeight($candidateCities), 'destCityID' => Util::choiceRandomUsingWeight($candidateCities),
]); ]);
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
@@ -2651,7 +2651,7 @@ class GeneralAI
} }
$cmd = buildGeneralCommandClass('che_귀환', $this->general, $this->env); $cmd = buildGeneralCommandClass('che_귀환', $this->general, $this->env);
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
@@ -2723,7 +2723,7 @@ class GeneralAI
$cmd = buildGeneralCommandClass('che_이동', $general, $this->env, [ $cmd = buildGeneralCommandClass('che_이동', $general, $this->env, [
'destCityID'=>Util::choiceRandomUsingWeight($targetCity) 'destCityID'=>Util::choiceRandomUsingWeight($targetCity)
]); ]);
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
@@ -2756,7 +2756,7 @@ class GeneralAI
} }
$cmd = buildGeneralCommandClass('che_거병', $general, $this->env, null); $cmd = buildGeneralCommandClass('che_거병', $general, $this->env, null);
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
@@ -2766,7 +2766,7 @@ class GeneralAI
protected function do해산(): ?GeneralCommand protected function do해산(): ?GeneralCommand
{ {
$cmd = buildGeneralCommandClass('che_해산', $this->general, $this->env, null); $cmd = buildGeneralCommandClass('che_해산', $this->general, $this->env, null);
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
@@ -2782,7 +2782,7 @@ class GeneralAI
'nationType' => $nationType, 'nationType' => $nationType,
'colorType' => $nationColor 'colorType' => $nationColor
]); ]);
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
@@ -2796,7 +2796,7 @@ class GeneralAI
'destGeneralID' => $db->queryFirstField('SELECT `no` FROM general WHERE nation = %i AND npc != 5 ORDER BY RAND() LIMIT 1', $this->general->getNationID()) 'destGeneralID' => $db->queryFirstField('SELECT `no` FROM general WHERE nation = %i AND npc != 5 ORDER BY RAND() LIMIT 1', $this->general->getNationID())
]); ]);
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
@@ -2820,7 +2820,7 @@ class GeneralAI
if ($rulerNation) { if ($rulerNation) {
$cmd = buildGeneralCommandClass('che_임관', $general, $env, ['destNationID' => $rulerNation]); $cmd = buildGeneralCommandClass('che_임관', $general, $env, ['destNationID' => $rulerNation]);
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
@@ -2849,7 +2849,7 @@ class GeneralAI
//랜임 커맨드 입력. //랜임 커맨드 입력.
$cmd = buildGeneralCommandClass('che_랜덤임관', $general, $env); $cmd = buildGeneralCommandClass('che_랜덤임관', $general, $env);
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
@@ -2860,7 +2860,7 @@ class GeneralAI
$paths = array_keys(CityConst::byID($city['city'])->path); $paths = array_keys(CityConst::byID($city['city'])->path);
$cmd = buildGeneralCommandClass('che_이동', $general, $env, ['destCityID' => Util::choiceRandom($paths)]); $cmd = buildGeneralCommandClass('che_이동', $general, $env, ['destCityID' => Util::choiceRandom($paths)]);
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return null; return null;
} }
@@ -2919,7 +2919,7 @@ class GeneralAI
$cmd = buildGeneralCommandClass(Util::choiceRandom($candidate), $this->general, $this->env); $cmd = buildGeneralCommandClass(Util::choiceRandom($candidate), $this->general, $this->env);
if(!$cmd->isRunnable()){ if(!$cmd->hasFullConditionMet()){
return buildGeneralCommandClass('che_물자조달', $this->general, $this->env); return buildGeneralCommandClass('che_물자조달', $this->general, $this->env);
} }
return $cmd; return $cmd;
@@ -3105,7 +3105,7 @@ class GeneralAI
} }
if(!($reservedCommand instanceof Command\Nation\휴식)){ if(!($reservedCommand instanceof Command\Nation\휴식)){
if($reservedCommand->isRunnable()){ if($reservedCommand->hasFullConditionMet()){
$reservedCommand->reason = 'reserved'; $reservedCommand->reason = 'reserved';
return $reservedCommand; return $reservedCommand;
} }
@@ -3136,7 +3136,7 @@ class GeneralAI
} }
public function chooseInstantNationTurn(NationCommand $reservedCommand): ?NationCommand{ public function chooseInstantNationTurn(NationCommand $reservedCommand): ?NationCommand{
if($reservedCommand->isRunnable()){ if($reservedCommand->hasFullConditionMet()){
return $reservedCommand; return $reservedCommand;
} }
+1 -1
View File
@@ -84,7 +84,7 @@ class ScoutMessage extends Message{
'month'=>$this->msgOption['month'] 'month'=>$this->msgOption['month']
]); ]);
if(!$commandObj->isRunnable()){ if(!$commandObj->hasFullConditionMet()){
$logger->pushGeneralActionLog($commandObj->getFailString()); $logger->pushGeneralActionLog($commandObj->getFailString());
return self::DECLINED; return self::DECLINED;
} }
+2 -4
View File
@@ -67,8 +67,7 @@ class TurnExecutionHelper
$general = $this->getGeneral(); $general = $this->getGeneral();
while(true){ while(true){
$failReason = $commandObj->testRunnable(); if($commandObj->hasFullConditionMet()){
if($failReason){
$date = $general->getTurnTime($general::TURNTIME_HM); $date = $general->getTurnTime($general::TURNTIME_HM);
$failString = $commandObj->getFailString(); $failString = $commandObj->getFailString();
$text = "{$failString} <1>{$date}</>"; $text = "{$failString} <1>{$date}</>";
@@ -110,8 +109,7 @@ class TurnExecutionHelper
$commandClassName = $commandObj->getName(); $commandClassName = $commandObj->getName();
while(true){ while(true){
$failReason = $commandObj->testRunnable(); if($commandObj->hasFullConditionMet()){
if($failReason){
$date = $general->getTurnTime($general::TURNTIME_HM); $date = $general->getTurnTime($general::TURNTIME_HM);
$failString = $commandObj->getFailString(); $failString = $commandObj->getFailString();
$text = "{$failString} <1>{$date}</>"; $text = "{$failString} <1>{$date}</>";
+177 -181
View File
@@ -1,7 +1,8 @@
<?php <?php
namespace sammo; namespace sammo;
require(__DIR__.'/vendor/autoload.php'); require(__DIR__ . '/vendor/autoload.php');
if (!class_exists('\\sammo\\RootDB')) { if (!class_exists('\\sammo\\RootDB')) {
header('Location:install.php'); header('Location:install.php');
@@ -21,19 +22,20 @@ if ($session->isLoggedIn()) {
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="ko"> <html lang="ko">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<title>삼국지 모의전투 HiDCHe</title> <title>삼국지 모의전투 HiDCHe</title>
<?=WebUtil::printJS('e_lib/jquery-3.3.1.min.js')?> <?= WebUtil::printJS('e_lib/jquery-3.3.1.min.js') ?>
<?=WebUtil::printJS('e_lib/bootstrap.bundle.min.js')?> <?= WebUtil::printJS('e_lib/bootstrap.bundle.min.js') ?>
<?=WebUtil::printJS('e_lib/jquery.validate.min.js')?> <?= WebUtil::printJS('e_lib/jquery.validate.min.js') ?>
<?=WebUtil::printJS('e_lib/sha512.min.js')?> <?= WebUtil::printJS('e_lib/sha512.min.js') ?>
<?=WebUtil::printJS('js/common.js')?> <?= WebUtil::printJS('js/common.js') ?>
<?=WebUtil::printJS('js/login.js')?> <?= WebUtil::printJS('js/login.js') ?>
<?=WebUtil::printCSS('e_lib/bootstrap.min.css')?> <?= WebUtil::printCSS('e_lib/bootstrap.min.css') ?>
<?=WebUtil::printCSS('css/login.css')?> <?= WebUtil::printCSS('css/login.css') ?>
<meta name="description" content="실시간으로 진행되는 삼국지 웹게임(삼모전)입니다"> <meta name="description" content="실시간으로 진행되는 삼국지 웹게임(삼모전)입니다">
<meta name="keywords" content="삼국지,삼모전,웹게임,힏체,힏체섭,히데체,히데체섭,HiDCHe,체섭"> <meta name="keywords" content="삼국지,삼모전,웹게임,힏체,힏체섭,히데체,히데체섭,HiDCHe,체섭">
<meta property="og:type" content="website"> <meta property="og:type" content="website">
@@ -41,196 +43,190 @@ if ($session->isLoggedIn()) {
<meta property="og:description" content="실시간으로 진행되는 삼국지 웹게임(삼모전)입니다"> <meta property="og:description" content="실시간으로 진행되는 삼국지 웹게임(삼모전)입니다">
<meta property="og:url" content="https://sam.hided.net"> <meta property="og:url" content="https://sam.hided.net">
<script> <script>
var oauthMode = null;
var oauthMode = null; function getOAuthToken(mode, scope_list) {
if (mode === undefined) {
mode = 'login';
}
if (scope_list === undefined) {
scope_list = null;
}
oauthMode = mode;
var url = 'https://kauth.kakao.com/oauth/authorize?' +
'client_id=<?= KakaoKey::REST_KEY ?>&' +
'redirect_uri=<?= KakaoKey::REDIRECT_URI ?>&' +
'response_type=code';
if (Array.isArray(scope_list)) {
url += '&scope=' + scope_list.join(',');
} else if (typeof scope_list === 'string' || scope_list instanceof String) {
url += '&scope=' + scope_list;
}
function getOAuthToken(mode, scope_list){ window.open(url, "KakaoAccountLogin", "width=600,height=450,resizable=yes,scrollbars=yes");
if(mode === undefined){ }
mode = 'login';
}
if(scope_list === undefined){
scope_list = null;
}
oauthMode = mode;
var url = 'https://kauth.kakao.com/oauth/authorize?'+
'client_id=<?=KakaoKey::REST_KEY?>&'+
'redirect_uri=<?=KakaoKey::REDIRECT_URI?>&'+
'response_type=code';
if(Array.isArray(scope_list)){
url += '&scope='+scope_list.join(',');
}
else if(typeof scope_list === 'string' || scope_list instanceof String){
url += '&scope='+scope_list;
}
window.open(url,"KakaoAccountLogin","width=600,height=450,resizable=yes,scrollbars=yes"); function sendTempPasswordToKakaoTalk() {
} $.post({
url: 'oauth_kakao/j_login_oauth.php',
dataType: 'json'
}).then(function(obj) {
var t = $.Deferred();
if (!obj.result) {
t.reject();
}
return $.post({
url: 'oauth_kakao/j_change_pw.php',
dataType: 'json'
});
}).then(function(obj) {
if (!obj.result) {
alert(obj.reason);
} else {
alert('임시 비밀번호가 카카오톡으로 전송되었습니다.');
}
});
}
function sendTempPasswordToKakaoTalk(){ function doLoginUsingOAuth() {
$.post({ $.post({
url:'oauth_kakao/j_login_oauth.php', url: 'oauth_kakao/j_login_oauth.php',
dataType:'json' dataType: 'json'
}).then(function(obj){ }).then(function(obj) {
var t = $.Deferred(); if (obj.result) {
if(!obj.result){ window.location.href = "./";
t.reject(); return;
} }
return $.post({ if (!obj.reqOTP) {
url:'oauth_kakao/j_change_pw.php', alert(obj.reason);
dataType:'json' return;
}); }
}).then(function(obj){ $('#modalOTP').modal().on('shown.bs.modal', function() {
if(!obj.result){ $('#otp_code').focus();
alert(obj.reason); });
}
else{
alert('임시 비밀번호가 카카오톡으로 전송되었습니다.');
}
});
}
function doLoginUsingOAuth(){ });
$.post({
url:'oauth_kakao/j_login_oauth.php',
dataType:'json'
}).then(function(obj){
if(obj.result){
window.location.href = "./";
return;
} }
if(!obj.reqOTP){
alert(obj.reason);
return;
}
$('#modalOTP').modal().on('shown.bs.modal', function(){
$('#otp_code').focus();
});
}); function postOAuthResult(result) {
} if (result == 'join') {
window.location.href = 'oauth_kakao/join.php';
function postOAuthResult(result){ } else if (result == 'req_email') {
if(result == 'join'){ alert('이메일 정보 공유를 허가해 주셔야 합니다.');
window.location.href = 'oauth_kakao/join.php'; } else if (result == 'login') {
} console.log('로그인모드');
else if(result == 'req_email'){ if (oauthMode == 'change_pw') {
alert('이메일 정보 공유를 허가해 주셔야 합니다.'); sendTempPasswordToKakaoTalk();
} } else {
else if(result == 'login'){ doLoginUsingOAuth();
console.log('로그인모드'); }
if(oauthMode=='change_pw'){ } else {
sendTempPasswordToKakaoTalk(); alert('예외 발생!');
}
} }
else{ </script>
doLoginUsingOAuth();
}
}
else{
alert('예외 발생!');
}
}
</script>
</head> </head>
<body> <body>
<nav class="navbar navbar-expand-lg fixed-top navbar-light bg-light"> <nav class="navbar navbar-expand-lg fixed-top navbar-light bg-light">
<a class="navbar-brand" href=".">삼국지 모의전투 HiDCHe</a> <a class="navbar-brand" href=".">삼국지 모의전투 HiDCHe</a>
<button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"> <button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
</button> </button>
<div class="collapse navbar-collapse" id="navbarNav"> <div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav"> <ul class="navbar-nav">
<?=WebUtil::drawMenu(ROOT.'/d_shared/menu.json')?> <?= WebUtil::drawMenu(ROOT . '/d_shared/menu.json') ?>
</ul> </ul>
</div> </div>
</nav> </nav>
<div class="full-content"> <div class="full-content">
<div class="vertical-center"> <div class="vertical-center">
<div class="container"> <div class="container">
<h1 class="row justify-content-md-center">삼국지 모의전투 HiDCHe</h1> <h1 class="row justify-content-md-center">삼국지 모의전투 HiDCHe</h1>
<div class="row justify-content-md-center"> <div class="row justify-content-md-center">
<div class="col" style="max-width:450px;"> <div class="col" style="max-width:450px;">
<div class="card" id="login_card"> <div class="card" id="login_card">
<h3 class="card-header"> <h3 class="card-header">
로그인 로그인
</h3> </h3>
<div class="card-body"> <div class="card-body">
<form id="main_form" method="post" action="#">
<div class="form-group row">
<label for="username" class="col-5 col-md-4 col-form-label">계정명</label>
<div class="col-7 col-md-8">
<input autocomplete="username" type="text" class="form-control"
name="username" id="username" autofocus="autofocus" placeholder="계정명"/>
</div>
</div>
<form id="main_form" method="post" action="#">
<div class="form-group row"> <div class="form-group row">
<label for="password" class="col-5 col-md-4 col-form-label">비밀번호</label> <label for="username" class="col-5 col-md-4 col-form-label">계정명</label>
<div class="col-7 col-md-8"> <div class="col-7 col-md-8">
<input autocomplete="current-password" type="password" <input autocomplete="username" type="text" class="form-control" name="username" id="username" autofocus="autofocus" placeholder="계정명" />
class="form-control" name="password" id="password" placeholder="비밀번호"/> </div>
</div>
</div>
<input type="hidden" id="global_salt" name="global_salt" value="<?=RootDB::getGlobalSalt()?>">
<div class="form-group row">
<div class="col-5 col-md-4 " style="position:relative;"><button type="button" onclick="getOAuthToken('login', ['account_email','talk_message']);" id="btn_kakao_login" title="카카오톡으로 가입&amp;로그인"></button></div>
<div class="col-7 col-md-8">
<div class="btn-group btn-group-lg d-flex login_btn_group" role="group">
<button type="submit" class="btn btn-primary login-button w-100">로그인</button>
<div class="btn-group" role="group">
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> </button>
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="btnGroupDrop1">
<a class="dropdown-item" href="javascript:getOAuthToken('change_pw', 'talk_message');">비밀번호 초기화</a>
</div> </div>
</div>
<div class="form-group row">
<label for="password" class="col-5 col-md-4 col-form-label">비밀번호</label>
<div class="col-7 col-md-8">
<input autocomplete="current-password" type="password" class="form-control" name="password" id="password" placeholder="비밀번호" />
</div>
</div>
<input type="hidden" id="global_salt" name="global_salt" value="<?= RootDB::getGlobalSalt() ?>">
<div class="form-group row">
<div class="col-5 col-md-4 " style="position:relative;"><button type="button" onclick="getOAuthToken('login', ['account_email','talk_message']);" id="btn_kakao_login" title="카카오톡으로 가입&amp;로그인"></button></div>
<div class="col-7 col-md-8">
<div class="btn-group btn-group-lg d-flex login_btn_group" role="group">
<button type="submit" class="btn btn-primary login-button w-100">로그인</button>
<div class="btn-group" role="group">
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> </button>
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="btnGroupDrop1">
<a class="dropdown-item" href="javascript:getOAuthToken('change_pw', 'talk_message');">비밀번호 초기화</a>
</div>
</div>
</div>
</div>
</div>
</form>
</div> </div>
</div> </div>
</div> </div>
</div>
</div>
</div>
<div id="bottom_box">
<div class="container"><a href="terms.2.html">개인정보처리방침</a> &amp; <a href="terms.1.html">이용약관</a><br>© 2020 • HideD
<br>크롬과 파이어폭스에 최적화되어있습니다.</div>
</div>
</div>
<div class="modal fade" id="modalOTP" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<form id="otp_form" method="post" action="#">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">인증 코드 필요</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div>
인증 코드가 필요합니다.<br><br>
카카오톡의 '나와의 채팅'란을 확인해 주세요.<br>
(별도의 알림[소리, 진동, 숫자]이 발생하지 않습니다.)
</div>
<div class="input-group mt-4" role="group">
<div class="input-group-prepend">
<span class="input-group-text">인증 코드</span>
</div>
<input type="number" class="form-control" name='otp' id="otp_code" placeholder="인증 코드">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">취소</button>
<button type="submit" class="btn btn-primary">제출</button>
</div>
</form> </form>
</div> </div>
</div> </div>
</div>
</div>
</div> </div>
</div>
<div id="bottom_box">
<div class="container"><a href="terms.2.html">개인정보처리방침</a> &amp; <a href="terms.1.html">이용약관</a><br>© 2020 • HideD
<br>크롬과 파이어폭스에 최적화되어있습니다.</div></div>
</div>
<div class="modal fade" id="modalOTP" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<form id="otp_form" method="post" action="#">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">인증 코드 필요</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div>
인증 코드가 필요합니다.<br><br>
카카오톡의 '나와의 채팅'란을 확인해 주세요.<br>
(별도의 알림[소리, 진동, 숫자]이 발생하지 않습니다.)
</div>
<div class="input-group mt-4" role="group">
<div class="input-group-prepend">
<span class="input-group-text">인증 코드</span>
</div>
<input type="number" class="form-control" name='otp' id="otp_code" placeholder="인증 코드">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">취소</button>
<button type="submit" class="btn btn-primary">제출</button>
</div>
</form>
</div>
</div>
</div>
</body> </body>
</html>
</html>
+75 -73
View File
@@ -1,69 +1,71 @@
<?php <?php
namespace sammo; namespace sammo;
require(__DIR__.'/vendor/autoload.php'); require(__DIR__ . '/vendor/autoload.php');
require(__DIR__.'/oauth_kakao/lib.join.php'); require(__DIR__ . '/oauth_kakao/lib.join.php');
use \kakao\Kakao_REST_API_Helper as Kakao_REST_API_Helper; use \kakao\Kakao_REST_API_Helper as Kakao_REST_API_Helper;
$RootDB = RootDB::db(); $RootDB = RootDB::db();
$session = Session::getInstance(); $session = Session::getInstance();
if($session->isLoggedIn()){ if ($session->isLoggedIn()) {
$session->logout(); $session->logout();
} }
$username = mb_strtolower(Util::getReq('username'), 'utf-8'); $username = mb_strtolower(Util::getReq('username'), 'utf-8');
$password = Util::getReq('password'); $password = Util::getReq('password');
if(!$username || !$password){ if (!$username || !$password) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reqOTP'=>false, 'reqOTP' => false,
'reason'=>'올바르지 않은 입력입니다.' 'reason' => '올바르지 않은 입력입니다.'
]); ]);
} }
function kakaoOAuthCheck(array $userInfo) : ?array { function kakaoOAuthCheck(array $userInfo): ?array
{
if(!\kakao\KakaoKey::REST_KEY){ if (!\kakao\KakaoKey::REST_KEY) {
return [false, '카카오 API 앱이 등록되지 않았습니다. 관리자에게 문의해 주세요.']; return [false, '카카오 API 앱이 등록되지 않았습니다. 관리자에게 문의해 주세요.'];
} }
$oauthID = $userInfo['oauth_id']; $oauthID = $userInfo['oauth_id'];
$oauthInfo = Json::decode($userInfo['oauth_info'])??[]; $oauthInfo = Json::decode($userInfo['oauth_info']) ?? [];
if(!$oauthInfo){ if (!$oauthInfo) {
return [false, 'OAuth 정보가 보관되어 있지 않습니다. 카카오 로그인을 수행해 주세요.']; return [false, 'OAuth 정보가 보관되어 있지 않습니다. 카카오 로그인을 수행해 주세요.'];
} }
$accessToken = $oauthInfo['accessToken']??null; $accessToken = $oauthInfo['accessToken'] ?? null;
$refreshToken = $oauthInfo['refreshToken']??null; $refreshToken = $oauthInfo['refreshToken'] ?? null;
$accessTokenValidUntil = $oauthInfo['accessTokenValidUntil']??null; $accessTokenValidUntil = $oauthInfo['accessTokenValidUntil'] ?? null;
$refreshTokenValidUntil = $oauthInfo['refreshTokenValidUntil']??null; $refreshTokenValidUntil = $oauthInfo['refreshTokenValidUntil'] ?? null;
$OTPValue = $oauthInfo['OTPValue']??null; $OTPValue = $oauthInfo['OTPValue'] ?? null;
$OTPTrialUntil = $oauthInfo['OTPTrialUntil']??null; $OTPTrialUntil = $oauthInfo['OTPTrialUntil'] ?? null;
$tokenValidUntil = $userInfo['token_valid_until']; $tokenValidUntil = $userInfo['token_valid_until'];
if(!$accessToken || !$refreshToken || !$accessTokenValidUntil || !$refreshTokenValidUntil){ if (!$accessToken || !$refreshToken || !$accessTokenValidUntil || !$refreshTokenValidUntil) {
return [false, 'OAuth 정보가 보관되어 있지 않습니다. 카카오 로그인을 수행해 주세요.']; return [false, 'OAuth 정보가 보관되어 있지 않습니다. 카카오 로그인을 수행해 주세요.'];
} }
$now = TimeUtil::now(); $now = TimeUtil::now();
if($now > $refreshTokenValidUntil){ if ($now > $refreshTokenValidUntil) {
return [false, '로그인 토큰이 만료되었습니다. 카카오 로그인을 수행해 주세요.']; return [false, '로그인 토큰이 만료되었습니다. 카카오 로그인을 수행해 주세요.'];
} }
if($now > $accessTokenValidUntil){ if ($now > $accessTokenValidUntil) {
$apiHelper = new Kakao_REST_API_Helper($accessToken); $apiHelper = new Kakao_REST_API_Helper($accessToken);
$refreshResult = $apiHelper->refresh_access_token($refreshToken); $refreshResult = $apiHelper->refresh_access_token($refreshToken);
if(!$refreshResult){ if (!$refreshResult) {
return [false, '로그인 토큰 자동 갱신을 실패했습니다. 카카오 로그인을 수행해 주세요.']; return [false, '로그인 토큰 자동 갱신을 실패했습니다. 카카오 로그인을 수행해 주세요.'];
} }
$accessToken = $refreshResult['access_token']??null; $accessToken = $refreshResult['access_token'] ?? null;
if(!$accessToken){ if (!$accessToken) {
trigger_error("refreshToken 에러 ".Json::encode($refreshResult).",".$refreshToken.",".substr(\kakao\KakaoKey::REST_KEY, 0, 6), E_USER_NOTICE); trigger_error("refreshToken 에러 " . Json::encode($refreshResult) . "," . $refreshToken . "," . substr(\kakao\KakaoKey::REST_KEY, 0, 6), E_USER_NOTICE);
return [false, '로그인 토큰 자동 갱신을 실패했습니다. 카카오 로그인을 수행해 주세요.']; return [false, '로그인 토큰 자동 갱신을 실패했습니다. 카카오 로그인을 수행해 주세요.'];
} }
$accessTokenValidUntil = TimeUtil::nowAddSeconds($refreshResult['expires_in']); $accessTokenValidUntil = TimeUtil::nowAddSeconds($refreshResult['expires_in']);
@@ -71,20 +73,20 @@ function kakaoOAuthCheck(array $userInfo) : ?array {
$oauthInfo['accessToken'] = $accessToken; $oauthInfo['accessToken'] = $accessToken;
$oauthInfo['accessTokenValidUntil'] = $accessTokenValidUntil; $oauthInfo['accessTokenValidUntil'] = $accessTokenValidUntil;
$refreshToken = $refreshResult['refresh_token']??null; $refreshToken = $refreshResult['refresh_token'] ?? null;
if($refreshToken){ if ($refreshToken) {
$refreshTokenValidUntil = TimeUtil::nowAddSeconds($refreshResult['refresh_token_expires_in']); $refreshTokenValidUntil = TimeUtil::nowAddSeconds($refreshResult['refresh_token_expires_in']);
$oauthInfo['refreshToken'] = $refreshToken; $oauthInfo['refreshToken'] = $refreshToken;
$oauthInfo['refresh_token_expires_in'] = $refreshTokenValidUntil; $oauthInfo['refresh_token_expires_in'] = $refreshTokenValidUntil;
} }
RootDB::db()->update('member', [ RootDB::db()->update('member', [
'oauth_info'=>Json::encode($oauthInfo) 'oauth_info' => Json::encode($oauthInfo)
], 'no=%i', $userInfo['no']); ], 'no=%i', $userInfo['no']);
} }
if($tokenValidUntil && $now <= $tokenValidUntil){ if ($tokenValidUntil && $now <= $tokenValidUntil) {
return null; return null;
} }
@@ -95,7 +97,7 @@ function kakaoOAuthCheck(array $userInfo) : ?array {
$session->refresh_token = $refreshToken; $session->refresh_token = $refreshToken;
$session->refresh_token_expires = $refreshTokenValidUntil; $session->refresh_token_expires = $refreshTokenValidUntil;
if(!createOTPbyUserNO($userInfo['no'])){ if (!createOTPbyUserNO($userInfo['no'])) {
return [false, '인증 코드를 보내는데 실패했습니다.']; return [false, '인증 코드를 보내는데 실패했습니다.'];
} }
@@ -103,75 +105,75 @@ function kakaoOAuthCheck(array $userInfo) : ?array {
} }
$userInfo = $RootDB->queryFirstRow( $userInfo = $RootDB->queryFirstRow(
'SELECT `no`, `id`, `name`, `grade`, `delete_after`, `acl`, oauth_id, oauth_type, oauth_info, token_valid_until '. 'SELECT `no`, `id`, `name`, `grade`, `delete_after`, `acl`, oauth_id, oauth_type, oauth_info, token_valid_until ' .
'from member where id=%s_username AND '. 'from member where id=%s_username AND ' .
'pw=sha2(concat(salt, %s_password, salt), 512)',[ 'pw=sha2(concat(salt, %s_password, salt), 512)',
'username'=>$username, [
'password'=>$password 'username' => $username,
]); 'password' => $password
]
);
if(!$userInfo){ if (!$userInfo) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reqOTP'=>false, 'reqOTP' => false,
'reason'=>'아이디나 비밀번호가 올바르지 않습니다.' 'reason' => '아이디나 비밀번호가 올바르지 않습니다.'
]); ]);
} }
$canLogin = $RootDB->queryFirstField('SELECT `LOGIN` FROM `system` WHERE `NO` = 1'); $canLogin = $RootDB->queryFirstField('SELECT `LOGIN` FROM `system` WHERE `NO` = 1');
if($canLogin != 'Y' && $userInfo['grade'] < 5){ if ($canLogin != 'Y' && $userInfo['grade'] < 5) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>'현재는 로그인이 금지되어있습니다!' 'reason' => '현재는 로그인이 금지되어있습니다!'
]); ]);
} }
$nowDate = TimeUtil::now(); $nowDate = TimeUtil::now();
if($userInfo['delete_after']){ if ($userInfo['delete_after']) {
if($userInfo['delete_after'] < $nowDate){ if ($userInfo['delete_after'] < $nowDate) {
$RootDB->delete('member', 'no=%i', $userInfo['no']); $RootDB->delete('member', 'no=%i', $userInfo['no']);
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reqOTP'=>false, 'reqOTP' => false,
'reason'=>"기간 만기로 삭제되었습니다. 재 가입을 시도해주세요." 'reason' => "기간 만기로 삭제되었습니다. 재 가입을 시도해주세요."
]); ]);
} } else {
else{
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reqOTP'=>false, 'reqOTP' => false,
'reason'=>"삭제 요청된 계정입니다.[{$userInfo['delete_after']}]" 'reason' => "삭제 요청된 계정입니다.[{$userInfo['delete_after']}]"
]); ]);
} }
} }
$RootDB->insert('member_log',[ $RootDB->insert('member_log', [
'member_no'=>$userInfo['no'], 'member_no' => $userInfo['no'],
'action_type'=>'login', 'action_type' => 'login',
'action'=>Json::encode([ 'action' => Json::encode([
'ip'=>Util::get_client_ip(true), 'ip' => Util::get_client_ip(true),
'type'=>'plain' 'type' => 'plain'
]) ])
]); ]);
if($userInfo['oauth_type'] == 'KAKAO'){ if ($userInfo['oauth_type'] == 'KAKAO') {
$oauthFailResult = kakaoOAuthCheck($userInfo); $oauthFailResult = kakaoOAuthCheck($userInfo);
if($oauthFailResult !== null){ if ($oauthFailResult !== null) {
$session->login($userInfo['no'], $userInfo['id'], $userInfo['grade'], true, $userInfo['token_valid_until'], Json::decode($userInfo['acl']??'{}')); $session->login($userInfo['no'], $userInfo['id'], $userInfo['grade'], true, $userInfo['token_valid_until'], Json::decode($userInfo['acl'] ?? '{}'));
[$oauthReqOTP, $oauthFailReason] = $oauthFailResult; [$oauthReqOTP, $oauthFailReason] = $oauthFailResult;
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reqOTP'=>$oauthReqOTP, 'reqOTP' => $oauthReqOTP,
'reason'=>$oauthFailReason 'reason' => $oauthFailReason
]); ]);
} }
} }
$session->login($userInfo['no'], $userInfo['id'], $userInfo['grade'], false, $userInfo['token_valid_until'], Json::decode($userInfo['acl']??'{}')); $session->login($userInfo['no'], $userInfo['id'], $userInfo['grade'], false, $userInfo['token_valid_until'], Json::decode($userInfo['acl'] ?? '{}'));
Json::die([ Json::die([
'result'=>true, 'result' => true,
'reqOTP'=>false, 'reqOTP' => false,
'reason'=>'로그인 되었습니다.' 'reason' => '로그인 되었습니다.'
]); ]);
+85 -86
View File
@@ -1,21 +1,21 @@
<?php <?php
namespace sammo; namespace sammo;
require(__DIR__.'/vendor/autoload.php'); require(__DIR__ . '/vendor/autoload.php');
function getVersion($target=null){ function getVersion($target = null)
if($target){ {
if ($target) {
$command = sprintf('git describe %s --long --tags', escapeshellarg($target)); $command = sprintf('git describe %s --long --tags', escapeshellarg($target));
} } else {
else{
$command = 'git describe --long --tags'; $command = 'git describe --long --tags';
} }
exec($command, $output); exec($command, $output);
if(is_array($output)){ if (is_array($output)) {
$output = join('', $output); $output = join('', $output);
} }
return trim($output); return trim($output);
} }
$session = Session::requireLogin(null)->setReadOnly(); $session = Session::requireLogin(null)->setReadOnly();
@@ -32,10 +32,10 @@ $v->rule('required', [
'server' 'server'
])->rule('regex', 'target', '/^[0-9a-zA-Z^{}\\/\-_,.@]+$/'); ])->rule('regex', 'target', '/^[0-9a-zA-Z^{}\\/\-_,.@]+$/');
if(!$v->validate()){ if (!$v->validate()) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>$v->errorStr() 'reason' => $v->errorStr()
]); ]);
} }
@@ -43,177 +43,174 @@ $target = Util::getReq('target');
$server = basename($request['server']); $server = basename($request['server']);
$allowFullUpdate = in_array('fullUpdate', $session->acl[$server]??[]); $allowFullUpdate = in_array('fullUpdate', $session->acl[$server] ?? []);
$allowFullUpdate |= $session->userGrade >= 6; $allowFullUpdate |= $session->userGrade >= 6;
$allowUpdate = in_array('update', $session->acl[$server]??[]); $allowUpdate = in_array('update', $session->acl[$server] ?? []);
$allowUpdate |= $session->userGrade >= 5; $allowUpdate |= $session->userGrade >= 5;
$allowUpdate |= $allowFullUpdate; $allowUpdate |= $allowFullUpdate;
if(!$allowUpdate){ if (!$allowUpdate) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>'권한이 충분하지 않습니다' 'reason' => '권한이 충분하지 않습니다'
]); ]);
} }
$src_target = $storage->$server; $src_target = $storage->$server;
if($src_target){ if ($src_target) {
$src_target = $src_target[0]; $src_target = $src_target[0];
} }
if(!$allowFullUpdate || !$target){ if (!$allowFullUpdate || !$target) {
$target = $src_target; $target = $src_target;
} } else {
else{
$target = $request['target']; $target = $request['target'];
} }
$baseServerName = Util::array_last_key(AppConf::getList()); $baseServerName = Util::array_last_key(AppConf::getList());
if(!$target && $server != $baseServerName){ if (!$target && $server != $baseServerName) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>'git -ish target이 제대로 지정되지 않았습니다.' 'reason' => 'git -ish target이 제대로 지정되지 않았습니다.'
]); ]);
} }
$targetDir =$target.':'.$baseServerName; $targetDir = $target . ':' . $baseServerName;
if(!key_exists($server, AppConf::getList())){ if (!key_exists($server, AppConf::getList())) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>'불가능한 서버 이름입니다.' 'reason' => '불가능한 서버 이름입니다.'
]); ]);
} }
if(\file_exists($server) && !is_dir($server)){ if (\file_exists($server) && !is_dir($server)) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>'같은 이름을 가진 파일이 있습니다.' 'reason' => '같은 이름을 가진 파일이 있습니다.'
]); ]);
} }
if(file_exists($server) && !is_writable($server)){ if (file_exists($server) && !is_writable($server)) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>$server.' 디렉토리 쓰기 권한이 없습니다.' 'reason' => $server . ' 디렉토리 쓰기 권한이 없습니다.'
]); ]);
} }
if(!file_exists($server)){ if (!file_exists($server)) {
if(!is_writable('.')){ if (!is_writable('.')) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>$server.' 디렉토리가 없지만 생성할 권한이 없습니다.' 'reason' => $server . ' 디렉토리가 없지만 생성할 권한이 없습니다.'
]); ]);
} }
mkdir($server, 0755); mkdir($server, 0755);
} }
if($server == $baseServerName){ if ($server == $baseServerName) {
exec("git fetch -q 2>&1", $output); exec("git fetch -q 2>&1", $output);
if($output){ if ($output) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>'git pull 작업 : '.join(', ', $output) 'reason' => 'git pull 작업 : ' . join(', ', $output)
]); ]);
} }
if($target != $src_target){ if ($target != $src_target) {
$command = sprintf('git checkout %s -q 2>&1', $target); $command = sprintf('git checkout %s -q 2>&1', $target);
exec($command, $output); exec($command, $output);
if($output){ if ($output) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>join(', ', $output) 'reason' => join(', ', $output)
]); ]);
} }
} }
exec("git pull -q 2>&1", $output); exec("git pull -q 2>&1", $output);
if($output && $output[0] != 'Already up-to-date.'){ if ($output && $output[0] != 'Already up-to-date.') {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>'git pull 작업 : '.join(', ', $output) 'reason' => 'git pull 작업 : ' . join(', ', $output)
]); ]);
} }
$version = getVersion(); $version = getVersion();
$result = Util::generateFileUsingSimpleTemplate( $result = Util::generateFileUsingSimpleTemplate(
__DIR__.'/'.$server.'/d_setting/VersionGit.orig.php', __DIR__ . '/' . $server . '/d_setting/VersionGit.orig.php',
__DIR__.'/'.$server.'/d_setting/VersionGit.php',[ __DIR__ . '/' . $server . '/d_setting/VersionGit.php',
'verionGit'=>$version [
], true 'verionGit' => $version
],
true
); );
if(ServConfig::$imageRequestKey){ if (ServConfig::$imageRequestKey) {
try { try {
$imagePullPath = ServConfig::getImagePullURI(); $imagePullPath = ServConfig::getImagePullURI();
$pullResult = @file_get_contents($imagePullPath); $pullResult = @file_get_contents($imagePullPath);
if($pullResult === false){ if ($pullResult === false) {
throw new \ErrorException('Invalid URI'); throw new \ErrorException('Invalid URI');
} }
$pullResult = Json::decode($pullResult); $pullResult = Json::decode($pullResult);
if($pullResult['result']){ if ($pullResult['result']) {
$imgResult = true; $imgResult = true;
$imgDetail = $pullResult['version']; $imgDetail = $pullResult['version'];
} } else {
else{
$imgResult = false; $imgResult = false;
$imgDetail = $pullResult['reason']; $imgDetail = $pullResult['reason'];
} }
} } catch (\Exception $e) {
catch(\Exception $e){
$imgResult = false; $imgResult = false;
$imgDetail = $e->getMessage(); $imgDetail = $e->getMessage();
} }
} } else {
else{
$imgResult = true; $imgResult = true;
$imgDetail = 'No key'; $imgDetail = 'No key';
} }
$storage->$server = [$target, $version]; $storage->$server = [$target, $version];
opcache_reset(); opcache_reset();
Json::die([ Json::die([
'server'=>$server, 'server' => $server,
'result'=>true, 'result' => true,
'version'=>$version, 'version' => $version,
'imgResult'=>$imgResult, 'imgResult' => $imgResult,
'imgDetail'=>$imgDetail, 'imgDetail' => $imgDetail,
]); ]);
} }
$command = sprintf('git archive --format=zip -o %s %s', escapeshellarg($tmpFile), escapeshellarg($targetDir)); $command = sprintf('git archive --format=zip -o %s %s', escapeshellarg($tmpFile), escapeshellarg($targetDir));
exec("$command 2>&1", $output); exec("$command 2>&1", $output);
if($output){ if ($output) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>join(', ', $output) 'reason' => join(', ', $output)
]); ]);
} }
$zip = new \ZipArchive; $zip = new \ZipArchive;
if($zip->open($tmpFile) !== true){ if ($zip->open($tmpFile) !== true) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>'archive가 생성되지 않았습니다.' 'reason' => 'archive가 생성되지 않았습니다.'
]); ]);
} }
if(!$zip->extractTo($server)){ if (!$zip->extractTo($server)) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>'생성한 archive를 제대로 옮기지 못했습니다.' 'reason' => '생성한 archive를 제대로 옮기지 못했습니다.'
]); ]);
} }
@@ -222,10 +219,12 @@ $zip->close();
$version = getVersion($target); $version = getVersion($target);
$result = Util::generateFileUsingSimpleTemplate( $result = Util::generateFileUsingSimpleTemplate(
__DIR__.'/'.$server.'/d_setting/VersionGit.orig.php', __DIR__ . '/' . $server . '/d_setting/VersionGit.orig.php',
__DIR__.'/'.$server.'/d_setting/VersionGit.php',[ __DIR__ . '/' . $server . '/d_setting/VersionGit.php',
'verionGit'=>$version [
], true 'verionGit' => $version
],
true
); );
$storage->$server = [$target, $version]; $storage->$server = [$target, $version];
@@ -233,7 +232,7 @@ $storage->$server = [$target, $version];
opcache_reset(); opcache_reset();
Json::die([ Json::die([
'server'=>$server, 'server' => $server,
'result'=>true, 'result' => true,
'version'=>$version 'version' => $version
]); ]);
+48 -45
View File
@@ -1,38 +1,38 @@
<?php <?php
namespace sammo; namespace sammo;
require(__DIR__.'/vendor/autoload.php'); require(__DIR__ . '/vendor/autoload.php');
$session = Session::requireLogin('./')->setReadOnly(); $session = Session::requireLogin('./')->setReadOnly();
if(key_exists('from', $_REQUEST) && is_numeric($_REQUEST['from'])){ if (key_exists('from', $_REQUEST) && is_numeric($_REQUEST['from'])) {
$from = (int)$_REQUEST['from']; $from = (int) $_REQUEST['from'];
if($from < 0){ if ($from < 0) {
$from = 0; $from = 0;
} }
} } else {
else{
$from = 0; $from = 0;
} }
$allowUpdate = false; $allowUpdate = false;
foreach($session->acl as $eachAcl){ foreach ($session->acl as $eachAcl) {
if(in_array('fullUpdate', $eachAcl)){ if (in_array('fullUpdate', $eachAcl)) {
$allowUpdate = true; $allowUpdate = true;
break; break;
} }
if(in_array('update', $eachAcl)){ if (in_array('update', $eachAcl)) {
$allowUpdate = true; $allowUpdate = true;
break; break;
} }
} }
$allowUpdate |= $session->userGrade >= 5; $allowUpdate |= $session->userGrade >= 5;
if(!$allowUpdate){ if (!$allowUpdate) {
header('Location:./'); header('Location:./');
} }
$fdb = FileDB::db(ROOT.'/d_log/err_log.sqlite3', ROOT.'/f_install/sql/err_log.sql'); $fdb = FileDB::db(ROOT . '/d_log/err_log.sqlite3', ROOT . '/f_install/sql/err_log.sql');
$err_logs = $fdb->select('err_log', [ $err_logs = $fdb->select('err_log', [
'date', 'date',
@@ -42,48 +42,51 @@ $err_logs = $fdb->select('err_log', [
'trace', 'trace',
'webuser' 'webuser'
], [ ], [
'ORDER'=>['id'=>'DESC'], 'ORDER' => ['id' => 'DESC'],
'LIMIT'=>[$from, 100] 'LIMIT' => [$from, 100]
]); ]);
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" />
<title>에러 로그</title>
<!-- 스타일 --> <head>
<?=WebUtil::printCSS('e_lib/bootstrap.min.css')?> <meta charset="UTF-8">
<?=WebUtil::printCSS('d_shared/common.css')?> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" />
<title>에러 로그</title>
<?=WebUtil::printJS('e_lib/jquery-3.3.1.min.js')?> <!-- 스타일 -->
<?=WebUtil::printJS('d_shared/common_path.js')?> <?= WebUtil::printCSS('e_lib/bootstrap.min.css') ?>
<?=WebUtil::printJS('e_lib/bootstrap.bundle.min.js')?> <?= WebUtil::printCSS('d_shared/common.css') ?>
<?= WebUtil::printJS('e_lib/jquery-3.3.1.min.js') ?>
<?= WebUtil::printJS('d_shared/common_path.js') ?>
<?= WebUtil::printJS('e_lib/bootstrap.bundle.min.js') ?>
</head> </head>
<body> <body>
<div class="container"> <div class="container">
<?php foreach($err_logs as $err): ?> <?php foreach ($err_logs as $err) : ?>
<div class="card"> <div class="card">
<div class="card-header"> <div class="card-header">
<?=htmlspecialchars($err['err'])?> - <?=$err['date']?> <?= htmlspecialchars($err['err']) ?> - <?= $err['date'] ?>
</div> </div>
<div class="card-body"> <div class="card-body">
<div class="card-title"><?=htmlspecialchars($err['errstr'])?></div> <div class="card-title"><?= htmlspecialchars($err['errstr']) ?></div>
<ul class="list-group list-group-flush"> <ul class="list-group list-group-flush">
<?php if($err['errpath']): ?> <?php if ($err['errpath']) : ?>
<li class="list-group-item"><?=htmlspecialchars($err['errpath'])?></li> <li class="list-group-item"><?= htmlspecialchars($err['errpath']) ?></li>
<?php endif; ?> <?php endif; ?>
<?php foreach(Json::decode($err['trace']) as $trace): ?> <?php foreach (Json::decode($err['trace']) as $trace) : ?>
<li class="list-group-item"><?=htmlspecialchars($trace)?></li> <li class="list-group-item"><?= htmlspecialchars($trace) ?></li>
<?php endforeach; ?> <?php endforeach; ?>
<li class="list-group-item"><?=htmlspecialchars($err['webuser'])?></li> <li class="list-group-item"><?= htmlspecialchars($err['webuser']) ?></li>
</ul> </ul>
</div> </div>
</div>
<?php endforeach; ?>
<a href="showErrorLog.php?from=<?= $from + 100 ?>" class="btn btn-primary btn-lg active" role="button">+100</a>
</div> </div>
<?php endforeach; ?>
<a href="showErrorLog.php?from=<?=$from+100?>" class="btn btn-primary btn-lg active" role="button">+100</a>
</div>
</body> </body>
</html> </html>
+8 -4
View File
@@ -451,7 +451,8 @@ class JosaUtil{
private static $init = false; private static $init = false;
private static function init(){ private static function init()
{
if(JosaUtil::$init){ if(JosaUtil::$init){
return; return;
} }
@@ -502,7 +503,8 @@ class JosaUtil{
return false; return false;
} }
private static function checkCode(int $code, bool $isRo){ private static function checkCode(int $code, bool $isRo)
{
JosaUtil::init(); JosaUtil::init();
$jongsung = ($code - JosaUtil::KO_START_CODE) % 28; $jongsung = ($code - JosaUtil::KO_START_CODE) % 28;
@@ -517,7 +519,8 @@ class JosaUtil{
return true; return true;
} }
public static function check(string $text, string $type){ public static function check(string $text, string $type)
{
JosaUtil::init(); JosaUtil::init();
$htarget = preg_replace(JosaUtil::REG_INVALID_CHAR_W_HANJA, ' ', $text); $htarget = preg_replace(JosaUtil::REG_INVALID_CHAR_W_HANJA, ' ', $text);
@@ -560,7 +563,8 @@ class JosaUtil{
return JosaUtil::checkText($target, $isRo); return JosaUtil::checkText($target, $isRo);
} }
public static function pick($text, string $wJongsung, string $woJongsung=''){ public static function pick($text, string $wJongsung, string $woJongsung='')
{
/* NOTE:원본 코드와 인자 순서가 다름. /* NOTE:원본 코드와 인자 순서가 다름.
* 원본은 pick('바람', '랑', '이랑'); 이었다면 JosaUtil::pick('바람', '이랑', '랑'); 으로 바뀜. * 원본은 pick('바람', '랑', '이랑'); 이었다면 JosaUtil::pick('바람', '이랑', '랑'); 으로 바뀜.
* JosaUtil::pick('바람', '은', '는'); JosaUti::pick('바람', '이', '가');처럼 쓰기 위해서임. * JosaUtil::pick('바람', '은', '는'); JosaUti::pick('바람', '이', '가');처럼 쓰기 위해서임.