Compare commits

..
3 Commits
Author SHA1 Message Date
Hide_D 3762d9050c fix: GetCityInfo에서 출력됨 2023-03-26 02:55:42 +09:00
Hide_D 75d88d48b6 feat,wip: GetCityInfo 2023-03-26 02:43:33 +09:00
Hide_D 633defcb21 feat: wip, 도시정보 2023-03-26 01:04:09 +09:00
205 changed files with 2595 additions and 3035 deletions
-2
View File
@@ -69,5 +69,3 @@ gateway/js/*
gateway/css/* gateway/css/*
*.db-journal *.db-journal
d_log/cachegrind.*
+1 -1
View File
@@ -29,5 +29,5 @@
"josa", "josa",
"sammo" "sammo"
], ],
"editor.tabSize": 4 "editor.tabSize": 2
} }
+3 -3
View File
@@ -30,10 +30,10 @@ require(__DIR__ . '/../vendor/autoload.php');
<body> <body>
<div class="container"> <div class="container">
<h1 class="row justify-content-lg-center">삼국지 모의전투 HiDCHe 설치</h1> <h1 class="row justify-content-md-center">삼국지 모의전투 HiDCHe 설치</h1>
<div class="row justify-content-lg-center"> <div class="row justify-content-md-center">
<div class="col col-12 col-lg-10 col-lg-7"> <div class="col col-12 col-md-10 col-lg-7">
<div class="card" id="db_form_card" style="display:none"> <div class="card" id="db_form_card" style="display:none">
<h3 class="card-header"> <h3 class="card-header">
설치(DB 설정) 설치(DB 설정)
+22 -1
View File
@@ -74,7 +74,28 @@ switch ($btn) {
case "120분턴": $turnterm = 120; break; case "120분턴": $turnterm = 120; break;
default: throw new \Exception("알 수 없는 턴 기간"); default: throw new \Exception("알 수 없는 턴 기간");
} }
ServerTool::changeServerTerm($turnterm); $oldunit = $admin['turnterm'] * 60;
$unit = $turnterm * 60;
$unitDiff = $unit / $oldunit;
$servTurnTime = new \DateTimeImmutable($admin['turntime']);
foreach ($db->query('SELECT no,turntime FROM general') as $gen) {
$genTurnTime = new \DateTimeImmutable($gen['turntime']);
$timeDiff = TimeUtil::DateIntervalToSeconds($genTurnTime->diff($servTurnTime));
$timeDiff *= $unitDiff;
$newGenTurnTime = $servTurnTime->add(TimeUtil::secondsToDateInterval($timeDiff));
$db->update('general', [
'turntime'=>$newGenTurnTime->format('Y-m-d H:i:s.u')
], 'no=%i', $gen['no']);
}
$turn = ($admin['year'] - $admin['startyear']) * 12 + $admin['month'] - 1;
$starttime = $servTurnTime->sub(TimeUtil::secondsToDateInterval($turn * $unit))->format('Y-m-d H:i:s');
$starttime = cutTurn($starttime, $turnterm, false);
$gameStor->turnterm = $turnterm;
$gameStor->starttime = $starttime;
pushGlobalHistoryLog(["<R>★</>턴시간이 <C>$btn</>으로 변경됩니다."]);
break; break;
} }
+10 -10
View File
@@ -38,13 +38,13 @@ if ($genlist) {
} }
switch ($btn) { switch ($btn) {
case "전체 접속허용": case "전체 접속허용":
$db->update('general_access_log', [ $db->update('general', [
'refresh_score' => 0 'con' => 0
], true); ], true);
break; break;
case "전체 접속제한": case "전체 접속제한":
$db->update('general_access_log', [ $db->update('general', [
'refresh_score' => 1000 'con' => 1000
], true); ], true);
break; break;
case "블럭 해제": case "블럭 해제":
@@ -186,14 +186,14 @@ switch ($btn) {
], '`no` IN %li', $genlist); ], '`no` IN %li', $genlist);
break; break;
case "접속 허용": case "접속 허용":
$db->update('general_access_log', [ $db->update('general', [
'refresh_score' => 0 'con' => 0
], '`general_id` IN %li', $genlist); ], '`no` IN %li', $genlist);
break; break;
case "접속 제한": case "접속 제한":
$db->update('general_access_log', [ $db->update('general', [
'refresh_score' => 1000 'con' => 1000
], '`general_id` IN %li', $genlist); ], '`no` IN %li', $genlist);
break; break;
case "메세지 전달": case "메세지 전달":
$text = $msg ?? ''; $text = $msg ?? '';
+133
View File
@@ -0,0 +1,133 @@
<?php
namespace sammo;
include "lib.php";
include "func.php";
//로그인 검사
$session = Session::requireGameLogin()->setReadOnly();
if ($session->userGrade < 5) {
die(requireAdminPermissionHTML());
}
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$conlimit = $gameStor->conlimit;
$ipGroupList = Util::arrayGroupBy(
$db->query(
'SELECT name,ip,lastconnect,owner,block,substring_index(ip,".",3) as ip_c from general WHERE ip!="" and npc<2'
),
'ip_c'
);
function colorBlockedName($general)
{
if (!$general['blocked']) {
return $general['name'];
}
return "<span style='color:magenta;'>{$general['name']}</span>";
}
?>
<!DOCTYPE html>
<html>
<head>
<title>멀티관리</title>
<meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" />
<?= WebUtil::printCSS('../d_shared/common.css') ?>
<?= WebUtil::printDist('ts', 'common', true) ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.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:14px'>";
foreach ($db->query('SELECT no,name,npc,block,con from general where ip!=\'\' order by npc,ip') as $general) {
$style = "style=;";
if ($general['block'] > 0) {
$style .= "background-color:red;";
}
$npcColor = getNPCColor($general['npc']);
if($npcColor !== null){
$style .= "color:{$npcColor};";
}
echo "
<option value={$general['no']} $style>{$general['name']}</option>";
}
echo "
</select>";
?>
</td>
<td width=100 align=center>블럭</td>
<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>
1단계:발언권, 2단계:턴블럭
</td>
</tr>
<tr>
<td align=center>강제 사망</td>
<td><input type=submit name=btn value='강제 사망'></td>
</tr>
<tr>
<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>
</tr>
</table>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td align=center width=100>장수명</td>
<td align=center width=180>최근로그인</td>
<td align=center width=129>IP</td>
<td align=center width=100>ID</td>
</tr>
<?php foreach ($ipGroupList as $ipGroupC => $users) : ?>
<tr>
<td><?= join('<br>', array_map('\sammo\colorBlockedName', $users)) ?></td>
<td><?= join('<br>', array_column($users, 'lastconnect')) ?></td>
<td><?= join('<br>', array_column($users, 'ip')) ?></td>
<td><?= join('<br>', array_column($users, 'owner')) ?></td>
</tr>
<?php endforeach; ?>
</table>
<?php
//NOTE: password의 md5 해시가 같은지 확인하는 방식으로는 앞으로 잡아낼 수 없다. 폐기
?>
</form>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td><?= backButton() ?></td>
</tr>
<tr>
<td><?= banner() ?> </td>
</tr>
</table>
</body>
</html>
+86
View File
@@ -0,0 +1,86 @@
<?php
namespace sammo;
use sammo\Enums\MessageType;
include "lib.php";
include "func.php";
//로그인 검사
$session = Session::requireGameLogin()->setReadOnly();
if ($session->userGrade < 5) {
header('location:_admin4.php');
die();
}
$btn = Util::getPost('btn');
$genlist = Util::getPost('genlist', 'array_int');
$msg = Util::getPost('msg', 'string', '메시지');
$db = DB::db();
//NOTE: 왜 기능이 admin2와 admin4가 같이 있는가?
//NOTE: 왜 블럭 시 admin4에선 금쌀을 없애지 않는가?
switch ($btn) {
case "블럭 해제":
DB::db()->query('update general set block=0 where no IN %li', $genlist);
break;
case "1단계 블럭":
$date = TimeUtil::now();
$db = DB::db();
$db->query('update general set block=1,killturn=24 where no IN %li', $genlist);
//FIXME: subquery로 하는게 더 빠를 듯.
$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);
break;
case "2단계 블럭":
$date = TimeUtil::now();
$db = DB::db();
$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);
RootDB::db()->query('update member set block_num=block_num+1,block_date=%s where id IN %ls', $date, $uid);
break;
case "3단계 블럭":
$date = TimeUtil::now();
$db = DB::db();
$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);
RootDB::db()->query('update member set block_num=block_num+1,block_date=%s where id IN %ls', $date, $uid);
break;
case "무한삭턴":
DB::db()->query('update general set killturn=8000 where no IN %li', $genlist);
break;
case "강제 사망":
$date = TimeUtil::now(true);
$db->update('general', [
'killturn' => 0,
'turntime' => $date,
], '`no` IN %li', $genlist);
$db->update('general_turn', [
'action' => '휴식',
'arg' => '{}',
'brief' => '휴식'
], 'general_id IN %li AND turn_idx = 0', $genlist);
break;
case "메세지 전달":
$date = TimeUtil::now();
$src = MessageTarget::buildQuick($session->generalID);
foreach($genlist as $generalID){
$msgObj = new Message(
MessageType::private,
$src,
MessageTarget::buildQuick($generalID),
$msg,
new \DateTime(),
new \DateTime('9999-12-31'),
[]
);
if ($msgObj) {
$msgObj->send(true);
}
}
break;
}
header('location:_admin4.php');
+14
View File
@@ -66,6 +66,8 @@ $sel2[$type2] = "selected";
<option <?= $sel[8] ?? '' ?> value=8>평무</option> <option <?= $sel[8] ?? '' ?> value=8>평무</option>
<option <?= $sel[9] ?? '' ?> value=9>평지</option> <option <?= $sel[9] ?? '' ?> value=9>평지</option>
<option <?= $sel[10] ?? '' ?> value=10>평Lv</option> <option <?= $sel[10] ?? '' ?> value=10>평Lv</option>
<option <?= $sel[11] ?? '' ?> value=11>접속률</option>
<option <?= $sel[12] ?? '' ?> value=12>단기접</option>
<option <?= $sel[13] ?? '' ?> value=13>보숙</option> <option <?= $sel[13] ?? '' ?> value=13>보숙</option>
<option <?= $sel[14] ?? '' ?> value=14>궁숙</option> <option <?= $sel[14] ?? '' ?> value=14>궁숙</option>
<option <?= $sel[15] ?? '' ?> value=15>기숙</option> <option <?= $sel[15] ?? '' ?> value=15>기숙</option>
@@ -103,6 +105,8 @@ $sel2[$type2] = "selected";
<table align=center width=1600 class="tb_layout bg0"> <table align=center width=1600 class="tb_layout bg0">
<tr class='bg1'> <tr class='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>
@@ -143,6 +147,8 @@ SELECT
A.gold, A.gold,
A.rice, A.rice,
COUNT(B.nation) AS gennum, COUNT(B.nation) AS gennum,
ROUND(AVG(B.connect), 1) AS connect,
ROUND(AVG(B.con), 1) AS con,
ROUND(AVG(B.dex1)) AS dex1, ROUND(AVG(B.dex1)) AS dex1,
ROUND(AVG(B.dex2)) AS dex2, ROUND(AVG(B.dex2)) AS dex2,
ROUND(AVG(B.dex3)) AS dex3, ROUND(AVG(B.dex3)) AS dex3,
@@ -187,6 +193,12 @@ GROUP BY B.nation
case 10: case 10:
$query .= " order by avg(B.explevel) desc"; $query .= " order by avg(B.explevel) desc";
break; break;
case 11:
$query .= " order by avg(B.connect) desc";
break;
case 12:
$query .= " order by avg(B.con) desc";
break;
case 13: case 13:
$query .= " order by avg(B.dex1) desc"; $query .= " order by avg(B.dex1) desc";
break; break;
@@ -228,6 +240,8 @@ from city where nation=%i', $nation['nation']);
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['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>
+1 -3
View File
@@ -2,8 +2,6 @@
namespace sammo; namespace sammo;
use sammo\Enums\GeneralQueryMode;
include "lib.php"; include "lib.php";
include "func.php"; include "func.php";
@@ -76,7 +74,7 @@ if (!$gen) {
$gen = $generalBasicList[0]['no']; $gen = $generalBasicList[0]['no'];
} }
$generalObj = General::createGeneralObjFromDB($gen, null, GeneralQueryMode::FullWithAccessLog); $generalObj = General::createGeneralObjFromDB($gen);
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
+8 -16
View File
@@ -16,13 +16,10 @@ $gameStor = KVStorage::getStorage($db, 'game_env');
increaseRefresh("장수일람", 2); increaseRefresh("장수일람", 2);
$me = $db->queryFirstRow( $me = $db->queryFirstRow('SELECT con,turntime FROM general WHERE owner = %i', $userID);
'SELECT refresh_score,turntime FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner = %i', $userID
);
$limitState = checkLimit($me['refresh_score']); $con = checkLimit($me['con']);
if ($limitState >= 2) { if ($con >= 2) {
printLimitMsg($me['turntime']); printLimitMsg($me['turntime']);
exit(); exit();
} }
@@ -105,7 +102,7 @@ if ($gameStor->isunited) {
6 => ['dedication', true], 6 => ['dedication', true],
7 => ['officer_level', true], 7 => ['officer_level', true],
8 => ['killturn', false], 8 => ['killturn', false],
9 => ['refresh_score_total', true], 9 => ['connect', true],
10 => ['experience', true], 10 => ['experience', true],
11 => ['personal', true], 11 => ['personal', true],
12 => ['special', true], 12 => ['special', true],
@@ -114,12 +111,7 @@ if ($gameStor->isunited) {
15 => ['npc', true], 15 => ['npc', true],
][$type]; ][$type];
$generalList = $db->query( $generalList = $db->query('SELECT owner,no,picture,imgsvr,npc,age,nation,special,special2,personal,name,injury,leadership,strength,intel,experience,dedication,officer_level,killturn,connect from general order by %b %l', $orderKey, $orderDesc ? 'desc' : '');
'SELECT owner,no,picture,imgsvr,npc,age,nation,special,special2,personal,name,injury,leadership,strength,intel,experience,dedication,officer_level,killturn,refresh_score_total
FROM `general` LEFT JOIN `general_access_log` ON general.no = general_access_log.general_id order by %b %l',
$orderKey,
$orderDesc ? 'desc' : ''
);
echo " echo "
<table align=center width=1000 class='tb_layout bg0'> <table align=center width=1000 class='tb_layout bg0'>
@@ -171,7 +163,7 @@ if ($gameStor->isunited) {
$name = $name . '<br><small>(' . $ownerNameList[$general['owner']] . ')</small>'; $name = $name . '<br><small>(' . $ownerNameList[$general['owner']] . ')</small>';
} }
$general['refresh_score_total'] = Util::round($general['refresh_score_total'], -1); $general['connect'] = Util::round($general['connect'], -1);
$imageTemp = GetImageURL($general['imgsvr']); $imageTemp = GetImageURL($general['imgsvr']);
echo " echo "
@@ -200,8 +192,8 @@ if ($gameStor->isunited) {
<td align=center>$strength</td> <td align=center>$strength</td>
<td align=center>$intel</td> <td align=center>$intel</td>
<td align=center>{$general['killturn']}</td> <td align=center>{$general['killturn']}</td>
<td align=center>" . $general['refresh_score_total'] ?? 0; <td align=center>{$general['connect']}";
echo "<br>【" . getRefreshScoreText($general['refresh_score_total'] ?? 0) . "】</td> echo "<br>【" . getConnect($general['connect']) . "】</td>
</tr>"; </tr>";
} }
echo " echo "
+3 -6
View File
@@ -13,13 +13,10 @@ $gameStor = KVStorage::getStorage($db, 'game_env');
$gameStor->cacheValues(['killturn', 'autorun_user', 'turnterm']); $gameStor->cacheValues(['killturn', 'autorun_user', 'turnterm']);
increaseRefresh("세력일람", 2); increaseRefresh("세력일람", 2);
$me = $db->queryFirstRow( $me = $db->queryFirstRow('SELECT con, turntime FROM general WHERE owner=%i', $userID);
'SELECT refresh_score, turntime FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$limitState = checkLimit($me['refresh_score']); $con = checkLimit($me['con']);
if ($limitState >= 2) { if ($con >= 2) {
printLimitMsg($me['turntime']); printLimitMsg($me['turntime']);
exit(); exit();
} }
+8 -15
View File
@@ -2,8 +2,6 @@
namespace sammo; namespace sammo;
use sammo\Enums\GeneralAccessLogColumn;
include "lib.php"; include "lib.php";
include "func.php"; include "func.php";
@@ -25,10 +23,10 @@ $online = [];
$curonline = getOnlineNum(); $curonline = getOnlineNum();
foreach ($log as $i => $value) { foreach ($log as $i => $value) {
$parse = Json::decode($value); $parse = Json::decode($value);
if (is_array($parse) === false) { if(is_array($parse) === false){
continue; continue;
} }
if (count($parse) < 5) { if(count($parse) < 5){
continue; continue;
} }
$date[$i] = $parse[0]; $date[$i] = $parse[0];
@@ -195,24 +193,19 @@ if ($admin['maxonline'] < $curonline) {
</td> </td>
</tr> </tr>
<?php <?php
$totalRefresh = [ $max_refresh = $db->queryFirstRow('SELECT sum(refresh) as refresh, sum(`connect`) as `connect` from general');
...$db->queryFirstRow('SELECT sum(`refresh`) as `refresh`, sum(`refresh_score_total`) as `refresh_score_total` from general_access_log'), $max_refresh['name'] = '접속자 총합';
'name' => '접속자 총합'
];
$top5Refresh = $db->query( $refresh_result = array_merge([$max_refresh], $db->query('SELECT `name`,refresh,`connect` FROM general ORDER BY refresh DESC LIMIT 5'));
'SELECT `name`, `log`.`refresh`, `refresh_score_total` FROM `general_access_log` AS `log`
INNER JOIN `general` ON `log`.`general_id` = `general`.`no` ORDER BY `log`.`refresh` DESC LIMIT 5'
);
foreach (array_merge([$totalRefresh], $top5Refresh) as $i => $user) { foreach ($refresh_result as $i => $user) {
$w = round($user['refresh'] / max(1, $totalRefresh['refresh']) * 100, 1); $w = round($user['refresh'] / max(1, $max_refresh['refresh']) * 100, 1);
$w2 = round(100 - $w, 1); $w2 = round(100 - $w, 1);
$color = getTrafficColor($w); $color = getTrafficColor($w);
?> ?>
<tr> <tr>
<td width=98 align=center><?= $user['name'] ?></td> <td width=98 align=center><?= $user['name'] ?></td>
<td width=98 align=center><?= $user['refresh_score_total'] ?>(<?= $user['refresh'] ?>)</td> <td width=98 align=center><?= $user['connect'] ?>(<?= $user['refresh'] ?>)</td>
<td width=798> <td width=798>
<?php if ($w == 0) : ?> <?php if ($w == 0) : ?>
<?php elseif ($w < 10) : ?> <?php elseif ($w < 10) : ?>
+5 -9
View File
@@ -2,7 +2,6 @@
namespace sammo; namespace sammo;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\RankColumn; use sammo\Enums\RankColumn;
include "lib.php"; include "lib.php";
@@ -22,15 +21,12 @@ $generalID = $session->generalID;
$me = $db->queryFirstRow( $me = $db->queryFirstRow('SELECT no,tournament,con,turntime from general where owner=%i', $userID);
'SELECT no,tournament,refresh_score,turntime FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id where owner=%i', $userID
);
$admin = $gameStor->getValues(['tournament', 'phase', 'tnmt_type', 'turnterm', 'develcost']); $admin = $gameStor->getValues(['tournament', 'phase', 'tnmt_type', 'turnterm', 'develcost']);
$turnTerm = $admin['turnterm']; $turnTerm = $admin['turnterm'];
$limitState = checkLimit($me['refresh_score']); $con = checkLimit($me['con']);
if ($limitState >= 2) { if ($con >= 2) {
printLimitMsg($me['turntime']); printLimitMsg($me['turntime']);
exit(); exit();
} }
@@ -111,7 +107,7 @@ if ($str3) {
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<?php if ($limitState == 1) { <?php if ($con == 1) {
MessageBox("접속제한이 얼마 남지 않았습니다!"); MessageBox("접속제한이 얼마 남지 않았습니다!");
} ?> } ?>
@@ -567,7 +563,7 @@ if ($str3) {
$tournamentRankerList = General::createGeneralObjListFromDB( $tournamentRankerList = General::createGeneralObjListFromDB(
$db->queryFirstColumn('SELECT general_id FROM rank_data WHERE `type`= %s ORDER BY value DESC LIMIT 40', $gameColumn->value), $db->queryFirstColumn('SELECT general_id FROM rank_data WHERE `type`= %s ORDER BY value DESC LIMIT 40', $gameColumn->value),
[$prizeColumn->value, $gameColumn->value, $winColumn->value, $drawColumn->value, $loseColumn->value, 'leadership', 'strength', 'intel', 'no', 'npc', 'name'], [$prizeColumn->value, $gameColumn->value, $winColumn->value, $drawColumn->value, $loseColumn->value, 'leadership', 'strength', 'intel', 'no', 'npc', 'name'],
GeneralQueryMode::Core 0
); );
usort($tournamentRankerList, function (General $lhs, General $rhs) use ($gameColumn, $winColumn, $drawColumn, $loseColumn) { usort($tournamentRankerList, function (General $lhs, General $rhs) use ($gameColumn, $winColumn, $drawColumn, $loseColumn) {
$result = - ($lhs->getRankVar($gameColumn) <=> $rhs->getRankVar($gameColumn)); $result = - ($lhs->getRankVar($gameColumn) <=> $rhs->getRankVar($gameColumn));
+2 -2
View File
@@ -211,7 +211,7 @@ $templates = new \League\Plates\Engine('templates');
$city['trade'] = "- "; $city['trade'] = "- ";
} }
$dbColumns = General::mergeQueryColumn(['npc', 'defence_train', 'no', 'picture', 'imgsvr', 'name', 'injury', 'leadership', 'strength', 'intel', 'officer_level', 'nation', 'crewtype', 'crew', 'train', 'atmos'])[0]; $dbColumns = General::mergeQueryColumn(['npc', 'defence_train', 'no', 'picture', 'imgsvr', 'name', 'injury', 'leadership', 'strength', 'intel', 'officer_level', 'nation', 'crewtype', 'crew', 'train', 'atmos'], 2)[0];
if ($showDetailedInfo) { if ($showDetailedInfo) {
$generals = $db->query( $generals = $db->query(
'SELECT %l from general where city=%i order by turntime', 'SELECT %l from general where city=%i order by turntime',
@@ -327,7 +327,7 @@ $templates = new \League\Plates\Engine('templates');
if ($ourGeneral && !$isNPC) { if ($ourGeneral && !$isNPC) {
$turnText = []; $turnText = [];
$generalObj = new General($general, null, null, null, null, null, null, false); $generalObj = new General($general, null, null, null, null, null, false);
foreach ($generalTurnList[$generalObj->getID()] as $turnRawIdx => $turn) { foreach ($generalTurnList[$generalObj->getID()] as $turnRawIdx => $turn) {
$turnIdx = $turnRawIdx + 1; $turnIdx = $turnRawIdx + 1;
$turnText[] = "{$turnIdx} : $turn"; $turnText[] = "{$turnIdx} : $turn";
+4 -7
View File
@@ -19,15 +19,12 @@ $gameStor = KVStorage::getStorage($db, 'game_env');
increaseRefresh("암행부", 1); increaseRefresh("암행부", 1);
$me = $db->queryFirstRow( $me = $db->queryFirstRow('SELECT no,nation,officer_level,con,turntime,belong,permission,penalty from general where owner=%i', $userID);
'SELECT no,nation,officer_level,refresh_score,turntime,belong,permission,penalty FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$nationLevel = $db->queryFirstField('SELECT level FROM nation WHERE nation=%i', $me['nation']); $nationLevel = $db->queryFirstField('SELECT level FROM nation WHERE nation=%i', $me['nation']);
$limitState = checkLimit($me['refresh_score']); $con = checkLimit($me['con']);
if ($limitState >= 2) { if ($con >= 2) {
printLimitMsg($me['turntime']); printLimitMsg($me['turntime']);
exit(); exit();
} }
@@ -48,7 +45,7 @@ $templates = new \League\Plates\Engine('templates');
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<?php if ($limitState == 1) { <?php if ($con == 1) {
MessageBox("접속제한이 얼마 남지 않았습니다!"); MessageBox("접속제한이 얼마 남지 않았습니다!");
} ?> } ?>
+4 -6
View File
@@ -97,7 +97,7 @@ if ($gameStor->isunited) {
7 => ['gold', true], 7 => ['gold', true],
8 => ['rice', true], 8 => ['rice', true],
9 => ['crew', true], 9 => ['crew', true],
10 => ['refresh_score_total', true], 10 => ['connect', true],
11 => ['personal', true], 11 => ['personal', true],
12 => ['special', true], 12 => ['special', true],
13 => ['special2', true], 13 => ['special2', true],
@@ -105,9 +105,7 @@ if ($gameStor->isunited) {
15 => ['npc', true], 15 => ['npc', true],
][$type]; ][$type];
$generalList = $db->query( $generalList = $db->query('SELECT owner,no,picture,imgsvr,npc,age,nation,special,special2,personal,name,injury,leadership,strength,intel,experience,dedication,officer_level,killturn,connect,gold,rice,crew,belong from general where nation = %i order by %b %l', $me['nation'], $orderKey, $orderDesc ? 'desc' : '');
'SELECT owner,no,picture,imgsvr,npc,age,nation,special,special2,personal,name,injury,leadership,strength,intel,experience,dedication,officer_level,killturn,refresh_score_total,gold,rice,crew,belong
FROM `general` LEFT JOIN `general_access_log` ON general.no = general_access_log.general_id where nation = %i order by %b %l', $me['nation'], $orderKey, $orderDesc ? 'desc' : '');
echo " echo "
<table align=center class='tb_layout bg0'> <table align=center class='tb_layout bg0'>
@@ -175,8 +173,8 @@ if ($gameStor->isunited) {
<td align=center>" . displayCharInfo($general['personal']) . "</td> <td align=center>" . displayCharInfo($general['personal']) . "</td>
<td align=center>" . displaySpecialDomesticInfo($general['special']) . " / " . displaySpecialWarInfo($general['special2']) . "</td> <td align=center>" . displaySpecialDomesticInfo($general['special']) . " / " . displaySpecialWarInfo($general['special2']) . "</td>
<td align=center>{$general['belong']}</td> <td align=center>{$general['belong']}</td>
<td align=center>". $general['refresh_score_total'] ?? 0; <td align=center>{$general['connect']}";
echo "<br>(" . getRefreshScoreText($general['refresh_score_total'] ?? 0) . ")</td> echo "<br>(" . getConnect($general['connect']) . ")</td>
</tr>"; </tr>";
} }
echo " echo "
+8 -19
View File
@@ -2,10 +2,6 @@
namespace sammo; namespace sammo;
use sammo\Enums\GeneralAccessLogColumn;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\TableName;
include "lib.php"; include "lib.php";
include "func.php"; include "func.php";
@@ -24,7 +20,7 @@ $gameStor->cacheValues(['turntime', 'opentime', 'autorun_user', 'npcmode']);
increaseRefresh("내정보", 1); increaseRefresh("내정보", 1);
$me = General::createGeneralObjFromDB($generalID, null, GeneralQueryMode::FullWithAccessLog); $me = General::createGeneralObjFromDB($generalID);
$myset = $me->getVar('myset'); $myset = $me->getVar('myset');
if ($myset > 0) { if ($myset > 0) {
@@ -33,14 +29,7 @@ if ($myset > 0) {
$submit = 'hidden'; $submit = 'hidden';
} }
$lastRefresh = $db->queryFirstField( $targetTime = addTurn($me->getVar('lastrefresh'), $gameStor->turnterm, GameConst::$minTurnDieOnPrestart);
'SELECT %b FROM %b WHERE %b = %i',
GeneralAccessLogColumn::lastRefresh->value,
TableName::generalAccessLog->value,
GeneralAccessLogColumn::generalID->value, $generalID
);
$targetTime = addTurn($lastRefresh, $gameStor->turnterm, GameConst::$minTurnDieOnPrestart);
if ($gameStor->turntime <= $gameStor->opentime) { if ($gameStor->turntime <= $gameStor->opentime) {
//서버 가오픈시 할 수 있는 행동 //서버 가오픈시 할 수 있는 행동
if ($me->getNPCType() == 0 && $me->getNationID() == 0) { if ($me->getNPCType() == 0 && $me->getNationID() == 0) {
@@ -92,13 +81,13 @@ $use_auto_nation_turn = $me->getAuxVar('use_auto_nation_turn') ?? 1;
<div class="col">내 정 보<br><?= backButton() ?></div> <div class="col">내 정 보<br><?= backButton() ?></div>
</div> </div>
<div class="row gx-0"> <div class="row gx-0">
<div class="col col-12 col-lg-6"> <div class="col col-12 col-md-6">
<div class="row"> <div class="row">
<div class="col"><?php generalInfo($me); ?><?php generalInfo2($me); ?></div> <div class="col"><?php generalInfo($me); ?><?php generalInfo2($me); ?></div>
</div> </div>
</div> </div>
<div class="col col-12 col-lg-6"> <div class="col col-12 col-md-6">
<div class="row mx-0 gx-0"> <div class="row mx-0 gx-0">
<div class="col" style='padding-left:2ch;'> <div class="col" style='padding-left:2ch;'>
토너먼트 【 토너먼트 【
@@ -189,7 +178,7 @@ $use_auto_nation_turn = $me->getAuxVar('use_auto_nation_turn') ?? 1;
</div> </div>
</div> </div>
</div> </div>
<div class="col col-12 col-lg-6"> <div class="col col-12 col-md-6">
<div class="row gx-0"> <div class="row gx-0">
<div class="col bg1 text-center"> <div class="col bg1 text-center">
<h4 style='color:skyblue'>개인 기록</h4> <h4 style='color:skyblue'>개인 기록</h4>
@@ -202,7 +191,7 @@ $use_auto_nation_turn = $me->getAuxVar('use_auto_nation_turn') ?? 1;
<button type="button" class="load_old_log btn btn-secondary" data-log_type="generalAction">이전 로그 불러오기</button> <button type="button" class="load_old_log btn btn-secondary" data-log_type="generalAction">이전 로그 불러오기</button>
</div> </div>
</div> </div>
<div class="col col-12 col-lg-6"> <div class="col col-12 col-md-6">
<div class="row gx-0"> <div class="row gx-0">
<div class="col bg1 text-center"> <div class="col bg1 text-center">
<h4 style='color:orange'>전투 기록</h4> <h4 style='color:orange'>전투 기록</h4>
@@ -216,7 +205,7 @@ $use_auto_nation_turn = $me->getAuxVar('use_auto_nation_turn') ?? 1;
</div> </div>
</div> </div>
<div class="col col-12 col-lg-6"> <div class="col col-12 col-md-6">
<div class="row gx-0"> <div class="row gx-0">
<div class="col bg1 text-center"> <div class="col bg1 text-center">
<h4 style='color:skyblue'>장수 열전</h4> <h4 style='color:skyblue'>장수 열전</h4>
@@ -226,7 +215,7 @@ $use_auto_nation_turn = $me->getAuxVar('use_auto_nation_turn') ?? 1;
<?= formatHistoryToHTML(getGeneralHistoryLogAll($generalID)) ?> <?= formatHistoryToHTML(getGeneralHistoryLogAll($generalID)) ?>
</div> </div>
</div> </div>
<div class="col col-12 col-lg-6"> <div class="col col-12 col-md-6">
<div class="row gx-0"> <div class="row gx-0">
<div class="col bg1 text-center"> <div class="col bg1 text-center">
<h4 style='color:orange'>전투 결과</h4> <h4 style='color:orange'>전투 결과</h4>
+5 -7
View File
@@ -14,16 +14,14 @@ $gameStor = KVStorage::getStorage($db, 'game_env');
increaseRefresh("토너먼트", 1); increaseRefresh("토너먼트", 1);
TurnExecutionHelper::executeAllCommand(); TurnExecutionHelper::executeAllCommand();
$me = $db->queryFirstRow( $me = $db->queryFirstRow('select no,tournament,con,turntime from general where owner=%i', $userID);
'SELECT no,tournament,refresh_score,turntime from `general` $generalID = $session->generalID;
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id where owner=%i', $userID
);
$admin = $gameStor->getValues(['tournament', 'phase', 'turnterm', 'tnmt_msg', 'tnmt_type', 'develcost', 'tnmt_trig']); $admin = $gameStor->getValues(['tournament', 'phase', 'turnterm', 'tnmt_msg', 'tnmt_type', 'develcost', 'tnmt_trig']);
$turnTerm = $admin['turnterm']; $turnTerm = $admin['turnterm'];
$limitState = checkLimit($me['refresh_score']); $con = checkLimit($me['con']);
if ($limitState >= 2) { if ($con >= 2) {
printLimitMsg($me['turntime']); printLimitMsg($me['turntime']);
exit(); exit();
} }
@@ -102,7 +100,7 @@ $globalBetTotal = array_sum($globalBet);
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<?php if ($limitState == 1) { <?php if ($con == 1) {
MessageBox("접속제한이 얼마 남지 않았습니다! 제한량이 모자라다면 참여를 해보세요^^"); MessageBox("접속제한이 얼마 남지 않았습니다! 제한량이 모자라다면 참여를 해보세요^^");
} ?> } ?>
-6
View File
@@ -1,6 +0,0 @@
<?php
namespace sammo;
class ServerEnv extends ServerDefaultEnv {
//ServerEnv 기본값을 변경하고 싶다면 orig를 제거한 복사본을 만들고 수정
}
+65 -75
View File
@@ -5,9 +5,6 @@ namespace sammo;
use DateTime; use DateTime;
use Ds\Set; use Ds\Set;
use sammo\Enums\AuctionType; use sammo\Enums\AuctionType;
use sammo\Enums\GeneralAccessLogColumn;
use sammo\Enums\GeneralColumn;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\InheritanceKey; use sammo\Enums\InheritanceKey;
use sammo\Enums\RankColumn; use sammo\Enums\RankColumn;
@@ -106,9 +103,10 @@ function GetImageURL($imgsvr, $filepath = '')
} }
/** /**
* @param null|int $refreshScore 장수의 벌점 * @param null|int $con 장수의 벌점
* @param null|int $conlimit 최대 벌점
*/ */
function checkLimit($refreshScore = null) function checkLimit($con = null)
{ {
$session = Session::getInstance(); $session = Session::getInstance();
if ($session->userGrade >= 4) { if ($session->userGrade >= 4) {
@@ -118,15 +116,15 @@ function checkLimit($refreshScore = null)
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
if ($refreshScore === null) { if ($con === null) {
$refreshScore = $db->queryFirstField('SELECT refresh_score FROM general_access_log WHERE `general_id`=%i', Session::getGeneralID()); $con = $db->queryFirstField('SELECT con FROM general WHERE `owner`=%i', Session::getUserID());
} }
$refreshLimit = $gameStor->refreshLimit; $conlimit = $gameStor->conlimit;
if ($refreshScore > $refreshLimit) { if ($con > $conlimit) {
return 2; return 2;
//접속제한 90%이면 경고문구 //접속제한 90%이면 경고문구
} elseif ($refreshScore > $refreshLimit * 0.9) { } elseif ($con > $conlimit * 0.9) {
return 1; return 1;
} else { } else {
return 0; return 0;
@@ -644,7 +642,7 @@ function generalInfo(General $generalObj)
$age = "<font color=red>{$age} 세</font>"; $age = "<font color=red>{$age} 세</font>";
} }
$refreshScoreTotal = round($generalObj->getAccessLogVar(GeneralAccessLogColumn::refreshScoreTotal) ?? 0, -1); $connectCnt = round($generalObj->getVar('connect'), -1);
$specialDomestic = $generalObj->getVar('special') === GameConst::$defaultSpecialDomestic $specialDomestic = $generalObj->getVar('special') === GameConst::$defaultSpecialDomestic
? "{$generalObj->getVar('specage')}세" ? "{$generalObj->getVar('specage')}세"
: "<font color=limegreen>" . displayiActionObjInfo($generalObj->getSpecialDomestic()) . "</font>"; : "<font color=limegreen>" . displayiActionObjInfo($generalObj->getSpecialDomestic()) . "</font>";
@@ -753,7 +751,7 @@ function generalInfo(General $generalObj)
<td style='text-align:center;' class='bg1'><b>부대</b></td> <td style='text-align:center;' class='bg1'><b>부대</b></td>
<td style='text-align:center;' colspan=3>{$troopInfo}</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;' class='bg1'><b>벌점</b></td>
<td style='text-align:center;' colspan=5>" . getRefreshScoreText($refreshScoreTotal) . " {$refreshScoreTotal}({$generalObj->getAccessLogVar(GeneralAccessLogColumn::refreshScore)})</td> <td style='text-align:center;' colspan=5>" . getConnect($connectCnt) . " {$connectCnt}({$generalObj->getVar('con')})</td>
</tr> </tr>
</table>"; </table>";
} }
@@ -1000,69 +998,52 @@ function increaseRefresh($type = "", $cnt = 1)
$generalID = $session->generalID; $generalID = $session->generalID;
$userGrade = $session->userGrade; $userGrade = $session->userGrade;
$dateObj = new \DateTimeImmutable(); $date = TimeUtil::now();
$date = TimeUtil::format($dateObj, false);
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
$isunited = $gameStor->isunited; $isunited = $gameStor->isunited;
$opentime = $gameStor->opentime; $opentime = $gameStor->opentime;
if ($userGrade == 6) { if($userGrade == 6){
return; return;
} }
if ($isunited == 2) { if($isunited == 2){
return; return;
} }
if (!$generalID) { if(!$generalID){
return; return;
} }
if ($opentime > $date) { if($opentime > $date){
return; return;
} }
$gameStor->refresh = $gameStor->refresh + $cnt; //TODO: +로 증가하는 값은 별도로 분리 $gameStor->refresh = $gameStor->refresh + $cnt; //TODO: +로 증가하는 값은 별도로 분리
$db->insertUpdate('general_access_log', [ $db->update('general', [
GeneralAccessLogColumn::generalID->value => $generalID, 'lastrefresh' => $date,
GeneralAccessLogColumn::userID->value => $userID, 'con' => $db->sqleval('con + %i', $cnt),
GeneralAccessLogColumn::lastRefresh->value => $date, 'connect' => $db->sqleval('connect + %i', $cnt),
GeneralAccessLogColumn::refreshTotal->value => $cnt, 'refcnt' => $db->sqleval('refcnt + %i', $cnt),
GeneralAccessLogColumn::refresh->value => $cnt, 'refresh' => $db->sqleval('refresh + %i', $cnt)
GeneralAccessLogColumn::refreshScore->value => $cnt, ], 'owner=%i', $userID);
GeneralAccessLogColumn::refreshScoreTotal->value => $cnt,
], [
GeneralAccessLogColumn::lastRefresh->value => $date,
GeneralAccessLogColumn::refreshTotal->value => $db->sqleval('%b + %i', GeneralAccessLogColumn::refreshTotal->value, $cnt),
GeneralAccessLogColumn::refresh->value => $db->sqleval('%b + %i', GeneralAccessLogColumn::refresh->value, $cnt),
GeneralAccessLogColumn::refreshScore->value => $db->sqleval('%b + %i', GeneralAccessLogColumn::refreshScore->value, $cnt),
GeneralAccessLogColumn::refreshScoreTotal->value => $db->sqleval('%b + %i', GeneralAccessLogColumn::refreshScoreTotal->value, $cnt),
]);
$serverPath = __DIR__; $date = date('Y_m_d H:i:s');
$date2 = substr($date, 0, 10);
$serverID = UniqueConst::$serverID; $online = getOnlineNum();
$logPath = "{$serverPath}/logs/{$serverID}/api_log.db"; file_put_contents(
__DIR__ . "/logs/" . UniqueConst::$serverID . "/_{$date2}_refresh.txt",
$logDB = FileDB::db($logPath, $serverPath . '/../f_install/sql/api_log.sql'); sprintf(
"%s, %s, %s, %s, %s, %d\n",
$ip = $_SERVER['REMOTE_ADDR'] ?? 'local'; $date,
$date = date('Y-m-d H:i:s'); $session->userName,
$session->generalName,
$logDB->insert('api_log', [ $session->ip,
'user_id' => $session->userID, $type,
'ip' => $ip, $online
'date' => $date, ),
'path' => "refresh", FILE_APPEND
'arg' => JSON::encode([ );
'type' => $type,
]),
'aux' => JSON::encode([
'generalID' => $generalID,
'generalName' => $session->generalName,
'userName' => $session->userName,
]),
]);
} }
function updateTraffic() function updateTraffic()
@@ -1073,6 +1054,9 @@ function updateTraffic()
$admin = $gameStor->getValues(['year', 'month', 'refresh', 'maxonline', 'maxrefresh']); $admin = $gameStor->getValues(['year', 'month', 'refresh', 'maxonline', 'maxrefresh']);
/** @var array{year:int,month:int,refresh:int,maxonline:int,maxrefresh:int} $admin */ /** @var array{year:int,month:int,refresh:int,maxonline:int,maxrefresh:int} $admin */
//최다갱신자
$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']; $admin['maxrefresh'] = $admin['refresh'];
} }
@@ -1083,7 +1067,22 @@ function updateTraffic()
$gameStor->maxrefresh = $admin['maxrefresh']; $gameStor->maxrefresh = $admin['maxrefresh'];
$gameStor->maxonline = $admin['maxonline']; $gameStor->maxonline = $admin['maxonline'];
$db->update('general_access_log', ['refresh' => 0], true); $db->update('general', ['refresh' => 0], true);
$date = TimeUtil::now();
//일시|년|월|총갱신|접속자|최다갱신자
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
);
} }
function CheckOverhead() function CheckOverhead()
@@ -1091,13 +1090,13 @@ function CheckOverhead()
//서버정보 //서버정보
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
[$turnterm, $refreshLimit] = $gameStor->getValuesAsArray(['turnterm', 'refreshLimit']); list($turnterm, $conlimit) = $gameStor->getValuesAsArray(['turnterm', 'conlimit']);
$nextRefreshLimit = Util::round(pow($turnterm, 0.6) * 3) * 10; $con = Util::round(pow($turnterm, 0.6) * 3) * 10;
if ($nextRefreshLimit != $refreshLimit) { if ($con != $conlimit) {
$gameStor->refreshLimit = $nextRefreshLimit; $gameStor->conlimit = $con;
} }
} }
@@ -1201,16 +1200,7 @@ function updateOnline()
//동접수 //동접수
$startTurn = cutTurn($gameStor->turntime, $gameStor->turnterm, false); $startTurn = cutTurn($gameStor->turntime, $gameStor->turnterm, false);
$onlineUser = $db->query( $onlineUser = $db->query('SELECT no,name,nation FROM general WHERE lastrefresh >= %s AND npc < 2', $startTurn);
'SELECT %b, %b, %b FROM `general_access_log` as `log` INNER JOIN `general` ON `log`.%b = `general`.%b WHERE %b >= %s',
GeneralColumn::no->value,
GeneralColumn::name->value,
GeneralColumn::nation->value,
GeneralAccessLogColumn::generalID->value,
GeneralColumn::no->value,
GeneralAccessLogColumn::lastRefresh->value,
$startTurn
);
$onlineNum = count($onlineUser); $onlineNum = count($onlineUser);
$onlineNationUsers = Util::arrayGroupBy($onlineUser, 'nation'); $onlineNationUsers = Util::arrayGroupBy($onlineUser, 'nation');
@@ -1324,7 +1314,7 @@ function CheckHall($no)
["betrate", 'calc'], ["betrate", 'calc'],
]; ];
$generalObj = General::createGeneralObjFromDB($no); $generalObj = General::createGeneralObjFromDB($no, null, 2);
$ttw = $generalObj->getRankVar(RankColumn::ttw); $ttw = $generalObj->getRankVar(RankColumn::ttw);
$ttd = $generalObj->getRankVar(RankColumn::ttd); $ttd = $generalObj->getRankVar(RankColumn::ttd);
@@ -1721,7 +1711,7 @@ function deleteNation(General $lord, bool $applyDB): array
$lordID $lordID
), ),
['npc', 'owner', 'gold', 'rice', 'experience', 'explevel', 'dedication', 'dedlevel', 'belong', 'aux'], ['npc', 'owner', 'gold', 'rice', 'experience', 'explevel', 'dedication', 'dedlevel', 'belong', 'aux'],
GeneralQueryMode::Lite, 1
); );
$nationGeneralList[$lordID] = $lord; $nationGeneralList[$lordID] = $lord;
@@ -1738,7 +1728,7 @@ function deleteNation(General $lord, bool $applyDB): array
// 전 장수 재야로 // 전 장수 재야로
foreach ($nationGeneralList as $general) { foreach ($nationGeneralList as $general) {
if ($general->getNPCType() < 2) { if($general->getNPCType() < 2){
$general->setAuxVar( $general->setAuxVar(
InheritanceKey::max_belong->value, InheritanceKey::max_belong->value,
max( max(
+12 -49
View File
@@ -133,19 +133,19 @@ function getNationType(?string $type) {
} }
function getRefreshScoreText($score) { function getConnect($con) {
if($score < 50) $scoreName = '안함'; if($con < 50) $conname = '안함';
elseif($score < 100) $scoreName = '무관심'; elseif($con < 100) $conname = '무관심';
elseif($score < 200) $scoreName = '가끔'; elseif($con < 200) $conname = '가끔';
elseif($score < 400) $scoreName = '보통'; elseif($con < 400) $conname = '보통';
elseif($score < 800) $scoreName = '자주'; elseif($con < 800) $conname = '자주';
elseif($score < 1600) $scoreName = '열심'; elseif($con < 1600) $conname = '열심';
elseif($score < 3200) $scoreName = '중독'; elseif($con < 3200) $conname = '중독';
elseif($score < 6400) $scoreName = '폐인'; elseif($con < 6400) $conname = '폐인';
elseif($score < 12800) $scoreName = '경고'; elseif($con < 12800) $conname = '경고';
else $scoreName = '헐...'; else $conname = '헐...';
return $scoreName; return $conname;
} }
function getNationType2(?string $type) { function getNationType2(?string $type) {
@@ -326,41 +326,6 @@ function buildGeneralSpecialWarClass(?string $type):BaseSpecial{
return $obj; return $obj;
} }
function getActionCrewTypeClass(?string $type){
if($type === null || $type === ''){
$type = 'None';
}
static $basePath = __NAMESPACE__.'\\ActionCrewType\\';
$classPath = ($basePath.$type);
if(class_exists($classPath)){
return $classPath;
}
$classPath = ($basePath.'che_'.$type);
if(class_exists($classPath)){
return $classPath;
}
throw new \InvalidArgumentException("{$type}은 올바른 병종 효과가 아님");
}
function buildActionCrewTypeClass(?string $type):iAction{
static $cache = [];
if($type === null){
$type = 'None';
}
if(key_exists($type, $cache)){
return $cache[$type];
}
$class = getActionCrewTypeClass($type);
$obj = new $class();
$cache[$type]= $obj;
return $obj;
}
function getGeneralCommandClass(?string $type){ function getGeneralCommandClass(?string $type){
if($type === null || $type === ''){ if($type === null || $type === ''){
$type = '휴식'; $type = '휴식';
@@ -577,8 +542,6 @@ function getExpLevel($experience) {
$level = Util::toInt(sqrt($experience/10)); $level = Util::toInt(sqrt($experience/10));
} }
$level = Util::clamp($level, 0, GameConst::$maxLevel);
return $level; return $level;
} }
+5 -34
View File
@@ -202,10 +202,8 @@ function preUpdateMonthly()
$admin = $gameStor->getValues(['startyear', 'year', 'month']); $admin = $gameStor->getValues(['startyear', 'year', 'month']);
//접률감소, 건국제한-1 //접률감소, 건국제한-1
$db->update('general_access_log', [
'refresh_score_total' => $db->sqleval('floor(refresh_score_total*0.99)'),
], true);
$db->update('general', [ $db->update('general', [
'connect' => $db->sqleval('floor(connect*0.99)'),
'makelimit' => $db->sqleval('greatest(0, makelimit - 1)'), 'makelimit' => $db->sqleval('greatest(0, makelimit - 1)'),
], true); ], true);
//전략제한-1, 외교제한-1, 세율동기화 //전략제한-1, 외교제한-1, 세율동기화
@@ -303,6 +301,7 @@ function postUpdateMonthly(RandUtil $rng)
WHERE g.nation = A.nation) WHERE g.nation = A.nation)
+(select round(sum(dex1+dex2+dex3+dex4+dex5)/1000) from general where nation=A.nation) +(select round(sum(dex1+dex2+dex3+dex4+dex5)/1000) from general where nation=A.nation)
+(select round(sum(experience+dedication)/100) from general where nation=A.nation) +(select round(sum(experience+dedication)/100) from general where nation=A.nation)
+(select round(avg(connect)) from general where nation=A.nation)
)/10) )/10)
as power, as power,
(select sum(crew) from general where nation=A.nation) as totalCrew (select sum(crew) from general where nation=A.nation) as totalCrew
@@ -698,7 +697,7 @@ function checkEmperior()
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
$admin = $gameStor->getValues(['year', 'month', 'isunited', 'refreshLimit']); $admin = $gameStor->getValues(['year', 'month', 'isunited', 'conlimit']);
if ($admin['isunited'] != 0) { if ($admin['isunited'] != 0) {
return; return;
} }
@@ -760,7 +759,7 @@ function checkEmperior()
} }
$gameStor->isunited = 2; $gameStor->isunited = 2;
$gameStor->refreshLimit = $gameStor->refreshLimit * 100; $gameStor->conlimit = $gameStor->conlimit * 100;
foreach ($db->queryFirstColumn('SELECT no FROM general WHERE npc<2 AND age>=%i', GameConst::$minPushHallAge) as $hallGeneralNo) { foreach ($db->queryFirstColumn('SELECT no FROM general WHERE npc<2 AND age>=%i', GameConst::$minPushHallAge) as $hallGeneralNo) {
CheckHall($hallGeneralNo); CheckHall($hallGeneralNo);
@@ -772,7 +771,7 @@ function checkEmperior()
$chiefs = Util::convertArrayToDict( $chiefs = Util::convertArrayToDict(
$db->query( $db->query(
'SELECT no,npc,name,picture,belong,officer_level FROM general WHERE nation=%i AND officer_level >= 5', 'SELECT no,name,picture,belong,officer_level FROM general WHERE nation=%i AND officer_level >= 5',
$nationID $nationID
), ),
'officer_level' 'officer_level'
@@ -909,34 +908,6 @@ function checkEmperior()
//연감 월결산 //연감 월결산
LogHistory(); LogHistory();
$availableInvaderGame = false;
foreach(CityConst::all() as $city){
if($city->level == 4){
$availableInvaderGame = true;
break;
}
}
if($availableInvaderGame){
$invaderMsgCnt = 2;
foreach(range(12, 5, -1) as $chiefLevel){
if(!key_exists($chiefLevel, $chiefs)){
continue;
}
$targetChief = $chiefs[$chiefLevel];
if($targetChief['npc'] >= 2){
continue;
}
$invaderMsgs = RaiseInvaderMessage::buildRaiseInvaderMessage($targetChief['no']);
foreach($invaderMsgs as $invaderMsg){
$invaderMsg->send();
}
$invaderMsgCnt--;
if($invaderMsgCnt <= 0){
break;
}
}
}
} }
function updateMaxDomesticCritical(General $general, $score) function updateMaxDomesticCritical(General $general, $score)
+1 -1
View File
@@ -383,7 +383,7 @@ function disaster(RandUtil $rng) {
$generalList = array_map( $generalList = array_map(
function($rawGeneral) use ($city, $year, $month){ function($rawGeneral) use ($city, $year, $month){
return new General($rawGeneral, null, null, $city, null, $year, $month, false); return new General($rawGeneral, null, $city, null, $year, $month, false);
}, },
$generalListByCity[$city['city']]??[] $generalListByCity[$city['city']]??[]
); );
+2 -2
View File
@@ -39,8 +39,8 @@ if ($session->userGrade < 5 && !$allowReset) {
<body> <body>
<div class="container"> <div class="container">
<h1 class="row justify-content-lg-center">삼국지 모의전투 HiDCHe 리셋</h1> <h1 class="row justify-content-md-center">삼국지 모의전투 HiDCHe 리셋</h1>
<div class="row justify-content-lg-center"> <div class="row justify-content-md-center">
<div class="col col-lg-8"> <div class="col col-lg-8">
<div class="card" id="game_form_card"> <div class="card" id="game_form_card">
+2 -2
View File
@@ -32,8 +32,8 @@ if ($session->userGrade == 5) {
<body> <body>
<div class="container" style="min-width:720px;"> <div class="container" style="min-width:720px;">
<h1 class="row justify-content-lg-center">삼국지 모의전투 HiDCHe 리셋</h1> <h1 class="row justify-content-md-center">삼국지 모의전투 HiDCHe 리셋</h1>
<div class="row justify-content-lg-center"> <div class="row justify-content-md-center">
<div class="col col-lg-8"> <div class="col col-lg-8">
<div class="card" id="db_form_card"> <div class="card" id="db_form_card">
+3 -6
View File
@@ -17,13 +17,10 @@ $text = Util::getPost('text');
increaseRefresh("회의실", 1); increaseRefresh("회의실", 1);
$me = $db->queryFirstRow( $me = $db->queryFirstRow('SELECT no, nation, name, officer_level, permission, con, turntime, belong, penalty, `picture`,`imgsvr` FROM general WHERE owner=%i', $userID);
'SELECT no, nation, name, officer_level, permission, refresh_score, turntime, belong, penalty, `picture`,`imgsvr` FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$limitState = checkLimit($me['refresh_score']); $con = checkLimit($me['con']);
if ($limitState >= 2) { if ($con >= 2) {
Json::die([ Json::die([
'result'=>false, 'result'=>false,
'reason'=>'접속 제한입니다.' 'reason'=>'접속 제한입니다.'
+3 -6
View File
@@ -16,13 +16,10 @@ $text = Util::getPost('text');
increaseRefresh("회의실", 1); increaseRefresh("회의실", 1);
$me = $db->queryFirstRow( $me = $db->queryFirstRow('SELECT no, nation, name, officer_level, permission, con, turntime, belong, penalty FROM general WHERE owner=%i', $userID);
'SELECT no, nation, name, officer_level, permission, refresh_score, turntime, belong, penalty FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$limitState = checkLimit($me['refresh_score']); $con = checkLimit($me['con']);
if ($limitState >= 2) { if ($con >= 2) {
Json::die([ Json::die([
'result'=>false, 'result'=>false,
'reason'=>'접속 제한입니다.' 'reason'=>'접속 제한입니다.'
+4 -6
View File
@@ -16,14 +16,11 @@ $isSecretBoard = Util::getPost('isSecret', 'bool', false);
increaseRefresh("회의실", 1); increaseRefresh("회의실", 1);
$me = $db->queryFirstRow( $me = $db->queryFirstRow('SELECT no, nation, officer_level, permission, con, turntime, belong, penalty FROM general WHERE owner=%i', $userID);
'SELECT no, nation, officer_level, permission, refresh_score, turntime, belong, penalty FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$limitState = checkLimit($me['refresh_score']); $con = checkLimit($me['con']);
if ($limitState >= 2) { if ($con >= 2) {
Json::die([ Json::die([
'result'=>false, 'result'=>false,
'reason'=>'접속 제한입니다.' 'reason'=>'접속 제한입니다.'
@@ -75,3 +72,4 @@ Json::die([
'articles'=>$articles, 'articles'=>$articles,
'reason'=>'success' 'reason'=>'success'
]); ]);
+3 -6
View File
@@ -17,13 +17,10 @@ $letterNo = Util::getPost('letterNo', 'int');
increaseRefresh("외교부", 1); increaseRefresh("외교부", 1);
$me = $db->queryFirstRow( $me = $db->queryFirstRow('SELECT no, name, nation, officer_level, permission, con, turntime, belong, penalty, picture, imgsvr FROM general WHERE owner=%i', $userID);
'SELECT no, name, nation, officer_level, permission, refresh_score, turntime, belong, penalty, picture, imgsvr FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$limitState = checkLimit($me['refresh_score']); $con = checkLimit($me['con']);
if ($limitState >= 2) { if ($con >= 2) {
Json::die([ Json::die([
'result'=>false, 'result'=>false,
'reason'=>'접속 제한입니다.' 'reason'=>'접속 제한입니다.'
+4 -6
View File
@@ -16,14 +16,11 @@ $isSecretBoard = Util::getPost('isSecret', 'bool', false);
increaseRefresh("외교부", 1); increaseRefresh("외교부", 1);
$me = $db->queryFirstRow( $me = $db->queryFirstRow('SELECT no, nation, officer_level, permission, con, turntime, belong, penalty FROM general WHERE owner=%i', $userID);
'SELECT no, nation, officer_level, permission, refresh_score, turntime, belong, penalty FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$limitState = checkLimit($me['refresh_score']); $con = checkLimit($me['con']);
if ($limitState >= 2) { if ($con >= 2) {
Json::die([ Json::die([
'result'=>false, 'result'=>false,
'reason'=>'접속 제한입니다.' 'reason'=>'접속 제한입니다.'
@@ -86,3 +83,4 @@ Json::die([
'myNationID'=>$me['nation'], 'myNationID'=>$me['nation'],
'reason'=>'success' 'reason'=>'success'
]); ]);
+3 -6
View File
@@ -22,13 +22,10 @@ $reason = Util::getPost('reason', 'string', '');
increaseRefresh("외교부", 1); increaseRefresh("외교부", 1);
$me = $db->queryFirstRow( $me = $db->queryFirstRow('SELECT no, name, nation, officer_level, permission, con, turntime, belong, penalty, picture, imgsvr FROM general WHERE owner=%i', $userID);
'SELECT no, name, nation, officer_level, permission, refresh_score, turntime, belong, penalty, picture, imgsvr FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$limitState = checkLimit($me['refresh_score']); $con = checkLimit($me['con']);
if ($limitState >= 2) { if ($con >= 2) {
Json::die([ Json::die([
'result'=>false, 'result'=>false,
'reason'=>'접속 제한입니다.' 'reason'=>'접속 제한입니다.'
+3 -6
View File
@@ -17,13 +17,10 @@ $letterNo = Util::getPost('letterNo', 'int');
increaseRefresh("외교부", 1); increaseRefresh("외교부", 1);
$me = $db->queryFirstRow( $me = $db->queryFirstRow('SELECT no, name, nation, officer_level, permission, con, turntime, belong, penalty, picture, imgsvr FROM general WHERE owner=%i', $userID);
'SELECT no, name, nation, officer_level, permission, refresh_score, turntime, belong, penalty, picture, imgsvr FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$limitState = checkLimit($me['refresh_score']); $con = checkLimit($me['con']);
if ($limitState >= 2) { if ($con >= 2) {
Json::die([ Json::die([
'result'=>false, 'result'=>false,
'reason'=>'접속 제한입니다.' 'reason'=>'접속 제한입니다.'
+3 -6
View File
@@ -24,13 +24,10 @@ if($prevNo < 1){
$prevNo = null; $prevNo = null;
} }
$me = $db->queryFirstRow( $me = $db->queryFirstRow('SELECT no, name, nation, officer_level, permission, con, turntime, belong, penalty, picture, imgsvr FROM general WHERE owner=%i', $userID);
'SELECT no, name, nation, officer_level, permission, refresh_score, turntime, belong, penalty, picture, imgsvr FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$limitState = checkLimit($me['refresh_score']); $con = checkLimit($me['con']);
if ($limitState >= 2) { if ($con >= 2) {
Json::die([ Json::die([
'result'=>false, 'result'=>false,
'reason'=>'접속 제한입니다.' 'reason'=>'접속 제한입니다.'
+3 -6
View File
@@ -33,15 +33,12 @@ if($generalID <= 0 || $reqTo <= 0){
$db = DB::db(); $db = DB::db();
$me = $db->queryFirstRow( $me = $db->queryFirstRow('SELECT no,nation,officer_level,con,turntime,belong,permission,penalty from general where owner=%i', $userID);
'SELECT no,nation,officer_level,refresh_score,turntime,belong,permission,penalty FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$nationID = $me['nation']; $nationID = $me['nation'];
$limitState = checkLimit($me['refresh_score']); $con = checkLimit($me['con']);
if ($limitState >= 2) { if ($con >= 2) {
Json::die([ Json::die([
'result'=>false, 'result'=>false,
'reason'=>'접속 제한입니다.' 'reason'=>'접속 제한입니다.'
+1 -2
View File
@@ -1,7 +1,6 @@
<?php <?php
namespace sammo; namespace sammo;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\MessageType; use sammo\Enums\MessageType;
include "lib.php"; include "lib.php";
@@ -51,7 +50,7 @@ else{
'troop','officer_level','npc','picture','imgsvr', 'troop','officer_level','npc','picture','imgsvr',
'permission','penalty','belong', 'crewtype', 'permission','penalty','belong', 'crewtype',
'experience', 'dedication', 'betray', 'dedlevel', 'explevel', 'makelimit', 'aux', 'experience', 'dedication', 'betray', 'dedlevel', 'explevel', 'makelimit', 'aux',
], GeneralQueryMode::Lite); ], 1);
if($general instanceof DummyGeneral){ if($general instanceof DummyGeneral){
Json::die([ Json::die([
-7
View File
@@ -1,8 +1,6 @@
<?php <?php
namespace sammo; namespace sammo;
use sammo\Enums\GeneralAccessLogColumn;
include "lib.php"; include "lib.php";
include "func.php"; include "func.php";
@@ -88,11 +86,6 @@ $db->update('general', [
'owner'=>$userID, 'owner'=>$userID,
'aux'=>Json::encode($genAux) 'aux'=>Json::encode($genAux)
], 'owner <= 0 AND npc = 2 AND no = %i', $pick); ], 'owner <= 0 AND npc = 2 AND no = %i', $pick);
$db->insertIgnore('general_access_log', [
GeneralAccessLogColumn::generalID->value => $generalID,
GeneralAccessLogColumn::userID->value => $userID,
GeneralAccessLogColumn::lastRefresh->value => $now,
]);
if(!$db->affectedRows()){ if(!$db->affectedRows()){
Json::die([ Json::die([
+1 -4
View File
@@ -39,10 +39,7 @@ if (!$data || !is_array($data)) {
$db = DB::db(); $db = DB::db();
$me = $db->queryFirstRow( $me = $db->queryFirstRow('SELECT no, name, npc, nation, city, officer_level, con, turntime, belong, permission, penalty FROM general WHERE owner=%i', $userID);
'SELECT no, name, npc, nation, city, officer_level, refresh_score, turntime, belong, permission, penalty FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$nationID = $me['nation']; $nationID = $me['nation'];
+223 -280
View File
@@ -1,5 +1,4 @@
<?php <?php
namespace sammo; namespace sammo;
use Ds\Map; use Ds\Map;
@@ -16,48 +15,48 @@ $userID = Session::getUserID();
increaseRefresh("시뮬레이터", 0); increaseRefresh("시뮬레이터", 0);
$query = Util::getPost('query'); $query = Util::getPost('query');
if ($query === null) { if($query === null){
Json::die([ Json::die([
'result' => false, 'result'=>false,
'reason' => '입력값이 없습니다.' 'reason'=>'입력값이 없습니다.'
]); ]);
} }
$action = Util::getPost('action'); $action = Util::getPost('action');
if ($action === null || !in_array($action, ['reorder', 'battle'])) { if($action === null || !in_array($action, ['reorder', 'battle'])){
Json::die([ Json::die([
'result' => false, 'result'=>false,
'reason' => '원하는 동작이 지정되지 않았습니다.' 'reason'=>'원하는 동작이 지정되지 않았습니다.'
]); ]);
} }
$query = Json::decode($query); $query = Json::decode($query);
if ($query === null) { if($query === null){
Json::die([ Json::die([
'result' => false, 'result'=>false,
'reason' => '올바르지 않은 JSON입니다.' 'reason'=>'올바르지 않은 JSON입니다.'
]); ]);
} }
$defaultCheck = [ $defaultCheck = [
'required' => [ 'required'=>[
'attackerGeneral', 'attackerCity', 'attackerNation', 'attackerGeneral', 'attackerCity', 'attackerNation',
'defenderGenerals', 'defenderCity', 'defenderNation', 'defenderGenerals', 'defenderCity', 'defenderNation',
'year', 'month', 'repeatCnt' 'year', 'month', 'repeatCnt'
], ],
'integer' => [ 'integer'=>[
'year', 'month', 'repeatCnt' 'year','month','repeatCnt'
], ],
'between' => [ 'between'=>[
['month', [1, 12]] ['month', [1, 12]]
], ],
'in' => [ 'in'=>[
['repeatCnt', [1, 1000]] ['repeatCnt', [1, 1000]]
], ],
'min' => [ 'min'=>[
['year', 0] ['year', 0]
], ],
'array' => [ 'array'=>[
'attackerGeneral', 'attackerCity', 'attackerNation', 'attackerGeneral', 'attackerCity', 'attackerNation',
'defenderGenerals', 'defenderCity', 'defenderNation' 'defenderGenerals', 'defenderCity', 'defenderNation'
], ],
@@ -65,10 +64,10 @@ $defaultCheck = [
$v = new Validator($query); $v = new Validator($query);
$v->rules($defaultCheck); $v->rules($defaultCheck);
if (!$v->validate()) { if(!$v->validate()){
Json::die([ Json::die([
'result' => false, 'result'=>false,
'reason' => $v->errorStr() 'reason'=>$v->errorStr()
]); ]);
} }
@@ -87,110 +86,20 @@ $rawDefenderNation = $query['defenderNation'];
$warSeed = $query['seed'] ?? ''; $warSeed = $query['seed'] ?? '';
$cityCheck = [
'required' => [
'city', 'nation', 'supply', 'name',
'pop', 'agri', 'comm', 'secu', 'def', 'wall',
'trust', 'level',
'pop_max', 'agri_max', 'comm_max', 'secu_max', 'def_max', 'wall_max',
'dead', 'state', 'conflict',
],
'numeric' => [
'pop', 'agri', 'comm', 'secu', 'def', 'wall', 'trust', 'dead'
],
'integer' => [
'city', 'nation', 'supply',
'pop_max', 'agri_max', 'comm_max', 'secu_max', 'def_max', 'wall_max',
'state',
],
'min' => [
['def', 0],
['wall', 0],
['trust', 0],
['pop', 0],
['comm', 0],
['secu', 0],
['city', 1],
['nation', 0]
],
'in' => [
['level', array_keys(getCityLevelList())]
]
];
$v = new Validator($rawAttackerCity);
$v->rules($cityCheck);
if (!$v->validate()) {
Json::die([
'result' => false,
'reason' => '[출병도시]' . $v->errorStr()
]);
}
$v = new Validator($rawDefenderCity);
$v->rules($cityCheck);
if (!$v->validate()) {
Json::die([
'result' => false,
'reason' => '[수비도시]' . $v->errorStr()
]);
}
$nationCheck = [
'required' => [
'type', 'tech', 'level', 'capital',
'nation', 'name', 'gold', 'rice', 'gennum'
],
'integer' => [
'level', 'capital', 'nation', 'gennum',
],
'numeric' => [
'tech', 'gold', 'rice'
],
'min' => [
['tech', 0],
['gold', 0],
['rice', 0],
['gennum', 1],
],
'in' => [
['type', GameConst::$availableNationType],
['level', array_keys(getNationLevelList())]
]
];
$v = new Validator($rawAttackerNation);
$v->rules($nationCheck);
if (!$v->validate()) {
Json::die([
'result' => false,
'reason' => '[출병국]' . $v->errorStr()
]);
}
$v = new Validator($rawDefenderNation);
$v->rules($nationCheck);
if (!$v->validate()) {
Json::die([
'result' => false,
'reason' => '[수비국]' . $v->errorStr()
]);
}
$generalCheck = [ $generalCheck = [
'required' => [ 'required'=>[
'no', 'name', 'nation', 'turntime', 'personal', 'special2', 'crew', 'crewtype', 'atmos', 'train', 'no', 'name', 'nation', 'turntime', 'personal', 'special2', 'crew', 'crewtype', 'atmos', 'train',
'intel', 'intel_exp', 'book', 'strength', 'strength_exp', 'weapon', 'injury', 'leadership', 'leadership_exp', 'horse', 'item', 'intel', 'intel_exp', 'book', 'strength', 'strength_exp', 'weapon', 'injury', 'leadership', 'leadership_exp', 'horse', 'item',
'explevel', 'experience', 'dedication', 'officer_level', 'officer_city', 'gold', 'rice', 'dex1', 'dex2', 'dex3', 'dex4', 'dex5', 'explevel', 'experience', 'dedication', 'officer_level', 'officer_city', 'gold', 'rice', 'dex1', 'dex2', 'dex3', 'dex4', 'dex5',
'recent_war', 'warnum', 'killnum', 'killcrew', 'recent_war', 'warnum', 'killnum', 'killcrew',
], ],
'integer' => [ 'integer'=>[
'no', 'nation', 'crew', 'crewtype', 'atmos', 'train', 'no', 'nation', 'crew', 'crewtype', 'atmos', 'train',
'intel', 'intel_exp', 'strength', 'strength_exp', 'injury', 'leadership', 'leadership_exp', 'intel', 'intel_exp', 'strength', 'strength_exp', 'injury', 'leadership', 'leadership_exp',
'explevel', 'experience', 'dedication', 'officer_level', 'officer_city', 'gold', 'rice', 'dex1', 'dex2', 'dex3', 'dex4', 'dex5', 'explevel', 'experience', 'dedication', 'officer_level', 'officer_city', 'gold', 'rice', 'dex1', 'dex2', 'dex3', 'dex4', 'dex5',
'warnum', 'killnum', 'killcrew', 'warnum', 'killnum', 'killcrew',
], ],
'min' => [ 'min'=>[
['no', 1], ['no', 1],
['nation', 1], ['nation', 1],
['crew', 0], ['crew', 0],
@@ -209,14 +118,14 @@ $generalCheck = [
['killnum', 0], ['killnum', 0],
['killcrew', 0], ['killcrew', 0],
], ],
'between' => [ 'between'=>[
['train', [40, GameConst::$maxTrainByWar]], ['train', [40, GameConst::$maxTrainByWar]],
['atmos', [40, GameConst::$maxAtmosByWar]], ['atmos', [40, GameConst::$maxAtmosByWar]],
['explevel', [0, 300]], ['explevel', [0, 300]],
['injury', [0, 80]], ['injury', [0, 80]],
['officer_level', [1, 12]] ['officer_level', [1, 12]]
], ],
'in' => [ 'in'=>[
['personal', array_merge(GameConst::$availablePersonality, GameConst::$optionalPersonality)], ['personal', array_merge(GameConst::$availablePersonality, GameConst::$optionalPersonality)],
['special2', array_merge(GameConst::$availableSpecialWar, GameConst::$optionalSpecialWar)], ['special2', array_merge(GameConst::$availableSpecialWar, GameConst::$optionalSpecialWar)],
['crewtype', array_keys(GameUnitConst::all())], ['crewtype', array_keys(GameUnitConst::all())],
@@ -225,11 +134,11 @@ $generalCheck = [
['book', array_merge(array_keys(GameConst::$allItems['book']), ['None'])], ['book', array_merge(array_keys(GameConst::$allItems['book']), ['None'])],
['item', array_merge(array_keys(GameConst::$allItems['item']), ['None'])], ['item', array_merge(array_keys(GameConst::$allItems['item']), ['None'])],
], ],
'array' => ['inheritBuff'], 'array'=>['inheritBuff'],
]; ];
$inheritBuffCheck = [ $inheritBuffCheck = [
'between' => [ 'between'=>[
[TriggerInheritBuff::WAR_AVOID_RATIO, [0, 5]], [TriggerInheritBuff::WAR_AVOID_RATIO, [0, 5]],
[TriggerInheritBuff::WAR_CRITICAL_RATIO, [0, 5]], [TriggerInheritBuff::WAR_CRITICAL_RATIO, [0, 5]],
[TriggerInheritBuff::WAR_MAGIC_TRIAL_PROB, [0, 5]], [TriggerInheritBuff::WAR_MAGIC_TRIAL_PROB, [0, 5]],
@@ -240,67 +149,49 @@ $inheritBuffCheck = [
] ]
]; ];
if(!$warSeed){
$warSeed = bin2hex(random_bytes(16));
}
else {
$repeatCnt = 1;
}
$tmpRNG = new RandUtil(new LiteHashDRBG($warSeed));
$v = new Validator($rawAttacker); $v = new Validator($rawAttacker);
$v->rules($generalCheck); $v->rules($generalCheck);
if (!$v->validate()) { if(!$v->validate()){
Json::die([ Json::die([
'result' => false, 'result'=>false,
'reason' => '[출병자]' . $v->errorStr() 'reason'=>'[출병자]'.$v->errorStr()
]); ]);
} }
$rawAttacker['aux'] = []; $rawAttacker['aux'] = [];
if (key_exists('inheritBuff', $rawAttacker)) { if(key_exists('inheritBuff', $rawAttacker)){
$v = new Validator($rawAttacker['inheritBuff']); $v = new Validator($rawAttacker['inheritBuff']);
$v->rules($inheritBuffCheck); $v->rules($inheritBuffCheck);
if (!$v->validate()) { if(!$v->validate()){
Json::die([ Json::die([
'result' => false, 'result'=>false,
'reason' => '[출병자]' . $v->errorStr() 'reason'=>'[출병자]'.$v->errorStr()
]); ]);
} }
$rawAttacker['aux']['inheritBuff'] = $rawAttacker['inheritBuff']; $rawAttacker['aux']['inheritBuff'] = $rawAttacker['inheritBuff'];
} }
$rawAttacker['aux'] = Json::encode($rawAttacker['aux']); $rawAttacker['aux'] = Json::encode($rawAttacker['aux']);
$rawAttacker['owner'] = 0; $rawAttacker['owner'] = 0;
$attackerGeneral = new General($rawAttacker, extractRankVar($rawAttacker), null, $rawAttackerCity, $rawAttackerNation, $year, $month);
$attacker = new WarUnitGeneral(
$tmpRNG,
$attackerGeneral,
$rawAttackerNation,
true
);
/** @var WarUnit[] */
$defenderList = []; $defenderList = [];
foreach($rawDefenderList as $idx=>$rawDefenderGeneral){
foreach ($rawDefenderList as $idx => $rawDefenderGeneral) {
$v = new Validator($rawDefenderGeneral); $v = new Validator($rawDefenderGeneral);
$v->rules($generalCheck); $v->rules($generalCheck);
if (!$v->validate()) { if(!$v->validate()){
$idx += 1; $idx+=1;
Json::die([ Json::die([
'result' => false, 'result'=>false,
'reason' => "[수비자{$idx}]" . $v->errorStr() 'reason'=>"[수비자{$idx}]".$v->errorStr()
]); ]);
} }
$rawDefenderGeneral['aux'] = []; $rawDefenderGeneral['aux'] = [];
if (key_exists('inheritBuff', $rawDefenderGeneral)) { if(key_exists('inheritBuff', $rawDefenderGeneral)){
$v = new Validator($rawDefenderGeneral['inheritBuff']); $v = new Validator($rawDefenderGeneral['inheritBuff']);
$v->rules($inheritBuffCheck); $v->rules($inheritBuffCheck);
if (!$v->validate()) { if(!$v->validate()){
$idx += 1; $idx+=1;
Json::die([ Json::die([
'result' => false, 'result'=>false,
'reason' => "[수비자{$idx}]" . $v->errorStr() 'reason'=>"[수비자{$idx}]".$v->errorStr()
]); ]);
} }
$rawDefenderGeneral['aux']['inheritBuff'] = $rawDefenderGeneral['inheritBuff']; $rawDefenderGeneral['aux']['inheritBuff'] = $rawDefenderGeneral['inheritBuff'];
@@ -308,54 +199,135 @@ foreach ($rawDefenderList as $idx => $rawDefenderGeneral) {
$rawDefenderGeneral['aux'] = Json::encode($rawDefenderGeneral['aux']); $rawDefenderGeneral['aux'] = Json::encode($rawDefenderGeneral['aux']);
$rawDefenderGeneral['owner'] = 0; $rawDefenderGeneral['owner'] = 0;
$defenderGeneral = new General($rawDefenderGeneral, extractRankVar($rawDefenderGeneral), null, $rawDefenderCity, $rawAttackerNation, $year, $month, true); $defenderList[] = new General($rawDefenderGeneral, extractRankVar($rawDefenderGeneral), $rawDefenderCity, $rawAttackerNation, $year, $month, true);
$defenderList[] = new WarUnitGeneral(
$tmpRNG,
$defenderGeneral,
$rawDefenderNation,
false
);
} }
if ($action == 'reorder') {
$noRng = NoRNG::rngInstance();
usort($defenderList, function (WarUnit $lhs, WarUnit $rhs) use ($attacker) { $cityCheck = [
return - (extractBattleOrder($lhs, $attacker) <=> extractBattleOrder($rhs, $attacker)); 'required'=>[
}); 'city', 'nation', 'supply', 'name',
'pop', 'agri', 'comm', 'secu', 'def', 'wall',
$order = []; 'trust', 'level',
foreach ($defenderList as $defender) { 'pop_max', 'agri_max', 'comm_max', 'secu_max', 'def_max', 'wall_max',
$order[] = $defender->getGeneral()->getID(); 'dead', 'state', 'conflict',
} ],
'numeric'=>[
'pop', 'agri', 'comm', 'secu', 'def', 'wall', 'trust', 'dead'
],
'integer'=>[
'city', 'nation', 'supply',
'pop_max', 'agri_max', 'comm_max', 'secu_max', 'def_max', 'wall_max',
'state',
],
'min'=>[
['def', 0],
['wall', 0],
['trust', 0],
['pop', 0],
['comm', 0],
['secu', 0],
['city', 1],
['nation', 0]
],
'in'=>[
['level', array_keys(getCityLevelList())]
]
];
$v = new Validator($rawAttackerCity);
$v->rules($cityCheck);
if(!$v->validate()){
Json::die([ Json::die([
'result' => true, 'result'=>false,
'reason' => 'success', 'reason'=>'[출병도시]'.$v->errorStr()
'order' => $order
]); ]);
} }
$rawDefenderList = []; $v = new Validator($rawDefenderCity);
foreach($defenderList as $unit){ $v->rules($cityCheck);
if(extractBattleOrder($unit, $attacker) <= 0){ if(!$v->validate()){
continue; Json::die([
} 'result'=>false,
$rawDefenderList[] = $unit->getRaw(); 'reason'=>'[수비도시]'.$v->errorStr()
]);
} }
$nationCheck = [
'required'=>[
'type', 'tech', 'level', 'capital',
'nation', 'name', 'gold', 'rice', 'gennum'
],
'integer'=>[
'level', 'capital', 'nation', 'gennum',
],
'numeric'=>[
'tech', 'gold', 'rice'
],
'min'=>[
['tech', 0],
['gold', 0],
['rice', 0],
['gennum', 1],
],
'in'=>[
['type', GameConst::$availableNationType],
['level', array_keys(getNationLevelList())]
]
];
$v = new Validator($rawAttackerNation);
$v->rules($nationCheck);
if(!$v->validate()){
Json::die([
'result'=>false,
'reason'=>'[출병국]'.$v->errorStr()
]);
}
$v = new Validator($rawDefenderNation);
$v->rules($nationCheck);
if(!$v->validate()){
Json::die([
'result'=>false,
'reason'=>'[수비국]'.$v->errorStr()
]);
}
if($action == 'reorder'){
usort($defenderList, function(General $lhs, General $rhs){
return -(extractBattleOrder($lhs) <=> extractBattleOrder($rhs));
});
$order = [];
foreach($defenderList as $defenderGeneral){
$order[] = $defenderGeneral->getID();
}
Json::die([
'result'=>true,
'reason'=>'success',
'order'=>$order
]);
}
usort($defenderList, function(General $lhs, General $rhs){
return -(extractBattleOrder($lhs) <=> extractBattleOrder($rhs));
});
$rawDefenderList = array_map(function(General $general){
return $general->getRaw();
}, $defenderList);
unset($defenderList); unset($defenderList);
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
$startYear = $gameStor->startyear; $startYear = $gameStor->startyear;
function extractRankVar(array $rawVal): Map function extractRankVar(array $rawVal):Map{
{
$rankVars = new Map; $rankVars = new Map;
foreach ($rawVal as $rawKey => $rawVal) { foreach($rawVal as $rawKey=>$rawVal){
$key = RankColumn::tryFrom($rawKey); $key = RankColumn::tryFrom($rawKey);
if ($key === null) { if($key === null){
continue; continue;
} }
$rankVars[$key] = $rawVal; $rankVars[$key] = $rawVal;
@@ -364,104 +336,80 @@ function extractRankVar(array $rawVal): Map
} }
function simulateBattle( function simulateBattle(
$rawAttacker, $rawAttacker, $rawAttackerCity, $rawAttackerNation,
$rawAttackerCity, $rawDefenderList, $rawDefenderCity, $rawDefenderNation,
$rawAttackerNation, $startYear, $year, $month, $warSeed
$rawDefenderList, ){
$rawDefenderCity,
$rawDefenderNation,
$startYear,
$year,
$month,
$warSeed
) {
if (!$warSeed) { if(!$warSeed){
$warSeed = bin2hex(random_bytes(16)); $warSeed = bin2hex(random_bytes(16));
} }
$warRng = new RandUtil(new LiteHashDRBG($warSeed)); $warRng = new RandUtil(new LiteHashDRBG($warSeed));
$attackerGeneral = new General($rawAttacker, extractRankVar($rawAttacker), null, $rawAttackerCity, $rawAttackerNation, $year, $month);
$attacker = new WarUnitGeneral( $attacker = new WarUnitGeneral(
$warRng, $warRng,
$attackerGeneral, new General($rawAttacker, extractRankVar($rawAttacker), $rawAttackerCity, $rawAttackerNation, $year, $month),
$rawAttackerNation, $rawAttackerNation,
true true
); );
$city = new WarUnitCity($warRng, $rawDefenderCity, $rawDefenderNation, $year, $month, $startYear); $city = new WarUnitCity($warRng, $rawDefenderCity, $rawDefenderNation, $year, $month, $startYear);
/** @var WarUnit[] */ $iterDefender = new \ArrayIterator($rawDefenderList);
$defenderList = [];
foreach ($rawDefenderList as $rawDefenderGeneral) {
$defenderGeneral = new General($rawDefenderGeneral, extractRankVar($rawDefenderGeneral), null, $rawDefenderCity, $rawAttackerNation, $year, $month, true);
$defenderList[] = new WarUnitGeneral(
$warRng,
$defenderGeneral,
$rawDefenderNation,
false
);
}
if(count($defenderList) && extractBattleOrder($city, $attacker) > 0){
$defenderList[] = $city;
}
usort($defenderList, function (WarUnit $lhs, WarUnit $rhs) use ($attacker) {
return - (extractBattleOrder($lhs, $attacker) <=> extractBattleOrder($rhs, $attacker));
});
$iterDefender = new \ArrayIterator($defenderList);
$iterDefender->rewind(); $iterDefender->rewind();
$battleResult = []; $battleResult = [];
$attackerRice = $attacker->getGeneral()->getVar('rice'); $attackerRice = $rawAttacker['rice'];
$defenderRice = 0; $defenderRice = 0;
$getNextDefender = function (?WarUnit $prevDefender, bool $reqNext) $getNextDefender = function(?WarUnit $prevDefender, bool $reqNext)
use ($iterDefender, &$battleResult, &$defenderRice, $attacker): ?WarUnit { use ($warRng, $iterDefender, $rawDefenderCity, $rawDefenderNation, $year, $month, &$battleResult, &$defenderRice) {
if ($prevDefender !== null) { if($prevDefender !== null){
$prevDefender->getLogger()->rollback(); $prevDefender->getLogger()->rollback();
$battleResult[] = $prevDefender; $battleResult[] = $prevDefender;
if ($prevDefender instanceof WarUnitGeneral) { if($prevDefender instanceof WarUnitGeneral){
$defenderRice -= $prevDefender->getVar('rice'); $defenderRice -= $prevDefender->getVar('rice');
} }
} }
if (!$reqNext) { if(!$reqNext){
return null; return null;
} }
if (!$iterDefender->valid()) { if(!$iterDefender->valid()){
return null; return null;
} }
/** @var WarUnit */ $defenderObj = new General($iterDefender->current(), extractRankVar($iterDefender->current()), $rawDefenderCity, $rawDefenderNation, $year, $month);
$defender = $iterDefender->current(); if(extractBattleOrder($defenderObj) <= 0){
if (extractBattleOrder($defender, $attacker) <= 0) {
return null; return null;
} }
if($defender instanceof WarUnitGeneral){ $defenderRice += $defenderObj->getVar('rice');
$defenderRice += $defender->getVar('rice');
}
$retVal = new WarUnitGeneral(
$warRng,
$defenderObj,
$rawDefenderNation,
false
);
$iterDefender->next(); $iterDefender->next();
return $defender; return $retVal;
}; };
$conquerCity = processWar_NG($warSeed, $attacker, $getNextDefender, $city); $conquerCity = processWar_NG($warSeed, $attacker, $getNextDefender, $city, $year - $startYear);
$rawDefenderCity = $city->getRaw();
$updateAttackerNation = [];
$updateDefenderNation = [];
$attackerRice -= $attacker->getVar('rice'); $attackerRice -= $attacker->getVar('rice');
if ($city->getPhase() > 0) { if($city->getPhase() > 0){
$rice = $city->getKilled() / 100 * 0.8; $rice = $city->getKilled() / 100 * 0.8;
$rice *= $city->getCrewType()->rice; $rice *= $city->getCrewType()->rice;
$rice *= getTechCost($city->getRawNation()['tech']); $rice *= getTechCost($rawDefenderNation['tech']);
$rice *= $city->getCityTrainAtmos() / 100 - 0.2; $rice *= $city->getCityTrainAtmos() / 100 - 0.2;
Util::setRound($rice); Util::setRound($rice);
@@ -469,8 +417,8 @@ function simulateBattle(
} }
$totalDead = $attacker->getKilled() + $attacker->getDead(); $totalDead = $attacker->getKilled() + $attacker->getDead();
//$attackerCityDead = $totalDead * 0.4; $attackerCityDead = $totalDead * 0.4;
//$defenderCityDead = $totalDead * 0.6; $defenderCityDead = $totalDead * 0.6;
return [$attacker, $city, $battleResult, $conquerCity, $attackerRice, $defenderRice]; return [$attacker, $city, $battleResult, $conquerCity, $attackerRice, $defenderRice];
} }
@@ -496,26 +444,18 @@ $avgWar = 0;
$attackerActivatedSkills = []; $attackerActivatedSkills = [];
$defendersActivatedSkills = []; $defendersActivatedSkills = [];
if($warSeed){
$repeatCnt = 1;
}
foreach (Util::range($repeatCnt) as $repeatIdx) { foreach(Util::range($repeatCnt) as $repeatIdx){
if($repeatIdx > 0){
$warSeed = bin2hex(random_bytes(16));
}
/** @var WarUnit $attacker */ /** @var WarUnit $attacker */
[$attacker, $city, $battleResult, $conquerCity, $attackerRice, $defenderRice] = simulateBattle( [$attacker, $city, $battleResult, $conquerCity, $attackerRice, $defenderRice] = simulateBattle(
$rawAttacker, $rawAttacker, $rawAttackerCity, $rawAttackerNation,
$rawAttackerCity, $rawDefenderList, $rawDefenderCity, $rawDefenderNation,
$rawAttackerNation, $startYear, $year, $month, $warSeed
$rawDefenderList,
$rawDefenderCity,
$rawDefenderNation,
$startYear,
$year,
$month,
$warSeed
); );
$lastWarLog = Util::mapWithKey(function ($key, $values) { $lastWarLog = Util::mapWithKey(function($key, $values){
return ConvertLog(join('<br>', $values)); return ConvertLog(join('<br>', $values));
}, $attacker->getLogger()->rollback()); }, $attacker->getLogger()->rollback());
@@ -538,45 +478,48 @@ foreach (Util::range($repeatCnt) as $repeatIdx) {
$avgWar += count($battleResult) / $repeatCnt; $avgWar += count($battleResult) / $repeatCnt;
foreach ($attacker->getActivatedSkillLog() as $skillName => $skillCnt) { foreach($attacker->getActivatedSkillLog() as $skillName => $skillCnt){
if (!key_exists($skillName, $attackerActivatedSkills)) { if(!key_exists($skillName, $attackerActivatedSkills)){
$attackerActivatedSkills[$skillName] = $skillCnt / $repeatCnt; $attackerActivatedSkills[$skillName] = $skillCnt / $repeatCnt;
} else { }
else{
$attackerActivatedSkills[$skillName] += $skillCnt / $repeatCnt; $attackerActivatedSkills[$skillName] += $skillCnt / $repeatCnt;
} }
} }
foreach ($battleResult as $idx => $defender) { foreach($battleResult as $idx=>$defender){
while ($idx >= count($defendersActivatedSkills)) { while($idx >= count($defendersActivatedSkills)){
$defendersActivatedSkills[] = []; $defendersActivatedSkills[] = [];
} }
$activatedSkills = &$defendersActivatedSkills[$idx]; $activatedSkills = &$defendersActivatedSkills[$idx];
foreach ($defender->getActivatedSkillLog() as $skillName => $skillCnt) { foreach($defender->getActivatedSkillLog() as $skillName => $skillCnt){
if (!key_exists($skillName, $activatedSkills)) { if(!key_exists($skillName, $activatedSkills)){
$activatedSkills[$skillName] = $skillCnt / $repeatCnt; $activatedSkills[$skillName] = $skillCnt / $repeatCnt;
} else { }
else{
$activatedSkills[$skillName] += $skillCnt / $repeatCnt; $activatedSkills[$skillName] += $skillCnt / $repeatCnt;
} }
} }
} }
} }
Json::die([ Json::die([
'result' => true, 'result'=>true,
'datetime' => $rawAttacker['turntime'], 'datetime'=>$rawAttacker['turntime'],
'reason' => 'success', 'reason'=>'success',
'lastWarLog' => $lastWarLog, 'lastWarLog'=>$lastWarLog,
'avgWar' => $avgWar, 'avgWar'=>$avgWar,
'phase' => $avgPhase, 'phase'=>$avgPhase,
'killed' => $attackerKilled, 'killed'=>$attackerKilled,
'maxKilled' => $attackerMaxKilled, 'maxKilled'=>$attackerMaxKilled,
'minKilled' => $attackerMinKilled, 'minKilled'=>$attackerMinKilled,
'dead' => $attackerDead, 'dead'=>$attackerDead,
'maxDead' => $attackerMaxDead, 'maxDead'=>$attackerMaxDead,
'minDead' => $attackerMinDead, 'minDead'=>$attackerMinDead,
'attackerRice' => $attackerAvgRice, 'attackerRice'=>$attackerAvgRice,
'defenderRice' => $defenderAvgRice, 'defenderRice'=>$defenderAvgRice,
'attackerSkills' => $attackerActivatedSkills, 'attackerSkills'=>$attackerActivatedSkills,
'defendersSkills' => $defendersActivatedSkills, 'defendersSkills'=>$defendersActivatedSkills,
]); ]);
+28 -30
View File
@@ -3,7 +3,6 @@
namespace sammo; namespace sammo;
use sammo\DTO\VoteInfo; use sammo\DTO\VoteInfo;
use sammo\Enums\GeneralQueryMode;
include "lib.php"; include "lib.php";
include "func.php"; include "func.php";
@@ -30,8 +29,7 @@ if (!$session->isGameLoggedIn()) {
} }
$me = $db->queryFirstRow( $me = $db->queryFirstRow(
'SELECT no,refresh_score,turntime,newmsg,newvote,`officer_level` FROM `general` 'SELECT no,con,turntime,newmsg,newvote,`officer_level` from general where owner = %i',
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner = %i',
$userID $userID
); );
@@ -53,13 +51,13 @@ if ($me['newmsg'] == 1 || $me['newvote'] == 1) {
$plock = boolval($db->queryFirstField('SELECT plock FROM plock WHERE `type`="GAME" LIMIT 1')); $plock = boolval($db->queryFirstField('SELECT plock FROM plock WHERE `type`="GAME" LIMIT 1'));
$limitState = checkLimit($me['refresh_score']); $con = checkLimit($me['con']);
if ($limitState >= 2) { if ($con >= 2) {
printLimitMsg($me['turntime']); printLimitMsg($me['turntime']);
exit(); exit();
} }
$generalObj = General::createGeneralObjFromDB($me['no'], null, GeneralQueryMode::FullWithAccessLog); $generalObj = General::createGeneralObjFromDB($me['no']);
$generalObj->setRawCity($db->queryFirstRow('SELECT * FROM city WHERE city = %i', $generalObj->getCityID())); $generalObj->setRawCity($db->queryFirstRow('SELECT * FROM city WHERE city = %i', $generalObj->getCityID()));
$scenario = $gameStor->scenario_text; $scenario = $gameStor->scenario_text;
@@ -182,44 +180,44 @@ if ($lastVoteID) {
</div> </div>
<div class="row center gx-0"> <div class="row center gx-0">
<div class="s-border-t col py-2 col-8 col-lg-4" style="color:<?= $color ?>;"> <div class="s-border-t col py-2 col-8 col-md-4" style="color:<?= $color ?>;">
<?= $scenario ?> <?= $scenario ?>
</div> </div>
<div class="s-border-t col py-2 col-4 col-lg-2" style="color:<?= $color ?>;"> <div class="s-border-t col py-2 col-4 col-md-2" style="color:<?= $color ?>;">
NPC 수, 상성 : <?= $extend ?>,<?= $fiction ?> NPC 수, 상성 : <?= $extend ?>,<?= $fiction ?>
</div> </div>
<div class="s-border-t col py-2 col-4 col-lg-2" style="color:<?= $color ?>;"> <div class="s-border-t col py-2 col-4 col-md-2" style="color:<?= $color ?>;">
NPC선택 : <?= $npcmode ?> NPC선택 : <?= $npcmode ?>
</div> </div>
<div class="s-border-t col py-2 col-4 col-lg-2" style="color:<?= $color ?>;"> <div class="s-border-t col py-2 col-4 col-md-2" style="color:<?= $color ?>;">
토너먼트 : <?= getTournamentTermText($gameStor->turnterm) ?> 토너먼트 : <?= getTournamentTermText($gameStor->turnterm) ?>
</div> </div>
<div class="s-border-t col py-2 col-4 col-lg-2" style="color:<?= $color ?>;"> <div class="s-border-t col py-2 col-4 col-md-2" style="color:<?= $color ?>;">
기타 설정: <?= $otherTextInfo ?> 기타 설정: <?= $otherTextInfo ?>
</div> </div>
<div class="s-border-t col py-2 col-8 col-lg-4"><?= info(2) ?></div> <div class="s-border-t col py-2 col-8 col-md-4"><?= info(2) ?></div>
<div class="s-border-t col py-2 col-4 col-lg-2">전체 접속자 수 : <?= $gameStor->online_user_cnt ?> 명</div> <div class="s-border-t col py-2 col-4 col-md-2">전체 접속자 수 : <?= $gameStor->online_user_cnt ?> 명</div>
<div class="s-border-t col py-2 col-4 col-lg-2">턴당 갱신횟수 : <?= $gameStor->refreshLimit ?>회</div> <div class="s-border-t col py-2 col-4 col-md-2">턴당 갱신횟수 : <?= $gameStor->conlimit ?>회</div>
<div class="s-border-t col py-2 col-8 col-lg-4"><?= info(3) ?></div> <div class="s-border-t col py-2 col-8 col-md-4"><?= info(3) ?></div>
<div class="s-border-t py-2 col col-6 col-lg-4"> <div class="s-border-t py-2 col col-6 col-md-4">
<?php if ($isTournamentActive) : ?> <?php if ($isTournamentActive) : ?>
↑<span style='color:cyan'><?= (['전력전', '통솔전', '일기토', '설전',])[$gameStor->tnmt_type] ?? '' ?> <?= getTournament($gameStor->tournament) ?> <?= getTournamentTime() ?></span>↑ ↑<span style='color:cyan'><?= (['전력전', '통솔전', '일기토', '설전',])[$gameStor->tnmt_type] ?? '' ?> <?= getTournament($gameStor->tournament) ?> <?= getTournamentTime() ?></span>↑
<?php else : ?> <?php else : ?>
<span style='color:magenta'>현재 토너먼트 경기 없음</span> <span style='color:magenta'>현재 토너먼트 경기 없음</span>
<?php endif; ?> <?php endif; ?>
</div> </div>
<div class="s-border-t py-2 col col-6 col-lg-2"> <div class="s-border-t py-2 col col-6 col-md-2">
<div style="display:inline-block;"><?= $plock ? ("<span style='color:magenta;'>동작 시각: " . substr($gameStor->turntime, 5, 14) . "</span>") : ("<span style='color:cyan;'>동작 시각: " . substr($gameStor->turntime, 5, 14) . "</span>") ?></div> <div style="display:inline-block;"><?= $plock ? ("<span style='color:magenta;'>동작 시각: " . substr($gameStor->turntime, 5, 14) . "</span>") : ("<span style='color:cyan;'>동작 시각: " . substr($gameStor->turntime, 5, 14) . "</span>") ?></div>
</div> </div>
<div class="s-border-t py-2 col col-6 col-lg-2"> <div class="s-border-t py-2 col col-6 col-md-2">
<?php if ($auctionCount > 0) : ?> <?php if ($auctionCount > 0) : ?>
<span style='color:cyan'><?= $auctionCount ?>건</span> 거래 진행중 <span style='color:cyan'><?= $auctionCount ?>건</span> 거래 진행중
<?php else : ?> <?php else : ?>
<span style='color:magenta'>진행중 거래 없음</span> <span style='color:magenta'>진행중 거래 없음</span>
<?php endif; ?> <?php endif; ?>
</div> </div>
<div class="s-border-t py-2 col col-6 col-lg-4 vote-cell"> <div class="s-border-t py-2 col col-6 col-md-4 vote-cell">
<?php <?php
?> ?>
<?php if ($lastVote === null) : ?> <?php if ($lastVote === null) : ?>
@@ -312,11 +310,11 @@ if ($lastVoteID) {
</div> </div>
</div> </div>
<div class="row gx-0"> <div class="row gx-0">
<div class="col-lg-6" id="general_public_record-position"> <div class="col-md-6" id="general_public_record-position">
<div class="bg1 center s-border-tb"><b>장수 동향</b></div> <div class="bg1 center s-border-tb"><b>장수 동향</b></div>
<div id="general_public_record" style="text-align:left;"><?= formatHistoryToHTML(getGlobalActionLogRecent(15)) ?></div> <div id="general_public_record" style="text-align:left;"><?= formatHistoryToHTML(getGlobalActionLogRecent(15)) ?></div>
</div> </div>
<div class="col-lg-6" id="general_log-position"> <div class="col-md-6" id="general_log-position">
<div class="bg1 center s-border-tb"><b>개인 기록</b></div> <div class="bg1 center s-border-tb"><b>개인 기록</b></div>
<div id="general_log" style="text-align:left;"><?= formatHistoryToHTML(getGeneralActionLogRecent($me['no'], 15)) ?></div> <div id="general_log" style="text-align:left;"><?= formatHistoryToHTML(getGeneralActionLogRecent($me['no'], 15)) ?></div>
</div> </div>
@@ -330,34 +328,34 @@ if ($lastVoteID) {
<div id="message_board" class="row gx-0"> <div id="message_board" class="row gx-0">
<div class="message_input_form bg0 gx-0 row"> <div class="message_input_form bg0 gx-0 row">
<div id="mailbox_list-col" class="col-6 col-lg-2 d-grid"> <div id="mailbox_list-col" class="col-6 col-md-2 d-grid">
<select id="mailbox_list" size="1" class="form-control bg-dark text-white"> <select id="mailbox_list" size="1" class="form-control bg-dark text-white">
</select> </select>
</div> </div>
<div id="msg_input-col" class="col-12 col-lg-8 d-grid"> <div id="msg_input-col" class="col-12 col-md-8 d-grid">
<input type="text" id="msg_input" maxlength="99" class="form-control"> <input type="text" id="msg_input" maxlength="99" class="form-control">
</div> </div>
<div id="msg_submit-col" class="col-6 col-lg-2 d-grid"><button id="msg_submit" class="btn btn-primary">서신전달&amp;갱신</button></div> <div id="msg_submit-col" class="col-6 col-md-2 d-grid"><button id="msg_submit" class="btn btn-primary">서신전달&amp;갱신</button></div>
</div> </div>
<div class="col-lg-6 board_side bg0"><a id="public_talk_position"></a> <div class="col-md-6 board_side bg0"><a id="public_talk_position"></a>
<div class="board_header bg0">전체 메시지(최고99자)</div> <div class="board_header bg0">전체 메시지(최고99자)</div>
<section class="public_message"> <section class="public_message">
<div class="d-grid"><button type="button" class="load_old_message btn btn-secondary" data-msg_type="public">이전 메시지 불러오기</button></div> <div class="d-grid"><button type="button" class="load_old_message btn btn-secondary" data-msg_type="public">이전 메시지 불러오기</button></div>
</section> </section>
</div> </div>
<div class="col-lg-6 board_side bg0"><a id="national_talk_position"></a> <div class="col-md-6 board_side bg0"><a id="national_talk_position"></a>
<div class="board_header bg0">국가 메시지(최고99자)</div> <div class="board_header bg0">국가 메시지(최고99자)</div>
<section class="national_message"> <section class="national_message">
<div class="d-grid"><button type="button" class="load_old_message btn btn-secondary" data-msg_type="national">이전 메시지 불러오기</button></div> <div class="d-grid"><button type="button" class="load_old_message btn btn-secondary" data-msg_type="national">이전 메시지 불러오기</button></div>
</section> </section>
</div> </div>
<div class="col-lg-6 board_side bg0"><a id="private_talk_position"></a> <div class="col-md-6 board_side bg0"><a id="private_talk_position"></a>
<div class="board_header bg0">개인 메시지(최고99자)</div> <div class="board_header bg0">개인 메시지(최고99자)</div>
<section class="private_message"> <section class="private_message">
<div class="d-grid"><button type="button" class="load_old_message btn btn-secondary" data-msg_type="private">이전 메시지 불러오기</button></div> <div class="d-grid"><button type="button" class="load_old_message btn btn-secondary" data-msg_type="private">이전 메시지 불러오기</button></div>
</section> </section>
</div> </div>
<div class="col-lg-6 board_side bg0"><a id="diplomacy_talk_position"></a> <div class="col-md-6 board_side bg0"><a id="diplomacy_talk_position"></a>
<div class="board_header bg0">외교 메시지(최고99자)</div> <div class="board_header bg0">외교 메시지(최고99자)</div>
<section class="diplomacy_message"> <section class="diplomacy_message">
<div class="d-grid"><button type="button" class="load_old_message btn btn-secondary" data-msg_type="diplomacy">이전 메시지 불러오기</button></div> <div class="d-grid"><button type="button" class="load_old_message btn btn-secondary" data-msg_type="diplomacy">이전 메시지 불러오기</button></div>
@@ -369,7 +367,7 @@ if ($lastVoteID) {
</div> </div>
</div> </div>
<?php <?php
if ($limitState == 1) { if ($con == 1) {
MessageBox("접속제한이 얼마 남지 않았습니다!"); MessageBox("접속제한이 얼마 남지 않았습니다!");
} }
if ($me['newmsg'] == 1) { if ($me['newmsg'] == 1) {
@@ -381,7 +379,7 @@ if ($lastVoteID) {
} }
?> ?>
</div> </div>
<nav class="navbar navbar-expand fixed-bottom navbar-dark bg-dark d-sm-block d-lg-none p-0" id="navbar500"> <nav class="navbar navbar-expand fixed-bottom navbar-dark bg-dark d-sm-block d-md-none p-0" id="navbar500">
<div class="container-fluid px-0"> <div class="container-fluid px-0">
<div class="collapse navbar-collapse"> <div class="collapse navbar-collapse">
<ul class="navbar-nav me-auto mx-auto"> <ul class="navbar-nav me-auto mx-auto">
+34 -67
View File
@@ -3,7 +3,6 @@
namespace sammo; namespace sammo;
use sammo\Enums\EventTarget; use sammo\Enums\EventTarget;
use sammo\Enums\GeneralQueryMode;
function processWar(string $warSeed, General $attackerGeneral, array $rawAttackerNation, array $rawDefenderCity) function processWar(string $warSeed, General $attackerGeneral, array $rawAttackerNation, array $rawDefenderCity)
{ {
@@ -38,32 +37,16 @@ function processWar(string $warSeed, General $attackerGeneral, array $rawAttacke
$city = new WarUnitCity($rng, $rawDefenderCity, $rawDefenderNation, $year, $month, $startYear); $city = new WarUnitCity($rng, $rawDefenderCity, $rawDefenderNation, $year, $month, $startYear);
$defenderIDList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND city=%i AND nation!=0 and crew > 0 and rice>(crew/100) and train>=defence_train and atmos>=defence_train', $city->getVar('nation'), $city->getVar('city')); $defenderIDList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND city=%i AND nation!=0 and crew > 0 and rice>(crew/100) and train>=defence_train and atmos>=defence_train', $city->getVar('nation'), $city->getVar('city'));
$defenderGeneralList = General::createGeneralObjListFromDB($defenderIDList, null); $defenderList = General::createGeneralObjListFromDB($defenderIDList, null, 2);
/** @var WarUnit[] */ usort($defenderList, function (General $lhs, General $rhs) {
$defenderList = []; return - (extractBattleOrder($lhs) <=> extractBattleOrder($rhs));
foreach($defenderGeneralList as $defenderGeneral){
$defenderGeneral->setRawCity($rawDefenderCity);
$defenderCandidate = new WarUnitGeneral($rng, $defenderGeneral, $rawDefenderNation, false);
if(extractBattleOrder($defenderCandidate, $attacker) <= 0){
continue;
}
$defenderList[] = $defenderCandidate;
}
if(count($defenderList) && extractBattleOrder($city, $attacker) > 0){
$defenderList[] = $city;
}
usort($defenderList, function (WarUnit $lhs, WarUnit $rhs) use ($attacker) {
return - (extractBattleOrder($lhs, $attacker) <=> extractBattleOrder($rhs, $attacker));
}); });
$iterDefender = new \ArrayIterator($defenderList); $iterDefender = new \ArrayIterator($defenderList);
$iterDefender->rewind(); $iterDefender->rewind();
$getNextDefender = function (?WarUnit $prevDefender, bool $reqNext) use ($iterDefender, $db, $attacker) { $getNextDefender = function (?WarUnit $prevDefender, bool $reqNext) use ($rng, $iterDefender, $rawDefenderNation, $rawDefenderCity, $db) {
if ($prevDefender !== null) { if ($prevDefender !== null) {
$prevDefender->applyDB($db); $prevDefender->applyDB($db);
} }
@@ -76,16 +59,24 @@ function processWar(string $warSeed, General $attackerGeneral, array $rawAttacke
return null; return null;
} }
/** @var WarUnit */
$nextDefender = $iterDefender->current(); $nextDefender = $iterDefender->current();
if (extractBattleOrder($nextDefender, $attacker) <= 0) { $nextDefender->setRawCity($rawDefenderCity);
if (extractBattleOrder($nextDefender) <= 0) {
return null; return null;
} }
$retVal = new WarUnitGeneral(
$rng,
$nextDefender,
$rawDefenderNation,
false
);
$iterDefender->next(); $iterDefender->next();
return $nextDefender; return $retVal;
}; };
$conquerCity = processWar_NG($warSeed, $attacker, $getNextDefender, $city); $conquerCity = processWar_NG($warSeed, $attacker, $getNextDefender, $city, $year - $startYear);
$attacker->applyDB($db); $attacker->applyDB($db);
@@ -189,17 +180,8 @@ function processWar(string $warSeed, General $attackerGeneral, array $rawAttacke
], $attacker->getGeneral(), $city->getRaw()); ], $attacker->getGeneral(), $city->getRaw());
} }
function extractBattleOrder(WarUnit $defender, WarUnit $attacker) function extractBattleOrder(General $general)
{ {
if($defender instanceof WarUnitCity){
if(!($attacker instanceof WarUnitGeneral)){
return 0;
}
$attackerGeneral = $attacker->getGeneral();
return $attackerGeneral->onCalcOpposeStat($defender->getGeneral(), 'cityBattleOrder', -1);
}
$general = $defender->getGeneral();
if ($general->getVar('crew') == 0) { if ($general->getVar('crew') == 0) {
return 0; return 0;
} }
@@ -230,6 +212,7 @@ function processWar_NG(
WarUnitGeneral $attacker, WarUnitGeneral $attacker,
callable $getNextDefender, callable $getNextDefender,
WarUnitCity $city, WarUnitCity $city,
int $relYear
): bool { ): bool {
$templates = new \League\Plates\Engine(__DIR__ . '/templates'); $templates = new \League\Plates\Engine(__DIR__ . '/templates');
@@ -242,7 +225,6 @@ function processWar_NG(
$attackerNationUpdate = []; $attackerNationUpdate = [];
$defenderNationUpdate = []; $defenderNationUpdate = [];
/** @var WarUnit */
$defender = ($getNextDefender)(null, true); $defender = ($getNextDefender)(null, true);
$conquerCity = false; $conquerCity = false;
@@ -258,7 +240,6 @@ function processWar_NG(
$logWritten = false; $logWritten = false;
if ($defender === null) { if ($defender === null) {
$defender = $city; $defender = $city;
$defender->setSiege();
if ($city->getNationVar('rice') <= 0 && $city->getVar('supply')) { if ($city->getNationVar('rice') <= 0 && $city->getVar('supply')) {
//병량 패퇴 //병량 패퇴
@@ -425,28 +406,21 @@ function processWar_NG(
$attacker->logBattleResult(); $attacker->logBattleResult();
$defender->logBattleResult(); $defender->logBattleResult();
if (!($defender instanceof WarUnitCity) || $defender->isSiege()){ $attacker->addWin();
$attacker->addWin(); $defender->addLose();
$defender->addLose();
$attacker->tryWound(); $attacker->tryWound();
$defender->tryWound(); $defender->tryWound();
if ($defender === $city) { if ($defender === $city) {
$attacker->addLevelExp(1000); $attacker->addLevelExp(1000);
$conquerCity = true; $conquerCity = true;
break; break;
}
} }
$josaYi = JosaUtil::pick($defender->getCrewTypeName(), '이'); $josaYi = JosaUtil::pick($defender->getCrewTypeName(), '이');
if ($defender instanceof WarUnitCity && !$defender->isSiege()){ if ($noRice) {
//실제 공성을 위해 다시 초기화
$defender->setOppose(null);
}
else if ($noRice) {
$logger->pushGlobalActionLog("<Y>{$defender->getName()}</>의 {$defender->getCrewTypeName()}{$josaYi} 패퇴했습니다."); $logger->pushGlobalActionLog("<Y>{$defender->getName()}</>의 {$defender->getCrewTypeName()}{$josaYi} 패퇴했습니다.");
$attacker->getLogger()->pushGeneralActionLog("<Y>{$defender->getName()}</>의 {$defender->getCrewTypeName()}{$josaYi} 패퇴했습니다.", ActionLogger::PLAIN); $attacker->getLogger()->pushGeneralActionLog("<Y>{$defender->getName()}</>의 {$defender->getCrewTypeName()}{$josaYi} 패퇴했습니다.", ActionLogger::PLAIN);
$defender->getLogger()->pushGeneralActionLog("군량 부족으로 패퇴합니다.", ActionLogger::PLAIN); $defender->getLogger()->pushGeneralActionLog("군량 부족으로 패퇴합니다.", ActionLogger::PLAIN);
@@ -481,18 +455,12 @@ function processWar_NG(
$attacker->finishBattle(); $attacker->finishBattle();
$defender->finishBattle(); $defender->finishBattle();
if($city->getDead() || $defender instanceof WarUnitCity){ if ($defender instanceof WarUnitCity) {
if($city !== $defender){ $newConflict = $defender->addConflict();
$city->setOppose($attacker);
$city->setSiege();
$city->finishBattle();
}
$newConflict = $city->addConflict();
if ($newConflict) { if ($newConflict) {
$nationName = $attacker->getNationVar('name'); $nationName = $attacker->getNationVar('name');
$josaYi = JosaUtil::pick($nationName, '이'); $josaYi = JosaUtil::pick($nationName, '이');
$logger->pushGlobalHistoryLog("<M><b>【분쟁】</b></><D><b>{$nationName}</b></>{$josaYi} <G><b>{$city->getName()}</b></> 공략에 가담하여 분쟁이 발생하고 있습니다."); $logger->pushGlobalHistoryLog("<M><b>【분쟁】</b></><D><b>{$nationName}</b></>{$josaYi} <G><b>{$defender->getName()}</b></> 공략에 가담하여 분쟁이 발생하고 있습니다.");
} }
} }
@@ -596,10 +564,10 @@ function ConquerCity(array $admin, General $general, array $city)
$lord = new General($db->queryFirstRow( $lord = new General($db->queryFirstRow(
'SELECT %l FROM general WHERE nation = %i AND officer_level = %i LIMIT 1', 'SELECT %l FROM general WHERE nation = %i AND officer_level = %i LIMIT 1',
Util::formatListOfBackticks(General::mergeQueryColumn(['npc', 'gold', 'rice', 'experience', 'explevel', 'belong', 'dedication', 'dedlevel', 'aux'], GeneralQueryMode::Lite)[0]), Util::formatListOfBackticks(General::mergeQueryColumn(['npc', 'gold', 'rice', 'experience', 'explevel', 'belong', 'dedication', 'dedlevel', 'aux'], 1)[0]),
$defenderNationID, $defenderNationID,
12 12
), null, null, $city, $loseNation, $year, $month, false); ), null, $city, $loseNation, $year, $month, false);
$josaUl = JosaUtil::pick($defenderNationName, '을'); $josaUl = JosaUtil::pick($defenderNationName, '을');
$attackerLogger->pushNationalHistoryLog("<D><b>{$defenderNationName}</b></>{$josaUl} 정복"); $attackerLogger->pushNationalHistoryLog("<D><b>{$defenderNationName}</b></>{$josaUl} 정복");
@@ -696,12 +664,11 @@ function ConquerCity(array $admin, General $general, array $city)
$minCity = findNextCapital($cityID, $defenderNationID); $minCity = findNextCapital($cityID, $defenderNationID);
$minCityName = CityConst::byID($minCity)->name; $minCityName = CityConst::byID($minCity)->name;
$josaRo = JosaUtil::pick($minCityName, '로');
$josaYi = JosaUtil::pick($defenderNationName, '이'); $josaYi = JosaUtil::pick($defenderNationName, '이');
$attackerLogger->pushGlobalHistoryLog("<M><b>【긴급천도】</b></><D><b>{$defenderNationName}</b></>{$josaYi} 수도가 함락되어 <G><b>$minCityName</b></>{$josaRo} 긴급천도하였습니다."); $attackerLogger->pushGlobalHistoryLog("<M><b>【긴급천도】</b></><D><b>{$defenderNationName}</b></>{$josaYi} 수도가 함락되어 <G><b>$minCityName</b></>으로 긴급천도하였습니다.");
$moveLog = "수도가 함락되어 <G><b>$minCityName</b></>{$josaRo} <M>긴급천도</>합니다."; $moveLog = "수도가 함락되어 <G><b>$minCityName</b></>으로 <M>긴급천도</>합니다.";
//아국 수뇌부에게 로그 전달 //아국 수뇌부에게 로그 전달
foreach ($db->queryFirstColumn( foreach ($db->queryFirstColumn(
'SELECT no FROM general WHERE nation=%i AND officer_level>=5', 'SELECT no FROM general WHERE nation=%i AND officer_level>=5',
@@ -10,7 +10,6 @@ use sammo\DTO\AuctionBidItem;
use sammo\DTO\AuctionInfo; use sammo\DTO\AuctionInfo;
use sammo\Enums\APIRecoveryType; use sammo\Enums\APIRecoveryType;
use sammo\Enums\AuctionType; use sammo\Enums\AuctionType;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\InheritanceKey; use sammo\Enums\InheritanceKey;
use sammo\InheritancePointManager; use sammo\InheritancePointManager;
use sammo\TimeUtil; use sammo\TimeUtil;
@@ -77,7 +76,7 @@ class GetUniqueItemAuctionDetail extends \sammo\BaseAPI
$inheritMgr = InheritancePointManager::getInstance(); $inheritMgr = InheritancePointManager::getInstance();
//preveious라서 column을 최대한 비울 수 있다. //preveious라서 column을 최대한 비울 수 있다.
$remainPoint = $inheritMgr->getInheritancePoint( $remainPoint = $inheritMgr->getInheritancePoint(
General::createGeneralObjFromDB($generalID, ['owner'], GeneralQueryMode::Core), General::createGeneralObjFromDB($generalID, ['owner'], 0),
InheritanceKey::previous InheritanceKey::previous
); );
+3 -6
View File
@@ -42,12 +42,9 @@ class GetBettingList extends \sammo\BaseAPI
$bettingStor = KVStorage::getStorage($db, 'betting'); $bettingStor = KVStorage::getStorage($db, 'betting');
$userID = $session->userID; $userID = $session->userID;
$me = $db->queryFirstRow( $me = $db->queryFirstRow('SELECT no,nation,officer_level,con,turntime,belong,penalty,permission FROM general WHERE owner=%i', $userID);
'SELECT no,nation,officer_level,refresh_score,turntime,belong,penalty,permission FROM `general` $con = checkLimit($me['con']);
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID if ($con >= 2) {
);
$limitState = checkLimit($me['refresh_score']);
if ($limitState >= 2) {
return "접속 제한중입니다."; return "접속 제한중입니다.";
} }
+332
View File
@@ -0,0 +1,332 @@
<?php
namespace sammo\API\City;
use ArrayObject;
use Ds\Set;
use sammo\CityConst;
use sammo\DB;
use sammo\Enums\APIRecoveryType;
use sammo\General;
use sammo\Json;
use sammo\Session;
use sammo\Util;
use sammo\Validator;
use function sammo\calcLeadershipBonus;
use function sammo\checkLimit;
use function sammo\checkSecretPermission;
use function sammo\getAllNationStaticInfo;
use function sammo\getBillByLevel;
use function sammo\getDedLevelText;
use function sammo\getHonor;
use function sammo\getNationStaticInfo;
use function sammo\getOfficerLevelText;
use function sammo\increaseRefresh;
class GetCityInfo extends \sammo\BaseAPI
{
const FAR_CITY = 0;
const NEAR_CITY = 1;
const ON_CITY = 2;
const OUR_NATION = 3;
static $viewColumns = [
'no' => self::NEAR_CITY,
'name' => self::NEAR_CITY,
'nation' => self::NEAR_CITY,
'npc' => self::NEAR_CITY,
'injury' => self::NEAR_CITY,
'leadership' => self::NEAR_CITY,
'strength' => self::NEAR_CITY,
'intel' => self::NEAR_CITY,
'picture' => self::NEAR_CITY,
'imgsvr' => self::NEAR_CITY,
'city' => self::NEAR_CITY,
'officer_level' => self::NEAR_CITY,
'officer_city' => self::NEAR_CITY,
'defence_train' => self::OUR_NATION,
'crewtype' => self::OUR_NATION,
'crew' => self::ON_CITY,
'train' => self::OUR_NATION,
'atmos' => self::OUR_NATION,
];
static $columnRemap = [
'nation' => 'nationID',
];
static $customViewColumns = [
'officerLevel' => self::NEAR_CITY,
'officerLevelText' => self::NEAR_CITY,
'lbonus' => self::NEAR_CITY,
'reservedCommand' => self::OUR_NATION,
'isOurNation' => self::NEAR_CITY,
];
public function validateArgs(): ?string
{
$v = new Validator($this->args);
$v->rule('int', 'troopID');
if (!$v->validate()) {
return $v->errorStr();
}
return null;
}
public function getRequiredSessionMode(): int
{
return static::REQ_GAME_LOGIN | static::REQ_READ_ONLY;
}
private function getOfficerLevel($rawGeneral)
{
$level = $rawGeneral['officer_level'];
return $level;
}
private function filterCity(array $rawCity, int $showLevel)
{
$cityID = $rawCity['city'];
$db = DB::db();
$officerList = $db->query(
'SELECT no, npc, name, nation, picture, imgsvr FROM general WHERE city = %i AND 2 <= officer_level AND officer_level <= 4',
$cityID
);
$filteredCity = [
'city' => $cityID,
'name' => $rawCity['name'],
'level' => $rawCity['level'],
'nation' => $rawCity['nation'],
'supply' => $rawCity['supply'],
'pop_max' => $rawCity['pop_max'],
'agri_max' => $rawCity['agri_max'],
'comm_max' => $rawCity['comm_max'],
'secu_max' => $rawCity['secu_max'],
'trade' => $rawCity['trade'],
'def_max' => $rawCity['def_max'],
'wall_max' => $rawCity['wall_max'],
'region' => $rawCity['region'],
'officerList' => $officerList,
];
if ($showLevel >= self::ON_CITY) {
$filteredCity = array_merge($filteredCity, [
'pop' => $rawCity['pop'],
'agri' => $rawCity['agri'],
'comm' => $rawCity['comm'],
'secu' => $rawCity['secu'],
'def' => $rawCity['def'],
'wall' => $rawCity['wall'],
'officer_set' => $rawCity['officer_set'],
]);
}
return $filteredCity;
}
private function getGeneralList(int $cityID, int $nationID, int $showLevel)
{
if ($showLevel == self::FAR_CITY) {
return [
'column' => [],
'list' => []
];
}
$db = DB::db();
$nationStaticList = getAllNationStaticInfo();
$rawGeneralList = Util::convertArrayToDict($db->query('SELECT %l from general WHERE city = %i ORDER BY turntime ASC', Util::formatListOfBackticks(array_keys(static::$viewColumns)), $cityID), 'no');
$ourNationGeneralIDList = new Set();
foreach ($rawGeneralList as $rawGeneral) {
if ($rawGeneral['nation'] == $nationID) {
$ourNationGeneralIDList->add($rawGeneral['no']);
}
}
$reservedCommand = [];
$reservedCommandTargetGeneralIDList = [];
foreach ($rawGeneralList as $rawGeneral) {
if ($rawGeneral['nation'] != $nationID) {
continue;
}
if ($rawGeneral['npc'] < 2) {
$reservedCommandTargetGeneralIDList[$rawGeneral['no']] = $rawGeneral['no'];
}
}
if ($reservedCommandTargetGeneralIDList) {
$rawTurnList = $db->query(
'SELECT general_id, turn_idx, action, arg, brief FROM general_turn WHERE general_id IN %li AND turn_idx < 5 ORDER BY general_id asc, turn_idx asc',
array_values($reservedCommandTargetGeneralIDList)
);
foreach ($rawTurnList as $rawTurn) {
[
'general_id' => $generalID,
'action' => $action,
'arg' => $arg,
'brief' => $brief,
] = $rawTurn;
if (!key_exists($generalID, $reservedCommand)) {
$reservedCommand[$generalID] = [];
}
$reservedCommand[$generalID][] = [
'action' => $action,
'arg' => $arg,
'brief' => $brief
];
}
}
$specialViewFilter = [
'officerLevel' => fn ($rawGeneral) => $this->getOfficerLevel($rawGeneral),
'officerLevelText' => fn ($rawGeneral) => getOfficerLevelText($this->getOfficerLevel($rawGeneral), $nationStaticList[$rawGeneral['nation']]['level']),
'lbonus' => fn ($rawGeneral) => calcLeadershipBonus($rawGeneral['officer_level'], $nationStaticList[$rawGeneral['nation']]['level']),
'reservedCommand' => fn ($rawGeneral) => $reservedCommand[$rawGeneral['no']] ?? null,
'isOurNation' => fn ($rawGeneral) => $rawGeneral['nation'] == $nationID,
];
$showFullColumn = $showLevel == self::OUR_NATION || $ourNationGeneralIDList->count() > 0;
$resultColumns = [];
foreach (static::$viewColumns as $column => $reqShowLevel) {
if (!$showFullColumn && $reqShowLevel > $showLevel) {
continue;
}
if (key_exists($column, static::$columnRemap)) {
$newColumn = static::$columnRemap[$column];
if ($newColumn !== null) {
$resultColumns[$newColumn] = $column;
}
} else {
$resultColumns[$column] = $column;
}
}
foreach (static::$customViewColumns as $column => $reqShowLevel) {
if (!$showFullColumn && $reqShowLevel > $showLevel) {
continue;
}
$resultColumns[$column] = $column;
}
$generalList = [];
foreach ($rawGeneralList as $rawGeneral) {
$item = [];
foreach ($resultColumns as $column) {
$reqShowLevel = static::$viewColumns[$column];
if ($rawGeneral['nation'] != $nationID && $reqShowLevel == self::OUR_NATION) {
$item[] = null;
continue;
}
if (key_exists($column, $specialViewFilter)) {
$value = $specialViewFilter[$column]($rawGeneral);
} else {
$value = $rawGeneral[$column];
}
$item[] = $value;
}
$generalList[] = $item;
}
return [
'column' => array_keys($resultColumns),
'list' => $generalList,
];
}
private function calcShowLevel(int $cityID, int $currentCityID, int $nationID, Set $cityList, bool $isSpyPresent): int
{
$db = DB::db();
if ($cityList->contains($currentCityID)) {
return self::OUR_NATION;
}
if ($cityID == $currentCityID) {
return self::ON_CITY;
}
if ($isSpyPresent) {
return self::ON_CITY;
}
$existsGeneralID = $db->queryFirstField(
'SELECT no FROM general WHERE city = %i AND nation = %i LIMIT 1',
$cityID,
$nationID
);
if ($existsGeneralID) {
return self::ON_CITY;
}
$cityConstObj = CityConst::byID($cityID);
$nearCityIDList = array_keys($cityConstObj->path);
foreach ($nearCityIDList as $nearCityID) {
if ($cityList->contains($nearCityID)) {
return self::NEAR_CITY;
}
}
return self::FAR_CITY;
}
public function launch(Session $session, ?\DateTimeInterface $modifiedSince, ?string $reqEtag): null | string | array | APIRecoveryType
{
increaseRefresh("도시정보", 1);
$db = DB::db();
$gameStor = \sammo\KVStorage::getStorage($db, 'game_env');
$lastExecuted = $gameStor->getValue('turntime');
$me = $db->queryFirstRow('SELECT con, turntime, belong, city, nation, officer_level, permission, penalty FROM general WHERE owner=%i', $session->getUserID());
if (key_exists('cityID', $this->args)) {
$cityID = (int)$this->args['cityID'];
} else {
$cityID = $me['city'];
}
$con = checkLimit($me['con']);
if ($con >= 2) {
return '접속 제한중입니다. 1턴 이내에 너무 많은 갱신을 하셨습니다.';
}
$nationID = $me['nation'];
$currentCityID = $me['city'];
//TODO: 조건 조사
$cityList = new Set($db->queryFirstColumn('SELECT city FROM city WHERE nation=%i', $nationID));
$spyList = JSON::decode($db->queryFirstField('SELECT spy FROM nation WHERE nation=%i', $nationID));
$showLevel = $this->calcShowLevel($cityID, $currentCityID, $nationID, $cityList, key_exists($cityID, $spyList));
$rawCity = $db->queryFirstRow('SELECT * FROM city WHERE city=%i', $cityID);
$filteredCity = $this->filterCity($rawCity, $showLevel);
$result = [
'result' => true,
'lastExcuted' => $lastExecuted,
'cityInfo' => $filteredCity,
'spyList' => $spyList,
'nationCityList' => $cityList->toArray(),
'myGeneralID' => $session->generalID,
'currentCityID' => $currentCityID,
'showLevel' => $showLevel,
'cityGeneralList' => $this->getGeneralList($cityID, $nationID, $showLevel)
];
return $result;
}
}
@@ -39,7 +39,7 @@ class BuildNationCandidate extends \sammo\BaseAPI
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
$gameStor->cacheValues(['opentime', 'turntime']); $gameStor->cacheValues(['opentime', 'turntime']);
$general = $db->queryFirstRow('SELECT no,name,nation,owner_name,npc FROM general WHERE owner=%i', $userID); $general = $db->queryFirstRow('SELECT no,name,nation,owner_name,npc,lastrefresh FROM general WHERE owner=%i', $userID);
if (!$general) { if (!$general) {
return '장수가 없습니다'; return '장수가 없습니다';
+2 -9
View File
@@ -5,7 +5,6 @@ namespace sammo\API\General;
use sammo\DB; use sammo\DB;
use sammo\DummyGeneral; use sammo\DummyGeneral;
use sammo\Enums\APIRecoveryType; use sammo\Enums\APIRecoveryType;
use sammo\Enums\GeneralAccessLogColumn;
use sammo\GameConst; use sammo\GameConst;
use sammo\Session; use sammo\Session;
use sammo\General; use sammo\General;
@@ -38,13 +37,7 @@ class DieOnPrestart extends \sammo\BaseAPI
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
$gameStor->cacheValues(['turnterm', 'opentime', 'turntime', 'year', 'month']); $gameStor->cacheValues(['turnterm', 'opentime', 'turntime', 'year', 'month']);
$general = $db->queryFirstRow('SELECT no,name,nation,owner_name,npc FROM general WHERE owner=%i AND npc = 0', $userID); $general = $db->queryFirstRow('SELECT no,name,nation,owner_name,npc,lastrefresh FROM general WHERE owner=%i AND npc = 0', $userID);
$lastRefresh = $db->queryFirstField(
'SELECT %b FROM general_access_log WHERE %b = %i',
GeneralAccessLogColumn::lastRefresh->value,
GeneralAccessLogColumn::generalID->value,
$general['no']
);
if (!$general) { if (!$general) {
return '장수가 없습니다'; return '장수가 없습니다';
@@ -62,7 +55,7 @@ class DieOnPrestart extends \sammo\BaseAPI
} }
//서버 가오픈시 할 수 있는 행동 //서버 가오픈시 할 수 있는 행동
$targetTime = addTurn($lastRefresh, $gameStor->turnterm, GameConst::$minTurnDieOnPrestart); $targetTime = addTurn($general['lastrefresh'], $gameStor->turnterm, GameConst::$minTurnDieOnPrestart);
if ($targetTime > TimeUtil::now()) { if ($targetTime > TimeUtil::now()) {
$targetTimeShort = substr($targetTime, 0, 19); $targetTimeShort = substr($targetTime, 0, 19);
return "아직 삭제할 수 없습니다. {$targetTimeShort} 부터 가능합니다."; return "아직 삭제할 수 없습니다. {$targetTimeShort} 부터 가능합니다.";
+6 -9
View File
@@ -9,9 +9,7 @@ use sammo\DB;
use sammo\DTO\VoteInfo; use sammo\DTO\VoteInfo;
use sammo\Enums\APIRecoveryType; use sammo\Enums\APIRecoveryType;
use sammo\Enums\CityColumn; use sammo\Enums\CityColumn;
use sammo\Enums\GeneralAccessLogColumn;
use sammo\Enums\GeneralColumn; use sammo\Enums\GeneralColumn;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\RankColumn; use sammo\Enums\RankColumn;
use sammo\GameConst; use sammo\GameConst;
use sammo\General; use sammo\General;
@@ -175,7 +173,7 @@ class GetFrontInfo extends \sammo\BaseAPI
'online_nation', 'online_user_cnt', 'online_nation', 'online_user_cnt',
'year', 'month', 'startyear', 'year', 'month', 'startyear',
'maxgeneral', 'maxgeneral',
'refreshLimit', 'conlimit',
'server_cnt', 'server_cnt',
]); ]);
@@ -385,8 +383,7 @@ class GetFrontInfo extends \sammo\BaseAPI
'specialWar' => $general->getVar(GeneralColumn::special2), // GameObjClassKey; 'specialWar' => $general->getVar(GeneralColumn::special2), // GameObjClassKey;
'personal' => $general->getVar(GeneralColumn::personal), // GameObjClassKey; 'personal' => $general->getVar(GeneralColumn::personal), // GameObjClassKey;
'belong' => $general->getVar(GeneralColumn::belong), // number; 'belong' => $general->getVar(GeneralColumn::belong), // number;
'connect' => $general->getVar(GeneralColumn::connect), // number;
'refreshScoreTotal' => $general->getAccessLogVar(GeneralAccessLogColumn::refreshScoreTotal, 0), // number;
'officerLevel' => $general->getVar(GeneralColumn::officer_level), // number; 'officerLevel' => $general->getVar(GeneralColumn::officer_level), // number;
'officerLevelText' => getOfficerLevelText($general->getVar(GeneralColumn::officer_level), $rawNation['level']), // string; 'officerLevelText' => getOfficerLevelText($general->getVar(GeneralColumn::officer_level), $rawNation['level']), // string;
@@ -403,7 +400,7 @@ class GetFrontInfo extends \sammo\BaseAPI
'troop' => $general->getVar(GeneralColumn::troop), // number; 'troop' => $general->getVar(GeneralColumn::troop), // number;
//P0 End //P0 End
'refreshScore' => $general->getAccessLogVar(GeneralAccessLogColumn::refreshScore, 0), // number; 'con' => $general->getVar(GeneralColumn::con), // number;
'specage' => $general->getVar(GeneralColumn::specage), // number; 'specage' => $general->getVar(GeneralColumn::specage), // number;
'specage2' => $general->getVar(GeneralColumn::specage2), // number; 'specage2' => $general->getVar(GeneralColumn::specage2), // number;
'leadership_exp' => $general->getVar(GeneralColumn::leadership_exp), // number; 'leadership_exp' => $general->getVar(GeneralColumn::leadership_exp), // number;
@@ -534,12 +531,12 @@ class GetFrontInfo extends \sammo\BaseAPI
{ {
$generalID = $session->generalID; $generalID = $session->generalID;
//NOTE: 이 경우 staticNation 정보를 조회한다. //NOTE: 이 경우 staticNation 정보를 조회한다.
$general = General::createGeneralObjFromDB($generalID, null, GeneralQueryMode::FullWithAccessLog); $general = General::createGeneralObjFromDB($generalID);
$nationID = $general->getNationID(); $nationID = $general->getNationID();
$cityID = $general->getCityID(); $cityID = $general->getCityID();
$limitState = checkLimit($general->getAccessLogVar(GeneralAccessLogColumn::refreshScore, 0)); $con = checkLimit($general->getVar('con'));
if ($limitState >= 2) { if ($con >= 2) {
return [ return [
'result' => false, 'result' => false,
'reason' => '접속 제한중입니다.', 'reason' => '접속 제한중입니다.',
+2 -6
View File
@@ -8,7 +8,6 @@ use sammo\Auction;
use sammo\CityConst; use sammo\CityConst;
use sammo\DB; use sammo\DB;
use sammo\Enums\APIRecoveryType; use sammo\Enums\APIRecoveryType;
use sammo\Enums\GeneralAccessLogColumn;
use sammo\Enums\RankColumn; use sammo\Enums\RankColumn;
use sammo\GameConst; use sammo\GameConst;
use sammo\GameUnitConst; use sammo\GameUnitConst;
@@ -415,6 +414,8 @@ class Join extends \sammo\BaseAPI
'officer_level' => 0, 'officer_level' => 0,
'turntime' => $turntime, 'turntime' => $turntime,
'killturn' => 6, 'killturn' => 6,
'lastconnect' => $now,
'lastrefresh' => $now,
'crewtype' => GameUnitConst::DEFAULT_CREWTYPE, 'crewtype' => GameUnitConst::DEFAULT_CREWTYPE,
'makelimit' => 0, 'makelimit' => 0,
'betray' => $betray, 'betray' => $betray,
@@ -427,11 +428,6 @@ class Join extends \sammo\BaseAPI
'special2' => $special2 'special2' => $special2
]); ]);
$generalID = $db->insertId(); $generalID = $db->insertId();
$db->insert('general_access_log', [
GeneralAccessLogColumn::generalID->value => $generalID,
GeneralAccessLogColumn::userID->value => $userID,
GeneralAccessLogColumn::lastRefresh->value => $now,
]);
if($blockCustomGeneralName){ if($blockCustomGeneralName){
//XXX: 클래스가 이게 맞나? //XXX: 클래스가 이게 맞나?
+6 -12
View File
@@ -42,12 +42,9 @@ class GeneralList extends \sammo\BaseAPI
$userID = $session->userID; $userID = $session->userID;
if ($session->isGameLoggedIn()) { if ($session->isGameLoggedIn()) {
increaseRefresh("장수일람", 2); increaseRefresh("장수일람", 2);
$me = $db->queryFirstRow( $me = $db->queryFirstRow('SELECT con, turntime FROM general WHERE owner=%i', $userID);
'SELECT refresh_score, turntime FROM `general` $con = checkLimit($me['con']);
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID if ($con >= 2) {
);
$limitState = checkLimit($me['refresh_score']);
if ($limitState >= 2) {
return '접속 제한중입니다. 1턴 이내에 너무 많은 갱신을 하셨습니다.'; return '접속 제한중입니다. 1턴 이내에 너무 많은 갱신을 하셨습니다.';
} }
} else { } else {
@@ -65,8 +62,7 @@ class GeneralList extends \sammo\BaseAPI
$session->setReadOnly(); $session->setReadOnly();
$rawGeneralList = $db->queryAllLists( $rawGeneralList = $db->queryAllLists('SELECT owner,no,picture,imgsvr,npc,age,nation,special,special2,personal,name,owner_name as ownerName,injury,leadership,strength,intel,experience,dedication,officer_level,killturn,connect from general');
'SELECT owner,no,picture,imgsvr,npc,age,nation,special,special2,personal,name,owner_name as ownerName,injury,leadership,strength,intel,experience,dedication,officer_level,killturn,refresh_score_total from `general` LEFT JOIN `general_access_log` ON general.no = general_access_log.general_id');
$ownerNameList = []; $ownerNameList = [];
if ($gameStor->isunited) { if ($gameStor->isunited) {
@@ -77,7 +73,7 @@ class GeneralList extends \sammo\BaseAPI
$generalList = []; $generalList = [];
foreach ($rawGeneralList as $rawGeneral) { foreach ($rawGeneralList as $rawGeneral) {
[$owner, $no, $picture, $imgsvr, $npc, $age, $nation, $special, $special2, $personal, $name, $ownerName, $injury, $leadership, $strength, $intel, $experience, $dedication, $officerLevel, $killturn, $refreshScoreTotal] = $rawGeneral; [$owner, $no, $picture, $imgsvr, $npc, $age, $nation, $special, $special2, $personal, $name, $ownerName, $injury, $leadership, $strength, $intel, $experience, $dedication, $officerLevel, $killturn, $connectCnt] = $rawGeneral;
if (key_exists($owner, $ownerNameList)) { if (key_exists($owner, $ownerNameList)) {
$ownerName = $ownerNameList[$owner]; $ownerName = $ownerNameList[$owner];
@@ -108,7 +104,7 @@ class GeneralList extends \sammo\BaseAPI
getDed($dedication), getDed($dedication),
getOfficerLevelText($officerLevel, $nationArr['level']), getOfficerLevelText($officerLevel, $nationArr['level']),
$killturn, $killturn,
$refreshScoreTotal ?: 0, $connectCnt
]; ];
} }
@@ -133,8 +129,6 @@ class GeneralList extends \sammo\BaseAPI
'honorText', 'honorText',
'dedLevelText', 'dedLevelText',
'officerLevelText', 'officerLevelText',
'killturn',
'refreshScoreTotal',
]; ];
$result = [ $result = [
+3 -6
View File
@@ -148,16 +148,13 @@ class GetHistory extends \sammo\BaseAPI
} }
increaseRefresh("연감", 1); increaseRefresh("연감", 1);
$me = $db->queryFirstRow( $me = $db->queryFirstRow('SELECT con, turntime FROM general WHERE owner = %i', $session->userID);
'SELECT refresh_score, turntime FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner = %i', $session->userID
);
if (!$me) { if (!$me) {
return '장수가 사망했습니다.'; return '장수가 사망했습니다.';
} }
$limitState = checkLimit($me['refresh_score']); $con = checkLimit($me['con']);
if ($limitState >= 2) { if ($con >= 2) {
return templateLimitMsg($me['turntime']); return templateLimitMsg($me['turntime']);
} }
} }
+1 -1
View File
@@ -75,7 +75,7 @@ class GetOldMessage extends \sammo\BaseAPI
$db = DB::db(); $db = DB::db();
$me = $db->queryFirstRow('SELECT `no`,`name`,`nation`,`officer_level`,`picture`,`imgsvr`,penalty,permission FROM general WHERE `owner`=%i', $userID); $me = $db->queryFirstRow('SELECT `no`,`name`,`nation`,`officer_level`,`con`,`picture`,`imgsvr`,penalty,permission FROM general WHERE `owner`=%i', $userID);
if ($me === null) { if ($me === null) {
return '장수가 사망했습니다.'; return '장수가 사망했습니다.';
+1 -1
View File
@@ -73,7 +73,7 @@ class GetRecentMessage extends \sammo\BaseAPI
$db = DB::db(); $db = DB::db();
$me = $db->queryFirstRow('SELECT `no`,`name`,`nation`,`officer_level`,`picture`,`imgsvr`,penalty,permission FROM general WHERE `owner`=%i', $userID); $me = $db->queryFirstRow('SELECT `no`,`name`,`nation`,`officer_level`,`con`,`picture`,`imgsvr`,penalty,permission FROM general WHERE `owner`=%i', $userID);
if ($me === null) { if ($me === null) {
return '장수가 사망했습니다.'; return '장수가 사망했습니다.';
+4 -7
View File
@@ -108,7 +108,7 @@ class SendMessage extends \sammo\BaseAPI
$unlimited = new \DateTime('9999-12-31'); $unlimited = new \DateTime('9999-12-31');
$db = DB::db(); $db = DB::db();
$destUser = $db->queryFirstRow('SELECT `no`,`name`,`nation`,`officer_level`,`picture`,`imgsvr`,permission,penalty FROM general WHERE `no`=%i', $destGeneralID); $destUser = $db->queryFirstRow('SELECT `no`,`name`,`nation`,`officer_level`,`con`,`picture`,`imgsvr`,permission,penalty FROM general WHERE `no`=%i', $destGeneralID);
if (!$destUser) { if (!$destUser) {
return '존재하지 않는 유저입니다.'; return '존재하지 않는 유저입니다.';
@@ -160,18 +160,15 @@ class SendMessage extends \sammo\BaseAPI
} }
$db = DB::db(); $db = DB::db();
$me = $db->queryFirstRow( $me = $db->queryFirstRow('SELECT `no`,`name`,`nation`,`officer_level`,`con`,`picture`,`imgsvr`,penalty,permission,belong FROM general WHERE `owner`=%i', $userID);
'SELECT `no`,`name`,`nation`,`officer_level`,`refresh_score`,`picture`,`imgsvr`,penalty,permission,belong FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE `owner`=%i', $userID
);
if (!$me) { if (!$me) {
$session->logoutGame(); $session->logoutGame();
return '장수가 없습니다.'; return '장수가 없습니다.';
} }
$limitState = checkLimit($me['refresh_score']); $con = checkLimit($me['con']);
if ($limitState >= 2) { if ($con >= 2) {
return '접속 제한입니다.'; return '접속 제한입니다.';
} }
+13 -31
View File
@@ -5,7 +5,6 @@ namespace sammo\API\Nation;
use ArrayObject; use ArrayObject;
use sammo\DB; use sammo\DB;
use sammo\Enums\APIRecoveryType; use sammo\Enums\APIRecoveryType;
use sammo\Enums\GeneralQueryMode;
use sammo\General; use sammo\General;
use sammo\Session; use sammo\Session;
use sammo\Util; use sammo\Util;
@@ -45,10 +44,12 @@ class GeneralList extends \sammo\BaseAPI
'special2' => 0, 'special2' => 0,
'personal' => 0, 'personal' => 0,
'belong' => 0, 'belong' => 0,
'connect' => 0,
'troop' => 0, 'troop' => 0,
'city' => 0, 'city' => 0,
'con' => 1,
'specage' => 0, 'specage' => 0,
'specage2' => 0, 'specage2' => 0,
'leadership_exp' => 1, 'leadership_exp' => 1,
@@ -82,11 +83,6 @@ class GeneralList extends \sammo\BaseAPI
'owner_name' => 9, //안씀. 'owner_name' => 9, //안씀.
//accessLog
'refresh_score_total' => 0,
'refresh_score' => 1,
//RANK //RANK
'warnum' => 1, 'warnum' => 1,
'killnum' => 1, 'killnum' => 1,
@@ -99,8 +95,6 @@ class GeneralList extends \sammo\BaseAPI
static $columnRemap = [ static $columnRemap = [
'special' => 'specialDomestic', 'special' => 'specialDomestic',
'special2' => 'specialWar', 'special2' => 'specialWar',
'refresh_score_total' => 'refreshScoreTotal',
'refresh_score' => 'refreshScore',
'aux' => null, 'aux' => null,
]; ];
@@ -149,12 +143,9 @@ class GeneralList extends \sammo\BaseAPI
$gameStor = \sammo\KVStorage::getStorage($db, 'game_env'); $gameStor = \sammo\KVStorage::getStorage($db, 'game_env');
$env = $gameStor->getValues(['year', 'month', 'turntime', 'turnterm', 'autorun_user', 'killturn']); $env = $gameStor->getValues(['year', 'month', 'turntime', 'turnterm', 'autorun_user', 'killturn']);
$me = $db->queryFirstRow( $me = $db->queryFirstRow('SELECT con, turntime, belong, nation, officer_level, permission, penalty FROM general WHERE owner=%i', $session->getUserID());
'SELECT refresh_score, turntime, belong, nation, officer_level, permission, penalty FROM `general` $con = checkLimit($me['con']);
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $session->getUserID() if ($con >= 2) {
);
$limitState = checkLimit($me['refresh_score']);
if ($limitState >= 2) {
return '접속 제한중입니다. 1턴 이내에 너무 많은 갱신을 하셨습니다.'; return '접속 제한중입니다. 1턴 이내에 너무 많은 갱신을 하셨습니다.';
} }
@@ -165,18 +156,9 @@ class GeneralList extends \sammo\BaseAPI
[$queryColumns, $rankColumns, $accessLogColumns] = General::mergeQueryColumn(array_keys(static::$viewColumns), GeneralQueryMode::Lite); [$queryColumns, $rankColumns] = General::mergeQueryColumn(array_keys(static::$viewColumns), 1);
$rawGeneralList = Util::convertArrayToDict( $rawGeneralList = Util::convertArrayToDict($db->query('SELECT %l from general WHERE nation = %i ORDER BY turntime ASC', Util::formatListOfBackticks($queryColumns), $nationID), 'no');
$db->query(
'SELECT %l, %l from `general` LEFT JOIN general_access_log
ON `general`.`no` = general_access_log.general_id WHERE nation = %i ORDER BY turntime ASC',
Util::formatListOfBackticks($queryColumns),
Util::formatListOfBackticks($accessLogColumns),
$nationID
),
'no'
);
/** @var ArrayObject[] */ /** @var ArrayObject[] */
$troops = []; $troops = [];
@@ -197,19 +179,19 @@ class GeneralList extends \sammo\BaseAPI
if ($this->permission >= 1 || count($troops)) { if ($this->permission >= 1 || count($troops)) {
$reservedCommandTargetGeneralIDList = []; $reservedCommandTargetGeneralIDList = [];
if ($this->permission >= 1) { if($this->permission >= 1){
foreach ($rawGeneralList as $rawGeneral) { foreach ($rawGeneralList as $rawGeneral) {
if ($rawGeneral['npc'] < 2) { if ($rawGeneral['npc'] < 2) {
$reservedCommandTargetGeneralIDList[$rawGeneral['no']] = $rawGeneral['no']; $reservedCommandTargetGeneralIDList[$rawGeneral['no']] = $rawGeneral['no'];
} }
} }
} }
foreach ($troops as $troop) { foreach($troops as $troop){
$reservedCommandTargetGeneralIDList[$troop['id']] = $troop['id']; $reservedCommandTargetGeneralIDList[$troop['id']] = $troop['id'];
} }
if ($reservedCommandTargetGeneralIDList) { if($reservedCommandTargetGeneralIDList){
$rawTurnList = $db->query( $rawTurnList = $db->query(
'SELECT general_id, turn_idx, action, arg, brief FROM general_turn WHERE general_id IN %li AND turn_idx < 5 ORDER BY general_id asc, turn_idx asc', 'SELECT general_id, turn_idx, action, arg, brief FROM general_turn WHERE general_id IN %li AND turn_idx < 5 ORDER BY general_id asc, turn_idx asc',
array_values($reservedCommandTargetGeneralIDList) array_values($reservedCommandTargetGeneralIDList)
@@ -296,11 +278,11 @@ class GeneralList extends \sammo\BaseAPI
$resultColumns[$column] = $column; $resultColumns[$column] = $column;
} }
foreach ($troops as $troop) { foreach ($troops as $troop){
$troopLeaderID = $troop['id']; $troopLeaderID = $troop['id'];
$troop['reservedCommand'] = array_map(function ($turnObj) { $troop['reservedCommand'] = array_map(function($turnObj){
$brief = $turnObj['brief']; $brief = $turnObj['brief'];
if ($brief == '집합') { if($brief == '집합'){
return $brief; return $brief;
} }
return '-'; return '-';
+3 -5
View File
@@ -109,12 +109,10 @@ class GetGeneralLog extends \sammo\BaseAPI
$reqTo = $this->args['reqTo'] ?? null; $reqTo = $this->args['reqTo'] ?? null;
$db = DB::db(); $db = DB::db();
$me = $db->queryFirstRow( $me = $db->queryFirstRow('SELECT no,nation,officer_level,con,turntime,belong,permission,penalty from general where owner=%i', $userID);
'SELECT no,nation,officer_level,refresh_score,turntime,belong,permission,penalty FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID);
$limitState = checkLimit($me['refresh_score']); $con = checkLimit($me['con']);
if ($limitState >= 2) { if ($con >= 2) {
return '접속 제한입니다.'; return '접속 제한입니다.';
} }
+1 -2
View File
@@ -4,7 +4,6 @@ namespace sammo\API\Nation;
use sammo\DB; use sammo\DB;
use sammo\Enums\APIRecoveryType; use sammo\Enums\APIRecoveryType;
use sammo\Enums\GeneralQueryMode;
use sammo\GameConst; use sammo\GameConst;
use sammo\General; use sammo\General;
use sammo\KVStorage; use sammo\KVStorage;
@@ -66,7 +65,7 @@ class GetNationInfo extends \sammo\BaseAPI
]; ];
} }
$generalObj = General::createGeneralObjFromDB($session->generalID, null, GeneralQueryMode::FullWithoutIAction); $generalObj = General::createGeneralObjFromDB($session->generalID, null, 1);
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
$gameEnv = $gameStor->getValues(['year', 'month', 'startyear']); $gameEnv = $gameStor->getValues(['year', 'month', 'startyear']);
@@ -6,7 +6,6 @@ use sammo\Session;
use DateTimeInterface; use DateTimeInterface;
use sammo\DB; use sammo\DB;
use sammo\Enums\APIRecoveryType; use sammo\Enums\APIRecoveryType;
use sammo\Enums\GeneralQueryMode;
use sammo\GameConst; use sammo\GameConst;
use sammo\General; use sammo\General;
use sammo\Json; use sammo\Json;
@@ -40,15 +39,12 @@ class GetReservedCommand extends \sammo\BaseAPI
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
$userID = $session->userID; $userID = $session->userID;
$me = $db->queryFirstRow( $me = $db->queryFirstRow('SELECT no,nation,officer_level,con,turntime,belong,penalty,permission FROM general WHERE owner=%i', $userID);
'SELECT no,nation,officer_level,refresh_score,turntime,belong,penalty,permission FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$nationLevel = $db->queryFirstField('SELECT level FROM nation WHERE nation = %i', $me['nation']); $nationLevel = $db->queryFirstField('SELECT level FROM nation WHERE nation = %i', $me['nation']);
$nationID = $me['nation']; $nationID = $me['nation'];
$limitState = checkLimit($me['refresh_score']); $con = checkLimit($me['con']);
if ($limitState >= 2) { if ($con >= 2) {
return "접속 제한중입니다. 1턴 이내에 너무 많은 갱신을 하셨습니다. (다음 갱신 가능 시각 : {$me['turntime']})"; return "접속 제한중입니다. 1턴 이내에 너무 많은 갱신을 하셨습니다. (다음 갱신 가능 시각 : {$me['turntime']})";
} }
@@ -63,7 +59,7 @@ class GetReservedCommand extends \sammo\BaseAPI
$generals = []; $generals = [];
foreach ($db->query('SELECT no,name,turntime,npc,city,nation,officer_level FROM general WHERE nation = %i AND officer_level >= 5', $nationID) as $rawGeneral) { foreach ($db->query('SELECT no,name,turntime,npc,city,nation,officer_level FROM general WHERE nation = %i AND officer_level >= 5', $nationID) as $rawGeneral) {
$generals[$rawGeneral['officer_level']] = new General($rawGeneral, null, null, null, null, $year, $month, false); $generals[$rawGeneral['officer_level']] = new General($rawGeneral, null, null, null, $year, $month, false);
} }
$nationTurnList = []; $nationTurnList = [];
@@ -113,7 +109,7 @@ class GetReservedCommand extends \sammo\BaseAPI
]; ];
} }
$generalObj = General::createGeneralObjFromDB($session->generalID, null, GeneralQueryMode::FullWithoutIAction); $generalObj = General::createGeneralObjFromDB($session->generalID);
return [ return [
+1 -2
View File
@@ -6,7 +6,6 @@ use DateTimeInterface;
use sammo\DB; use sammo\DB;
use sammo\DTO\VoteComment; use sammo\DTO\VoteComment;
use sammo\Enums\APIRecoveryType; use sammo\Enums\APIRecoveryType;
use sammo\Enums\GeneralQueryMode;
use sammo\General; use sammo\General;
use sammo\Session; use sammo\Session;
use sammo\TimeUtil; use sammo\TimeUtil;
@@ -41,7 +40,7 @@ class AddComment extends \sammo\BaseAPI
$text = mb_substr($this->args['text'], 0, 200); $text = mb_substr($this->args['text'], 0, 200);
$generalID = $session->generalID; $generalID = $session->generalID;
$general = General::createGeneralObjFromDB($generalID, null, GeneralQueryMode::Core); $general = General::createGeneralObjFromDB($generalID, [], 0);
$generalName = $general->getName(); $generalName = $general->getName();
$nationID = $general->getNationID(); $nationID = $general->getNationID();
$nationName = $general->getStaticNation()['name']; $nationName = $general->getStaticNation()['name'];
+1 -2
View File
@@ -6,7 +6,6 @@ use DateTimeInterface;
use sammo\DB; use sammo\DB;
use sammo\DTO\VoteInfo; use sammo\DTO\VoteInfo;
use sammo\Enums\APIRecoveryType; use sammo\Enums\APIRecoveryType;
use sammo\Enums\GeneralQueryMode;
use sammo\General; use sammo\General;
use sammo\Json; use sammo\Json;
use sammo\KVStorage; use sammo\KVStorage;
@@ -106,7 +105,7 @@ class Vote extends \sammo\BaseAPI
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
$voteReward = $gameStor->getValue('develcost') * 5; $voteReward = $gameStor->getValue('develcost') * 5;
$general = General::createGeneralObjFromDB($generalID, ['gold', 'horse', 'weapon', 'book', 'item', 'npc', 'imgsvr', 'picture', 'aux'], GeneralQueryMode::Lite); $general = General::createGeneralObjFromDB($generalID, ['gold', 'horse', 'weapon', 'book', 'item', 'npc', 'imgsvr', 'picture', 'aux'], 2);
$general->increaseVar('gold', $voteReward); $general->increaseVar('gold', $voteReward);
$uniqueRng = new RandUtil(new LiteHashDRBG(Util::simpleSerialize( $uniqueRng = new RandUtil(new LiteHashDRBG(Util::simpleSerialize(
UniqueConst::$hiddenSeed, UniqueConst::$hiddenSeed,
-12
View File
@@ -1,12 +0,0 @@
<?php
namespace sammo\ActionCrewType;
use \sammo\iAction;
use \sammo\General;
class None implements iAction{
use \sammo\DefaultAction;
protected $id = -1;
protected $name = '-';
protected $info = '';
}
@@ -1,20 +0,0 @@
<?php
namespace sammo\ActionCrewType;
use \sammo\iAction;
use \sammo\General;
class che_성벽선제 implements iAction{
use \sammo\DefaultAction;
protected $name = '성벽선제';
protected $info = '전투 가능한 성벽이라면 선제공격을 합니다.';
public function onCalcOpposeStat(General $general, string $statName, $value, $aux = null)
{
if($statName == 'cityBattleOrder'){
// battleOrder는 스탯과 유사한 수치를 가지므로, 아주 충분히 높은값을 설정한다.
return 10000;
}
return $value;
}
}
+1 -1
View File
@@ -31,7 +31,7 @@ class che_병가 extends \sammo\BaseNation{
public function onCalcNationalIncome(string $type, $amount):int{ public function onCalcNationalIncome(string $type, $amount):int{
if($type == 'pop' && $amount > 0){ if($type == 'pop' && $amount > 0){
return $amount * 0.8; return Util::toInt($amount * 0.8);
} }
return $amount; return $amount;
+2 -3
View File
@@ -5,7 +5,6 @@ namespace sammo;
use Ds\Map; use Ds\Map;
use sammo\DTO\BettingInfo; use sammo\DTO\BettingInfo;
use sammo\DTO\BettingItem; use sammo\DTO\BettingItem;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\RankColumn; use sammo\Enums\RankColumn;
class Betting class Betting
@@ -244,7 +243,7 @@ class Betting
return $this->_calcRewardExclusive($winnerType); return $this->_calcRewardExclusive($winnerType);
} }
if ($this->info->isExclusive) { if ($this->info->isExlusive) {
return $this->_calcRewardExclusive($winnerType); return $this->_calcRewardExclusive($winnerType);
} }
//아래는 2개 이상, 복합 보상 옵션 //아래는 2개 이상, 복합 보상 옵션
@@ -402,7 +401,7 @@ class Betting
$userLogger->flush(); $userLogger->flush();
} }
} else { } else {
$generalList = General::createGeneralObjListFromDB(array_unique(Util::squeezeFromArray($rewardList, 'generalID')), ['gold', 'npc', 'betgold'], GeneralQueryMode::Lite); $generalList = General::createGeneralObjListFromDB(array_unique(Util::squeezeFromArray($rewardList, 'generalID')), ['gold', 'npc', 'betgold'], 1);
foreach ($rewardList as $rewardItem) { foreach ($rewardList as $rewardItem) {
$gambler = $generalList[$rewardItem['generalID']]; $gambler = $generalList[$rewardItem['generalID']];
$reward = Util::round($rewardItem['amount']); $reward = Util::round($rewardItem['amount']);
+2 -2
View File
@@ -21,7 +21,7 @@ use function \sammo\getNationStaticInfo;
use function sammo\tryUniqueItemLottery; use function sammo\tryUniqueItemLottery;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\GeneralQueryMode;
class che_등용 extends Command\GeneralCommand class che_등용 extends Command\GeneralCommand
{ {
@@ -77,7 +77,7 @@ class che_등용 extends Command\GeneralCommand
protected function initWithArg() protected function initWithArg()
{ {
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['nation', 'experience', 'dedication'], GeneralQueryMode::Lite); $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['nation', 'experience', 'dedication'], 0);
$this->setDestGeneral($destGeneral); $this->setDestGeneral($destGeneral);
[$reqGold, $reqRice] = $this->getCost(); [$reqGold, $reqRice] = $this->getCost();
@@ -68,7 +68,7 @@ class che_등용수락 extends Command\GeneralCommand{
protected function initWithArg() protected function initWithArg()
{ {
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], null); $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], null, 2);
$this->setDestGeneral($destGeneral); $this->setDestGeneral($destGeneral);
$this->setDestNation($this->arg['destNationID'], ['gennum', 'scout']); $this->setDestNation($this->arg['destNationID'], ['gennum', 'scout']);
@@ -77,7 +77,6 @@ class che_등용수락 extends Command\GeneralCommand{
$this->fullConditionConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::ReqEnvValue('join_mode', '!=', 'onlyRandom', '랜덤 임관만 가능합니다'), ConstraintHelper::ReqEnvValue('join_mode', '!=', 'onlyRandom', '랜덤 임관만 가능합니다'),
ConstraintHelper::ExistsDestNation(), ConstraintHelper::ExistsDestNation(),
ConstraintHelper::BeNeutral(),
ConstraintHelper::AllowJoinDestNation($relYear), ConstraintHelper::AllowJoinDestNation($relYear),
ConstraintHelper::ReqDestNationValue('level', '국가규모', '>', 0, '방랑군에는 임관할 수 없습니다.'), ConstraintHelper::ReqDestNationValue('level', '국가규모', '>', 0, '방랑군에는 임관할 수 없습니다.'),
ConstraintHelper::DifferentDestNation(), ConstraintHelper::DifferentDestNation(),
+4 -24
View File
@@ -21,7 +21,6 @@ use \sammo\Constraint\ConstraintHelper;
class che_물자조달 extends Command\GeneralCommand{ class che_물자조달 extends Command\GeneralCommand{
static protected $actionName = '물자조달'; static protected $actionName = '물자조달';
static protected $debuffFront = 0.5;
protected function argTest():bool{ protected function argTest():bool{
$this->arg = null; $this->arg = null;
@@ -96,31 +95,9 @@ class che_물자조달 extends Command\GeneralCommand{
$score = $general->onCalcDomestic('조달', 'score', $score); $score = $general->onCalcDomestic('조달', 'score', $score);
$score = Util::round($score); $score = Util::round($score);
$exp = $score * 0.7 / 3;
$ded = $score * 1.0 / 3;
$logger = $general->getLogger();
if(in_array($this->city['front'], [1, 3])){
$debuffFront = static::$debuffFront;
if($this->nation['capital'] == $this->city['city']){
$gameStor = \sammo\KVStorage::getStorage($db, 'game_env');
[$year, $startYear] = $gameStor->getValuesAsArray(['year', 'startyear']);
$relYear = $year - $startYear;
if($relYear < 25){
$debuffScale = Util::clamp($relYear - 5, 0, 20) * 0.05;
$debuffFront = ($debuffScale * $debuffFront) + (1 - $debuffScale);
}
}
$score *= $debuffFront;
}
$scoreText = number_format($score, 0); $scoreText = number_format($score, 0);
$logger = $general->getLogger();
if($pick == 'fail'){ if($pick == 'fail'){
$logger->pushGeneralActionLog("조달을 <span class='ev_failed'>실패</span>하여 {$resName}을 <C>$scoreText</> 조달했습니다. <1>$date</>"); $logger->pushGeneralActionLog("조달을 <span class='ev_failed'>실패</span>하여 {$resName}을 <C>$scoreText</> 조달했습니다. <1>$date</>");
@@ -132,6 +109,9 @@ class che_물자조달 extends Command\GeneralCommand{
$logger->pushGeneralActionLog("{$resName}을 <C>$scoreText</> 조달했습니다. <1>$date</>"); $logger->pushGeneralActionLog("{$resName}을 <C>$scoreText</> 조달했습니다. <1>$date</>");
} }
$exp = $score * 0.7 / 3;
$ded = $score * 1.0 / 3;
$incStat = $rng->choiceUsingWeight([ $incStat = $rng->choiceUsingWeight([
'leadership_exp'=>$general->getLeadership(false, false, false, false), 'leadership_exp'=>$general->getLeadership(false, false, false, false),
'strength_exp'=>$general->getStrength(false, false, false, false), 'strength_exp'=>$general->getStrength(false, false, false, false),
+2 -15
View File
@@ -185,21 +185,8 @@ class che_상업투자 extends Command\GeneralCommand{
$logger->pushGeneralActionLog(static::$actionName."{$josaUl} 하여 <C>$scoreText</> 상승했습니다. <1>$date</>"); $logger->pushGeneralActionLog(static::$actionName."{$josaUl} 하여 <C>$scoreText</> 상승했습니다. <1>$date</>");
} }
if(in_array($this->city['front'], [1, 3])){ if(in_array($this->city['front'], [1, 3]) && $this->nation['capital'] != $this->city['city']){
$debuffFront = static::$debuffFront; $score *= static::$debuffFront;
if($this->nation['capital'] == $this->city['city']){
$gameStor = \sammo\KVStorage::getStorage($db, 'game_env');
[$year, $startYear] = $gameStor->getValuesAsArray(['year', 'startyear']);
$relYear = $year - $startYear;
if($relYear < 25){
$debuffScale = Util::clamp($relYear - 5, 0, 20) * 0.05;
$debuffFront = ($debuffScale * $debuffFront) + (1 - $debuffScale);
}
}
$score *= $debuffFront;
} }
//NOTE: 내정량 상승시 초과 가능? //NOTE: 내정량 상승시 초과 가능?
+1 -2
View File
@@ -19,7 +19,6 @@ use function\sammo\tryUniqueItemLottery;
use \sammo\Constraint\Constraint; use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\InheritanceKey; use sammo\Enums\InheritanceKey;
class che_선양 extends Command\GeneralCommand class che_선양 extends Command\GeneralCommand
@@ -66,7 +65,7 @@ class che_선양 extends Command\GeneralCommand
protected function initWithArg() protected function initWithArg()
{ {
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['gold', 'nation'], GeneralQueryMode::Lite); $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['gold', 'nation'], 1);
$this->setDestGeneral($destGeneral); $this->setDestGeneral($destGeneral);
$this->fullConditionConstraints = [ $this->fullConditionConstraints = [
@@ -17,7 +17,6 @@ use function \sammo\tryUniqueItemLottery;
use function \sammo\getNationStaticInfo; use function \sammo\getNationStaticInfo;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\InheritanceKey; use sammo\Enums\InheritanceKey;
class che_장수대상임관 extends Command\GeneralCommand{ class che_장수대상임관 extends Command\GeneralCommand{
@@ -84,7 +83,7 @@ class che_장수대상임관 extends Command\GeneralCommand{
protected function initWithArg() protected function initWithArg()
{ {
$destGeneralID = $this->arg['destGeneralID']; $destGeneralID = $this->arg['destGeneralID'];
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['nation'], GeneralQueryMode::Lite); $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['nation'], 0);
$this->setDestGeneral($destGeneral); $this->setDestGeneral($destGeneral);
$this->setDestNation($this->destGeneralObj->getVar('nation'), ['gennum', 'scout']); $this->setDestNation($this->destGeneralObj->getVar('nation'), ['gennum', 'scout']);
@@ -87,12 +87,6 @@ class che_전투특기초기화 extends Command\GeneralCommand{
$yearMonth = Util::joinYearMonth($env['year'], $env['month']); $yearMonth = Util::joinYearMonth($env['year'], $env['month']);
$oldSpecialList = $general->getAuxVar($oldTypeKey)??[]; $oldSpecialList = $general->getAuxVar($oldTypeKey)??[];
$oldSpecialList[] = $general->getVar(static::$specialType); $oldSpecialList[] = $general->getVar(static::$specialType);
if(static::$specialType == 'special' && count($oldSpecialList) == count(GameConst::$availableSpecialDomestic)){
$oldSpecialList = [$general->getVar(static::$specialType)];
}
else if(static::$specialType == 'special2' && count($oldSpecialList) == count(GameConst::$availableSpecialWar)){
$oldSpecialList = [$general->getVar(static::$specialType)];
}
$general->setAuxVar($oldTypeKey, $oldSpecialList); $general->setAuxVar($oldTypeKey, $oldSpecialList);
$general->setVar(static::$specialType, 'None'); $general->setVar(static::$specialType, 'None');
+1 -2
View File
@@ -15,7 +15,6 @@ use \sammo\Command;
use \sammo\Constraint\Constraint; use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\GeneralQueryMode;
use function sammo\tryUniqueItemLottery; use function sammo\tryUniqueItemLottery;
@@ -87,7 +86,7 @@ class che_증여 extends Command\GeneralCommand
protected function initWithArg() protected function initWithArg()
{ {
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['gold', 'rice', 'nation'], GeneralQueryMode::Lite); $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['gold', 'rice', 'nation'], 1);
$this->setDestGeneral($destGeneral); $this->setDestGeneral($destGeneral);
$this->fullConditionConstraints = [ $this->fullConditionConstraints = [
+1 -2
View File
@@ -15,7 +15,6 @@ use function \sammo\searchDistance;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
use sammo\CityConst; use sammo\CityConst;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\RankColumn; use sammo\Enums\RankColumn;
use sammo\RandUtil; use sammo\RandUtil;
@@ -269,7 +268,7 @@ class che_화계 extends Command\GeneralCommand
$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', 'crewtype', 'crew', 'atmos', 'train']); $destCityGeneralList = General::createGeneralObjListFromDB($cityGeneralID, ['name', 'city', 'nation', 'officer_level', 'leadership', 'horse', 'strength', 'weapon', 'intel', 'book', 'item', 'last_turn', 'injury', 'special', 'special2', 'injury', 'crewtype', 'crew', 'atmos', 'train'], 2);
foreach ($destCityGeneralList as &$destCityGeneral) { foreach ($destCityGeneralList as &$destCityGeneral) {
$destCityGeneral->setRawCity($this->destCity); $destCityGeneral->setRawCity($this->destCity);
unset($destCityGeneral); unset($destCityGeneral);
+4 -7
View File
@@ -19,7 +19,6 @@ use function \sammo\GetImageURL;
use \sammo\Constraint\Constraint; use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\MessageType; use sammo\Enums\MessageType;
class che_몰수 extends Command\NationCommand class che_몰수 extends Command\NationCommand
@@ -92,7 +91,7 @@ class che_몰수 extends Command\NationCommand
protected function initWithArg() protected function initWithArg()
{ {
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['gold', 'rice', 'npc', 'nation', 'imgsvr', 'picture'], GeneralQueryMode::Lite); $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['gold', 'rice', 'npc', 'nation', 'imgsvr', 'picture'], 1);
$this->setDestGeneral($destGeneral); $this->setDestGeneral($destGeneral);
$env = $this->env; $env = $this->env;
@@ -174,7 +173,7 @@ class che_몰수 extends Command\NationCommand
$npcTexts = [ $npcTexts = [
'몰수를 하다니... 이것이 윗사람이 할 짓이란 말입니까...', '몰수를 하다니... 이것이 윗사람이 할 짓이란 말입니까...',
'사유재산까지 몰수해가면서 이 나라가 잘 될거라 믿습니까? 정말 이해할 수가 없군요...', '사유재산까지 몰수해가면서 이 나라가 잘 될거라 믿습니까? 정말 이해할 수가 없군요...',
'내 돈 내놔라! 내 돈! 몰수가 말이냐!', '내 돈 내놔라! 내 돈! 몰수가 말이냐!',
'몰수해간 내 자금... 언젠가 몰래 다시 빼내올 것이다...', '몰수해간 내 자금... 언젠가 몰래 다시 빼내올 것이다...',
'몰수로 인한 사기 저하는 몰수로 얻은 물자보다 더 손해란걸 모른단 말인가!' '몰수로 인한 사기 저하는 몰수로 얻은 물자보다 더 손해란걸 모른단 말인가!'
]; ];
@@ -206,10 +205,8 @@ class che_몰수 extends Command\NationCommand
$resKey => $db->sqleval('%b + %i', $resKey, $amount) $resKey => $db->sqleval('%b + %i', $resKey, $amount)
], 'nation=%i', $nationID); ], 'nation=%i', $nationID);
$josaUl = JosaUtil::pick($amountText, '을'); $destGeneral->getLogger()->pushGeneralActionLog("{$resName} {$amountText}을 몰수 당했습니다.", ActionLogger::PLAIN);
$logger->pushGeneralActionLog("<Y>{$destGeneral->getName()}</>에게서 {$resName} <C>$amountText</>을 몰수했습니다. <1>$date</>");
$destGeneral->getLogger()->pushGeneralActionLog("{$resName} {$amountText}{$josaUl} 몰수 당했습니다.", ActionLogger::PLAIN);
$logger->pushGeneralActionLog("<Y>{$destGeneral->getName()}</>에게서 {$resName} <C>$amountText</>{$josaUl} 몰수했습니다. <1>$date</>");
$this->setResultTurn(new LastTurn(static::getName(), $this->arg)); $this->setResultTurn(new LastTurn(static::getName(), $this->arg));
$general->applyDB($db); $general->applyDB($db);
@@ -215,16 +215,14 @@ class che_물자원조 extends Command\NationCommand
$chiefLogger->flush(); $chiefLogger->flush();
} }
$josaUlRiceAmount = JosaUtil::pick($riceAmountText, '을'); $logger->pushGeneralHistoryLog("<D><b>{$destNationName}</b></>{$josaRo} 금<C>{$goldAmountText}</> 쌀<C>{$riceAmountText}</>을 지원");
$logger->pushNationalHistoryLog("<D><b>{$destNationName}</b></>{$josaRo} 금<C>{$goldAmountText}</> 쌀<C>{$riceAmountText}</>을 지원");
$logger->pushGeneralHistoryLog("<D><b>{$destNationName}</b></>{$josaRo} 금<C>{$goldAmountText}</> 쌀<C>{$riceAmountText}</>{$josaUlRiceAmount} 지원");
$logger->pushNationalHistoryLog("<D><b>{$destNationName}</b></>{$josaRo} 금<C>{$goldAmountText}</> 쌀<C>{$riceAmountText}</>{$josaUlRiceAmount} 지원");
$logger->pushGlobalHistoryLog("<Y><b>【원조】</b></><D><b>{$nationName}</b></>에서 <D><b>{$destNationName}</b></>{$josaRo} 물자를 지원합니다"); $logger->pushGlobalHistoryLog("<Y><b>【원조】</b></><D><b>{$nationName}</b></>에서 <D><b>{$destNationName}</b></>{$josaRo} 물자를 지원합니다");
$logger->pushGeneralActionLog($broadcastMessage); $logger->pushGeneralActionLog($broadcastMessage);
$logger->pushGeneralActionLog("<D><b>{$destNationName}</b></>{$josaRo} 물자를 지원합니다. <1>$date</>", ActionLogger::PLAIN); $logger->pushGeneralActionLog("<D><b>{$destNationName}</b></>{$josaRo} 물자를 지원합니다. <1>$date</>", ActionLogger::PLAIN);
$destBroadcastMessage = $broadcastMessage = "<D><b>{$nationName}</b></>에서 금<C>{$goldAmountText}</> 쌀<C>{$riceAmountText}</>{$josaUlRiceAmount} 원조했습니다."; $destBroadcastMessage = $broadcastMessage = "<D><b>{$nationName}</b></>에서 금<C>{$goldAmountText}</> 쌀<C>{$riceAmountText}</> 원조했습니다.";
$destChiefList = $db->queryFirstColumn('SELECT no FROM general WHERE officer_level >= 5 AND nation = %i', $destNationID); $destChiefList = $db->queryFirstColumn('SELECT no FROM general WHERE officer_level >= 5 AND nation = %i', $destNationID);
foreach ($destChiefList as $destChiefID) { foreach ($destChiefList as $destChiefID) {
$destChiefLogger = new ActionLogger($destChiefID, $nationID, $year, $month); $destChiefLogger = new ActionLogger($destChiefID, $nationID, $year, $month);
@@ -234,7 +232,7 @@ class che_물자원조 extends Command\NationCommand
$josaRoSrc = JosaUtil::pick($nationName, '로'); $josaRoSrc = JosaUtil::pick($nationName, '로');
$destNationLogger = new ActionLogger(0, $destNationID, $year, $month); $destNationLogger = new ActionLogger(0, $destNationID, $year, $month);
$destNationLogger->pushNationalHistoryLog("<D><b>{$nationName}</b></>{$josaRoSrc}부터 금<C>{$goldAmountText}</> 쌀<C>{$riceAmountText}</>{$josaUlRiceAmount} 지원 받음"); $destNationLogger->pushNationalHistoryLog("<D><b>{$nationName}</b></>{$josaRoSrc}부터 금<C>{$goldAmountText}</> 쌀<C>{$riceAmountText}</> 지원 받음");
$destNationStor = KVStorage::getStorage(DB::db(), $destNationID, 'nation_env'); $destNationStor = KVStorage::getStorage(DB::db(), $destNationID, 'nation_env');
$destRecvAssist = $destNationStor->getValue('recv_assist') ?? []; $destRecvAssist = $destNationStor->getValue('recv_assist') ?? [];
+1 -2
View File
@@ -21,7 +21,6 @@ use function \sammo\cutTurn;
use \sammo\Constraint\Constraint; use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\GeneralQueryMode;
class che_발령 extends Command\NationCommand class che_발령 extends Command\NationCommand
{ {
@@ -72,7 +71,7 @@ class che_발령 extends Command\NationCommand
{ {
$this->setDestCity($this->arg['destCityID']); $this->setDestCity($this->arg['destCityID']);
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], null, GeneralQueryMode::Lite); $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], null, 1);
$this->setDestGeneral($destGeneral); $this->setDestGeneral($destGeneral);
if ($this->arg['destGeneralID'] == $this->getGeneral()->getID()) { if ($this->arg['destGeneralID'] == $this->getGeneral()->getID()) {
@@ -20,7 +20,6 @@ use function \sammo\getNationStaticInfo;
use \sammo\Constraint\Constraint; use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\GeneralQueryMode;
use sammo\Json; use sammo\Json;
use sammo\KVStorage; use sammo\KVStorage;
use sammo\RandUtil; use sammo\RandUtil;
@@ -104,7 +103,7 @@ class che_불가침수락 extends Command\NationCommand
$env = $this->env; $env = $this->env;
$relYear = $env['year'] - $env['startyear']; $relYear = $env['year'] - $env['startyear'];
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], null, GeneralQueryMode::Lite); $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], [], 1);
$this->setDestGeneral($destGeneral); $this->setDestGeneral($destGeneral);
$this->setDestNation($this->arg['destNationID']); $this->setDestNation($this->arg['destNationID']);
@@ -165,7 +165,6 @@ class che_불가침제의 extends Command\NationCommand
$nation = $this->nation; $nation = $this->nation;
$nationID = $nation['nation']; $nationID = $nation['nation'];
$nationName = $nation['name']; $nationName = $nation['name'];
$josaRo = JosaUtil::pick($nationName, '로');
$destNation = $this->destNation; $destNation = $this->destNation;
$destNationID = $destNation['nation']; $destNationID = $destNation['nation'];
@@ -177,7 +176,7 @@ class che_불가침제의 extends Command\NationCommand
$logger = $general->getLogger(); $logger = $general->getLogger();
$destLogger = new ActionLogger(0, $destNationID, $env['year'], $env['month']); $destLogger = new ActionLogger(0, $destNationID, $env['year'], $env['month']);
$logger->pushGeneralActionLog("<D><b>{$destNationName}</b></>{$josaRo} 불가침 제의 서신을 보냈습니다.<1>$date</>"); $logger->pushGeneralActionLog("<D><b>{$destNationName}</b></>으로 불가침 제의 서신을 보냈습니다.<1>$date</>");
// 상대에게 발송 // 상대에게 발송
$src = new MessageTarget( $src = new MessageTarget(
@@ -20,7 +20,6 @@ use function \sammo\getNationStaticInfo;
use \sammo\Constraint\Constraint; use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\GeneralQueryMode;
use sammo\RandUtil; use sammo\RandUtil;
class che_불가침파기수락 extends Command\NationCommand class che_불가침파기수락 extends Command\NationCommand
@@ -78,7 +77,7 @@ class che_불가침파기수락 extends Command\NationCommand
protected function initWithArg() protected function initWithArg()
{ {
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], null, GeneralQueryMode::Lite); $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], [], 1);
$this->setDestGeneral($destGeneral); $this->setDestGeneral($destGeneral);
$this->setDestNation($this->arg['destNationID']); $this->setDestNation($this->arg['destNationID']);
@@ -122,12 +122,11 @@ class che_불가침파기제의 extends Command\NationCommand{
$destNation = $this->destNation; $destNation = $this->destNation;
$destNationID = $destNation['nation']; $destNationID = $destNation['nation'];
$destNationName = $destNation['name']; $destNationName = $destNation['name'];
$josaRo = JosaUtil::pick($destNationName, '로');
$logger = $general->getLogger(); $logger = $general->getLogger();
$destLogger = new ActionLogger(0, $destNationID, $env['year'], $env['month']); $destLogger = new ActionLogger(0, $destNationID, $env['year'], $env['month']);
$logger->pushGeneralActionLog("<D><b>{$destNationName}</b></>{$josaRo} 불가침 파기 제의 서신을 보냈습니다.<1>$date</>"); $logger->pushGeneralActionLog("<D><b>{$destNationName}</b></>으로 불가침 파기 제의 서신을 보냈습니다.<1>$date</>");
// 상대에게 발송 // 상대에게 발송
$src = new MessageTarget( $src = new MessageTarget(
@@ -22,7 +22,6 @@ use function \sammo\getNationStaticInfo;
use \sammo\Constraint\Constraint; use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\GeneralQueryMode;
class che_종전수락 extends Command\NationCommand class che_종전수락 extends Command\NationCommand
{ {
@@ -87,7 +86,7 @@ class che_종전수락 extends Command\NationCommand
protected function initWithArg() protected function initWithArg()
{ {
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], null, GeneralQueryMode::Lite); $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], [], 1);
$this->setDestGeneral($destGeneral); $this->setDestGeneral($destGeneral);
$this->setDestNation($this->arg['destNationID']); $this->setDestNation($this->arg['destNationID']);
@@ -120,12 +120,11 @@ class che_종전제의 extends Command\NationCommand{
$destNation = $this->destNation; $destNation = $this->destNation;
$destNationID = $destNation['nation']; $destNationID = $destNation['nation'];
$destNationName = $destNation['name']; $destNationName = $destNation['name'];
$josaRo = JosaUtil::pick($destNationName, '로');
$logger = $general->getLogger(); $logger = $general->getLogger();
$destLogger = new ActionLogger(0, $destNationID, $env['year'], $env['month']); $destLogger = new ActionLogger(0, $destNationID, $env['year'], $env['month']);
$logger->pushGeneralActionLog("<D><b>{$destNationName}</b></>{$josaRo} 종전 제의 서신을 보냈습니다.<1>$date</>"); $logger->pushGeneralActionLog("<D><b>{$destNationName}</b></>으로 종전 제의 서신을 보냈습니다.<1>$date</>");
// 상대에게 발송 // 상대에게 발송
$src = new MessageTarget( $src = new MessageTarget(
+3 -6
View File
@@ -15,7 +15,6 @@ use \sammo\Command;
use \sammo\Constraint\Constraint; use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\GeneralQueryMode;
class che_포상 extends Command\NationCommand class che_포상 extends Command\NationCommand
{ {
@@ -82,7 +81,7 @@ class che_포상 extends Command\NationCommand
protected function initWithArg() protected function initWithArg()
{ {
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['gold', 'rice', 'nation'], GeneralQueryMode::Lite); $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['gold', 'rice', 'nation'], 1);
$this->setDestGeneral($destGeneral); $this->setDestGeneral($destGeneral);
if($this->arg['destGeneralID'] == $this->getGeneral()->getID()){ if($this->arg['destGeneralID'] == $this->getGeneral()->getID()){
@@ -168,10 +167,8 @@ class che_포상 extends Command\NationCommand
$resKey => $db->sqleval('%b - %i', $resKey, $amount) $resKey => $db->sqleval('%b - %i', $resKey, $amount)
], 'nation=%i', $nationID); ], 'nation=%i', $nationID);
$josaUl = JosaUtil::pick($amountText, '을'); $destGeneral->getLogger()->pushGeneralActionLog("{$resName} <C>{$amountText}</>을 포상으로 받았습니다.", ActionLogger::PLAIN);
$logger->pushGeneralActionLog("<Y>{$destGeneral->getName()}</>에게 {$resName} <C>$amountText</>을 수여했습니다. <1>$date</>");
$destGeneral->getLogger()->pushGeneralActionLog("{$resName} <C>{$amountText}</>{$josaUl} 포상으로 받았습니다.", ActionLogger::PLAIN);
$logger->pushGeneralActionLog("<Y>{$destGeneral->getName()}</>에게 {$resName} <C>$amountText</>{$josaUl} 수여했습니다. <1>$date</>");
$this->setResultTurn(new LastTurn(static::getName(), $this->arg)); $this->setResultTurn(new LastTurn(static::getName(), $this->arg));
$general->applyDB($db); $general->applyDB($db);
@@ -15,7 +15,6 @@ use \sammo\{
use \sammo\Constraint\Constraint; use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\GeneralQueryMode;
use sammo\Event\Action; use sammo\Event\Action;
class che_필사즉생 extends Command\NationCommand{ class che_필사즉생 extends Command\NationCommand{
@@ -95,7 +94,7 @@ class che_필사즉생 extends Command\NationCommand{
$broadcastMessage = "<Y>{$generalName}</>{$josaYi} <M>필사즉생</>을 발동하였습니다."; $broadcastMessage = "<Y>{$generalName}</>{$josaYi} <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(General::createGeneralObjListFromDB($targetGeneralList, ['train', 'atmos'], GeneralQueryMode::Lite) as $targetGeneral){ foreach(General::createGeneralObjListFromDB($targetGeneralList, ['train', 'atmos'], 1) as $targetGeneral){
$targetGeneral->getLogger()->pushGeneralActionLog($broadcastMessage, ActionLogger::PLAIN); $targetGeneral->getLogger()->pushGeneralActionLog($broadcastMessage, ActionLogger::PLAIN);
if($targetGeneral->getVar('train') < 100){ if($targetGeneral->getVar('train') < 100){
$targetGeneral->setVar('train', 100); $targetGeneral->setVar('train', 100);
@@ -39,7 +39,7 @@ class ReqGeneralCrewMargin extends Constraint{
//XXX: 왜 General -> obj -> General 변환을 하고 있나? //XXX: 왜 General -> obj -> General 변환을 하고 있나?
//FIXME: RankVar, city에 따라 통솔이 바뀐다면 이 부분에 문제가 발생. //FIXME: RankVar, city에 따라 통솔이 바뀐다면 이 부분에 문제가 발생.
$generalObj = new General($this->general, null, null, null, null, null, null, true); $generalObj = new General($this->general, null, null, null, null, null, true);
if($reqCrewType->id != $generalObj->getCrewTypeObj()->id){ if($reqCrewType->id != $generalObj->getCrewTypeObj()->id){
return true; return true;
-38
View File
@@ -1,38 +0,0 @@
<?php
namespace sammo\DTO;
use LDTO\Attr\Convert;
use LDTO\Attr\NullIsUndefined;
use LDTO\Attr\RawName;
use LDTO\Converter\DateTimeConverter;
class GeneralAccessLog extends \LDTO\DTO
{
public function __construct(
#[NullIsUndefined]
public ?int $id,
#[RawName('general_id')]
public int $generalID,
#[RawName('user_id')]
public ?int $userID,
#[RawName('last_refresh')]
#[Convert(DateTimeConverter::class)]
public \DateTimeImmutable $lastRefresh,
public int $refresh,
#[RawName('refresh_total')]
public int $refreshTotal,
#[RawName('refresh_score')]
public int $refreshScore,
#[RawName('refresh_score_total')]
public int $refreshScoreTotal,
) {
}
}
+3 -4
View File
@@ -1,7 +1,6 @@
<?php <?php
namespace sammo; namespace sammo;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\MessageType; use sammo\Enums\MessageType;
class DiplomaticMessage extends Message{ class DiplomaticMessage extends Message{
@@ -76,7 +75,7 @@ class DiplomaticMessage extends Message{
$gameStor = KVStorage::getStorage(DB::db(), 'game_env'); $gameStor = KVStorage::getStorage(DB::db(), 'game_env');
$destGeneralObj = General::createGeneralObjFromDB($this->dest->generalID, ['picture', 'imgsvr', 'aux'], GeneralQueryMode::Lite); $destGeneralObj = General::createGeneralObjFromDB($this->dest->generalID, ['picture', 'imgsvr', 'aux'], 1);
$commandObj = buildNationCommandClass('che_불가침수락', $destGeneralObj, $gameStor->getAll(true), new LastTurn(), [ $commandObj = buildNationCommandClass('che_불가침수락', $destGeneralObj, $gameStor->getAll(true), new LastTurn(), [
'destNationID'=>$this->src->nationID, 'destNationID'=>$this->src->nationID,
@@ -100,7 +99,7 @@ class DiplomaticMessage extends Message{
protected function cancelNA(){ protected function cancelNA(){
$gameStor = KVStorage::getStorage(DB::db(), 'game_env'); $gameStor = KVStorage::getStorage(DB::db(), 'game_env');
$destGeneralObj = General::createGeneralObjFromDB($this->dest->generalID, ['picture', 'imgsvr', 'aux'], GeneralQueryMode::Lite); $destGeneralObj = General::createGeneralObjFromDB($this->dest->generalID, ['picture', 'imgsvr', 'aux'], 1);
$commandObj = buildNationCommandClass('che_불가침파기수락', $destGeneralObj, $gameStor->getAll(true), new LastTurn(), [ $commandObj = buildNationCommandClass('che_불가침파기수락', $destGeneralObj, $gameStor->getAll(true), new LastTurn(), [
'destNationID'=>$this->src->nationID, 'destNationID'=>$this->src->nationID,
@@ -122,7 +121,7 @@ class DiplomaticMessage extends Message{
protected function stopWar(){ protected function stopWar(){
$gameStor = KVStorage::getStorage(DB::db(), 'game_env'); $gameStor = KVStorage::getStorage(DB::db(), 'game_env');
$destGeneralObj = General::createGeneralObjFromDB($this->dest->generalID, ['picture', 'imgsvr', 'aux'], GeneralQueryMode::Lite); $destGeneralObj = General::createGeneralObjFromDB($this->dest->generalID, ['picture', 'imgsvr', 'aux'], 1);
$commandObj = buildNationCommandClass('che_종전수락', $destGeneralObj, $gameStor->getAll(true), new LastTurn(), [ $commandObj = buildNationCommandClass('che_종전수락', $destGeneralObj, $gameStor->getAll(true), new LastTurn(), [
'destNationID'=>$this->src->nationID, 'destNationID'=>$this->src->nationID,
-12
View File
@@ -37,25 +37,13 @@ class DummyGeneral extends General
} }
} }
public function setCrewType(?GameUnitDetail $crewType){
$this->crewType = $crewType;
}
public function getBattleInitSkillTriggerList(WarUnit $unit): ?WarUnitTriggerCaller public function getBattleInitSkillTriggerList(WarUnit $unit): ?WarUnitTriggerCaller
{ {
//crewType에만 반응하자
if($this->crewType !== null){
return $this->crewType->getBattleInitSkillTriggerList($unit);
}
return new WarUnitTriggerCaller(); return new WarUnitTriggerCaller();
} }
public function getBattlePhaseSkillTriggerList(WarUnit $unit): ?WarUnitTriggerCaller public function getBattlePhaseSkillTriggerList(WarUnit $unit): ?WarUnitTriggerCaller
{ {
//crewType에만 반응하자
if($this->crewType !== null){
return $this->crewType->getBattlePhaseSkillTriggerList($unit);
}
return new WarUnitTriggerCaller(); return new WarUnitTriggerCaller();
} }
@@ -1,14 +0,0 @@
<?php
namespace sammo\Enums;
enum GeneralAccessLogColumn: string {
case id = 'id';
case generalID = 'general_id';
case userID = 'user_id';
case lastRefresh = 'last_refresh';
case refresh = 'refresh'; //순간 갱신 횟수(00:00에 초기화)
case refreshTotal = 'refresh_total'; //누적 갱신 횟수
case refreshScore = 'refresh_score'; //순간 벌점(턴 시간에 초기화)
case refreshScoreTotal = 'refresh_score_total'; //누적 벌점(지속적으로 감소, refreshScoreTotal <= refreshTotal)
}
+7
View File
@@ -15,6 +15,11 @@ enum GeneralColumn: string{
case bornyear = 'bornyear'; case bornyear = 'bornyear';
case deadyear = 'deadyear'; case deadyear = 'deadyear';
case newmsg = 'newmsg'; case newmsg = 'newmsg';
case con = 'con';
case connect = 'connect';
case refresh = 'refresh';
case logcnt = 'logcnt';
case refcnt = 'refcnt';
case picture = 'picture'; case picture = 'picture';
case imgsvr = 'imgsvr'; case imgsvr = 'imgsvr';
case name = 'name'; case name = 'name';
@@ -53,6 +58,8 @@ enum GeneralColumn: string{
case recent_war = 'recent_war'; case recent_war = 'recent_war';
case makelimit = 'makelimit'; case makelimit = 'makelimit';
case killturn = 'killturn'; case killturn = 'killturn';
case lastconnect = 'lastconnect';
case lastrefresh = 'lastrefresh';
case ip = 'ip'; case ip = 'ip';
case block = 'block'; case block = 'block';
case dedlevel = 'dedlevel'; case dedlevel = 'dedlevel';
-18
View File
@@ -1,18 +0,0 @@
<?php
namespace sammo\Enums;
// mergeQueryColumn, createGeneralObjListFromDB, createGeneralObjFromDB 호출시 column 특수 모드 지정
enum GeneralQueryMode: int
{
/** 장수 식별을 위한 최소한의 정보, logger 초기화 없음 */
case Core = 0;
/** 게임 내에서 필수 이벤트 처리를 위한 정보, iAction 제외 */
case Lite = 1;
/** 게임 내 모든 이벤트 처리를 위한 정보, iAction 제외 */
case FullWithoutIAction = 2;
/** 게임 내 모든 이벤트 처리를 위한 정보, iAction 포함 */
case Full = 3;
/** 접속 정보를 포함한 모든 정보 */
case FullWithAccessLog = 4;
}
-60
View File
@@ -1,60 +0,0 @@
<?php
namespace sammo\Enums;
enum TableName: string {
case general = 'general';
case generalTurn = 'general_turn';
case generalAccessLog = 'general_access_log';
case userRecord = 'user_record';
case nation = 'nation';
case nationTurn = 'nation_turn';
case nationEnv = 'nation_env';
case board = 'board';
case comment = 'comment';
case city = 'city';
case troop = 'troop';
case plock = 'plock';
case message = 'message';
case rankData = 'rank_data';
case hall = 'hall';
case oldNations = 'ng_old_nations';
case oldGenerals = 'ng_old_generals';
case emperior = 'emperior';
case diplomacy = 'diplomacy';
case diplomaticNotes = 'ng_diplomacy';
case tournament = 'tournament';
case betting = 'ng_betting';
case vote = 'vote';
case voteComment = 'vote_comment';
case auction = 'ng_auction';
case auctionBid = 'ng_auction_bid';
case statistic = 'statistic';
case history = 'ng_history';
case worldHistory = 'world_history';
case generalRecord = 'general_record';
case event = 'event';
case storage = 'storage';
case selectNPCToken = 'select_npc_token';
case selectPool = 'select_pool';
case games = 'ng_games';
case reservedOpen = 'reserved_open';
}
+5 -20
View File
@@ -31,39 +31,24 @@ class InvaderEnding extends \sammo\Event\Action{
$logger = new ActionLogger(0, 0, $env['year'], $env['month']); $logger = new ActionLogger(0, 0, $env['year'], $env['month']);
$needStop = false;
$userWin = false;
$cityCnt = $db->queryFirstField('SELECT count(*) FROM city WHERE nation = 0'); $cityCnt = $db->queryFirstField('SELECT count(*) FROM city WHERE nation = 0');
if($cityCnt == 0){ if($cityCnt == 0){
$needStop = true;
$nationName = $db->queryFirstField('SELECT name FROM nation LIMIT 1');
if(!\str_starts_with($nationName, 'ⓞ')){
$userWin = true;
}
}
else if($cityCnt == count(CityConst::all())){
$needStop = true;
$userWin = false;
}
if(!$needStop){
return [__CLASS__, "On Event"];
}
if($userWin){
//천통 엔딩 //천통 엔딩
$logger->pushGlobalHistoryLog("<L><b>【이벤트】</b></>이민족을 모두 소탕했습니다!"); $logger->pushGlobalHistoryLog("<L><b>【이벤트】</b></>이민족을 모두 소탕했습니다!");
$logger->pushGlobalHistoryLog("<L><b>【이벤트】</b></>중원은 당분간 태평성대를 누릴 것입니다."); $logger->pushGlobalHistoryLog("<L><b>【이벤트】</b></>중원은 당분간 태평성대를 누릴 것입니다.");
} }
else { else if($cityCnt == count(CityConst::all())){
//이민족 엔딩 //이민족 엔딩
$logger->pushGlobalHistoryLog("<L><b>【이벤트】</b></>중원은 이민족에 의해 혼란에 빠졌습니다."); $logger->pushGlobalHistoryLog("<L><b>【이벤트】</b></>중원은 이민족에 의해 혼란에 빠졌습니다.");
$logger->pushGlobalHistoryLog("<L><b>【이벤트】</b></>백성은 언젠가 영웅이 나타나길 기다립니다."); $logger->pushGlobalHistoryLog("<L><b>【이벤트】</b></>백성은 언젠가 영웅이 나타나길 기다립니다.");
} }
else{
return [__CLASS__, "On Event"];
}
$gameStor->setValue('isunited', 3); $gameStor->setValue('isunited', 3);
$logger->flush(); $logger->flush();
$gameStor->refreshLimit = $gameStor->refreshLimit * 100; $gameStor->conlimit = $gameStor->conlimit * 100;
$eventID = Util::array_get($env['currentEventID']); $eventID = Util::array_get($env['currentEventID']);
$db->delete('event', 'id = %i', $eventID); $db->delete('event', 'id = %i', $eventID);
@@ -18,7 +18,7 @@ class MergeInheritPointRank extends \sammo\Event\Action
{ {
$db = DB::db(); $db = DB::db();
$generals = General::createGeneralObjListFromDB(null, null); $generals = General::createGeneralObjListFromDB(null, null, 2);
$points = new Map(); $points = new Map();
$points->allocate(count($generals)); $points->allocate(count($generals));
+2 -2
View File
@@ -88,7 +88,7 @@ class ProcessIncome extends \sammo\Event\Action
// 각 장수들에게 지급 // 각 장수들에게 지급
foreach ($generalRawList as $rawGeneral) { foreach ($generalRawList as $rawGeneral) {
$generalObj = new General($rawGeneral, null, null, null, null, $year, $month, false); $generalObj = new General($rawGeneral, null, null, null, $year, $month, false);
$gold = Util::round(getBill($generalObj->getVar('dedication')) * $ratio); $gold = Util::round(getBill($generalObj->getVar('dedication')) * $ratio);
$generalObj->increaseVar('gold', $gold); $generalObj->increaseVar('gold', $gold);
@@ -169,7 +169,7 @@ class ProcessIncome extends \sammo\Event\Action
// 각 장수들에게 지급 // 각 장수들에게 지급
foreach ($generalRawList as $rawGeneral) { foreach ($generalRawList as $rawGeneral) {
$generalObj = new General($rawGeneral, null, null, null, null, $year, $month, false); $generalObj = new General($rawGeneral, null, null, null, $year, $month, false);
$rice = Util::round(getBill($generalObj->getVar('dedication')) * $ratio); $rice = Util::round(getBill($generalObj->getVar('dedication')) * $ratio);
$generalObj->increaseVar('rice', $rice); $generalObj->increaseVar('rice', $rice);
@@ -41,7 +41,7 @@ class ProvideNPCTroopLeader extends \sammo\Event\Action
foreach ($db->query('SELECT nation,name,level,tech,aux FROM nation') as $nation) { foreach ($db->query('SELECT nation,name,level,tech,aux FROM nation') as $nation) {
$nationID = $nation['nation']; $nationID = $nation['nation'];
$maxNPCTroopLeaderCnt = self::MaxNPCTroopLeaderCnt[$nation['level']] ?? 0; $maxNPCTroopLeaderCnt = self::MaxNPCTroopLeaderCnt[$nation['level']];
$NPCTroopLeaderCnt = $NPCTroopLeaderCntByNation[$nationID] ?? 0; $NPCTroopLeaderCnt = $NPCTroopLeaderCntByNation[$nationID] ?? 0;
if ($NPCTroopLeaderCnt >= $maxNPCTroopLeaderCnt) { if ($NPCTroopLeaderCnt >= $maxNPCTroopLeaderCnt) {
+1 -1
View File
@@ -131,7 +131,7 @@ class RaiseDisaster extends \sammo\Event\Action
$generalList = array_map( $generalList = array_map(
function ($rawGeneral) use ($city, $year, $month) { function ($rawGeneral) use ($city, $year, $month) {
return new General($rawGeneral, null, null, $city, null, $year, $month, false); return new General($rawGeneral, null, $city, null, $year, $month, false);
}, },
$generalListByCity[$city['city']] ?? [] $generalListByCity[$city['city']] ?? []
); );
+2 -31
View File
@@ -12,8 +12,6 @@ use sammo\LiteHashDRBG;
use sammo\RandUtil; use sammo\RandUtil;
use sammo\Scenario\GeneralBuilder; use sammo\Scenario\GeneralBuilder;
use sammo\Scenario\Nation; use sammo\Scenario\Nation;
use sammo\ServerEnv;
use sammo\ServerTool;
use sammo\UniqueConst; use sammo\UniqueConst;
use sammo\Util; use sammo\Util;
@@ -95,7 +93,6 @@ class RaiseInvader extends \sammo\Event\Action
public function run(array $env) public function run(array $env)
{ {
$db = DB::db(); $db = DB::db();
$npcEachCount = $this->npcEachCount; $npcEachCount = $this->npcEachCount;
/** @var \sammo\CityInitDetail[] */ /** @var \sammo\CityInitDetail[] */
@@ -107,16 +104,6 @@ class RaiseInvader extends \sammo\Event\Action
$cities[] = $cityObj; $cities[] = $cityObj;
} }
if(!$cities){
return [__CLASS__, 0];
}
$gameStor = KVStorage::getStorage($db, 'game_env');
$gameStor->setValue('isunited', 1);
$turnterm = $gameStor->turnterm;
$generalCnt = $db->queryFirstField('SELECT count(*) FROM general');
if ($npcEachCount < 0) { if ($npcEachCount < 0) {
$npcEachCount = $npcEachCount =
$db->queryFirstField('SELECT count(no) from general where npc < 4') / count($cities); $db->queryFirstField('SELECT count(no) from general where npc < 4') / count($cities);
@@ -124,19 +111,6 @@ class RaiseInvader extends \sammo\Event\Action
} }
$npcEachCount = max(10, Util::toInt($npcEachCount)); $npcEachCount = max(10, Util::toInt($npcEachCount));
$totalGenerals = $npcEachCount * count($cities) + $generalCnt;
if ($totalGenerals > ServerEnv::$maxGeneralsPerMinute * $turnterm) {
foreach ([1, 2, 5, 10, 20, 30, 60, 120] as $nextTurnterm) {
if ($totalGenerals > ServerEnv::$maxGeneralsPerMinute * $nextTurnterm) {
continue;
}
ServerTool::changeServerTerm($nextTurnterm, true);
break;
}
}
$specAvg = $this->specAvg; $specAvg = $this->specAvg;
if ($specAvg < 0) { if ($specAvg < 0) {
$specAvg = $db->queryFirstField('SELECT avg((`leadership` + `strength` + `intel`)) from general where npc < 4'); $specAvg = $db->queryFirstField('SELECT avg((`leadership` + `strength` + `intel`)) from general where npc < 4');
@@ -166,11 +140,6 @@ class RaiseInvader extends \sammo\Event\Action
$month, $month,
))); )));
$db->update('nation', [
'war' => 0,
'scout' => 0,
], '1');
$disabledInvaderCity = $this->moveCapital($rng); $disabledInvaderCity = $this->moveCapital($rng);
$serverID = UniqueConst::$serverID; $serverID = UniqueConst::$serverID;
$existNations = $db->queryFirstColumn("SELECT nation FROM `nation`"); $existNations = $db->queryFirstColumn("SELECT nation FROM `nation`");
@@ -291,6 +260,8 @@ class RaiseInvader extends \sammo\Event\Action
'secu' => $db->sqleval('secu_max'), 'secu' => $db->sqleval('secu_max'),
], true); ], true);
$gameStor = KVStorage::getStorage($db, 'game_env');
$gameStor->setValue('isunited', 1);
refreshNationStaticInfo(); refreshNationStaticInfo();
$logger = new ActionLogger(0, 0, $year, $env['month']); $logger = new ActionLogger(0, 0, $year, $env['month']);
+2 -3
View File
@@ -5,7 +5,6 @@ namespace sammo\Event\Action;
use sammo\ActionLogger; use sammo\ActionLogger;
use sammo\CityConst; use sammo\CityConst;
use sammo\DB; use sammo\DB;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\InheritanceKey; use sammo\Enums\InheritanceKey;
use sammo\GameConst; use sammo\GameConst;
use sammo\General; use sammo\General;
@@ -140,7 +139,7 @@ class UpdateNationLevel extends \sammo\Event\Action
$nation['nation'], $nation['nation'],
$targetKillTurn $targetKillTurn
); );
$nationGenList = General::createGeneralObjListFromDB($nationGenIDList, ['belong', 'npc', 'aux']); $nationGenList = General::createGeneralObjListFromDB($nationGenIDList, ['belong', 'npc', 'aux'], 2);
$chiefID = null; $chiefID = null;
$uniqueLotteryWeightList = []; $uniqueLotteryWeightList = [];
@@ -215,7 +214,7 @@ class UpdateNationLevel extends \sammo\Event\Action
} }
if ($chiefID) { if ($chiefID) {
$chiefObj = General::createGeneralObjFromDB($chiefID, ['belong', 'npc', 'aux'], GeneralQueryMode::Lite); $chiefObj = General::createGeneralObjFromDB($chiefID, ['belong', 'npc', 'aux'], 2);
$chiefObj->increaseInheritancePoint(InheritanceKey::unifier, 250 * $levelDiff); $chiefObj->increaseInheritancePoint(InheritanceKey::unifier, 250 * $levelDiff);
$chiefObj->applyDB($db); $chiefObj->applyDB($db);
} }
-3
View File
@@ -83,9 +83,6 @@ class GameConstBase
/** @var int 최대 하야 패널티 수 */ /** @var int 최대 하야 패널티 수 */
public static $maxBetrayCnt = 9; public static $maxBetrayCnt = 9;
/** @var int 최대 레벨 */
public static $maxLevel = 255;
/** @var int 최소 인구 증가량 */ /** @var int 최소 인구 증가량 */
public static $basePopIncreaseAmount = 5000; public static $basePopIncreaseAmount = 5000;
/** @var int 증축시 인구 증가량 */ /** @var int 증축시 인구 증가량 */
+40 -42
View File
@@ -41,7 +41,7 @@ class GameUnitConstBase{
[],//성벽은 공격할 수 없다. [],//성벽은 공격할 수 없다.
[self::T_FOOTMAN=>1.2], [self::T_FOOTMAN=>1.2],
['성벽입니다.','생성할 수 없습니다.'], ['성벽입니다.','생성할 수 없습니다.'],
null, ['che_선제사격시도', 'che_선제사격발동'], null null, null
], ],
[ [
@@ -51,7 +51,7 @@ class GameUnitConstBase{
[self::T_ARCHER=>1.2, self::T_CAVALRY=>0.8, self::T_SIEGE=>1.2], [self::T_ARCHER=>1.2, self::T_CAVALRY=>0.8, self::T_SIEGE=>1.2],
[self::T_ARCHER=>0.8, self::T_CAVALRY=>1.2, self::T_SIEGE=>0.8], [self::T_ARCHER=>0.8, self::T_CAVALRY=>1.2, self::T_SIEGE=>0.8],
['표준적인 보병입니다.','보병은 방어특화이며,','상대가 회피하기 어렵습니다.'], ['표준적인 보병입니다.','보병은 방어특화이며,','상대가 회피하기 어렵습니다.'],
null, ['che_방어력증가5p'], null null, ['che_방어력증가5p']
], ],
[ [
1101, self::T_FOOTMAN, '청주병', 1101, self::T_FOOTMAN, '청주병',
@@ -60,7 +60,7 @@ class GameUnitConstBase{
[self::T_ARCHER=>1.2, self::T_CAVALRY=>0.8, self::T_SIEGE=>1.2], [self::T_ARCHER=>1.2, self::T_CAVALRY=>0.8, self::T_SIEGE=>1.2],
[self::T_ARCHER=>0.8, self::T_CAVALRY=>1.2, self::T_SIEGE=>0.8], [self::T_ARCHER=>0.8, self::T_CAVALRY=>1.2, self::T_SIEGE=>0.8],
['저렴하고 튼튼합니다.'], ['저렴하고 튼튼합니다.'],
null, ['che_방어력증가5p'], null null, ['che_방어력증가5p']
], ],
[ [
1102, self::T_FOOTMAN, '수병', 1102, self::T_FOOTMAN, '수병',
@@ -69,7 +69,7 @@ class GameUnitConstBase{
[self::T_ARCHER=>1.2, self::T_CAVALRY=>0.8, self::T_SIEGE=>1.2], [self::T_ARCHER=>1.2, self::T_CAVALRY=>0.8, self::T_SIEGE=>1.2],
[self::T_ARCHER=>0.8, self::T_CAVALRY=>1.2, self::T_SIEGE=>0.8], [self::T_ARCHER=>0.8, self::T_CAVALRY=>1.2, self::T_SIEGE=>0.8],
['저렴하고 강력합니다.'], ['저렴하고 강력합니다.'],
null, ['che_방어력증가5p'], null null, ['che_방어력증가5p']
], ],
[ [
1103, self::T_FOOTMAN, '자객병', 1103, self::T_FOOTMAN, '자객병',
@@ -78,7 +78,7 @@ class GameUnitConstBase{
[self::T_ARCHER=>1.2, self::T_CAVALRY=>0.8, self::T_SIEGE=>1.2], [self::T_ARCHER=>1.2, self::T_CAVALRY=>0.8, self::T_SIEGE=>1.2],
[self::T_ARCHER=>0.8, self::T_CAVALRY=>1.2, self::T_SIEGE=>0.8], [self::T_ARCHER=>0.8, self::T_CAVALRY=>1.2, self::T_SIEGE=>0.8],
['은밀하고 날쌥니다.'], ['은밀하고 날쌥니다.'],
null, ['che_방어력증가5p'], null null, ['che_방어력증가5p']
], ],
[ [
1104, self::T_FOOTMAN, '근위병', 1104, self::T_FOOTMAN, '근위병',
@@ -87,7 +87,7 @@ class GameUnitConstBase{
[self::T_ARCHER=>1.2, self::T_CAVALRY=>0.8, self::T_SIEGE=>1.2], [self::T_ARCHER=>1.2, self::T_CAVALRY=>0.8, self::T_SIEGE=>1.2],
[self::T_ARCHER=>0.8, self::T_CAVALRY=>1.2, self::T_SIEGE=>0.8], [self::T_ARCHER=>0.8, self::T_CAVALRY=>1.2, self::T_SIEGE=>0.8],
['최강의 보병입니다.'], ['최강의 보병입니다.'],
null, ['che_방어력증가5p'], null null, ['che_방어력증가5p']
], ],
[ [
1105, self::T_FOOTMAN, '등갑병', 1105, self::T_FOOTMAN, '등갑병',
@@ -96,7 +96,7 @@ class GameUnitConstBase{
[self::T_ARCHER=>1.2, self::T_CAVALRY=>0.8, self::T_SIEGE=>1.2], [self::T_ARCHER=>1.2, self::T_CAVALRY=>0.8, self::T_SIEGE=>1.2],
[self::T_ARCHER=>0.8, self::T_CAVALRY=>1.2, self::T_SIEGE=>0.8], [self::T_ARCHER=>0.8, self::T_CAVALRY=>1.2, self::T_SIEGE=>0.8],
['등갑을 두른 보병입니다.'], ['등갑을 두른 보병입니다.'],
null, ['che_방어력증가5p'], null null, ['che_방어력증가5p']
], ],
[ [
1106, self::T_FOOTMAN, '백이병', 1106, self::T_FOOTMAN, '백이병',
@@ -105,7 +105,7 @@ class GameUnitConstBase{
[self::T_ARCHER=>1.1, self::T_CAVALRY=>0.9, self::T_SIEGE=>1.1], [self::T_ARCHER=>1.1, self::T_CAVALRY=>0.9, self::T_SIEGE=>1.1],
[self::T_ARCHER=>0.9, self::T_CAVALRY=>1.1, self::T_SIEGE=>0.9], [self::T_ARCHER=>0.9, self::T_CAVALRY=>1.1, self::T_SIEGE=>0.9],
['정예 보병입니다. 불리한 싸움도 버텨냅니다.'], ['정예 보병입니다. 불리한 싸움도 버텨냅니다.'],
null, ['che_방어력증가5p'], null null, ['che_방어력증가5p']
], ],
[ [
@@ -115,7 +115,7 @@ class GameUnitConstBase{
[self::T_CAVALRY=>1.2, self::T_FOOTMAN=>0.8, self::T_SIEGE=>1.2], [self::T_CAVALRY=>1.2, self::T_FOOTMAN=>0.8, self::T_SIEGE=>1.2],
[self::T_CAVALRY=>0.8, self::T_FOOTMAN=>1.2, self::T_SIEGE=>0.8], [self::T_CAVALRY=>0.8, self::T_FOOTMAN=>1.2, self::T_SIEGE=>0.8],
['표준적인 궁병입니다.','궁병은 선제사격을 하는 병종입니다.'], ['표준적인 궁병입니다.','궁병은 선제사격을 하는 병종입니다.'],
null, ['che_선제사격시도', 'che_선제사격발동'], null null, ['che_선제사격시도', 'che_선제사격발동']
], ],
[ [
1201, self::T_ARCHER, '궁기병', 1201, self::T_ARCHER, '궁기병',
@@ -124,7 +124,7 @@ class GameUnitConstBase{
[self::T_CAVALRY=>1.2, self::T_FOOTMAN=>0.9, self::T_SIEGE=>1.2], [self::T_CAVALRY=>1.2, self::T_FOOTMAN=>0.9, self::T_SIEGE=>1.2],
[self::T_CAVALRY=>0.8, self::T_FOOTMAN=>1.1, self::T_SIEGE=>0.8], [self::T_CAVALRY=>0.8, self::T_FOOTMAN=>1.1, self::T_SIEGE=>0.8],
['말을 타고 잘 피합니다. 특히 다른 궁병보다 보병에게 조금 더 강합니다.'], ['말을 타고 잘 피합니다. 특히 다른 궁병보다 보병에게 조금 더 강합니다.'],
null, ['che_선제사격시도', 'che_선제사격발동'], null null, ['che_선제사격시도', 'che_선제사격발동']
], ],
[ [
1202, self::T_ARCHER, '연노병', 1202, self::T_ARCHER, '연노병',
@@ -133,7 +133,7 @@ class GameUnitConstBase{
[self::T_CAVALRY=>1.2, self::T_FOOTMAN=>0.8, self::T_SIEGE=>1.2], [self::T_CAVALRY=>1.2, self::T_FOOTMAN=>0.8, self::T_SIEGE=>1.2],
[self::T_CAVALRY=>0.8, self::T_FOOTMAN=>1.2, self::T_SIEGE=>0.8], [self::T_CAVALRY=>0.8, self::T_FOOTMAN=>1.2, self::T_SIEGE=>0.8],
['화살을 연사합니다.'], ['화살을 연사합니다.'],
null, ['che_선제사격시도', 'che_선제사격발동'], null null, ['che_선제사격시도', 'che_선제사격발동']
], ],
[ [
1203, self::T_ARCHER, '강궁병', 1203, self::T_ARCHER, '강궁병',
@@ -142,7 +142,7 @@ class GameUnitConstBase{
[self::T_CAVALRY=>1.2, self::T_FOOTMAN=>0.8, self::T_SIEGE=>1.2], [self::T_CAVALRY=>1.2, self::T_FOOTMAN=>0.8, self::T_SIEGE=>1.2],
[self::T_CAVALRY=>0.8, self::T_FOOTMAN=>1.2, self::T_SIEGE=>0.8], [self::T_CAVALRY=>0.8, self::T_FOOTMAN=>1.2, self::T_SIEGE=>0.8],
['강건한 궁병입니다.'], ['강건한 궁병입니다.'],
null, ['che_선제사격시도', 'che_선제사격발동'], null null, ['che_선제사격시도', 'che_선제사격발동']
], ],
[ [
1204, self::T_ARCHER, '석궁병', 1204, self::T_ARCHER, '석궁병',
@@ -151,7 +151,7 @@ class GameUnitConstBase{
[self::T_CAVALRY=>1.2, self::T_FOOTMAN=>0.8, self::T_SIEGE=>1.2], [self::T_CAVALRY=>1.2, self::T_FOOTMAN=>0.8, self::T_SIEGE=>1.2],
[self::T_CAVALRY=>0.8, self::T_FOOTMAN=>1.2, self::T_SIEGE=>0.8], [self::T_CAVALRY=>0.8, self::T_FOOTMAN=>1.2, self::T_SIEGE=>0.8],
['강력한 화살을 쏩니다.'], ['강력한 화살을 쏩니다.'],
null, ['che_선제사격시도', 'che_선제사격발동'], null null, ['che_선제사격시도', 'che_선제사격발동']
], ],
[ [
@@ -161,7 +161,7 @@ class GameUnitConstBase{
[self::T_FOOTMAN=>1.2, self::T_ARCHER=>0.8, self::T_SIEGE=>1.2], [self::T_FOOTMAN=>1.2, self::T_ARCHER=>0.8, self::T_SIEGE=>1.2],
[self::T_FOOTMAN=>0.8, self::T_ARCHER=>1.2, self::T_SIEGE=>0.8], [self::T_FOOTMAN=>0.8, self::T_ARCHER=>1.2, self::T_SIEGE=>0.8],
['표준적인 기병입니다.','기병은 공격특화입니다.'], ['표준적인 기병입니다.','기병은 공격특화입니다.'],
null, ['che_기병병종전투'], null null, ['che_기병병종전투']
], ],
[ [
1301, self::T_CAVALRY, '백마병', 1301, self::T_CAVALRY, '백마병',
@@ -170,7 +170,7 @@ class GameUnitConstBase{
[self::T_FOOTMAN=>1.2, self::T_ARCHER=>0.8, self::T_SIEGE=>1.2], [self::T_FOOTMAN=>1.2, self::T_ARCHER=>0.8, self::T_SIEGE=>1.2],
[self::T_FOOTMAN=>0.8, self::T_ARCHER=>1.2, self::T_SIEGE=>0.8], [self::T_FOOTMAN=>0.8, self::T_ARCHER=>1.2, self::T_SIEGE=>0.8],
['백마의 위용을 보여줍니다.'], ['백마의 위용을 보여줍니다.'],
null, ['che_기병병종전투'], null null, ['che_기병병종전투']
], ],
[ [
1302, self::T_CAVALRY, '중장기병', 1302, self::T_CAVALRY, '중장기병',
@@ -179,7 +179,7 @@ class GameUnitConstBase{
[self::T_FOOTMAN=>1.2, self::T_ARCHER=>0.8, self::T_SIEGE=>1.2], [self::T_FOOTMAN=>1.2, self::T_ARCHER=>0.8, self::T_SIEGE=>1.2],
[self::T_FOOTMAN=>0.8, self::T_ARCHER=>1.2, self::T_SIEGE=>0.8], [self::T_FOOTMAN=>0.8, self::T_ARCHER=>1.2, self::T_SIEGE=>0.8],
['갑주를 두른 기병입니다.'], ['갑주를 두른 기병입니다.'],
null, ['che_기병병종전투'], null null, ['che_기병병종전투']
], ],
[ [
1303, self::T_CAVALRY, '돌격기병', 1303, self::T_CAVALRY, '돌격기병',
@@ -188,7 +188,7 @@ class GameUnitConstBase{
[self::T_FOOTMAN=>1.2, self::T_ARCHER=>0.8, self::T_SIEGE=>1.2], [self::T_FOOTMAN=>1.2, self::T_ARCHER=>0.8, self::T_SIEGE=>1.2],
[self::T_FOOTMAN=>0.8, self::T_ARCHER=>1.2, self::T_SIEGE=>0.8], [self::T_FOOTMAN=>0.8, self::T_ARCHER=>1.2, self::T_SIEGE=>0.8],
['저돌적으로 공격합니다.'], ['저돌적으로 공격합니다.'],
null, ['che_기병병종전투'], null null, ['che_기병병종전투']
], ],
[ [
1304, self::T_CAVALRY, '철기병', 1304, self::T_CAVALRY, '철기병',
@@ -197,7 +197,7 @@ class GameUnitConstBase{
[self::T_FOOTMAN=>1.2, self::T_ARCHER=>0.8, self::T_SIEGE=>1.2], [self::T_FOOTMAN=>1.2, self::T_ARCHER=>0.8, self::T_SIEGE=>1.2],
[self::T_FOOTMAN=>0.8, self::T_ARCHER=>1.2, self::T_SIEGE=>0.8], [self::T_FOOTMAN=>0.8, self::T_ARCHER=>1.2, self::T_SIEGE=>0.8],
['철갑을 두른 기병입니다.'], ['철갑을 두른 기병입니다.'],
null, ['che_기병병종전투'], null null, ['che_기병병종전투']
], ],
[ [
1305, self::T_CAVALRY, '수렵기병', 1305, self::T_CAVALRY, '수렵기병',
@@ -206,7 +206,7 @@ class GameUnitConstBase{
[self::T_FOOTMAN=>1.2, self::T_ARCHER=>0.8, self::T_SIEGE=>1.2], [self::T_FOOTMAN=>1.2, self::T_ARCHER=>0.8, self::T_SIEGE=>1.2],
[self::T_FOOTMAN=>0.8, self::T_ARCHER=>1.2, self::T_SIEGE=>0.8], [self::T_FOOTMAN=>0.8, self::T_ARCHER=>1.2, self::T_SIEGE=>0.8],
['날쎄고 빠른 기병입니다.'], ['날쎄고 빠른 기병입니다.'],
null, ['che_기병병종전투'], null null, ['che_기병병종전투']
], ],
[ [
1306, self::T_CAVALRY, '맹수병', 1306, self::T_CAVALRY, '맹수병',
@@ -215,7 +215,7 @@ class GameUnitConstBase{
[self::T_FOOTMAN=>1.2, self::T_ARCHER=>0.8, self::T_SIEGE=>1.2], [self::T_FOOTMAN=>1.2, self::T_ARCHER=>0.8, self::T_SIEGE=>1.2],
[self::T_FOOTMAN=>0.8, self::T_ARCHER=>1.2, self::T_SIEGE=>0.8], [self::T_FOOTMAN=>0.8, self::T_ARCHER=>1.2, self::T_SIEGE=>0.8],
['어느 누구보다 강력합니다.'], ['어느 누구보다 강력합니다.'],
null, ['che_기병병종전투'], null null, ['che_기병병종전투']
], ],
[ [
1307, self::T_CAVALRY, '호표기병', 1307, self::T_CAVALRY, '호표기병',
@@ -224,7 +224,7 @@ class GameUnitConstBase{
[self::T_FOOTMAN=>1.2, self::T_ARCHER=>0.8, self::T_SIEGE=>1.2], [self::T_FOOTMAN=>1.2, self::T_ARCHER=>0.8, self::T_SIEGE=>1.2],
[self::T_FOOTMAN=>0.8, self::T_ARCHER=>1.2, self::T_SIEGE=>0.8], [self::T_FOOTMAN=>0.8, self::T_ARCHER=>1.2, self::T_SIEGE=>0.8],
['정예 기병입니다.'], ['정예 기병입니다.'],
null, ['che_기병병종전투'], null null, ['che_기병병종전투']
], ],
[ [
@@ -234,7 +234,7 @@ class GameUnitConstBase{
[self::T_SIEGE=>1.2], [self::T_SIEGE=>1.2],
[self::T_SIEGE=>0.8], [self::T_SIEGE=>0.8],
['계략을 사용하는 병종입니다.'], ['계략을 사용하는 병종입니다.'],
null, null, null null, null
], ],
[ [
1401, self::T_WIZARD, '신귀병', 1401, self::T_WIZARD, '신귀병',
@@ -243,7 +243,7 @@ class GameUnitConstBase{
[self::T_SIEGE=>1.2], [self::T_SIEGE=>1.2],
[self::T_SIEGE=>0.8], [self::T_SIEGE=>0.8],
['신출귀몰한 귀병입니다.'], ['신출귀몰한 귀병입니다.'],
null, null, null null, null
], ],
[ [
1402, self::T_WIZARD, '백귀병', 1402, self::T_WIZARD, '백귀병',
@@ -252,7 +252,7 @@ class GameUnitConstBase{
[self::T_SIEGE=>1.2], [self::T_SIEGE=>1.2],
[self::T_SIEGE=>0.8], [self::T_SIEGE=>0.8],
['저렴하고 튼튼합니다.'], ['저렴하고 튼튼합니다.'],
null, null, null null, null
], ],
[ [
1403, self::T_WIZARD, '흑귀병', 1403, self::T_WIZARD, '흑귀병',
@@ -261,7 +261,7 @@ class GameUnitConstBase{
[self::T_SIEGE=>1.2], [self::T_SIEGE=>1.2],
[self::T_SIEGE=>0.8], [self::T_SIEGE=>0.8],
['저렴하고 강력합니다.'], ['저렴하고 강력합니다.'],
null, null, null null, null
], ],
[ [
1404, self::T_WIZARD, '악귀병', 1404, self::T_WIZARD, '악귀병',
@@ -270,7 +270,7 @@ class GameUnitConstBase{
[self::T_SIEGE=>1.2], [self::T_SIEGE=>1.2],
[self::T_SIEGE=>0.8], [self::T_SIEGE=>0.8],
['백병전에도 능숙합니다.'], ['백병전에도 능숙합니다.'],
null, null, null null, null
], ],
[ [
1405, self::T_WIZARD, '남귀병', 1405, self::T_WIZARD, '남귀병',
@@ -279,7 +279,7 @@ class GameUnitConstBase{
[self::T_SIEGE=>1.2], [self::T_SIEGE=>1.2],
[self::T_SIEGE=>0.8], [self::T_SIEGE=>0.8],
['전투를 포기하고 계략에 몰두합니다.'], ['전투를 포기하고 계략에 몰두합니다.'],
null, null, null null, null
], ],
[ [
1406, self::T_WIZARD, '황귀병', 1406, self::T_WIZARD, '황귀병',
@@ -288,7 +288,7 @@ class GameUnitConstBase{
[self::T_SIEGE=>1.2], [self::T_SIEGE=>1.2],
[self::T_SIEGE=>0.8], [self::T_SIEGE=>0.8],
['고도로 훈련된 귀병입니다.'], ['고도로 훈련된 귀병입니다.'],
null, null, null null, null
], ],
[ [
1407, self::T_WIZARD, '천귀병', 1407, self::T_WIZARD, '천귀병',
@@ -297,7 +297,7 @@ class GameUnitConstBase{
[self::T_SIEGE=>1.2], [self::T_SIEGE=>1.2],
[self::T_SIEGE=>0.8], [self::T_SIEGE=>0.8],
['갑주를 두른 귀병입니다.'], ['갑주를 두른 귀병입니다.'],
null, null, null null, null
], ],
[ [
1408, self::T_WIZARD, '마귀병', 1408, self::T_WIZARD, '마귀병',
@@ -306,7 +306,7 @@ class GameUnitConstBase{
[self::T_SIEGE=>1.2], [self::T_SIEGE=>1.2],
[self::T_SIEGE=>0.8], [self::T_SIEGE=>0.8],
['날카로운 무기를 가진 귀병입니다.'], ['날카로운 무기를 가진 귀병입니다.'],
null, null, null null, null
], ],
[ [
@@ -314,9 +314,9 @@ class GameUnitConstBase{
100, 100, 6, 0, 0, 14, 5, 100, 100, 6, 0, 0, 14, 5,
0, null, null, 3, 0, null, null, 3,
[self::T_FOOTMAN=>1.25, self::T_ARCHER=>1.25, self::T_CAVALRY=>1.25, self::T_WIZARD=>1.25, self::T_CASTLE=>1.8, 1106=>1.112], [self::T_FOOTMAN=>1.25, self::T_ARCHER=>1.25, self::T_CAVALRY=>1.25, self::T_WIZARD=>1.25, self::T_CASTLE=>1.8, 1106=>1.112],
[self::T_FOOTMAN=>1.2, self::T_ARCHER=>1.2, self::T_CAVALRY=>1.2, self::T_WIZARD=>1.2, 1106=>1.067], [self::T_FOOTMAN=>1.2, self::T_ARCHER=>1.2, self::T_CAVALRY=>1.2, self::T_WIZARD=>1.2],
['높은 구조물 위에서 공격합니다. 첫 공격은 성벽을 향합니다.'], ['높은 구조물 위에서 공격합니다.'],
['che_성벽부상무효'], ['che_선제사격시도', 'che_선제사격발동'], ['che_성벽선제'] ['che_성벽부상무효'], ['che_선제사격시도', 'che_선제사격발동']
], ],
[ [
1501, self::T_SIEGE, '충차', 1501, self::T_SIEGE, '충차',
@@ -325,25 +325,25 @@ class GameUnitConstBase{
[self::T_FOOTMAN=>0.8, self::T_ARCHER=>0.8, self::T_CAVALRY=>0.8, self::T_WIZARD=>0.8, self::T_CASTLE=>2.4], [self::T_FOOTMAN=>0.8, self::T_ARCHER=>0.8, self::T_CAVALRY=>0.8, self::T_WIZARD=>0.8, self::T_CASTLE=>2.4],
[self::T_FOOTMAN=>1.2, self::T_ARCHER=>1.2, self::T_CAVALRY=>1.2, self::T_WIZARD=>1.2], [self::T_FOOTMAN=>1.2, self::T_ARCHER=>1.2, self::T_CAVALRY=>1.2, self::T_WIZARD=>1.2],
['엄청난 위력으로 성벽을 부수어버립니다.'], ['엄청난 위력으로 성벽을 부수어버립니다.'],
['che_성벽부상무효'], null, null ['che_성벽부상무효'], null
], ],
[ [
1502, self::T_SIEGE, '벽력거', 1502, self::T_SIEGE, '벽력거',
150, 100, 6, 5, 0, 20, 5, 150, 100, 6, 5, 0, 20, 5,
3000, ['업'], null, 0, 3000, ['업'], null, 0,
[self::T_FOOTMAN=>1.25, self::T_ARCHER=>1.25, self::T_CAVALRY=>1.25, self::T_WIZARD=>1.25, self::T_CASTLE=>1.8, 1106=>1.112], [self::T_FOOTMAN=>1.25, self::T_ARCHER=>1.25, self::T_CAVALRY=>1.25, self::T_WIZARD=>1.25, self::T_CASTLE=>1.8, 1106=>1.112],
[self::T_FOOTMAN=>1.2, self::T_ARCHER=>1.2, self::T_CAVALRY=>1.2, self::T_WIZARD=>1.2, 1106=>1.067], [self::T_FOOTMAN=>0.833, self::T_ARCHER=>0.833, self::T_CAVALRY=>0.833, self::T_WIZARD=>0.833, 1106=>0.909],
['상대에게 돌덩이를 날립니다. 첫 공격은 성벽을 향합니다.'], ['상대에게 돌덩이를 날립니다.'],
['che_성벽부상무효'], ['che_선제사격시도', 'che_선제사격발동'], ['che_성벽선제'] ['che_성벽부상무효'], ['che_선제사격시도', 'che_선제사격발동']
], ],
[ [
1503, self::T_SIEGE, '목우', 1503, self::T_SIEGE, '목우',
50, 200, 5, 0, 0, 15, 5, 50, 200, 5, 0, 0, 15, 5,
3000, ['성도'], null, 0, 3000, ['성도'], null, 0,
[self::T_FOOTMAN=>1, self::T_ARCHER=>1, self::T_CAVALRY=>1, self::T_WIZARD=>1, self::T_CASTLE=>1.8], [self::T_FOOTMAN=>1.25, self::T_ARCHER=>1.25, self::T_CAVALRY=>1.25, self::T_WIZARD=>1.25, self::T_CASTLE=>1.8, 1106=>1.112],
[self::T_FOOTMAN=>1, self::T_ARCHER=>1, self::T_CAVALRY=>1, self::T_WIZARD=>1, 1106=>1], [self::T_FOOTMAN=>1, self::T_ARCHER=>1, self::T_CAVALRY=>1, self::T_WIZARD=>1, 1106=>1],
['상대를 저지하는 특수병기입니다.'], ['상대를 저지하는 특수병기입니다.'],
['che_성벽부상무효'], ['che_저지시도', 'che_저지발동'], null ['che_성벽부상무효'], ['che_저지시도', 'che_저지발동']
] ]
]; ];
@@ -466,7 +466,6 @@ class GameUnitConstBase{
$info, $info,
$initSkillTrigger, $initSkillTrigger,
$phaseSkillTrigger, $phaseSkillTrigger,
$iActionList,
] = $rawUnit; ] = $rawUnit;
if($reqYear > 0){ if($reqYear > 0){
@@ -510,8 +509,7 @@ class GameUnitConstBase{
$defenceCoef, $defenceCoef,
$info, $info,
$initSkillTrigger, $initSkillTrigger,
$phaseSkillTrigger, $phaseSkillTrigger
$iActionList,
); );
$constID[$id] = $unit; $constID[$id] = $unit;
+65 -166
View File
@@ -1,9 +1,7 @@
<?php <?php
namespace sammo; namespace sammo;
class GameUnitDetail implements iAction class GameUnitDetail implements iAction{
{
use DefaultAction; use DefaultAction;
public $id; public $id;
@@ -25,8 +23,6 @@ class GameUnitDetail implements iAction
public $info; public $info;
public $initSkillTrigger; public $initSkillTrigger;
public $phaseSkillTrigger; public $phaseSkillTrigger;
/** @var iAction[]|null iActionList */
public $iActionList;
public function __construct( public function __construct(
int $id, int $id,
@@ -47,9 +43,8 @@ class GameUnitDetail implements iAction
array $defenceCoef, array $defenceCoef,
array $info, array $info,
?array $initSkillTrigger, ?array $initSkillTrigger,
?array $phaseSkillTrigger, ?array $phaseSkillTrigger
?array $iActionList, ){
) {
$this->id = $id; $this->id = $id;
$this->name = $name; $this->name = $name;
$this->armType = $armType; $this->armType = $armType;
@@ -69,91 +64,78 @@ class GameUnitDetail implements iAction
$this->info = $info; $this->info = $info;
$this->initSkillTrigger = $initSkillTrigger; $this->initSkillTrigger = $initSkillTrigger;
$this->phaseSkillTrigger = $phaseSkillTrigger; $this->phaseSkillTrigger = $phaseSkillTrigger;
$this->iActionList = [];
foreach($iActionList ?? [] as $rawAction){
$action = buildActionCrewTypeClass($rawAction);
if(!$action){
continue;
}
$this->iActionList[] = $action;
}
} }
public function getInfo(): string public function getInfo():string{
{
return join("\n<br>", $this->info); return join("\n<br>", $this->info);
} }
public function getShortName(): string public function getShortName():string{
{
return StringUtil::subStringForWidth($this->name, 0, 4); return StringUtil::subStringForWidth($this->name, 0, 4);
} }
public function riceWithTech(int $tech, int $crew = 100): float public function riceWithTech(int $tech, int $crew=100):float{
{
return $this->rice * getTechCost($tech) * $crew / 100; return $this->rice * getTechCost($tech) * $crew / 100;
} }
public function costWithTech(int $tech, int $crew = 100): float public function costWithTech(int $tech, int $crew=100):float{
{
return $this->cost * getTechCost($tech) * $crew / 100; return $this->cost * getTechCost($tech) * $crew / 100;
} }
public function getAttackCoef(GameUnitDetail $opposeCrewType): float public function getAttackCoef(GameUnitDetail $opposeCrewType):float{
{
$opposeCrewTypeID = $opposeCrewType->id; $opposeCrewTypeID = $opposeCrewType->id;
if (key_exists($opposeCrewTypeID, $this->attackCoef)) { if(key_exists($opposeCrewTypeID, $this->attackCoef)){
return $this->attackCoef[$opposeCrewTypeID]; return $this->attackCoef[$opposeCrewTypeID];
} }
$opposeArmType = $opposeCrewType->armType; $opposeArmType = $opposeCrewType->armType;
return $this->attackCoef[$opposeArmType] ?? 1; return $this->attackCoef[$opposeArmType]??1;
} }
public function getDefenceCoef(GameUnitDetail $opposeCrewType): float public function getDefenceCoef(GameUnitDetail $opposeCrewType):float{
{
$opposeCrewTypeID = $opposeCrewType->id; $opposeCrewTypeID = $opposeCrewType->id;
if (key_exists($opposeCrewTypeID, $this->defenceCoef)) { if(key_exists($opposeCrewTypeID, $this->defenceCoef)){
return $this->defenceCoef[$opposeCrewTypeID]; return $this->defenceCoef[$opposeCrewTypeID];
} }
$opposeArmType = $opposeCrewType->armType; $opposeArmType = $opposeCrewType->armType;
return $this->defenceCoef[$opposeArmType] ?? 1; return $this->defenceCoef[$opposeArmType]??1;
} }
public function getComputedAttack(General $general, int $tech) public function getComputedAttack(General $general, int $tech){
{ if($this->armType == GameUnitConst::T_WIZARD){
if ($this->armType == GameUnitConst::T_WIZARD) { $ratio = $general->getIntel(true, true, true)*2 - 40;
$ratio = $general->getIntel(true, true, true) * 2 - 40; }
} else if ($this->armType == GameUnitConst::T_SIEGE) { else if($this->armType == GameUnitConst::T_SIEGE){
$ratio = $general->getLeadership(true, true, true) * 2 - 40; $ratio = $general->getLeadership(true, true, true)*2 - 40;
} else if ($this->armType == GameUnitConst::T_MISC) { }
else if($this->armType == GameUnitConst::T_MISC){
$ratio = $general->getIntel(true, true, true) + $ratio = $general->getIntel(true, true, true) +
$general->getLeadership(true, true, true) + $general->getLeadership(true, true, true) +
$general->getStrength(true, true, true); $general->getStrength(true, true, true);
$ratio = $ratio * 2 / 3 - 40; $ratio = $ratio*2/3 - 40;
} else {
$ratio = $general->getStrength(true, true, true) * 2 - 40;
} }
if ($ratio < 10) { else{
$ratio = $general->getStrength(true, true, true)*2 - 40;
}
if($ratio < 10){
$ratio = 10; $ratio = 10;
} }
if ($ratio > 100) { if($ratio > 100){
$ratio = 50 + $ratio / 2; $ratio = 50 + $ratio/2;
} }
$att = $this->attack + getTechAbil($tech); $att = $this->attack + getTechAbil($tech);
return $att * $ratio / 100; return $att * $ratio / 100;
} }
public function getComputedDefence(General $general, int $tech) public function getComputedDefence(General $general, int $tech){
{
$def = $this->defence + getTechAbil($tech); $def = $this->defence + getTechAbil($tech);
$crew = ($general->getVar('crew') / (7000 / 30)) + 70; $crew = ($general->getVar('crew') / (7000 / 30)) + 70;
return $def * $crew / 100; return $def * $crew / 100;
} }
public function getCriticalRatio(General $general) public function getCriticalRatio(General $general){
{ if($this->armType == GameUnitConst::T_CASTLE){
if ($this->armType == GameUnitConst::T_CASTLE) {
//성벽은 필살을 사용하지 않는다. //성벽은 필살을 사용하지 않는다.
return 0; return 0;
} }
@@ -161,19 +143,22 @@ class GameUnitDetail implements iAction
// 무장 무력 : 65 5%, 70 10%, 75 15%, 80 20% // 무장 무력 : 65 5%, 70 10%, 75 15%, 80 20%
// 지장 지력 : 65 5%, 70 8%, 75 10%, 80 13% // 지장 지력 : 65 5%, 70 8%, 75 10%, 80 13%
//충차장 통솔: 65 5%, 70 8%, 75 10%, 80 13% //충차장 통솔: 65 5%, 70 8%, 75 10%, 80 13%
if ($this->armType == GameUnitConst::T_WIZARD) { if($this->armType == GameUnitConst::T_WIZARD){
$mainstat = $general->getIntel(false, true, true, false); $mainstat = $general->getIntel(false, true, true, false);
$coef = 0.4; $coef = 0.4;
} else if ($this->armType == GameUnitConst::T_SIEGE) { }
else if($this->armType == GameUnitConst::T_SIEGE){
$mainstat = $general->getLeadership(false, true, true, false); $mainstat = $general->getLeadership(false, true, true, false);
$coef = 0.4; $coef = 0.4;
} else if ($this->armType == GameUnitConst::T_MISC) { }
else if($this->armType == GameUnitConst::T_MISC){
$mainstat = $general->getIntel(false, true, true, false) + $mainstat = $general->getIntel(false, true, true, false) +
$general->getLeadership(false, true, true, false) + $general->getLeadership(false, true, true, false) +
$general->getStrength(false, true, true, false); $general->getStrength(false, true, true, false);
$mainstat /= 3; $mainstat /= 3;
$coef = 0.4; $coef = 0.4;
} else { }
else{
$mainstat = $general->getStrength(false, true, true, false); $mainstat = $general->getStrength(false, true, true, false);
$coef = 0.5; $coef = 0.5;
} }
@@ -184,8 +169,7 @@ class GameUnitDetail implements iAction
return min(50, $ratio) / 100; return min(50, $ratio) / 100;
} }
public function pickScore($tech) public function pickScore($tech){
{
$defaultWar = GameConst::$armperphase + $this->attack + $this->defence + getTechAbil($tech) * 2; $defaultWar = GameConst::$armperphase + $this->attack + $this->defence + getTechAbil($tech) * 2;
$defaultWar *= 1 + $this->speed / 2; $defaultWar *= 1 + $this->speed / 2;
$defaultWar /= Util::valueFit(1 - $this->avoid / 100, 0.1); $defaultWar /= Util::valueFit(1 - $this->avoid / 100, 0.1);
@@ -193,41 +177,40 @@ class GameUnitDetail implements iAction
return $defaultWar; return $defaultWar;
} }
public function isValid($ownCities, $ownRegions, $relativeYear, $tech) public function isValid($ownCities, $ownRegions, $relativeYear, $tech){
{
//음수 없음 //음수 없음
$relativeYear = max(0, $relativeYear); $relativeYear = max(0, $relativeYear);
if ($relativeYear < $this->reqYear) { if($relativeYear < $this->reqYear){
return false; return false;
} }
if ($tech < $this->reqTech) { if($tech < $this->reqTech){
return false; return false;
} }
if ($this->reqCities !== null) { if($this->reqCities !== null){
$valid = false; $valid = false;
foreach ($this->reqCities as $reqCity) { foreach($this->reqCities as $reqCity){
if (\key_exists($reqCity, $ownCities)) { if(\key_exists($reqCity, $ownCities)){
$valid = true; $valid = true;
break; break;
} }
} }
if (!$valid) { if(!$valid){
return false; return false;
} }
} }
if ($this->reqRegions !== null) { if($this->reqRegions !== null){
$valid = false; $valid = false;
foreach ($this->reqRegions as $reqRegion) { foreach($this->reqRegions as $reqRegion){
if (\key_exists($reqRegion, $ownRegions)) { if(\key_exists($reqRegion, $ownRegions)){
$valid = true; $valid = true;
break; break;
} }
} }
if (!$valid) { if(!$valid){
return false; return false;
} }
} }
@@ -236,17 +219,17 @@ class GameUnitDetail implements iAction
} }
//iAction //iAction
public function getBattleInitSkillTriggerList(WarUnit $unit): ?WarUnitTriggerCaller public function getBattleInitSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
{ if(!$this->initSkillTrigger){
if (!$this->initSkillTrigger) {
return null; return null;
} }
$triggerList = []; $triggerList = [];
foreach ($this->initSkillTrigger as $triggerArgs) { foreach($this->initSkillTrigger as $triggerArgs){
if (is_string($triggerArgs)) { if(is_string($triggerArgs)){
$typeName = $triggerArgs; $typeName = $triggerArgs;
$triggerList[] = buildWarUnitTriggerClass($typeName, $unit); $triggerList[] = buildWarUnitTriggerClass($typeName, $unit);
} else { }
else{
$typeName = $triggerArgs[0]; $typeName = $triggerArgs[0];
//WarUnit 다음 인자는 $raiseType이며, 0이어야할 것이다 //WarUnit 다음 인자는 $raiseType이며, 0이어야할 것이다
$triggerArgs[0] = 0; $triggerArgs[0] = 0;
@@ -255,17 +238,17 @@ class GameUnitDetail implements iAction
} }
return new WarUnitTriggerCaller(...$triggerList); return new WarUnitTriggerCaller(...$triggerList);
} }
public function getBattlePhaseSkillTriggerList(WarUnit $unit): ?WarUnitTriggerCaller public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
{ if(!$this->phaseSkillTrigger){
if (!$this->phaseSkillTrigger) {
return null; return null;
} }
$triggerList = []; $triggerList = [];
foreach ($this->phaseSkillTrigger as $triggerArgs) { foreach($this->phaseSkillTrigger as $triggerArgs){
if (is_string($triggerArgs)) { if(is_string($triggerArgs)){
$typeName = $triggerArgs; $typeName = $triggerArgs;
$triggerList[] = buildWarUnitTriggerClass($typeName, $unit); $triggerList[] = buildWarUnitTriggerClass($typeName, $unit);
} else { }
else{
$typeName = $triggerArgs[0]; $typeName = $triggerArgs[0];
//WarUnit 다음 인자는 $raiseType이며, 0이어야할 것이다 //WarUnit 다음 인자는 $raiseType이며, 0이어야할 것이다
$triggerArgs[0] = 0; $triggerArgs[0] = 0;
@@ -273,90 +256,6 @@ class GameUnitDetail implements iAction
} }
} }
return new WarUnitTriggerCaller(...$triggerList); return new WarUnitTriggerCaller(...$triggerList);
}
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux = null): float
{
if (!$this->iActionList) {
return $value;
}
foreach ($this->iActionList as $iAction) {
$value = $iAction->onCalcDomestic($turnType, $varType, $value, $aux);
}
return $value;
}
public function onCalcStat(General $general, string $statName, $value, $aux = null)
{
if (!$this->iActionList) {
return $value;
}
foreach ($this->iActionList as $iAction) {
$value = $iAction->onCalcStat($general, $statName, $value, $aux);
}
return $value;
}
public function onCalcOpposeStat(General $general, string $statName, $value, $aux = null)
{
if (!$this->iActionList) {
return $value;
}
foreach ($this->iActionList as $iAction) {
$value = $iAction->onCalcOpposeStat($general, $statName, $value, $aux);
}
return $value;
}
public function onCalcStrategic(string $turnType, string $varType, $value)
{
if (!$this->iActionList) {
return $value;
}
foreach ($this->iActionList as $iAction) {
$value = $iAction->onCalcStrategic($turnType, $varType, $value);
}
return $value;
}
public function onCalcNationalIncome(string $type, $amount)
{
if (!$this->iActionList) {
return $amount;
}
foreach ($this->iActionList as $iAction) {
$amount = $iAction->onCalcNationalIncome($type, $amount);
}
return $amount;
}
public function getWarPowerMultiplier(WarUnit $unit): array
{
if (!$this->iActionList) {
return [1, 1];
}
$attack = 1;
$defence = 1;
foreach ($this->iActionList as $iAction) {
$attack *= $iAction->getWarPowerMultiplier($unit)[0];
$defence *= $iAction->getWarPowerMultiplier($unit)[1];
}
return [$attack, $defence];
}
public function onArbitraryAction(General $general, RandUtil $rng, string $actionType, ?string $phase = null, ?array $aux = null): null|array
{
if (!$this->iActionList) {
return $aux;
}
foreach ($this->iActionList as $iAction) {
$aux = $iAction->onArbitraryAction($general, $rng, $actionType, $phase, $aux);
}
return $aux;
} }
} }

Some files were not shown because too many files have changed in this diff Show More