국기 변경 수정, 아이템 보상 추가

This commit is contained in:
2020-05-05 17:24:03 +09:00
parent 8b8f749006
commit a378ac8738
8 changed files with 1240 additions and 1045 deletions
+710 -619
View File
@@ -1,4 +1,5 @@
<?php
namespace sammo;
use sammo\Event\Action;
@@ -26,7 +27,7 @@ require_once('func_command.php');
*
* @return array|null nationID에 해당하는 국가가 있을 경우 array 반환. 그외의 경우 null
*/
function getNationStaticInfo($nationID, $forceRefresh=false)
function getNationStaticInfo($nationID, $forceRefresh = false)
{
static $nationList = null;
@@ -35,38 +36,38 @@ function getNationStaticInfo($nationID, $forceRefresh=false)
}
if ($nationID === null) {
return null;
return null;
}
if($nationID === -1 && $nationList !== null){
if ($nationID === -1 && $nationList !== null) {
return $nationList;
}
if($nationID === 0){
if ($nationID === 0) {
return [
'nation'=>0,
'name'=>'재야',
'color'=>'#000000',
'type'=>GameConst::$neutralNationType,
'level'=>0,
'capital'=>0,
'gold'=>0,
'rice'=>2000,
'tech'=>0,
'gennum'=>1,
'power'=>1
'nation' => 0,
'name' => '재야',
'color' => '#000000',
'type' => GameConst::$neutralNationType,
'level' => 0,
'capital' => 0,
'gold' => 0,
'rice' => 2000,
'tech' => 0,
'gennum' => 1,
'power' => 1
];
}
if($nationList === null){
if ($nationList === null) {
$nationAll = DB::db()->query("select nation, name, color, type, level, capital, gennum, power from nation");
$nationList = Util::convertArrayToDict($nationAll, "nation");
}
if($nationID === -1){
if ($nationID === -1) {
return $nationList;
}
if(isset($nationList[$nationID])){
if (isset($nationList[$nationID])) {
return $nationList[$nationID];
}
return null;
@@ -88,8 +89,9 @@ function getAllNationStaticInfo()
return getNationStaticInfo(-1);
}
function GetImageURL($imgsvr, $filepath='') {
if($imgsvr == 0) {
function GetImageURL($imgsvr, $filepath = '')
{
if ($imgsvr == 0) {
return ServConfig::getSharedIconPath($filepath);
} else {
return AppConf::getUserIconPathWeb($filepath);
@@ -100,35 +102,38 @@ function GetImageURL($imgsvr, $filepath='') {
* @param null|int $con 장수의 벌점
* @param null|int $conlimit 최대 벌점
*/
function checkLimit($con = null) {
function checkLimit($con = null)
{
$session = Session::getInstance();
if($session->userGrade>=4){
if ($session->userGrade >= 4) {
return 0;
}
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
if($con === null){
if ($con === null) {
$con = $db->queryFirstField('SELECT con FROM general WHERE `owner`=%i', Session::getUserID());
}
$conlimit = $gameStor->conlimit;
if($con > $conlimit) {
if ($con > $conlimit) {
return 2;
//접속제한 90%이면 경고문구
} elseif($con > $conlimit * 0.9) {
//접속제한 90%이면 경고문구
} elseif ($con > $conlimit * 0.9) {
return 1;
} else {
return 0;
}
}
function getBlockLevel() {
function getBlockLevel()
{
return DB::db()->queryFirstField('select block from general where no = %i', Session::getInstance()->generalID);
}
function getRandGenName() {
function getRandGenName()
{
$firstname = Util::choiceRandom(GameConst::$randGenFirstName);
$middlename = Util::choiceRandom(GameConst::$randGenMiddleName);
$lastname = Util::choiceRandom(GameConst::$randGenLastName);
@@ -138,7 +143,8 @@ function getRandGenName() {
function cityInfo(General $generalObj) {
function cityInfo(General $generalObj)
{
$db = DB::db();
// 도시 정보
@@ -147,7 +153,7 @@ function cityInfo(General $generalObj) {
$nation = getNationStaticInfo($city['nation']);
if(!$nation){
if (!$nation) {
$nation = getNationStaticInfo(0);
}
@@ -158,12 +164,12 @@ function cityInfo(General $generalObj) {
$city['levelText'] = CityConst::$levelMap[$city['level']];
$officerName = [
2=>'-',
3=>'-',
4=>'-'
2 => '-',
3 => '-',
4 => '-'
];
foreach($db->query('SELECT `officer_level`, `name`, npc, no FROM general WHERE officer_city = %i', $cityID) as $officer){
foreach ($db->query('SELECT `officer_level`, `name`, npc, no FROM general WHERE officer_city = %i', $cityID) as $officer) {
$officerName[$officer['officer_level']] = getColoredName($officer['name'], $officer['npc']);
}
@@ -174,117 +180,146 @@ function cityInfo(General $generalObj) {
return $templates->render('mainCityInfo', $city);
}
function myNationInfo() {
function myNationInfo()
{
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$connect=$db->get();
$connect = $db->get();
$userID = Session::getUserID();
$admin = $gameStor->getValues(['startyear','year']);
$admin = $gameStor->getValues(['startyear', 'year']);
$query = "select no,nation from general where owner='{$userID}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$result = MYDB_query($query, $connect) or Error(__LINE__ . MYDB_error($connect), "");
$me = MYDB_fetch_array($result);
$query = "select nation,name,color,power,msg,gold,rice,bill,rate,scout,war,strategic_cmd_limit,surlimit,tech,level,type from nation where nation='{$me['nation']}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$result = MYDB_query($query, $connect) or Error(__LINE__ . MYDB_error($connect), "");
$nation = MYDB_fetch_array($result);
$query = "select COUNT(*) as cnt, SUM(pop) as totpop, SUM(pop_max) as maxpop from city where nation='{$nation['nation']}'"; // 도시 이름 목록
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$result = MYDB_query($query, $connect) or Error(__LINE__ . MYDB_error($connect), "");
$city = MYDB_fetch_array($result);
$query = "select COUNT(*) as cnt, SUM(crew) as totcrew,SUM(leadership)*100 as maxcrew from general where nation='{$nation['nation']}'"; // 장수 목록
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$result = MYDB_query($query, $connect) or Error(__LINE__ . MYDB_error($connect), "");
$general = MYDB_fetch_array($result);
$query = "select name from general where nation='{$nation['nation']}' and officer_level='12'";
$genresult = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$genresult = MYDB_query($query, $connect) or Error(__LINE__ . MYDB_error($connect), "");
$level12 = MYDB_fetch_array($genresult);
$query = "select name from general where nation='{$nation['nation']}' and officer_level='11'";
$genresult = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$genresult = MYDB_query($query, $connect) or Error(__LINE__ . MYDB_error($connect), "");
$level11 = MYDB_fetch_array($genresult);
echo "<table width=498 class='tb_layout bg2 nation_info'>
<tr>
<td colspan=4 ";
if($me['nation'] == 0) { echo "style='color:white;background-color:000000;font-weight:bold;font-size:13px;text-align:center;'>【재 야】"; }
else { echo "style='color:".newColor($nation['color']).";background-color:{$nation['color']};font-weight:bold;font-size:13px;text-align:center'>국가【 {$nation['name']} "; }
if ($me['nation'] == 0) {
echo "style='color:white;background-color:000000;font-weight:bold;font-size:13px;text-align:center;'>【재 야";
} else {
echo "style='color:" . newColor($nation['color']) . ";background-color:{$nation['color']};font-weight:bold;font-size:13px;text-align:center'>국가【 {$nation['name']}";
}
echo "
</td>
</tr>
<tr>
<td class='bg1 center'><b>성 향</b></td>
<td colspan=3 class='center'><font color=\"yellow\">".getNationType($nation['type'])."</font> (".getNationType2($nation['type']).")</td>
<td colspan=3 class='center'><font color=\"yellow\">" . getNationType($nation['type']) . "</font> (" . getNationType2($nation['type']) . ")</td>
</td>
</tr>
<tr>
<td width=68 class='bg1 center'><b>".getOfficerLevelText(12, $nation['level'])."</b></td>
<td width=178 class='center'>";echo $level12?$level12['name']:"-"; echo "</td>
<td width=68 class='bg1 center'><b>".getOfficerLevelText(11, $nation['level'])."</b></td>
<td width=178 class='center'>";echo $level11?$level11['name']:"-"; echo "</td>
<td width=68 class='bg1 center'><b>" . getOfficerLevelText(12, $nation['level']) . "</b></td>
<td width=178 class='center'>";
echo $level12 ? $level12['name'] : "-";
echo "</td>
<td width=68 class='bg1 center'><b>" . getOfficerLevelText(11, $nation['level']) . "</b></td>
<td width=178 class='center'>";
echo $level11 ? $level11['name'] : "-";
echo "</td>
</tr>
<tr>
<td class='bg1 center'><b>총주민</b></td>
<td class='center'>";echo $me['nation']==0?"해당 없음":"{$city['totpop']}/{$city['maxpop']}";echo "</td>
<td class='center'>";
echo $me['nation'] == 0 ? "해당 없음" : "{$city['totpop']}/{$city['maxpop']}";
echo "</td>
<td class='bg1 center'><b>총병사</b></td>
<td class='center'>";echo $me['nation']==0?"해당 없음":"{$general['totcrew']}/{$general['maxcrew']}"; echo "</td>
<td class='center'>";
echo $me['nation'] == 0 ? "해당 없음" : "{$general['totcrew']}/{$general['maxcrew']}";
echo "</td>
</td>
</tr>
<tr>
<td class='bg1 center'><b>국 고</b></td>
<td class='center'>";echo $me['nation']==0?"해당 없음":"{$nation['gold']}";echo "</td>
<td class='center'>";
echo $me['nation'] == 0 ? "해당 없음" : "{$nation['gold']}";
echo "</td>
<td class='bg1 center'><b>병 량</b></td>
<td class='center'>";echo $me['nation']==0?"해당 없음":"{$nation['rice']}";echo "</td>
<td class='center'>";
echo $me['nation'] == 0 ? "해당 없음" : "{$nation['rice']}";
echo "</td>
</tr>
<tr>
<td class='bg1 center'><b>지급률</b></td>
<td class='center'>";
if($me['nation'] == 0) {
if ($me['nation'] == 0) {
echo "해당 없음";
} else {
echo $nation['bill']==0?"0 %":"{$nation['bill']} %";
echo $nation['bill'] == 0 ? "0 %" : "{$nation['bill']} %";
}
echo "
</td>
<td class='bg1 center'><b>세 율</b></td>
<td class='center'>";
if($me['nation'] == 0) {
if ($me['nation'] == 0) {
echo "해당 없음";
} else {
echo $nation['rate']==0?"0 %":"{$nation['rate']} %";
echo $nation['rate'] == 0 ? "0 %" : "{$nation['rate']} %";
}
$techCall = getTechCall($nation['tech']);
if(TechLimit($admin['startyear'], $admin['year'], $nation['tech'])) { $nation['tech'] = "<font color=magenta>".floor($nation['tech'])."</font>"; }
else { $nation['tech'] = "<font color=limegreen>".floor($nation['tech'])."</font>"; }
if (TechLimit($admin['startyear'], $admin['year'], $nation['tech'])) {
$nation['tech'] = "<font color=magenta>" . floor($nation['tech']) . "</font>";
} else {
$nation['tech'] = "<font color=limegreen>" . floor($nation['tech']) . "</font>";
}
$nation['tech'] = "$techCall / {$nation['tech']}";
if($me['nation']==0){
if ($me['nation'] == 0) {
$nation['strategic_cmd_limit'] = "<font color=white>해당 없음</font>";
$nation['surlimit'] = "<font color=white>해당 없음</font>";
$nation['scout'] = "<font color=white>해당 없음</font>";
$nation['war'] = "<font color=white>해당 없음</font>";
$nation['power'] = "<font color=white>해당 없음</font>";
} else {
if($nation['strategic_cmd_limit'] != 0) { $nation['strategic_cmd_limit'] = "<font color=red>{$nation['strategic_cmd_limit']}턴</font>"; }
else { $nation['strategic_cmd_limit'] = "<font color=limegreen>가 능</font>"; }
if($nation['surlimit'] != 0) { $nation['surlimit'] = "<font color=red>{$nation['surlimit']}</font>"; }
else { $nation['surlimit'] = "<font color=limegreen>가 능</font>"; }
if($nation['scout'] != 0) { $nation['scout'] = "<font color=red>금 지</font>"; }
else { $nation['scout'] = "<font color=limegreen>허 가</font>"; }
if($nation['war'] != 0) { $nation['war'] = "<font color=red>금 지</font>"; }
else { $nation['war'] = "<font color=limegreen>허 가</font>"; }
if ($nation['strategic_cmd_limit'] != 0) {
$nation['strategic_cmd_limit'] = "<font color=red>{$nation['strategic_cmd_limit']}</font>";
} else {
$nation['strategic_cmd_limit'] = "<font color=limegreen>가 능</font>";
}
if ($nation['surlimit'] != 0) {
$nation['surlimit'] = "<font color=red>{$nation['surlimit']}</font>";
} else {
$nation['surlimit'] = "<font color=limegreen>가 능</font>";
}
if ($nation['scout'] != 0) {
$nation['scout'] = "<font color=red>금 지</font>";
} else {
$nation['scout'] = "<font color=limegreen>허 가</font>";
}
if ($nation['war'] != 0) {
$nation['war'] = "<font color=red>금 지</font>";
} else {
$nation['war'] = "<font color=limegreen>허 가</font>";
}
}
echo "
@@ -292,15 +327,21 @@ function myNationInfo() {
</tr>
<tr>
<td style='text-align:center;' class='bg1'><b>속 령</b></td>
<td style='text-align:center;'>";echo $me['nation']==0?"-":"{$city['cnt']}"; echo "</td>
<td style='text-align:center;'>";
echo $me['nation'] == 0 ? "-" : "{$city['cnt']}";
echo "</td>
<td style='text-align:center;' class='bg1'><b>장 수</b></td>
<td style='text-align:center;'>";echo $me['nation']==0?"-":"{$general['cnt']}"; echo "</td>
<td style='text-align:center;'>";
echo $me['nation'] == 0 ? "-" : "{$general['cnt']}";
echo "</td>
</tr>
<tr>
<td style='text-align:center;' class='bg1'><b>국 력</b></td>
<td style='text-align:center;'>{$nation['power']}</td>
<td style='text-align:center;' class='bg1'><b>기술력</b></td>
<td style='text-align:center;'>";echo $me['nation']==0?"-":"{$nation['tech']}"; echo "</td>
<td style='text-align:center;'>";
echo $me['nation'] == 0 ? "-" : "{$nation['tech']}";
echo "</td>
</tr>
<tr>
<td style='text-align:center;' class='bg1'><b>전 략</b></td>
@@ -318,60 +359,55 @@ function myNationInfo() {
";
}
function checkSecretMaxPermission($penalty){
function checkSecretMaxPermission($penalty)
{
$secretMax = 4;
if($penalty['noTopSecret']??false){
if ($penalty['noTopSecret'] ?? false) {
$secretMax = 1;
}
else if($penalty['noChief']??false){
} else if ($penalty['noChief'] ?? false) {
$secretMax = 1;
}
else if($penalty['noAmbassador']??false){
} else if ($penalty['noAmbassador'] ?? false) {
$secretMax = 2;
}
return $secretMax;
}
function checkSecretPermission(array $me, $checkSecretLimit=true){
if(!key_exists('penalty', $me) || !key_exists('permission', $me)){
trigger_error ('canAccessSecret() 함수에 필요한 인자가 부족');
function checkSecretPermission(array $me, $checkSecretLimit = true)
{
if (!key_exists('penalty', $me) || !key_exists('permission', $me)) {
trigger_error('canAccessSecret() 함수에 필요한 인자가 부족');
}
$penalty = Json::decode($me['penalty'])??[];
$penalty = Json::decode($me['penalty']) ?? [];
$permission = $me['permission'];
if(!$me['nation']){
if (!$me['nation']) {
return -1;
}
if($me['officer_level'] == 0){
if ($me['officer_level'] == 0) {
return -1;
}
if($penalty['noSecret']??false){
if ($penalty['noSecret'] ?? false) {
return 0;
}
$secretMin = 0;
$secretMax = checkSecretMaxPermission($me, $penalty);
if($me['officer_level'] == 12){
if ($me['officer_level'] == 12) {
$secretMin = 4;
}
else if($me['permission'] == 'ambassador'){
} else if ($me['permission'] == 'ambassador') {
$secretMin = 4;
}
else if($me['permission'] == 'auditor'){
} else if ($me['permission'] == 'auditor') {
$secretMin = 3;
}
else if($me['officer_level'] >= 5){
} else if ($me['officer_level'] >= 5) {
$secretMin = 2;
}
else if($me['officer_level'] > 1){
} else if ($me['officer_level'] > 1) {
$secretMin = 1;
}
else if($checkSecretLimit){
} else if ($checkSecretLimit) {
$db = DB::db();
$secretLimit = $db->queryFirstField('SELECT secretlimit FROM nation WHERE nation = %i', $me['nation']);
if ($me['belong'] >= $secretLimit) {
@@ -382,9 +418,10 @@ function checkSecretPermission(array $me, $checkSecretLimit=true){
return min($secretMin, $secretMax);
}
function addCommand($typename, $value, $valid = 1, $color=0) {
if($valid == 1) {
switch($color) {
function addCommand($typename, $value, $valid = 1, $color = 0)
{
if ($valid == 1) {
switch ($color) {
case 0:
echo "
<option style='color:white;background-color:black;' value='{$value}'>{$typename}</option>";
@@ -404,8 +441,9 @@ function addCommand($typename, $value, $valid = 1, $color=0) {
}
}
function commandGroup($typename, $type=0) {
if($type == 0) {
function commandGroup($typename, $type = 0)
{
if ($type == 0) {
echo "
<optgroup label='{$typename}' style='color:skyblue;background-color:black;'>";
} else {
@@ -414,7 +452,8 @@ function commandGroup($typename, $type=0) {
}
}
function printCommandTable(General $generalObj) {
function printCommandTable(General $generalObj)
{
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$userID = Session::getUserID();
@@ -423,50 +462,46 @@ function printCommandTable(General $generalObj) {
$env = $gameStor->getAll();
?>
<select id='generalCommandList' name='commandtype' size=1 style='height:20px;width:260px;color:white;background-color:black;font-size:12px;'>";
<?php
<select id='generalCommandList' name='commandtype' size=1 style='height:20px;width:260px;color:white;background-color:black;font-size:12px;'>";
<?php
//보정(Pros,Cons) 여부.
$getCompensateClassName = function($value){
if($value > 0){
return 'compensatePositive';
}
else if($value < 0){
return 'compensateNegative';
}
return 'compensateNeutral';
};
//보정(Pros,Cons) 여부.
$getCompensateClassName = function ($value) {
if ($value > 0) {
return 'compensatePositive';
} else if ($value < 0) {
return 'compensateNegative';
}
return 'compensateNeutral';
};
foreach(GameConst::$availableGeneralCommand as $commandCategory => $commandList){
if($commandCategory){
commandGroup("======= {$commandCategory} =======");
}
foreach (GameConst::$availableGeneralCommand as $commandCategory => $commandList) {
if ($commandCategory) {
commandGroup("======= {$commandCategory} =======");
}
foreach($commandList as $commandClassName){
$commandObj = buildGeneralCommandClass($commandClassName, $generalObj, $env);
if(!$commandObj->canDisplay()){
continue;
foreach ($commandList as $commandClassName) {
$commandObj = buildGeneralCommandClass($commandClassName, $generalObj, $env);
if (!$commandObj->canDisplay()) {
continue;
}
?>
<option class='commandBasic <?= $getCompensateClassName($commandObj->getCompensationStyle()) ?> <?= $commandObj->hasMinConditionMet() ? '' : 'commandImpossible' ?>' value='<?= Util::getClassNameFromObj($commandObj) ?>' data-reqArg='<?= ($commandObj::$reqArg) ? 'true' : 'false' ?>'><?= $commandObj->getCommandDetailTitle() ?><?= $commandObj->hasMinConditionMet() ? '' : '(불가)' ?></option>
<?php
}
if ($commandCategory) {
commandGroup('', 1);
}
?>
<option
class='commandBasic <?=$getCompensateClassName($commandObj->getCompensationStyle())?> <?=$commandObj->hasMinConditionMet()?'':'commandImpossible'?>'
value='<?=Util::getClassNameFromObj($commandObj)?>'
data-reqArg='<?=($commandObj::$reqArg)?'true':'false'?>'
><?=$commandObj->getCommandDetailTitle()?><?=$commandObj->hasMinConditionMet()?'':'(불가)'?></option>
<?php
}
if($commandCategory){
commandGroup('', 1);
}
}
?>
</select>
?>
</select>
<?php
}
function chiefCommandTable(General $generalObj) {
function chiefCommandTable(General $generalObj)
{
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$userID = Session::getUserID();
@@ -475,50 +510,46 @@ function chiefCommandTable(General $generalObj) {
$env = $gameStor->getAll();
?>
<select id='chiefCommandList' name='commandtype' size=1 style='height:20px;color:white;background-color:black;font-size:13px;display:inline-block;'>";
<?php
<select id='chiefCommandList' name='commandtype' size=1 style='height:20px;color:white;background-color:black;font-size:13px;display:inline-block;'>";
<?php
//보정(Pros,Cons) 여부.
$getCompensateClassName = function($value){
if($value > 0){
return 'compensatePositive';
}
else if($value < 0){
return 'compensateNegative';
}
return 'compensateNeutral';
};
//보정(Pros,Cons) 여부.
$getCompensateClassName = function ($value) {
if ($value > 0) {
return 'compensatePositive';
} else if ($value < 0) {
return 'compensateNegative';
}
return 'compensateNeutral';
};
foreach(GameConst::$availableChiefCommand as $commandCategory => $commandList){
if($commandCategory){
commandGroup("======= {$commandCategory} =======");
}
foreach (GameConst::$availableChiefCommand as $commandCategory => $commandList) {
if ($commandCategory) {
commandGroup("======= {$commandCategory} =======");
}
foreach($commandList as $commandClassName){
$commandObj = buildNationCommandClass($commandClassName, $generalObj, $env, new LastTurn());
if(!$commandObj->canDisplay()){
continue;
foreach ($commandList as $commandClassName) {
$commandObj = buildNationCommandClass($commandClassName, $generalObj, $env, new LastTurn());
if (!$commandObj->canDisplay()) {
continue;
}
?>
<option class='commandBasic <?= $getCompensateClassName($commandObj->getCompensationStyle()) ?> <?= $commandObj->hasMinConditionMet() ? '' : 'commandImpossible' ?>' value='<?= Util::getClassNameFromObj($commandObj) ?>' data-reqArg='<?= ($commandObj::$reqArg) ? 'true' : 'false' ?>'><?= $commandObj->getCommandDetailTitle() ?><?= $commandObj->hasMinConditionMet() ? '' : '(불가)' ?></option>
<?php
}
if ($commandCategory) {
commandGroup('', 1);
}
?>
<option
class='commandBasic <?=$getCompensateClassName($commandObj->getCompensationStyle())?> <?=$commandObj->hasMinConditionMet()?'':'commandImpossible'?>'
value='<?=Util::getClassNameFromObj($commandObj)?>'
data-reqArg='<?=($commandObj::$reqArg)?'true':'false'?>'
><?=$commandObj->getCommandDetailTitle()?><?=$commandObj->hasMinConditionMet()?'':'(불가)'?></option>
<?php
}
if($commandCategory){
commandGroup('', 1);
}
}
?>
</select>
?>
</select>
<?php
}
function generalInfo(General $generalObj) {
function generalInfo(General $generalObj)
{
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
@@ -528,24 +559,22 @@ function generalInfo(General $generalObj) {
$nation = getNationStaticInfo($generalObj->getNationID());
$lbonus = calcLeadershipBonus($generalObj->getVar('officer_level'), $nation['level']);
if($lbonus > 0) {
if ($lbonus > 0) {
$lbonus = "<font color=cyan>+{$lbonus}</font>";
} else {
$lbonus = "";
}
if($generalObj->getVar('troop') == 0){
if ($generalObj->getVar('troop') == 0) {
$troopInfo = '-';
}
else{
} else {
$troopCity = $db->queryFirstField('SELECT city FROM general WHERE no=%i', $generalObj->getVar('troop'));
$troopTurn = $db->queryFirstField('SELECT `brief` FROM general_turn WHERE general_id = %i AND turn_idx = 0', $generalObj->getVar('troop'));
$troopInfo = $db->queryFirstField('SELECT name FROM troop WHERE troop_leader = %i', $generalObj->getVar('troop'));
if($troopTurn !== '집합'){
if ($troopTurn !== '집합') {
$troopInfo = "<strike style='color:gray;'>{$troopInfo}</strike>";
}
else if($troopCity != $generalObj->getCityID()){
} else if ($troopCity != $generalObj->getCityID()) {
$troopCityName = CityConst::byID($troopCity)->name;
$troopInfo = "<span style='color:orange;'>{$troopInfo}({$troopCityName})</span>";
}
@@ -554,7 +583,7 @@ function generalInfo(General $generalObj) {
$officerLevel = $generalObj->getVar('officer_level');
$officerLevelText = getOfficerLevelText($officerLevel, $nation['level']);
if(2 <= $officerLevel && $officerLevel <= 4){
if (2 <= $officerLevel && $officerLevel <= 4) {
$cityOfficerName = CityConst::byID($generalObj->getVar('officer_city'))->name;
$officerLevelText = "{$cityOfficerName} {$officerLevelText}";
}
@@ -569,83 +598,97 @@ function generalInfo(General $generalObj) {
$leadership = $generalObj->getLeadership(true, false, false);
$strength = $generalObj->getStrength(true, false, false);
$intel = $generalObj->getIntel(true, false, false);
$injury = $generalObj->getVar('injury');
if($injury > 60) { $color = "<font color=red>"; $injury = "위독"; }
elseif($injury > 40) { $color = "<font color=magenta>"; $injury = "심각"; }
elseif($injury > 20) { $color = "<font color=orange>"; $injury = "중상"; }
elseif($injury > 0) { $color = "<font color=yellow>"; $injury = "경상"; }
else { $color = "<font color=white>"; $injury = "건강"; }
if ($injury > 60) {
$color = "<font color=red>";
$injury = "위독";
} elseif ($injury > 40) {
$color = "<font color=magenta>";
$injury = "심각";
} elseif ($injury > 20) {
$color = "<font color=orange>";
$injury = "중상";
} elseif ($injury > 0) {
$color = "<font color=yellow>";
$injury = "경상";
} else {
$color = "<font color=white>";
$injury = "건강";
}
$remaining = (new \DateTimeImmutable($generalObj->getTurnTime()))->diff(new \DateTimeImmutable())->i;
if($nation['color'] == "") { $nation['color'] = "#000000"; }
if ($nation['color'] == "") {
$nation['color'] = "#000000";
}
$age = $generalObj->getVar('age');
if($age < GameConst::$retirementYear*0.75) {$age = "<font color=limegreen>{$age} 세</font>"; }
elseif($age < GameConst::$retirementYear) { $age = "<font color=yellow>{$age} 세</font>"; }
else { $age = "<font color=red>{$age} 세</font>"; }
if ($age < GameConst::$retirementYear * 0.75) {
$age = "<font color=limegreen>{$age} 세</font>";
} elseif ($age < GameConst::$retirementYear) {
$age = "<font color=yellow>{$age} 세</font>";
} else {
$age = "<font color=red>{$age} 세</font>";
}
$connectCnt = round($generalObj->getVar('connect'), -1);
$specialDomestic = $generalObj->getVar('special')===GameConst::$defaultSpecialDomestic
?"{$generalObj->getVar('specage')}세"
: "<font color=limegreen>".displayiActionObjInfo($generalObj->getSpecialDomestic())."</font>";
$specialWar = $generalObj->getVar('special2')===GameConst::$defaultSpecialDomestic
?"{$generalObj->getVar('specage2')}세"
: "<font color=limegreen>".displayiActionObjInfo($generalObj->getSpecialWar())."</font>";
$specialDomestic = $generalObj->getVar('special') === GameConst::$defaultSpecialDomestic
? "{$generalObj->getVar('specage')}세"
: "<font color=limegreen>" . displayiActionObjInfo($generalObj->getSpecialDomestic()) . "</font>";
$specialWar = $generalObj->getVar('special2') === GameConst::$defaultSpecialDomestic
? "{$generalObj->getVar('specage2')}세"
: "<font color=limegreen>" . displayiActionObjInfo($generalObj->getSpecialWar()) . "</font>";
$atmos = $generalObj->getVar('atmos');
$atmosBonus = $generalObj->onCalcStat($generalObj, 'bonusAtmos', $atmos) - $atmos;
if($atmosBonus > 0){
if ($atmosBonus > 0) {
$atmos = "<font color=cyan>{$atmos} (+{$atmosBonus})</font>";
}
else if($atmosBonus < 0){
} else if ($atmosBonus < 0) {
$atmos = "<font color=magenta>{$atmos} ({$atmosBonus})</font>";
}
else{
} else {
$atmos = "$atmos";
}
$train = $generalObj->getVar('train');
$trainBonus = $generalObj->onCalcStat($generalObj, 'bonusTrain', $train) - $train;
if($trainBonus > 0){
if ($trainBonus > 0) {
$train = "<font color=cyan>{$train} (+{$trainBonus})</font>";
}
else if($trainBonus < 0){
} else if ($trainBonus < 0) {
$train = "<font color=magenta>{$train} ({$trainBonus})</font>";
}
else{
} else {
$train = "$train";
}
if($generalObj->getVar('defence_train') === 999){
if ($generalObj->getVar('defence_train') === 999) {
$defenceTrain = "<font color=red>수비 안함</font>";
}
else{
} else {
$defenceTrain = "<font color=limegreen>수비 함(훈사{$generalObj->getVar('defence_train')})</font>";
}
$crewType = $generalObj->getCrewTypeObj();
$weapImage = ServConfig::$gameImagePath."/crewtype{$crewType->id}.png";
if($show_img_level < 2) { $weapImage = ServConfig::$sharedIconPath."/default.jpg"; };
$weapImage = ServConfig::$gameImagePath . "/crewtype{$crewType->id}.png";
if ($show_img_level < 2) {
$weapImage = ServConfig::$sharedIconPath . "/default.jpg";
};
$imagePath = GetImageURL(...$generalObj->getVars('imgsvr', 'picture'));
echo "<table width=498 class='tb_layout bg2'>
<tr>
<td width=64 height=64 rowspan=3 class='generalIcon' style='text-align:center;background:no-repeat center url(\"{$imagePath}\");background-size:64px;'>&nbsp;</td>
<td colspan=9 height=16 style=text-align:center;color:".newColor($nation['color']).";background-color:{$nation['color']};font-weight:bold;font-size:13px;>{$generalObj->getName()} 【 {$officerLevelText} | {$call} | {$color}{$injury}</font> 】 ".$generalObj->getTurnTime($generalObj::TURNTIME_HMS)."</td>
<td colspan=9 height=16 style=text-align:center;color:" . newColor($nation['color']) . ";background-color:{$nation['color']};font-weight:bold;font-size:13px;>{$generalObj->getName()} 【 {$officerLevelText} | {$call} | {$color}{$injury}</font> 】 " . $generalObj->getTurnTime($generalObj::TURNTIME_HMS) . "</td>
</tr>
<tr height=16>
<td style='text-align:center;' class='bg1'><b>통솔</b></td>
<td style='text-align:center;'>&nbsp;{$color}{$leadership}</font>{$lbonus}&nbsp;</td>
<td style='text-align:center;' width=45>".bar(expStatus($generalObj->getVar('leadership_exp')), 20)."</td>
<td style='text-align:center;' width=45>" . bar(expStatus($generalObj->getVar('leadership_exp')), 20) . "</td>
<td style='text-align:center;' class='bg1'><b>무력</b></td>
<td style='text-align:center;'>&nbsp;{$color}{$strength}</font>&nbsp;</td>
<td style='text-align:center;' width=45>".bar(expStatus($generalObj->getVar('strength_exp')), 20)."</td>
<td style='text-align:center;' width=45>" . bar(expStatus($generalObj->getVar('strength_exp')), 20) . "</td>
<td style='text-align:center;' class='bg1'><b>지력</b></td>
<td style='text-align:center;'>&nbsp;{$color}{$intel}</font>&nbsp;</td>
<td style='text-align:center;' width=45>".bar(expStatus($generalObj->getVar('intel_exp')), 20)."</td>
<td style='text-align:center;' width=45>" . bar(expStatus($generalObj->getVar('intel_exp')), 20) . "</td>
</tr>
<tr>
<td style='text-align:center;' class='bg1'><b>명마</b></td>
@@ -670,7 +713,7 @@ function generalInfo(General $generalObj) {
<td style='text-align:center;' class='bg1'><b>병사</b></td>
<td style='text-align:center;' colspan=2>{$generalObj->getVar('crew')}</td>
<td style='text-align:center;' class='bg1'><b>성격</b></td>
<td style='text-align:center;' colspan=2>".displayiActionObjInfo($generalObj->getPersonality())."</td>
<td style='text-align:center;' colspan=2>" . displayiActionObjInfo($generalObj->getPersonality()) . "</td>
</tr>
<tr>
<td style='text-align:center;' class='bg1'><b>훈련</b></td>
@@ -683,7 +726,7 @@ function generalInfo(General $generalObj) {
<tr height=20>
<td style='text-align:center;' class='bg1'><b>Lv</b></td>
<td style='text-align:center;'>&nbsp;{$generalObj->getVar('explevel')}&nbsp;</td>
<td style='text-align:center;' colspan=5>".bar(getLevelPer(...$generalObj->getVars('experience', 'explevel')), 20)."</td>
<td style='text-align:center;' colspan=5>" . bar(getLevelPer(...$generalObj->getVars('experience', 'explevel')), 20) . "</td>
<td style='text-align:center;' class='bg1'><b>연령</b></td>
<td style='text-align:center;' colspan=2>{$age}</td>
</tr>
@@ -699,37 +742,34 @@ function generalInfo(General $generalObj) {
<td style='text-align:center;' class='bg1'><b>부대</b></td>
<td style='text-align:center;' colspan=3>{$troopInfo}</td>
<td style='text-align:center;' class='bg1'><b>벌점</b></td>
<td style='text-align:center;' colspan=5>".getConnect($connectCnt)." {$connectCnt}({$generalObj->getVar('con')})</td>
<td style='text-align:center;' colspan=5>" . getConnect($connectCnt) . " {$connectCnt}({$generalObj->getVar('con')})</td>
</tr>
</table>";
}
function generalInfo2(General $generalObj) {
function generalInfo2(General $generalObj)
{
$general = $generalObj->getRaw();
$winRate = round($generalObj->getRankVar('killnum')/max($generalObj->getRankVar('warnum'),1)*100, 2);
$killRate = round($generalObj->getRankVar('killcrew')/max($generalObj->getRankVar('deathcrew'),1)*100, 2);
$winRate = round($generalObj->getRankVar('killnum') / max($generalObj->getRankVar('warnum'), 1) * 100, 2);
$killRate = round($generalObj->getRankVar('killcrew') / max($generalObj->getRankVar('deathcrew'), 1) * 100, 2);
$experienceBonus = $generalObj->onCalcStat($generalObj, 'experience', 10000) - 10000;
if($experienceBonus > 0){
$experience = "<font color=cyan>".getHonor($general['experience'])." ({$general['experience']})</font>";
}
else if($experienceBonus < 0){
$experience = "<font color=magenta>".getHonor($general['experience'])." ({$general['experience']})</font>";
}
else{
$experience = getHonor($general['experience'])." ({$general['experience']})";
if ($experienceBonus > 0) {
$experience = "<font color=cyan>" . getHonor($general['experience']) . " ({$general['experience']})</font>";
} else if ($experienceBonus < 0) {
$experience = "<font color=magenta>" . getHonor($general['experience']) . " ({$general['experience']})</font>";
} else {
$experience = getHonor($general['experience']) . " ({$general['experience']})";
}
$dedicationBonus = $generalObj->onCalcStat($generalObj, 'dedication', 10000) - 10000;
if($dedicationBonus > 0){
$dedication = "<font color=cyan>".getHonor($general['dedication'])." ({$general['dedication']})</font>";
}
else if($dedicationBonus < 0){
$dedication = "<font color=magenta>".getHonor($general['dedication'])." ({$general['dedication']})</font>";
}
else{
$dedication = getHonor($general['dedication'])." ({$general['dedication']})";
if ($dedicationBonus > 0) {
$dedication = "<font color=cyan>" . getHonor($general['dedication']) . " ({$general['dedication']})</font>";
} else if ($dedicationBonus < 0) {
$dedication = "<font color=magenta>" . getHonor($general['dedication']) . " ({$general['dedication']})</font>";
} else {
$dedication = getHonor($general['dedication']) . " ({$general['dedication']})";
}
$dex1 = $general['dex1'] / GameConst::$dexLimit * 100;
@@ -738,11 +778,21 @@ function generalInfo2(General $generalObj) {
$dex4 = $general['dex4'] / GameConst::$dexLimit * 100;
$dex5 = $general['dex5'] / GameConst::$dexLimit * 100;
if($dex1 > 100) { $dex1 = 100; }
if($dex2 > 100) { $dex2 = 100; }
if($dex3 > 100) { $dex3 = 100; }
if($dex4 > 100) { $dex4 = 100; }
if($dex5 > 100) { $dex5 = 100; }
if ($dex1 > 100) {
$dex1 = 100;
}
if ($dex2 > 100) {
$dex2 = 100;
}
if ($dex3 > 100) {
$dex3 = 100;
}
if ($dex4 > 100) {
$dex4 = 100;
}
if ($dex5 > 100) {
$dex5 = 100;
}
$general['dex1_text'] = getDexCall($general['dex1']);
$general['dex2_text'] = getDexCall($general['dex2']);
@@ -750,11 +800,11 @@ function generalInfo2(General $generalObj) {
$general['dex4_text'] = getDexCall($general['dex4']);
$general['dex5_text'] = getDexCall($general['dex5']);
$general['dex1_short'] = sprintf('%.1fK', $general['dex1']/1000);
$general['dex2_short'] = sprintf('%.1fK', $general['dex2']/1000);
$general['dex3_short'] = sprintf('%.1fK', $general['dex3']/1000);
$general['dex4_short'] = sprintf('%.1fK', $general['dex4']/1000);
$general['dex5_short'] = sprintf('%.1fK', $general['dex5']/1000);
$general['dex1_short'] = sprintf('%.1fK', $general['dex1'] / 1000);
$general['dex2_short'] = sprintf('%.1fK', $general['dex2'] / 1000);
$general['dex3_short'] = sprintf('%.1fK', $general['dex3'] / 1000);
$general['dex4_short'] = sprintf('%.1fK', $general['dex4'] / 1000);
$general['dex5_short'] = sprintf('%.1fK', $general['dex5'] / 1000);
echo "<table width=498 class='tb_layout bg2'>
<tr><td style='text-align:center;' colspan=6 class='bg1'><b>추 가 정 보</b></td></tr>
@@ -795,96 +845,104 @@ function generalInfo2(General $generalObj) {
<td width=64 style='text-align:center;' class='bg1'><b>보병</b></td>
<td width=40> {$general['dex1_text']}</td>
<td width=60 align=right>{$general['dex1_short']}&nbsp;</td>
<td width=330 style='text-align:center;'>".bar($dex1, 16)."</td>
<td width=330 style='text-align:center;'>" . bar($dex1, 16) . "</td>
</tr>
<tr height=16>
<td style='text-align:center;' class='bg1'><b>궁병</b></td>
<td> {$general['dex2_text']}</td>
<td align=right>{$general['dex2_short']}&nbsp;</td>
<td style='text-align:center;'>".bar($dex2, 16)."</td>
<td style='text-align:center;'>" . bar($dex2, 16) . "</td>
</tr>
<tr height=16>
<td style='text-align:center;' class='bg1'><b>기병</b></td>
<td> {$general['dex3_text']}</td>
<td align=right>{$general['dex3_short']}&nbsp;</td>
<td style='text-align:center;'>".bar($dex3, 16)."</td>
<td style='text-align:center;'>" . bar($dex3, 16) . "</td>
</tr>
<tr height=16>
<td style='text-align:center;' class='bg1'><b>귀병</b></td>
<td> {$general['dex4_text']}</td>
<td align=right>{$general['dex4_short']}&nbsp;</td>
<td style='text-align:center;'>".bar($dex4, 16)."</td>
<td style='text-align:center;'>" . bar($dex4, 16) . "</td>
</tr>
<tr height=16>
<td style='text-align:center;' class='bg1'><b>차병</b></td>
<td> {$general['dex5_text']}</td>
<td align=right>{$general['dex5_short']}&nbsp;</td>
<td style='text-align:center;'>".bar($dex5, 16)."</td>
<td style='text-align:center;'>" . bar($dex5, 16) . "</td>
</tr>
</table>";
}
function getOnlineNum() {
function getOnlineNum()
{
return KVStorage::getStorage(DB::db(), 'game_env')->online;
}
function onlinegen() {
function onlinegen()
{
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$onlinegen = "";
$generalID = Session::getInstance()->generalID;
$nationID = DB::db()->queryFirstField('select `nation` from `general` where `no` = %i', $generalID);
if($nationID === null || Util::toInt($nationID) === 0) {
if ($nationID === null || Util::toInt($nationID) === 0) {
$onlinegen = $gameStor->onlinegen;
} else {
$onlinegen = DB::db()->queryFirstField('select onlinegen from nation where nation=%i',$nationID);
$onlinegen = DB::db()->queryFirstField('select onlinegen from nation where nation=%i', $nationID);
}
return $onlinegen;
}
function nationMsg(General $general) {
function nationMsg(General $general)
{
$db = DB::db();
$msg = $db->queryFirstField(
'SELECT msg FROM nation WHERE nation = %i',
$general->getNationID()
);
return $msg?:'';
return $msg ?: '';
}
function banner() {
function banner()
{
return sprintf(
'<font size=2>%s %s / %s</font>',
GameConst::$title,
VersionGit::$version,
GameConst::$banner);
GameConst::$banner
);
}
function addTurn($date, int $turnterm, int $turn=1, bool $withFraction=true) {
function addTurn($date, int $turnterm, int $turn = 1, bool $withFraction = true)
{
$date = new \DateTime($date);
$target = $turnterm*$turn;
$target = $turnterm * $turn;
$date->add(new \DateInterval("PT{$target}M"));
if($withFraction){
if ($withFraction) {
return $date->format('Y-m-d H:i:s.u');
}
return $date->format('Y-m-d H:i:s');
}
function subTurn($date, int $turnterm, int $turn=1, bool $withFraction=true) {
function subTurn($date, int $turnterm, int $turn = 1, bool $withFraction = true)
{
$date = new \DateTime($date);
$target = $turnterm*$turn;
$target = $turnterm * $turn;
$date->sub(new \DateInterval("PT{$target}M"));
if($withFraction){
if ($withFraction) {
return $date->format('Y-m-d H:i:s.u');
}
return $date->format('Y-m-d H:i:s');
}
function cutTurn($date, int $turnterm, bool $withFraction=true) {
function cutTurn($date, int $turnterm, bool $withFraction = true)
{
$date = new \DateTime($date);
$baseDate = new \DateTime($date->format('Y-m-d'));
$baseDate->sub(new \DateInterval("P1D"));
$baseDate->add(new \DateInterval("PT1H"));
@@ -893,16 +951,16 @@ function cutTurn($date, int $turnterm, bool $withFraction=true) {
$diffMin -= $diffMin % $turnterm;
$baseDate->add(new \DateInterval("PT{$diffMin}M"));
if($withFraction){
if ($withFraction) {
return $baseDate->format('Y-m-d H:i:s.u');
}
return $baseDate->format('Y-m-d H:i:s');
}
function cutDay($date, int $turnterm, bool $withFraction=true) {
function cutDay($date, int $turnterm, bool $withFraction = true)
{
$date = new \DateTime($date);
$baseDate = new \DateTime($date->format('Y-m-d'));
$baseDate->sub(new \DateInterval("P1D"));
$baseDate->add(new \DateInterval("PT1H"));
@@ -915,24 +973,24 @@ function cutDay($date, int $turnterm, bool $withFraction=true) {
$newMonth = intdiv($timeAdjust, $turnterm) + 1;
$yearPulled = false;
if($newMonth > 3){//3월 이후일때는
if ($newMonth > 3) { //3월 이후일때는
$yearPulled = true;
$diffMin += $baseGap;
}
$diffMin -= $timeAdjust;
$baseDate->add(new \DateInterval("PT{$diffMin}M"));
if($withFraction){
if ($withFraction) {
$dateTimeString = $baseDate->format('Y-m-d H:i:s.u');
}
else{
} else {
$dateTimeString = $baseDate->format('Y-m-d H:i:s');
}
return [$dateTimeString, $yearPulled, $newMonth];
}
function increaseRefresh($type="", $cnt=1) {
function increaseRefresh($type = "", $cnt = 1)
{
//FIXME: 로그인, 비로그인 시 처리가 명확하지 않음
$session = Session::getInstance();
$userID = $session->userID;
@@ -943,16 +1001,16 @@ function increaseRefresh($type="", $cnt=1) {
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$gameStor->refresh = $gameStor->refresh+$cnt; //TODO: +로 증가하는 값은 별도로 분리
$gameStor->refresh = $gameStor->refresh + $cnt; //TODO: +로 증가하는 값은 별도로 분리
$isunited = $gameStor->isunited;
if($isunited != 2 && $generalID && $userGrade < 6) {
if ($isunited != 2 && $generalID && $userGrade < 6) {
$db->update('general', [
'lastrefresh'=>$date,
'con'=>$db->sqleval('con + %i', $cnt),
'connect'=>$db->sqleval('connect + %i', $cnt),
'refcnt'=>$db->sqleval('refcnt + %i', $cnt),
'refresh'=>$db->sqleval('refresh + %i', $cnt)
'lastrefresh' => $date,
'con' => $db->sqleval('con + %i', $cnt),
'connect' => $db->sqleval('connect + %i', $cnt),
'refcnt' => $db->sqleval('refcnt + %i', $cnt),
'refresh' => $db->sqleval('refresh + %i', $cnt)
], 'owner=%i', $userID);
}
@@ -960,7 +1018,7 @@ function increaseRefresh($type="", $cnt=1) {
$date2 = substr($date, 0, 10);
$online = getOnlineNum();
file_put_contents(
__DIR__."/logs/".UniqueConst::$serverID."/_{$date2}_refresh.txt",
__DIR__ . "/logs/" . UniqueConst::$serverID . "/_{$date2}_refresh.txt",
sprintf(
"%s, %s, %s, %s, %s, %d\n",
$date,
@@ -992,12 +1050,12 @@ function increaseRefresh($type="", $cnt=1) {
);
$str = "";
foreach($proxy_headers as $x) {
if(isset($_SERVER[$x])) $str .= "//{$x}:{$_SERVER[$x]}";
foreach ($proxy_headers as $x) {
if (isset($_SERVER[$x])) $str .= "//{$x}:{$_SERVER[$x]}";
}
if($str != "") {
if ($str != "") {
file_put_contents(
__DIR__."/logs/".UniqueConst::$serverID."/_{$date2}_ipcheck.txt",
__DIR__ . "/logs/" . UniqueConst::$serverID . "/_{$date2}_ipcheck.txt",
sprintf(
"%s, %s, %s%s\n",
$session->userName,
@@ -1005,46 +1063,51 @@ function increaseRefresh($type="", $cnt=1) {
$_SERVER['REMOTE_ADDR'],
$str
),
FILE_APPEND);
FILE_APPEND
);
}
}
function updateTraffic() {
function updateTraffic()
{
$online = getOnlineNum();
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$admin = $gameStor->getValues(['year','month','refresh','maxonline','maxrefresh']);
$admin = $gameStor->getValues(['year', 'month', 'refresh', 'maxonline', 'maxrefresh']);
//최다갱신자
$user = $db->queryFirstRow('select name,refresh from general order by refresh desc limit 1');
if($admin['maxrefresh'] < $admin['refresh']) {
if ($admin['maxrefresh'] < $admin['refresh']) {
$admin['maxrefresh'] = $admin['refresh'];
}
if($admin['maxonline'] < $online) {
if ($admin['maxonline'] < $online) {
$admin['maxonline'] = $online;
}
$gameStor->refresh = 0;
$gameStor->maxrefresh = $admin['maxrefresh'];
$gameStor->maxonline = $admin['maxonline'];
$db->update('general', ['refresh'=>0], true);
$db->update('general', ['refresh' => 0], true);
$date = TimeUtil::now();
//일시|년|월|총갱신|접속자|최다갱신자
file_put_contents(__DIR__."/logs/".UniqueConst::$serverID."/_traffic.txt",
file_put_contents(
__DIR__ . "/logs/" . UniqueConst::$serverID . "/_traffic.txt",
Json::encode([
$date,
$admin['year'],
$admin['month'],
$admin['refresh'],
$online,
$user['name']."(".$user['refresh'].")"
])."\n"
, FILE_APPEND);
$user['name'] . "(" . $user['refresh'] . ")"
]) . "\n",
FILE_APPEND
);
}
function CheckOverhead() {
function CheckOverhead()
{
//서버정보
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
@@ -1053,39 +1116,43 @@ function CheckOverhead() {
$con = Util::round(pow($turnterm, 0.6) * 3) * 10;
if($con != $conlimit){
if ($con != $conlimit) {
$gameStor->conlimit = $con;
}
}
function isLock() {
function isLock()
{
return DB::db()->queryFirstField("SELECT plock from plock limit 1") != 0;
}
function tryLock():bool{
function tryLock(): bool
{
//NOTE: 게임 로직과 관련한 모든 insert, update 함수들은 lock을 거칠것을 권장함.
$db = DB::db();
// 잠금
$db->update('plock', [
'plock'=>1,
'locktime'=>TimeUtil::now(true)
'plock' => 1,
'locktime' => TimeUtil::now(true)
], 'plock=0');
return $db->affectedRows() > 0;
}
function unlock():bool{
function unlock(): bool
{
// 풀림
$db = DB::db();
$db->update('plock', [
'plock'=>0
'plock' => 0
], true);
return $db->affectedRows() > 0;
}
function timeover():bool {
function timeover(): bool
{
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
@@ -1095,11 +1162,15 @@ function timeover():bool {
$t = min($turnterm, 5);
$term = $diff;
if($term >= $t || $term < 0) { return true; }
else { return false; }
if ($term >= $t || $term < 0) {
return true;
} else {
return false;
}
}
function checkDelay() {
function checkDelay()
{
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
@@ -1107,21 +1178,19 @@ function checkDelay() {
$now = new \DateTimeImmutable();
$turntime = new \DateTimeImmutable($gameStor->turntime);
$timeMinDiff = intdiv($now->getTimestamp() - $turntime->getTimestamp(), 60);
// 1턴이상 갱신 없었으면 서버 지연
$term = $gameStor->turnterm;
if($term >= 20){
if ($term >= 20) {
$threshold = 1;
}
else if($term >= 10){
} else if ($term >= 10) {
$threshold = 3;
}
else{
} else {
$threshold = 6;
}
//지연 해야할 밀린 턴 횟수
$iter = intdiv($timeMinDiff, $term);
if($iter > $threshold) {
if ($iter > $threshold) {
$minute = $iter * $term;
$newTurntime = $turntime->add(new \DateInterval("PT{$minute}M"));
$newNextTurntime = $turntime->add(new \DateInterval("PT{$term}M"));
@@ -1131,85 +1200,87 @@ function checkDelay() {
->format('Y-m-d H:i:s');
$db->update('general', [
'turntime'=> $db->sqleval('DATE_ADD(turntime, INTERVAL %i MINUTE)', $minute)
'turntime' => $db->sqleval('DATE_ADD(turntime, INTERVAL %i MINUTE)', $minute)
], 'turntime<=DATE_ADD(turntime, INTERVAL %i MINUTE)', $term);
$db->update('auction', [
'expire'=> $db->sqleval('DATE_ADD(expire, INTERVAL %i MINUTE)', $minute)
'expire' => $db->sqleval('DATE_ADD(expire, INTERVAL %i MINUTE)', $minute)
], true);
}
}
function updateOnline() {
function updateOnline()
{
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$connect=$db->get();
$connect = $db->get();
$nationname = ["재야"];
//국가별 이름 매핑
foreach(getAllNationStaticInfo() as $nation) {
foreach (getAllNationStaticInfo() as $nation) {
$nationname[$nation['nation']] = $nation['name'];
}
//동접수
$query = "select no,name,nation from general where lastrefresh > DATE_SUB(NOW(), INTERVAL 5 MINUTE)";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$result = MYDB_query($query, $connect) or Error(__LINE__ . MYDB_error($connect), "");
$onlinenum = MYDB_num_rows($result);
$onnation = array();
$onnationstr = "";
$onnation = array();
$onnationstr = "";
//국가별 접속중인 장수
for($i=0; $i < $onlinenum; $i++) {
for ($i = 0; $i < $onlinenum; $i++) {
$general = MYDB_fetch_array($result);
if(isset($onnation[$general['nation']])){
$onnation[$general['nation']] .= $general['name'].', ';
}else {
$onnation[$general['nation']] = $general['name'].', ';
if (isset($onnation[$general['nation']])) {
$onnation[$general['nation']] .= $general['name'] . ', ';
} else {
$onnation[$general['nation']] = $general['name'] . ', ';
}
}
//$onnation이 empty라면 굳이 foreach를 수행 할 이유가 없음.
if(!empty($onnation)){
foreach($onnation as $key => $val) {
$onnationstr .= "【{$nationname[$key]}】, ";
if($key == 0) {
//$onnation이 empty라면 굳이 foreach를 수행 할 이유가 없음.
if (!empty($onnation)) {
foreach ($onnation as $key => $val) {
$onnationstr .= "【{$nationname[$key]}】, ";
if ($key == 0) {
$gameStor->onlinegen = $onnation[0];
} else {
$query = "update nation set onlinegen='$onnation[$key]' where nation='$key'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
}
}
}
} else {
$query = "update nation set onlinegen='$onnation[$key]' where nation='$key'";
MYDB_query($query, $connect) or Error(__LINE__ . MYDB_error($connect), "");
}
}
}
//접속중인 국가
$gameStor->online = $onlinenum;
$gameStor->onlinenation = $onnationstr;
}
function addAge() {
function addAge()
{
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
//나이와 호봉 증가
$db->update('general', [
'age'=>$db->sqleval('age+1'),
'belong'=>$db->sqleval('belong+1')
'age' => $db->sqleval('age+1'),
'belong' => $db->sqleval('belong+1')
], true);
[$startYear, $year, $month] = $gameStor->getValuesAsArray(['startyear', 'year', 'month']);
if($year >= $startYear+3) {
foreach($db->query('SELECT no,name,nation,leadership,strength,intel from general where specage<=age and special=%s', GameConst::$defaultSpecialDomestic) as $general){
if ($year >= $startYear + 3) {
foreach ($db->query('SELECT no,name,nation,leadership,strength,intel from general where specage<=age and special=%s', GameConst::$defaultSpecialDomestic) as $general) {
$generalID = $general['no'];
$special = SpecialityHelper::pickSpecialDomestic($general);
$specialClass = buildGeneralSpecialDomesticClass($special);
$specialText = $specialClass->getName();
$db->update('general', [
'special'=>$special
], 'no=%i',$generalID);
'special' => $special
], 'no=%i', $generalID);
$logger = new ActionLogger($generalID, $general['nation'], $year, $month);
@@ -1218,15 +1289,15 @@ function addAge() {
$logger->pushGeneralHistoryLog("특기 【<b><C>{$specialText}</></b>】{$josaUl} 습득");
}
foreach($db->query('SELECT no,name,nation,leadership,strength,intel,npc,dex1,dex2,dex3,dex4,dex5 from general where specage2<=age and special2=%s', GameConst::$defaultSpecialWar) as $general){
foreach ($db->query('SELECT no,name,nation,leadership,strength,intel,npc,dex1,dex2,dex3,dex4,dex5 from general where specage2<=age and special2=%s', GameConst::$defaultSpecialWar) as $general) {
$generalID = $general['no'];
$special2 = SpecialityHelper::pickSpecialWar($general);
$specialClass = buildGeneralSpecialWarClass($special2);
$specialText = $specialClass->getName();
$db->update('general', [
'special2'=>$special2
], 'no=%i',$general['no']);
'special2' => $special2
], 'no=%i', $general['no']);
$logger = new ActionLogger($generalID, $general['nation'], $year, $month);
@@ -1237,7 +1308,8 @@ function addAge() {
}
}
function turnDate($curtime) {
function turnDate($curtime)
{
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$admin = $gameStor->getValues(['startyear', 'starttime', 'turnterm', 'year', 'month']);
@@ -1245,17 +1317,17 @@ function turnDate($curtime) {
$turn = $admin['starttime'];
$curturn = cutTurn($curtime, $admin['turnterm']);
$term = $admin['turnterm'];
$num = intdiv((strtotime($curturn) - strtotime($turn)), $term*60);
$num = intdiv((strtotime($curturn) - strtotime($turn)), $term * 60);
$date = $admin['startyear'] * 12;
$date += $num;
$year = intdiv($date, 12);
$month = 1 + $date % 12;
$month = 1 + $date % 12;
// 바뀐 경우만 업데이트
if($admin['month'] != $month || $admin['year'] != $year) {
if ($admin['month'] != $month || $admin['year'] != $year) {
$gameStor->year = $year;
$gameStor->month = $month;
}
@@ -1264,22 +1336,26 @@ function turnDate($curtime) {
}
function triggerTournament() {
function triggerTournament()
{
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$admin = $gameStor->getValues(['tournament', 'tnmt_trig']);
//현재 토너먼트 없고, 자동개시 걸려있을때, 40%확률
if($admin['tournament'] == 0 && $admin['tnmt_trig'] > 0 && rand() % 100 < 40) {
if ($admin['tournament'] == 0 && $admin['tnmt_trig'] > 0 && rand() % 100 < 40) {
$type = rand() % 5; // 0 : 전력전, 1 : 통솔전, 2 : 일기토, 3 : 설전
//전력전 40%, 통, 일, 설 각 20%
if($type > 3) { $type = 0; }
if ($type > 3) {
$type = 0;
}
startTournament($admin['tnmt_trig'], $type);
}
}
function CheckHall($no) {
function CheckHall($no)
{
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
@@ -1305,7 +1381,7 @@ function CheckHall($no) {
["betwin", 'rank'],
["betwingold", 'rank'],
["betrate", 'calc'],
];//XXX: 순서가 DB에 박혀있다 ㅜㅜ
]; //XXX: 순서가 DB에 박혀있다 ㅜㅜ
$generalObj = General::createGeneralObjFromDB($no, null, 2);
@@ -1316,39 +1392,39 @@ function CheckHall($no) {
$tlw = $generalObj->getRankVar('tlw');
$tld = $generalObj->getRankVar('tld');
$tll = $generalObj->getRankVar('tll');
$tsw = $generalObj->getRankVar('tsw');
$tsd = $generalObj->getRankVar('tsd');
$tsl = $generalObj->getRankVar('tsl');
$tiw = $generalObj->getRankVar('tiw');
$tid = $generalObj->getRankVar('tid');
$til = $generalObj->getRankVar('til');
$betWinGold = $generalObj->getRankVar('betwingold');
$betGold = Util::valueFit($generalObj->getRankVar('betgold'), 1);
$win = $generalObj->getRankVar('killnum');
$war = Util::valueFit($generalObj->getRankVar('warnum'), 1);
$kill = $generalObj->getRankVar('killcrew');
$death = Util::valueFit($generalObj->getRankVar('deathcrew'), 1);
$tt = Util::valueFit($ttw+$ttd+$ttl, 1);
$tl = Util::valueFit($tlw+$tld+$tll, 1);
$ts = Util::valueFit($tsw+$tsd+$tsl, 1);
$ti = Util::valueFit($tiw+$tid+$til, 1);
$tt = Util::valueFit($ttw + $ttd + $ttl, 1);
$tl = Util::valueFit($tlw + $tld + $tll, 1);
$ts = Util::valueFit($tsw + $tsd + $tsl, 1);
$ti = Util::valueFit($tiw + $tid + $til, 1);
$calcVar = [];
$calcVar['ttrate'] = $ttw/$tt;
$calcVar['tlrate'] = $tlw/$tl;
$calcVar['tsrate'] = $tsw/$ts;
$calcVar['tirate'] = $tiw/$ti;
$calcVar['betrate'] = $betWinGold/$betGold;
$calcVar['winrate'] = $win/$war;
$calcVar['killrate'] = $kill/$death;
if($generalObj instanceof DummyGeneral){
$calcVar['ttrate'] = $ttw / $tt;
$calcVar['tlrate'] = $tlw / $tl;
$calcVar['tsrate'] = $tsw / $ts;
$calcVar['tirate'] = $tiw / $ti;
$calcVar['betrate'] = $betWinGold / $betGold;
$calcVar['winrate'] = $win / $war;
$calcVar['killrate'] = $kill / $death;
if ($generalObj instanceof DummyGeneral) {
return;
}
@@ -1360,170 +1436,138 @@ function CheckHall($no) {
[$scenarioIdx, $scenarioName, $startTime] = $gameStor->getValuesAsArray(['scenario', 'scenario_text', 'starttime']);
$ownerName = $generalObj->getVar('owner_name');
if($generalObj->getVar('owner')){
if ($generalObj->getVar('owner')) {
$ownerName = RootDB::db()->queryFirstField('SELECT name FROM member WHERE no = %i', $generalObj->getVar('owner'));
}
foreach($types as $idx=>[$typeName, $valueType]) {
if($valueType === 'natural'){
foreach ($types as $idx => [$typeName, $valueType]) {
if ($valueType === 'natural') {
$value = $generalObj->getVar($typeName);
}
else if($valueType === 'rank'){
} else if ($valueType === 'rank') {
$value = $generalObj->getRankVar($typeName);
}
else if($valueType === 'calc'){
} else if ($valueType === 'calc') {
$value = $calcVar[$typeName];
}
//승률,살상률인데 10회 미만 전투시 스킵
if(($typeName === 'winrate' || $typeName === 'killrate') && $generalObj->getRankVar('warnum')<10) { continue; }
if (($typeName === 'winrate' || $typeName === 'killrate') && $generalObj->getRankVar('warnum') < 10) {
continue;
}
//토너승률인데 50회 미만시 스킵
if($typeName === 'ttrate' && $tt < 50) { continue; }
if ($typeName === 'ttrate' && $tt < 50) {
continue;
}
//토너승률인데 50회 미만시 스킵
if($typeName === 'tlrate' && $tl < 50) { continue; }
if ($typeName === 'tlrate' && $tl < 50) {
continue;
}
//토너승률인데 50회 미만시 스킵
if($typeName === 'tsrate' && $ts < 50) { continue; }
if ($typeName === 'tsrate' && $ts < 50) {
continue;
}
//토너승률인데 50회 미만시 스킵
if($typeName === 'tirate' && $ti < 50) { continue; }
if ($typeName === 'tirate' && $ti < 50) {
continue;
}
//수익률인데 1000미만시 스킵
if($typeName === 'betrate' && $generalObj->getRankVar('betgold') < 1000) { continue; }
if ($typeName === 'betrate' && $generalObj->getRankVar('betgold') < 1000) {
continue;
}
if($value<=0){
if ($value <= 0) {
continue;
}
$aux = [
'name'=>$generalObj->getName(),
'nationName'=>$nation['name'],
'bgColor'=>$nation['color'],
'fgColor'=>newColor($nation['color']),
'picture'=>$generalObj->getVar('picture'),
'imgsvr'=>$generalObj->getVar('imgsvr'),
'startTime'=>$startTime,
'unitedTime'=>$unitedDate,
'ownerName'=>$ownerName,
'serverID'=>UniqueConst::$serverID,
'serverIdx'=>$serverCnt,
'serverName'=>UniqueConst::$serverName,
'scenarioName'=>$scenarioName,
'name' => $generalObj->getName(),
'nationName' => $nation['name'],
'bgColor' => $nation['color'],
'fgColor' => newColor($nation['color']),
'picture' => $generalObj->getVar('picture'),
'imgsvr' => $generalObj->getVar('imgsvr'),
'startTime' => $startTime,
'unitedTime' => $unitedDate,
'ownerName' => $ownerName,
'serverID' => UniqueConst::$serverID,
'serverIdx' => $serverCnt,
'serverName' => UniqueConst::$serverName,
'scenarioName' => $scenarioName,
];
$jsonAux = Json::encode($aux);
$db->insertIgnore('ng_hall', [
'server_id'=>UniqueConst::$serverID,
'season'=>UniqueConst::$seasonIdx,
'scenario'=>$scenarioIdx,
'general_no'=>$no,
'type'=>$idx,
'value'=>$value,
'owner'=>$generalObj->getVar('owner'),
'aux'=>$jsonAux
'server_id' => UniqueConst::$serverID,
'season' => UniqueConst::$seasonIdx,
'scenario' => $scenarioIdx,
'general_no' => $no,
'type' => $idx,
'value' => $value,
'owner' => $generalObj->getVar('owner'),
'aux' => $jsonAux
]);
if($db->affectedRows() == 0){
$db->update('ng_hall', [
'value'=>$value,
'aux'=>$jsonAux
],
'server_id = %s AND scenario = %i AND general_no = %i AND type = %i AND value < %d',
UniqueConst::$serverID,
$scenarioIdx,
$no,
$idx,
$value);
if ($db->affectedRows() == 0) {
$db->update(
'ng_hall',
[
'value' => $value,
'aux' => $jsonAux
],
'server_id = %s AND scenario = %i AND general_no = %i AND type = %i AND value < %d',
UniqueConst::$serverID,
$scenarioIdx,
$no,
$idx,
$value
);
}
}
}
function tryUniqueItemLottery(General $general, string $acquireType='아이템'):bool{
function giveRandomUniqueItem(General $general, string $acquireType): bool
{
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
if($general->getVar('npc') >= 2){
return false;
}
if($general->getVar('npc') > 6){
return false;
}
foreach($general->getItems() as $item){
if(!$item){
continue;
}
if(!$item->isBuyable()){
return false;
}
}
$scenario = $gameStor->scenario;
$genCount = $db->queryFirstField('SELECT count(*) FROM general WHERE npc<2');
if ($scenario < 100) {
$prob = 1 / ($genCount * 5); // 5~6개월에 하나씩 등장
}
else {
$prob = 1 / $genCount; // 1~2개월에 하나씩 등장
}
if($acquireType == '투표'){
$prob = 1 / ($genCount * 0.7 / 3); // 투표율 70%, 투표 한번에 2~3개 등장
}
else if($acquireType == '랜덤 임관'){
$prob = 1 / ($genCount / 10/ 2); // 랜임시 2개(10%) 등장(200명중 20명 랜임시도?)
}
else if($acquireType == '건국'){
$prob = 1 / ($genCount / 10/ 4); // 건국시 4개(20%) 등장(200명시 20국 정도 됨)
}
$prob = Util::valueFit($prob, 1/3, 1);
if(!Util::randBool($prob)){
return false;
}
//아이템 습득 상황
$availableUnique = [];
//TODO: 너무 바보 같다. 장기적으로는 유니크 아이템 테이블 같은게 필요하지 않을까?
//일단은 '획득' 시에만 동작하므로 이대로 사용하기로...
$occupiedUnique = [];
foreach (array_keys(GameConst::$allItems) as $itemType) {
foreach($db->queryAllLists('SELECT %b, count(*) as cnt FROM general GROUP BY %b', $itemType, $itemType) as [$itemCode, $cnt]){
foreach ($db->queryAllLists('SELECT %b, count(*) as cnt FROM general GROUP BY %b', $itemType, $itemType) as [$itemCode, $cnt]) {
$itemClass = buildItemClass($itemCode);
if(!$itemClass){
if (!$itemClass) {
continue;
}
if($itemClass->isBuyable()){
if ($itemClass->isBuyable()) {
continue;
}
$occupiedUnique[$itemCode] = $cnt;
}
}
foreach(GameConst::$allItems as $itemType=>$itemCategories){
foreach($itemCategories as $itemCode => $cnt){
if(!key_exists($itemCode, $occupiedUnique)){
foreach (GameConst::$allItems as $itemType => $itemCategories) {
foreach ($itemCategories as $itemCode => $cnt) {
if (!key_exists($itemCode, $occupiedUnique)) {
$availableUnique[] = [[$itemType, $itemCode], $cnt];
continue;
}
$remain = $cnt - $occupiedUnique[$itemCode];
if($remain > 0){
if ($remain > 0) {
$availableUnique[] = [[$itemType, $itemCode], $remain];
}
}
}
if(!$availableUnique){
if (!$availableUnique) {
return false;
}
[$itemType, $itemCode] = Util::choiceRandomUsingWeightPair($availableUnique);
$nationName = $general->getStaticNation()['name'];
$generalName = $general->getName();
$josaYi = JosaUtil::pick($generalName, '이');
@@ -1545,24 +1589,75 @@ function tryUniqueItemLottery(General $general, string $acquireType='아이템')
return true;
}
function getAdmin() {
function tryUniqueItemLottery(General $general, string $acquireType = '아이템'): bool
{
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
if ($general->getVar('npc') >= 2) {
return false;
}
if ($general->getVar('npc') > 6) {
return false;
}
foreach ($general->getItems() as $item) {
if (!$item) {
continue;
}
if (!$item->isBuyable()) {
return false;
}
}
$scenario = $gameStor->scenario;
$genCount = $db->queryFirstField('SELECT count(*) FROM general WHERE npc<2');
if ($scenario < 100) {
$prob = 1 / ($genCount * 5); // 5~6개월에 하나씩 등장
} else {
$prob = 1 / $genCount; // 1~2개월에 하나씩 등장
}
if ($acquireType == '투표') {
$prob = 1 / ($genCount * 0.7 / 3); // 투표율 70%, 투표 한번에 2~3개 등장
} else if ($acquireType == '랜덤 임관') {
$prob = 1 / ($genCount / 10 / 2); // 랜임시 2개(10%) 등장(200명중 20명 랜임시도?)
} else if ($acquireType == '건국') {
$prob = 1 / ($genCount / 10 / 4); // 건국시 4개(20%) 등장(200명시 20국 정도 됨)
}
$prob = Util::valueFit($prob, 1 / 3, 1);
if (!Util::randBool($prob)) {
return false;
}
return giveRandomUniqueItem($general, $acquireType);
}
function getAdmin()
{
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
return $gameStor->getAll();
}
function getCity($city, $sel="*") {
function getCity($city, $sel = "*")
{
$db = DB::db();
$connect=$db->get();
$connect = $db->get();
$query = "select {$sel} from city where city='$city'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$result = MYDB_query($query, $connect) or Error(__LINE__ . MYDB_error($connect), "");
$city = MYDB_fetch_array($result);
return $city;
}
function deleteNation(General $general) {
function deleteNation(General $general)
{
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
@@ -1591,27 +1686,27 @@ function deleteNation(General $general) {
// 전 장수 재야로 // 전 장수 소속 무소속으로
$db->update('general', [
'belong'=>0,
'troop'=>0,
'officer_level'=>0,
'officer_city'=>0,
'nation'=>0,
'makelimit'=>12,
'permission'=>'normal',
'belong' => 0,
'troop' => 0,
'officer_level' => 0,
'officer_city' => 0,
'nation' => 0,
'makelimit' => 12,
'permission' => 'normal',
], 'nation=%i', $nationID);
// 도시 공백지로
$db->update('city', [
'nation'=>0,
'front'=>0,
'nation' => 0,
'front' => 0,
], 'nation=%i', $nationID);
// 부대 삭제
$db->delete('troop', 'nation=%i', $nationID);
// 국가 삭제
$db->insert('ng_old_nations', [
'server_id'=>UniqueConst::$serverID,
'nation'=>$nationID,
'data'=>Json::encode($oldNation)
'server_id' => UniqueConst::$serverID,
'nation' => $nationID,
'data' => Json::encode($oldNation)
]);
$db->delete('nation', 'nation=%i', $nationID);
$db->delete('nation_turn', 'nation_id=%i', $nationID);
@@ -1621,10 +1716,11 @@ function deleteNation(General $general) {
refreshNationStaticInfo();
}
function nextRuler(General $general) {
function nextRuler(General $general)
{
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
[$year, $month] = $gameStor->getValuesAsArray(['year', 'month']);
$nation = $general->getStaticNation();
$nationName = $nation['name'];
@@ -1633,7 +1729,7 @@ function nextRuler(General $general) {
$candidate = null;
//npc or npc유저인 경우 후계 찾기
if($general->getVar('npc') > 0) {
if ($general->getVar('npc') > 0) {
$candidate = $db->queryFirstRow(
'SELECT no,name,officer_level,IF(ABS(affinity-%i)>75,150-ABS(affinity-%i),ABS(affinity-%i)) as npcmatch2 from general where nation=%i and officer_level!=12 and 1 <= npc and npc<=3 order by npcmatch2,rand() LIMIT 1',
$general->getVar('affinity'),
@@ -1642,13 +1738,13 @@ function nextRuler(General $general) {
$nationID
);
}
if(!$candidate){
if (!$candidate) {
$candidate = $db->queryFirstRow(
'SELECT no,name,npc,officer_level FROM general WHERE nation=%i and officer_level!= 12 AND officer_level >= 9 and npc != 5 ORDER BY officer_level DESC LIMIT 1',
$nationID
);
}
if(!$candidate){
if (!$candidate) {
$candidate = $db->queryFirstRow(
'SELECT no,name,npc,officer_level FROM general WHERE nation=%i and officer_level!= 12 and npc != 5 ORDER BY dedication DESC LIMIT 1',
$nationID
@@ -1656,7 +1752,7 @@ function nextRuler(General $general) {
}
if(!$candidate){
if (!$candidate) {
DeleteConflict($general->getNationID());
deleteNation($general);
return;
@@ -1669,10 +1765,10 @@ function nextRuler(General $general) {
$general->setVar('officer_city', 0);
$db->update('general', [
'officer_level'=>12,
'officer_city'=>0,
'officer_level' => 12,
'officer_city' => 0,
], 'no=%i AND nation=%i', $nextRulerID, $nationID);
if($db->affectedRows()==0){
if ($db->affectedRows() == 0) {
throw new \RuntimeException('선양되지 않음');
}
@@ -1691,7 +1787,8 @@ function nextRuler(General $general) {
* @param $maxDist 검색하고자 하는 최대 거리
* @param $distForm 리턴 타입. true일 경우 $result[$dist] = [...$city] 이며, false일 경우 $result[$city] = $dist 임
*/
function searchDistance(int $from, int $maxDist=99, bool $distForm = false) {
function searchDistance(int $from, int $maxDist = 99, bool $distForm = false)
{
$queue = new \SplQueue();
$cities = [];
@@ -1699,35 +1796,34 @@ function searchDistance(int $from, int $maxDist=99, bool $distForm = false) {
$queue->enqueue([$from, 0]);
while(!$queue->isEmpty()){
while (!$queue->isEmpty()) {
list($cityID, $dist) = $queue->dequeue();
if(key_exists($cityID, $cities)){
if (key_exists($cityID, $cities)) {
continue;
}
if(!key_exists($dist, $distanceList)){
if (!key_exists($dist, $distanceList)) {
$distanceList[$dist] = [];
}
$distanceList[$dist][] = $cityID;
$cities[$cityID] = $dist;
if($dist >= $maxDist){
if ($dist >= $maxDist) {
continue;
}
foreach(array_keys(CityConst::byID($cityID)->path) as $connCityID){
if(key_exists($connCityID, $cities)){
foreach (array_keys(CityConst::byID($cityID)->path) as $connCityID) {
if (key_exists($connCityID, $cities)) {
continue;
}
$queue->enqueue([$connCityID, $dist+1]);
$queue->enqueue([$connCityID, $dist + 1]);
}
}
if($distForm){
if ($distForm) {
unset($distanceList[0]);
return $distanceList;
}
else{
} else {
return $cities;
}
}
@@ -1739,63 +1835,60 @@ function searchDistance(int $from, int $maxDist=99, bool $distForm = false) {
* @param array|null $linkNationList 경로에 해당하는 국가 리스트, null인 경우 제한 없음
* @return null|int 거리.
*/
function calcCityDistance(int $from, int $to, ?array $linkNationList):?int{
function calcCityDistance(int $from, int $to, ?array $linkNationList): ?int
{
$queue = new \SplQueue();
$cities = [];
if($linkNationList === []){
if ($linkNationList === []) {
return null;
}
if($linkNationList !== null){
if ($linkNationList !== null) {
$db = DB::db();
//TODO: 도시-국가 캐싱이 있으면 쓸모 있지 않을까
$allowedCityList = [];
foreach($db->queryFirstColumn(
foreach ($db->queryFirstColumn(
'SELECT city FROM city WHERE nation IN %li',
$linkNationList
) as $cityID){
) as $cityID) {
$allowedCityList[$cityID] = $cityID;
}
}
else{
} else {
$allowedCityList = CityConst::all();
}
if(!key_exists($to, $allowedCityList)){
if (!key_exists($to, $allowedCityList)) {
return null;
}
if($from === $to){
if ($from === $to) {
return 0;
}
$queue->enqueue([$from, 0]);
while(!$queue->isEmpty()){
while (!$queue->isEmpty()) {
list($cityID, $dist) = $queue->dequeue();
if(key_exists($cityID, $cities)){
if (key_exists($cityID, $cities)) {
continue;
}
$cities[$cityID] = $dist;
if($cityID === $to){
if ($cityID === $to) {
return $dist;
}
foreach(array_keys(CityConst::byID($cityID)->path) as $connCityID){
if(!key_exists($connCityID, $allowedCityList)){
foreach (array_keys(CityConst::byID($cityID)->path) as $connCityID) {
if (!key_exists($connCityID, $allowedCityList)) {
continue;
}
if(key_exists($connCityID, $cities)){
if (key_exists($connCityID, $cities)) {
continue;
}
$queue->enqueue([$connCityID, $dist+1]);
$queue->enqueue([$connCityID, $dist + 1]);
}
}
@@ -1809,7 +1902,8 @@ function calcCityDistance(int $from, int $to, ?array $linkNationList):?int{
* @param $linkNationList 경로에 해당하는 국가 리스트
* @return array $dist=>[cityID, $nation] 배열 가장 앞이 가장 가까움
*/
function searchDistanceListToDest(int $from, int $to, array $linkNationList) {
function searchDistanceListToDest(int $from, int $to, array $linkNationList)
{
$queue = new \SplQueue();
$cities = [];
@@ -1818,49 +1912,48 @@ function searchDistanceListToDest(int $from, int $to, array $linkNationList) {
//TODO: 도시-국가 캐싱이 있으면 쓸모 있지 않을까
$allowedCityList = [];
foreach($db->queryAllLists(
foreach ($db->queryAllLists(
'SELECT city, nation FROM city WHERE nation IN %li',
$linkNationList
) as [$cityID, $nationID]){
) as [$cityID, $nationID]) {
$allowedCityList[$cityID] = $nationID;
}
$remainFromCities = [];
foreach(array_keys(CityConst::byID($from)->path) as $fromCityID){
if(key_exists($fromCityID, $allowedCityList)){
foreach (array_keys(CityConst::byID($from)->path) as $fromCityID) {
if (key_exists($fromCityID, $allowedCityList)) {
$remainFromCities[$fromCityID] = true;
}
}
if(!key_exists($to, $allowedCityList)){
if (!key_exists($to, $allowedCityList)) {
return [];
}
$result = [];
$queue->enqueue([$to, 0]);
while(!empty($remainFromCities) && !$queue->isEmpty()){
while (!empty($remainFromCities) && !$queue->isEmpty()) {
list($cityID, $dist) = $queue->dequeue();
if(key_exists($cityID, $cities)){
if (key_exists($cityID, $cities)) {
continue;
}
$cities[$cityID] = $dist;
if(key_exists($cityID, $remainFromCities)){
if (key_exists($cityID, $remainFromCities)) {
unset($remainFromCities[$cityID]);
$result[$dist][] = [$cityID, $allowedCityList[$cityID]];
}
foreach(array_keys(CityConst::byID($cityID)->path) as $connCityID){
if($allowedCityList !== null && !key_exists($connCityID, $allowedCityList)){
foreach (array_keys(CityConst::byID($cityID)->path) as $connCityID) {
if ($allowedCityList !== null && !key_exists($connCityID, $allowedCityList)) {
continue;
}
if(key_exists($connCityID, $cities)){
if (key_exists($connCityID, $cities)) {
continue;
}
$queue->enqueue([$connCityID, $dist+1]);
$queue->enqueue([$connCityID, $dist + 1]);
}
}
@@ -1872,20 +1965,21 @@ function searchDistanceListToDest(int $from, int $to, array $linkNationList) {
* @param $cityIDList 이동 가능한 도시 리스트.
* @return array [from][to] 로 표시되는 거리값
*/
function searchAllDistanceByCityList(array $cityIDList):array {
if(!$cityIDList){
function searchAllDistanceByCityList(array $cityIDList): array
{
if (!$cityIDList) {
return [];
}
$cityList = [];
foreach($cityIDList as $cityID){
foreach ($cityIDList as $cityID) {
$cityList[$cityID] = $cityID;
}
$distanceList = [];
foreach($cityIDList as $cityID){
$nearList = [$cityID=>0];
foreach(array_keys(CityConst::byID($cityID)->path) as $nextCityID){
if(!key_exists($nextCityID, $cityList)){
foreach ($cityIDList as $cityID) {
$nearList = [$cityID => 0];
foreach (array_keys(CityConst::byID($cityID)->path) as $nextCityID) {
if (!key_exists($nextCityID, $cityList)) {
continue;
}
$nearList[$nextCityID] = 1;
@@ -1894,21 +1988,21 @@ function searchAllDistanceByCityList(array $cityIDList):array {
}
//Floyd-Warshall
foreach($cityList as $cityStop){
foreach($cityList as $cityFrom){
foreach($cityList as $cityTo){
if(!key_exists($cityStop, $distanceList[$cityFrom])){
foreach ($cityList as $cityStop) {
foreach ($cityList as $cityFrom) {
foreach ($cityList as $cityTo) {
if (!key_exists($cityStop, $distanceList[$cityFrom])) {
continue;
}
if(!key_exists($cityTo, $distanceList[$cityStop])){
if (!key_exists($cityTo, $distanceList[$cityStop])) {
continue;
}
if(!key_exists($cityTo, $distanceList[$cityFrom])){
if (!key_exists($cityTo, $distanceList[$cityFrom])) {
$distanceList[$cityFrom][$cityTo] = $distanceList[$cityFrom][$cityStop] + $distanceList[$cityStop][$cityTo];
continue;
}
$distanceList[$cityFrom][$cityTo] = min($distanceList[$cityFrom][$cityStop] + $distanceList[$cityStop][$cityTo], $distanceList[$cityFrom][$cityTo]);
}
}
@@ -1923,42 +2017,42 @@ function searchAllDistanceByCityList(array $cityIDList):array {
* @param $suppliedCityOnly 보급된 도시만을 이용해 검색
* @return array [from][to] 로 표시되는 거리값
*/
function searchAllDistanceByNationList(array $linkNationList, bool $suppliedCityOnly=false):array {
if(!$linkNationList){
function searchAllDistanceByNationList(array $linkNationList, bool $suppliedCityOnly = false): array
{
if (!$linkNationList) {
return [];
}
$db = DB::db();
if($suppliedCityOnly){
$cityIDList = $db->queryFirstColumn('SELECT city FROM city WHERE nation IN %li AND supply=1',$linkNationList);
}
else{
$cityIDList = $db->queryFirstColumn('SELECT city FROM city WHERE nation IN %li',$linkNationList);
if ($suppliedCityOnly) {
$cityIDList = $db->queryFirstColumn('SELECT city FROM city WHERE nation IN %li AND supply=1', $linkNationList);
} else {
$cityIDList = $db->queryFirstColumn('SELECT city FROM city WHERE nation IN %li', $linkNationList);
}
return searchAllDistanceByCityList($cityIDList);
}
function isNeighbor(int $nation1, int $nation2, bool $includeNoSupply=true) {
if($nation1 === $nation2){
function isNeighbor(int $nation1, int $nation2, bool $includeNoSupply = true)
{
if ($nation1 === $nation2) {
return false;
}
$db = DB::db();
$nation1Cities = [];
if($includeNoSupply){
if ($includeNoSupply) {
$supplySql = '';
}
else{
} else {
$supplySql = 'AND supply = 1';
}
foreach($db->queryFirstColumn('SELECT city FROM city WHERE nation = %i %l', $nation1, $supplySql) as $city){
foreach ($db->queryFirstColumn('SELECT city FROM city WHERE nation = %i %l', $nation1, $supplySql) as $city) {
$nation1Cities[$city] = $city;
}
foreach($db->queryFirstColumn('SELECT city FROM city WHERE nation = %i %l', $nation2, $supplySql) as $city){
foreach(array_keys(CityConst::byID($city)->path) as $adjCity){
if(key_exists($adjCity, $nation1Cities)){
foreach ($db->queryFirstColumn('SELECT city FROM city WHERE nation = %i %l', $nation2, $supplySql) as $city) {
foreach (array_keys(CityConst::byID($city)->path) as $adjCity) {
if (key_exists($adjCity, $nation1Cities)) {
return true;
}
}
@@ -1967,16 +2061,17 @@ function isNeighbor(int $nation1, int $nation2, bool $includeNoSupply=true) {
return false;
}
function SabotageInjury(array $cityGeneralList, string $reason):int{
function SabotageInjury(array $cityGeneralList, string $reason): int
{
$injuryCount = 0;
$josaRo = JosaUtil::pick($reason, '로');
$text = "<M>{$reason}</>{$josaRo} 인해 <R>부상</>을 당했습니다.";
$db = DB::db();
foreach($cityGeneralList as $general){
foreach ($cityGeneralList as $general) {
/** @var General $general */
if(!Util::randBool(0.3)){
if (!Util::randBool(0.3)) {
continue;
}
$general->getLogger()->pushGeneralActionLog($text);
@@ -1985,7 +2080,7 @@ function SabotageInjury(array $cityGeneralList, string $reason):int{
$general->multiplyVar('crew', 0.98);
$general->multiplyVar('atmos', 0.98);
$general->multiplyVar('train', 0.98);
$general->applyDB($db);
$injuryCount += 1;
@@ -1994,39 +2089,35 @@ function SabotageInjury(array $cityGeneralList, string $reason):int{
return $injuryCount;
}
function getRandTurn($term, ?\DateTimeInterface $baseDateTime = null) {
if($baseDateTime === null){
function getRandTurn($term, ?\DateTimeInterface $baseDateTime = null)
{
if ($baseDateTime === null) {
$baseDateTime = new \DateTimeImmutable();
}
else if($baseDateTime instanceof \DateTime){
} else if ($baseDateTime instanceof \DateTime) {
$baseDateTime = \DateTimeImmutable::createFromMutable($baseDateTime);
}
else if($baseDateTime instanceof \DateTimeImmutable){
} else if ($baseDateTime instanceof \DateTimeImmutable) {
//do Nothing
}
else{
} else {
throw new MustNotBeReachedException();
}
$randSecond = Util::randRangeInt(0, 60 * $term - 1);
$randFraction = Util::randRangeInt(0, 999999) / 1000000;//6자리 소수
$randFraction = Util::randRangeInt(0, 999999) / 1000000; //6자리 소수
return $baseDateTime->add(TimeUtil::secondsToDateInterval($randSecond + $randFraction))->format('Y-m-d H:i:s');
}
function getRandTurn2($term, ?\DateTimeInterface $baseDateTime = null)
{
if($baseDateTime === null){
if ($baseDateTime === null) {
$baseDateTime = new \DateTimeImmutable();
}
else if($baseDateTime instanceof \DateTime){
} else if ($baseDateTime instanceof \DateTime) {
$baseDateTime = \DateTimeImmutable::createFromMutable($baseDateTime);
}
else{
} else {
throw new MustNotBeReachedException();
}
$randSecond = Util::randRangeInt(0, 60 * $term - 1);
$randFraction = Util::randRangeInt(0, 999999) / 1000000;//6자리 소수
$randFraction = Util::randRangeInt(0, 999999) / 1000000; //6자리 소수
return $baseDateTime->sub(TimeUtil::secondsToDateInterval($randSecond + $randFraction))->format('Y-m-d H:i:s');
}
}