Compare commits
10
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
84b0b69b67
|
||
|
|
47a4144757
|
||
|
|
625cf81f1f
|
||
|
|
0b8e91efe8
|
||
|
|
8db7aa3528
|
||
|
|
726679c933
|
||
|
|
ec9e7be5d8
|
||
|
|
43ee0015ea
|
||
|
|
a146735007
|
||
|
|
46bf5531d9
|
@@ -29,7 +29,6 @@ d_pic/*.jpg
|
||||
d_pic/*.gif
|
||||
d_pic/*.png
|
||||
d_pic/*.webp
|
||||
d_pic/*.avif
|
||||
d_pic/uploaded_image
|
||||
|
||||
/dist_js
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"brandonwamboldt/utilphp": "^1.1",
|
||||
"sergeytsalkov/meekrodb": "^2.5",
|
||||
"league/plates": "^3.5",
|
||||
"vlucas/valitron": "^1.4",
|
||||
|
||||
Generated
+52
-2
@@ -4,8 +4,58 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "7edae9b6be35e66ffd0d180f5fac6679",
|
||||
"content-hash": "deed9afdc95bc42f84784df67d295223",
|
||||
"packages": [
|
||||
{
|
||||
"name": "brandonwamboldt/utilphp",
|
||||
"version": "1.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/brandonwamboldt/utilphp.git",
|
||||
"reference": "36c32efc4f0679c05163464a550f45c8d83fe683"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/brandonwamboldt/utilphp/zipball/36c32efc4f0679c05163464a550f45c8d83fe683",
|
||||
"reference": "36c32efc4f0679c05163464a550f45c8d83fe683",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"satooshi/php-coveralls": "dev-master"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"utilphp\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Brandon Wamboldt",
|
||||
"email": "brandon.wamboldt@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "util.php is a collection of useful functions and snippets that you need or could use every day, designed to avoid conflicts with existing projects",
|
||||
"homepage": "https://github.com/brandonwamboldt/utilphp",
|
||||
"keywords": [
|
||||
"collection",
|
||||
"helpers",
|
||||
"php",
|
||||
"utility"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/brandonwamboldt/utilphp/issues",
|
||||
"source": "https://github.com/brandonwamboldt/utilphp/tree/master"
|
||||
},
|
||||
"time": "2015-02-02T17:56:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "brick/math",
|
||||
"version": "0.12.1",
|
||||
@@ -5671,5 +5721,5 @@
|
||||
"platform-overrides": {
|
||||
"php": "8.3"
|
||||
},
|
||||
"plugin-api-version": "2.6.0"
|
||||
"plugin-api-version": "2.3.0"
|
||||
}
|
||||
|
||||
Binary file not shown.
+1
-4
@@ -99,10 +99,7 @@ function logError(string $err, string $errstr, string $errpath, array $trace)
|
||||
$err = str_replace(ROOT, '{ROOT}', $err);
|
||||
$errstr = str_replace(ROOT, '{ROOT}', $errstr);
|
||||
$errpath = str_replace(ROOT, '{ROOT}', $errpath);
|
||||
$trace = array_map(function (string|array $text) {
|
||||
if (is_array($text)) {
|
||||
$text = Json::encode($text);
|
||||
}
|
||||
$trace = array_map(function (string $text) {
|
||||
return str_replace(ROOT, '{ROOT}', $text);
|
||||
}, $trace);
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ $rootDB->insert('member', [
|
||||
'token_valid_until' => '2999-01-01 00:00:00',
|
||||
'pw' => $finalPassword,
|
||||
'salt' => $userSalt,
|
||||
'grade' => 7,
|
||||
'grade' => 6,
|
||||
'name' => $nickname,
|
||||
'reg_date' => $nowDate
|
||||
]);
|
||||
|
||||
@@ -92,14 +92,4 @@ CREATE TABLE `login_token` (
|
||||
INDEX `by_date` (`user_id`, `expire_date`)
|
||||
)
|
||||
COLLATE='utf8mb4_general_ci'
|
||||
ENGINE=Aria;
|
||||
|
||||
CREATE TABLE `banned_member` (
|
||||
`no` INT NOT NULL AUTO_INCREMENT,
|
||||
`hashed_email` VARCHAR(128) NOT NULL COLLATE 'utf8mb4_general_ci' COMMENT 'SHA512(salt | email | salt )',
|
||||
`info` TEXT NULL COLLATE 'utf8mb4_general_ci' COMMENT '부가정보',
|
||||
PRIMARY KEY (`no`),
|
||||
UNIQUE INDEX `email` (`hashed_email`(128))
|
||||
)
|
||||
COLLATE='utf8mb4_general_ci'
|
||||
ENGINE = Aria;
|
||||
ENGINE=Aria;
|
||||
+2
-5
@@ -13,9 +13,6 @@ $db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
[$turntime, $tnmt_time] = $gameStor->getValuesAsArray(['turntime','tnmt_time']);
|
||||
$clock = GameClock::fromStorage($gameStor);
|
||||
$turntimeDisplay = $clock->formatTick(Util::toInt($turntime), true);
|
||||
$tnmtTimeDisplay = $tnmt_time === null ? '-' : $clock->formatTick(Util::toInt($tnmt_time), true);
|
||||
|
||||
$plock = $db->queryFirstField('SELECT plock FROM plock WHERE `type` ="GAME"');
|
||||
?>
|
||||
@@ -33,8 +30,8 @@ $plock = $db->queryFirstField('SELECT plock FROM plock WHERE `type` ="GAME"');
|
||||
</head>
|
||||
<body>
|
||||
<form action=_119_b.php method=post>
|
||||
시간조정 : <input type=text size=3 name=minute><input type=submit name=btn value='분당김'><input type=submit name=btn value='분지연'> 최종갱신 : <?=$turntimeDisplay?> (tick <?=$turntime?>)<br>
|
||||
시간조정 : <input type=text size=3 name=minute2><input type=submit name=btn value='토너분당김'><input type=submit name=btn value='토너분지연'> 토너먼트 : <?=$tnmtTimeDisplay?> (tick <?=$tnmt_time?>)<br>
|
||||
시간조정 : <input type=text size=3 name=minute><input type=submit name=btn value='분당김'><input type=submit name=btn value='분지연'> 최종갱신 : <?=$turntime?><br>
|
||||
시간조정 : <input type=text size=3 name=minute2><input type=submit name=btn value='토너분당김'><input type=submit name=btn value='토너분지연'> 토너먼트 : <?=$tnmt_time?><br>
|
||||
봉급지급 : <input type=submit name=btn value='금지급'><input type=submit name=btn value='쌀지급'><br>
|
||||
락 풀 기 : <input type=submit name=btn value='락걸기'><input type=submit name=btn value='락풀기'> 현재 : <?=$plock>0?"동결중":"가동중"?><br>
|
||||
</form>
|
||||
|
||||
+36
-9
@@ -38,9 +38,21 @@ switch ($btn) {
|
||||
usleep(500000);
|
||||
}
|
||||
|
||||
$clock = GameClock::fromStorage($gameStor);
|
||||
// 스케줄 전체를 벽시계에서 빼지 않고 논리 현재 tick만 앞으로 이동합니다.
|
||||
$clock->advance($gameStor, $clock->ticksFromMinutes($minute));
|
||||
$gameStor->cacheValues(['turntime', 'starttime', 'tnmt_time']);
|
||||
$turntime = (new \DateTimeImmutable($gameStor->turntime))->sub(new \DateInterval("PT{$minute}M"));
|
||||
$starttime = (new \DateTimeImmutable($gameStor->starttime))->sub(new \DateInterval("PT{$minute}M"));
|
||||
$tnmt_time = (new \DateTimeImmutable($gameStor->tnmt_time))->sub(new \DateInterval("PT{$minute}M"));
|
||||
|
||||
$gameStor->turntime = $turntime->format('Y-m-d H:i:s.u');
|
||||
$gameStor->starttime = $starttime->format('Y-m-d H:i:s');
|
||||
$gameStor->tnmt_time = $tnmt_time->format('Y-m-d H:i:s');
|
||||
|
||||
$db->update('general', [
|
||||
'turntime' => $db->sqleval('DATE_SUB(turntime, INTERVAL %i MINUTE)', $minute)
|
||||
], true);
|
||||
$db->update('ng_auction', [
|
||||
'close_date' => $db->sqleval('DATE_SUB(close_date, INTERVAL %i MINUTE)', $minute)
|
||||
], 'finished = 0');
|
||||
if ($locked) {
|
||||
unlock();
|
||||
}
|
||||
@@ -54,19 +66,34 @@ switch ($btn) {
|
||||
}
|
||||
usleep(500000);
|
||||
}
|
||||
$clock = GameClock::fromStorage($gameStor);
|
||||
$clock->advance($gameStor, -$clock->ticksFromMinutes($minute));
|
||||
$gameStor->cacheValues(['turntime', 'starttime', 'tnmt_time']);
|
||||
$turntime = (new \DateTimeImmutable($gameStor->turntime))->add(new \DateInterval("PT{$minute}M"));
|
||||
$starttime = (new \DateTimeImmutable($gameStor->starttime))->add(new \DateInterval("PT{$minute}M"));
|
||||
$tnmt_time = (new \DateTimeImmutable($gameStor->tnmt_time))->add(new \DateInterval("PT{$minute}M"));
|
||||
|
||||
$gameStor->turntime = $turntime->format('Y-m-d H:i:s.u');
|
||||
$gameStor->starttime = $starttime->format('Y-m-d H:i:s');
|
||||
$gameStor->tnmt_time = $tnmt_time->format('Y-m-d H:i:s');
|
||||
|
||||
$db->update('general', [
|
||||
'turntime' => $db->sqleval('DATE_ADD(turntime, INTERVAL %i MINUTE)', $minute)
|
||||
], true);
|
||||
$db->update('ng_auction', [
|
||||
'close_date' => $db->sqleval('DATE_ADD(close_date, INTERVAL %i MINUTE)', $minute)
|
||||
], 'finished = 0');
|
||||
if ($locked) {
|
||||
unlock();
|
||||
}
|
||||
break;
|
||||
case "토너분당김":
|
||||
$clock = GameClock::fromStorage($gameStor);
|
||||
$gameStor->tnmt_time = Util::toInt($gameStor->tnmt_time) - $clock->ticksFromMinutes($minute2);
|
||||
$tnmt_time = new \DateTime($gameStor->tnmt_time);
|
||||
$tnmt_time->sub(new \DateInterval("PT{$minute2}M"));
|
||||
$gameStor->tnmt_time = $tnmt_time->format('Y-m-d H:i:s');
|
||||
break;
|
||||
case "토너분지연":
|
||||
$clock = GameClock::fromStorage($gameStor);
|
||||
$gameStor->tnmt_time = Util::toInt($gameStor->tnmt_time) + $clock->ticksFromMinutes($minute2);
|
||||
$tnmt_time = new \DateTimeImmutable($gameStor->tnmt_time);
|
||||
$tnmt_time->add(new \DateInterval("PT{$minute2}M"));
|
||||
$gameStor->tnmt_time = $tnmt_time->format('Y-m-d H:i:s');
|
||||
break;
|
||||
case "금지급":
|
||||
processGoldIncome();
|
||||
|
||||
+3
-3
@@ -6,7 +6,7 @@ include "func.php";
|
||||
//로그인 검사
|
||||
$session = Session::requireGameLogin()->setReadOnly();
|
||||
|
||||
if($session->userGrade < 6) {
|
||||
if($session->userGrade < 5) {
|
||||
die(requireAdminPermissionHTML());
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ $admin = getAdmin();
|
||||
</tr>
|
||||
<tr>
|
||||
<td width=110 align=right>시작시간변경</td>
|
||||
<td width=285><input type=text size=20 maxlength=20 style=color:white;background-color:black;text-align:right; name=starttime value='<?=substr($admin['starttime_display'], 0, 19)?>'><input type=submit name=btn value=변경1></td>
|
||||
<td width=285><input type=text size=20 maxlength=20 style=color:white;background-color:black;text-align:right; name=starttime value='<?=substr($admin['starttime'], 0, 19)?>'><input type=submit name=btn value=변경1></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width=110 align=right>최대 장수</td>
|
||||
@@ -52,7 +52,7 @@ $admin = getAdmin();
|
||||
<td width=110 align=right>시작 년도</td>
|
||||
<td width=285><input type=text size=3 maxlength=3 style=color:white;background-color:black;text-align:right; name=startyear value='<?=$admin['startyear']?>'><input type=submit name=btn value=변경4></td>
|
||||
<td width=110 align=right>최근 갱신 시간</td>
|
||||
<td width=285> <?=$admin['turntime_display']?> (tick <?=$admin['turntime']?>)</td>
|
||||
<td width=285> <?=$admin['turntime']?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width=110 align=right>턴시간</td>
|
||||
|
||||
+4
-10
@@ -6,7 +6,7 @@ include "func.php";
|
||||
//로그인 검사
|
||||
$session = Session::requireGameLogin()->setReadOnly();
|
||||
|
||||
if ($session->userGrade < 6) {
|
||||
if ($session->userGrade < 5) {
|
||||
header('location:_admin1.php');
|
||||
die();
|
||||
}
|
||||
@@ -25,15 +25,13 @@ if (!$v->validate()) {
|
||||
$msg = Util::getPost('msg');
|
||||
$btn = Util::getPost('btn');
|
||||
$log = Util::getPost('log');
|
||||
$starttime = Util::getPost('starttime', 'string', null);
|
||||
$starttime = Util::getPost('starttime', 'string', (new \DateTime())->format('Y-m-d H:i:s'));
|
||||
$maxgeneral = Util::getPost('maxgeneral', 'int', GameConst::$defaultMaxGeneral);
|
||||
$maxnation = Util::getPost('maxnation', 'int', GameConst::$defaultMaxNation);
|
||||
$startyear = Util::getPost('startyear', 'int', GameConst::$defaultStartYear);
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$clock = GameClock::fromStorage($gameStor);
|
||||
$starttime ??= $clock->formatTick($clock->nowTick());
|
||||
|
||||
$admin = getAdmin();
|
||||
|
||||
@@ -45,11 +43,7 @@ switch ($btn) {
|
||||
pushGlobalHistoryLog(["<R>★</><S>{$log}</>"]);
|
||||
break;
|
||||
case "변경1":
|
||||
$gameStor->clock_base_time = TimeUtil::format(GameClock::baseTimeForProjection(
|
||||
new \DateTimeImmutable($starttime),
|
||||
Util::toInt($gameStor->starttime),
|
||||
$clock->getTurnTermMinutes(),
|
||||
), true);
|
||||
$gameStor->starttime = (new \DateTime($starttime))->format('Y-m-d H:i:s');
|
||||
break;
|
||||
case "변경2":
|
||||
$gameStor->maxgeneral = $maxgeneral;
|
||||
@@ -84,4 +78,4 @@ switch ($btn) {
|
||||
break;
|
||||
}
|
||||
|
||||
header('location:_admin1.php');
|
||||
header('location:_admin1.php');
|
||||
+1
-1
@@ -7,7 +7,7 @@ include "func.php";
|
||||
//로그인 검사
|
||||
$session = Session::requireGameLogin()->setReadOnly();
|
||||
|
||||
if ($session->userGrade < 6) {
|
||||
if ($session->userGrade < 5) {
|
||||
die(requireAdminPermissionHTML());
|
||||
}
|
||||
|
||||
|
||||
+10
-10
@@ -15,7 +15,7 @@ $msg = Util::getPost('msg', 'string');
|
||||
//로그인 검사
|
||||
$session = Session::requireLogin()->loginGame()->setReadOnly();
|
||||
|
||||
if ($session->userGrade < 6) {
|
||||
if ($session->userGrade < 5) {
|
||||
header('location:_admin2.php');
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ switch ($btn) {
|
||||
], '`no` IN %li', $genlist);
|
||||
break;
|
||||
case "강제 사망":
|
||||
$date = GameClock::fromStorage($gameStor)->nowTick();
|
||||
$date = TimeUtil::now(true);
|
||||
$db->update('general', [
|
||||
'killturn' => 0,
|
||||
'turntime' => $date,
|
||||
@@ -113,7 +113,7 @@ switch ($btn) {
|
||||
case "경험치1000":
|
||||
$text = $btn . " 지급!";
|
||||
foreach ($genlist as $generalID) {
|
||||
$msg = new Message(MessageType::private, $src, MessageTarget::buildQuick($generalID), $text, Message::gameNow(), new \DateTime('9999-12-31'), []);
|
||||
$msg = new Message(MessageType::private, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
|
||||
$msg->send(true);
|
||||
}
|
||||
$db->update('general', [
|
||||
@@ -124,7 +124,7 @@ switch ($btn) {
|
||||
case "공헌치1000":
|
||||
$text = $btn . " 지급!";
|
||||
foreach ($genlist as $generalID) {
|
||||
$msg = new Message(MessageType::private, $src, MessageTarget::buildQuick($generalID), $text, Message::gameNow(), new \DateTime('9999-12-31'), []);
|
||||
$msg = new Message(MessageType::private, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
|
||||
$msg->send(true);
|
||||
}
|
||||
$db->update('general', [
|
||||
@@ -135,7 +135,7 @@ switch ($btn) {
|
||||
case "보숙10000":
|
||||
$text = "보병숙련도+10000 지급!";
|
||||
foreach ($genlist as $generalID) {
|
||||
$msg = new Message(MessageType::private, $src, MessageTarget::buildQuick($generalID), $text, Message::gameNow(), new \DateTime('9999-12-31'), []);
|
||||
$msg = new Message(MessageType::private, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
|
||||
$msg->send(true);
|
||||
}
|
||||
$db->update('general', [
|
||||
@@ -145,7 +145,7 @@ switch ($btn) {
|
||||
case "궁숙10000":
|
||||
$text = "궁병숙련도+10000 지급!";
|
||||
foreach ($genlist as $generalID) {
|
||||
$msg = new Message(MessageType::private, $src, MessageTarget::buildQuick($generalID), $text, Message::gameNow(), new \DateTime('9999-12-31'), []);
|
||||
$msg = new Message(MessageType::private, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
|
||||
$msg->send(true);
|
||||
}
|
||||
$db->update('general', [
|
||||
@@ -156,7 +156,7 @@ switch ($btn) {
|
||||
$src = MessageTarget::buildQuick($session->generalID);
|
||||
$text = "기병숙련도+10000 지급!";
|
||||
foreach ($genlist as $generalID) {
|
||||
$msg = new Message(MessageType::private, $src, MessageTarget::buildQuick($generalID), $text, Message::gameNow(), new \DateTime('9999-12-31'), []);
|
||||
$msg = new Message(MessageType::private, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
|
||||
$msg->send(true);
|
||||
}
|
||||
$db->update('general', [
|
||||
@@ -167,7 +167,7 @@ switch ($btn) {
|
||||
$src = MessageTarget::buildQuick($session->generalID);
|
||||
$text = "귀병숙련도+10000 지급!";
|
||||
foreach ($genlist as $generalID) {
|
||||
$msg = new Message(MessageType::private, $src, MessageTarget::buildQuick($generalID), $text, Message::gameNow(), new \DateTime('9999-12-31'), []);
|
||||
$msg = new Message(MessageType::private, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
|
||||
$msg->send(true);
|
||||
}
|
||||
$db->update('general', [
|
||||
@@ -178,7 +178,7 @@ switch ($btn) {
|
||||
$src = MessageTarget::buildQuick($session->generalID);
|
||||
$text = "차병숙련도+10000 지급!";
|
||||
foreach ($genlist as $generalID) {
|
||||
$msg = new Message(MessageType::private, $src, MessageTarget::buildQuick($generalID), $text, Message::gameNow(), new \DateTime('9999-12-31'), []);
|
||||
$msg = new Message(MessageType::private, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
|
||||
$msg->send(true);
|
||||
}
|
||||
$db->update('general', [
|
||||
@@ -198,7 +198,7 @@ switch ($btn) {
|
||||
case "메세지 전달":
|
||||
$text = $msg ?? '';
|
||||
foreach ($genlist as $generalID) {
|
||||
$msg = new Message(MessageType::private, $src, MessageTarget::buildQuick($generalID), $text, Message::gameNow(), new \DateTime('9999-12-31'), []);
|
||||
$msg = new Message(MessageType::private, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
|
||||
$msg->send(true);
|
||||
}
|
||||
break;
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ if ($type2 < 0 || $type2 > 6) {
|
||||
//로그인 검사
|
||||
$session = Session::requireGameLogin()->setReadOnly();
|
||||
|
||||
if ($session->userGrade < 6) {
|
||||
if ($session->userGrade < 5) {
|
||||
die(requireAdminPermissionHTML());
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ $nation = Util::getPost('nation', 'int');
|
||||
$session = Session::requireGameLogin()->setReadOnly();
|
||||
$userID = Session::getUserID();
|
||||
|
||||
if ($session->userGrade < 6) {
|
||||
if ($session->userGrade < 5) {
|
||||
header('location:_admin5.php');
|
||||
die();
|
||||
}
|
||||
|
||||
+4
-5
@@ -31,18 +31,17 @@ $queryMap = [
|
||||
];
|
||||
|
||||
if ($reqQueryType === null || !key_exists($reqQueryType, $queryMap)) {
|
||||
$reqQueryType = array_key_first($queryMap);
|
||||
$reqQueryType = Util::array_first_key($queryMap);
|
||||
}
|
||||
|
||||
//로그인 검사
|
||||
$session = Session::requireGameLogin()->setReadOnly();
|
||||
|
||||
if ($session->userGrade < 6) {
|
||||
if ($session->userGrade < 5) {
|
||||
die(requireAdminPermissionHTML());
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
$clock = GameClock::fromStorage(KVStorage::getStorage($db, 'game_env'));
|
||||
|
||||
if ($btn == '정렬하기') {
|
||||
$gen = 0;
|
||||
@@ -112,7 +111,7 @@ $generalObj = General::createObjFromDB($gen, null, GeneralQueryMode::FullWithAcc
|
||||
대상장수 :
|
||||
<select name=gen size=1>
|
||||
<?php foreach ($generalBasicList as $general) : ?>
|
||||
<option <?= $gen == $general['no'] ? 'selected' : '' ?> value='<?= $general['no'] ?>'><?= $general['name'] ?> (<?= substr($clock->formatTick(Util::toInt($general['turntime'])), 14, 5) ?>)</option>
|
||||
<option <?= $gen == $general['no'] ? 'selected' : '' ?> value='<?= $general['no'] ?>'><?= $general['name'] ?> (<?= substr($general['turntime'], 14, 5) ?>)</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<input type=submit name=btn value='조회하기'>
|
||||
@@ -180,4 +179,4 @@ $generalObj = General::createObjFromDB($gen, null, GeneralQueryMode::FullWithAcc
|
||||
</table>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
+4
-2
@@ -12,7 +12,7 @@ $type = 0;
|
||||
//로그인 검사
|
||||
$session = Session::requireGameLogin()->setReadOnly();
|
||||
|
||||
if ($session->userGrade < 6) {
|
||||
if ($session->userGrade < 5) {
|
||||
die(requireAdminPermissionHTML());
|
||||
}
|
||||
|
||||
@@ -100,6 +100,8 @@ $sel[$type] = "selected";
|
||||
throw new \Exception("알 수 없는 외교 상태: {$dip['state']}");
|
||||
}
|
||||
|
||||
$date = TimeUtil::now();
|
||||
|
||||
echo "
|
||||
<tr>
|
||||
<td align=center style=color:" . newColor($nationColor[$me]) . ";background-color:{$nationColor[$me]};>$nationName[$me]</td>
|
||||
@@ -120,4 +122,4 @@ $sel[$type] = "selected";
|
||||
</table>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
@@ -7,7 +7,7 @@ include "func.php";
|
||||
//로그인 검사
|
||||
$session = Session::requireGameLogin()->setReadOnly();
|
||||
|
||||
if ($session->userGrade < 6) {
|
||||
if ($session->userGrade < 5) {
|
||||
die('권한 부족');
|
||||
}
|
||||
|
||||
|
||||
@@ -243,14 +243,11 @@ $templates = new \League\Plates\Engine(__DIR__ . '/templates');
|
||||
"SELECT nation,no,name,owner_name as ownerName, owner, picture, imgsvr,
|
||||
experience, dedication,
|
||||
dex1, dex2, dex3, dex4, dex5,
|
||||
horse, weapon, book, item, aux
|
||||
horse, weapon, book, item
|
||||
FROM general WHERE %l",
|
||||
$btn == "NPC 보기" ? "npc>=2" : "npc<2"
|
||||
) as $general) {
|
||||
$generalID = $general['no'];
|
||||
foreach (['dex1', 'dex2', 'dex3', 'dex4', 'dex5'] as $dexKey) {
|
||||
$general[$dexKey] = CentennialAllStarGrowthService::recordableRawValue($general, $dexKey);
|
||||
}
|
||||
$general['bgColor'] = $nationColor[$general['nation']] ?? GameConst::$basecolor4;
|
||||
$general['fgColor'] = newColor($general['bgColor']);
|
||||
$general['nationName'] = $nationName[$general['nation']];
|
||||
@@ -430,4 +427,4 @@ $templates = new \League\Plates\Engine(__DIR__ . '/templates');
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
+1
-2
@@ -9,7 +9,6 @@ include "func.php";
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$clock = GameClock::fromStorage($gameStor);
|
||||
|
||||
increaseRefresh("갱신정보", 1);
|
||||
|
||||
@@ -24,7 +23,7 @@ $recentTraffic[] = [
|
||||
'month' => $admin['month'],
|
||||
'refresh' => $admin['refresh'],
|
||||
'online' => $curonline,
|
||||
'date' => $clock->formatNow()
|
||||
'date' => TimeUtil::now()
|
||||
];
|
||||
|
||||
if ($admin['maxrefresh'] == 0) {
|
||||
|
||||
@@ -16,7 +16,7 @@ $db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
increaseRefresh("현재도시", 1);
|
||||
|
||||
$lastExecute = substr(GameClock::fromStorage($gameStor)->formatTick(Util::toInt($gameStor->turntime)), 5, 14);
|
||||
$lastExecute = substr($gameStor->turntime, 5, 14);
|
||||
|
||||
$me = $db->queryFirstRow('SELECT no,nation,officer_level,city from general where owner=%i', $userID);
|
||||
$myNation = $db->queryFirstRow('SELECT nation,level,spy FROM nation WHERE nation=%i', $me['nation']) ?? [
|
||||
@@ -177,7 +177,7 @@ $templates = new \League\Plates\Engine('templates');
|
||||
$valid = 1;
|
||||
}
|
||||
|
||||
if ($userGrade >= 6) {
|
||||
if ($userGrade >= 5) {
|
||||
$valid = true;
|
||||
$showDetailedInfo = true;
|
||||
}
|
||||
@@ -275,7 +275,7 @@ $templates = new \League\Plates\Engine('templates');
|
||||
$ourGeneral = false;
|
||||
}
|
||||
|
||||
if ($userGrade == 7) {
|
||||
if ($userGrade == 6) {
|
||||
$ourGeneral = true;
|
||||
}
|
||||
|
||||
@@ -537,4 +537,4 @@ $templates = new \League\Plates\Engine('templates');
|
||||
</table>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
+1
-3
@@ -129,7 +129,6 @@ $templates = new \League\Plates\Engine('templates');
|
||||
);
|
||||
|
||||
$generalTurnList = [];
|
||||
$clock = GameClock::fromStorage($gameStor);
|
||||
|
||||
foreach ($db->queryAllLists(
|
||||
'SELECT general_id, turn_idx, brief FROM general_turn WHERE general_id IN %li AND turn_idx < 5 ORDER BY general_id ASC, turn_idx ASC',
|
||||
@@ -143,7 +142,6 @@ $templates = new \League\Plates\Engine('templates');
|
||||
|
||||
$genCntEff = 0;
|
||||
foreach ($generals as &$general) {
|
||||
$general['turntime'] = $clock->formatTick(Util::toInt($general['turntime']), true);
|
||||
$general['cityText'] = CityConst::byID($general['city'])->name;
|
||||
$general['troopText'] = $troopName[$general['troop']] ?? '-';
|
||||
|
||||
@@ -286,4 +284,4 @@ $templates = new \League\Plates\Engine('templates');
|
||||
</table>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
+15
-41
@@ -19,10 +19,10 @@ $userID = Session::getUserID();
|
||||
$generalID = $session->generalID;
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$gameStor->cacheValues(['turntime', 'opentime', 'autorun_user', 'npcmode']);
|
||||
$clock = GameClock::fromStorage($gameStor);
|
||||
$nowTick = $clock->nowTick();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$gameStor->cacheValues(['turntime', 'opentime', 'autorun_user', 'npcmode']);
|
||||
|
||||
increaseRefresh("내정보", 1);
|
||||
|
||||
$me = General::createObjFromDB($generalID, null, GeneralQueryMode::FullWithAccessLog);
|
||||
|
||||
@@ -41,30 +41,12 @@ $lastRefresh = $db->queryFirstField(
|
||||
$generalID
|
||||
);
|
||||
|
||||
$nextChange = $me->getAuxVar('next_change');
|
||||
if (!is_int($nextChange)) {
|
||||
$nextChange = null;
|
||||
}
|
||||
$nextChangeDisplay = $nextChange === null ? null : $clock->formatTick($nextChange);
|
||||
|
||||
increaseRefresh("내정보", 1);
|
||||
if ($gameStor->turntime <= $gameStor->opentime) {
|
||||
$targetTime = $me->getAuxVar('prestart_delete_after');
|
||||
if (!is_int($targetTime)) {
|
||||
$targetTime = addTurn(
|
||||
$lastRefresh === null ? $nowTick : Util::toInt($lastRefresh),
|
||||
$gameStor->turnterm,
|
||||
GameConst::$minTurnDieOnPrestart
|
||||
);
|
||||
$me->setAuxVar('prestart_delete_after', $targetTime);
|
||||
$me->applyDB($db);
|
||||
}
|
||||
$targetTimeDisplay = $clock->formatTick($targetTime);
|
||||
|
||||
//서버 가오픈시 할 수 있는 행동
|
||||
if ($me->getNPCType() == 0 && $me->getNationID() == 0) {
|
||||
$targetTime = addTurn($lastRefresh, $gameStor->turnterm, GameConst::$minTurnDieOnPrestart);
|
||||
if ($gameStor->turntime <= $gameStor->opentime) {
|
||||
//서버 가오픈시 할 수 있는 행동
|
||||
if ($me->getNPCType() == 0 && $me->getNationID() == 0) {
|
||||
$showDieOnPrestartBtn = true;
|
||||
if ($targetTime <= $nowTick) {
|
||||
if ($targetTime <= TimeUtil::now()) {
|
||||
$availableDieOnPrestart = true;
|
||||
}
|
||||
}
|
||||
@@ -154,21 +136,13 @@ $changeDefence999Atmos = $me->onCalcDomestic('changeDefenceTrain', "atmos999", $
|
||||
<option value='<?= $targetDefenceTrain ?>' <?= $me->getVar('defence_train') == $targetDefenceTrain ? "selected" : ""; ?>><?= formatDefenceTrain($targetDefenceTrain) ?>(훈사<?= $targetDefenceTrain ?>)</option>
|
||||
<?php endforeach; ?>
|
||||
<option value=999 <?= $me->getVar('defence_train') == 999 ? "selected" : ""; ?>><?= formatDefenceTrain(999) ?>
|
||||
<?php if ($changeDefence999Train != 0 || $changeDefence999Train != 0) :
|
||||
?>[<?= $changeDefence999Train != 0 ? "훈련 {$changeDefence999Train}," : '' ?><?= $changeDefence999Atmos != 0 ? "사기 {$changeDefence999Atmos}" : ''
|
||||
?>]<?php endif ?></option>
|
||||
<?php if($changeDefence999Train != 0 || $changeDefence999Train != 0):
|
||||
?>[<?=$changeDefence999Train!=0?"훈련 {$changeDefence999Train},":''?><?=$changeDefence999Atmos!=0?"사기 {$changeDefence999Atmos}":''
|
||||
?>]<?php endif?></option>
|
||||
</select>
|
||||
】<br><br>
|
||||
<input type=<?= $submit ?> id='set_my_setting' name=btn style=background-color:<?= GameConst::$basecolor2 ?>;color:white;width:160px;height:30px;font-size:14px; value=설정저장><br>
|
||||
∞<span style='color:orange'>설정저장은 이달중 <?= $myset ?>회 남았습니다.</span><br><br>
|
||||
|
||||
<?php if ($me->getPenaltyList()->count()) : ?>
|
||||
징계 목록(저장 시 갱신)<br>
|
||||
<?php foreach ($me->getPenaltyList() as $penaltyKey => $penalty) : ?>
|
||||
<span style='color:red'><?= $penaltyKey->getHelptext() ?> : <?= $penalty ?></span><br>
|
||||
<?php endforeach; ?>
|
||||
<br />
|
||||
<?php endif; ?>
|
||||
<?php if (!($gameStor->autorun_user['limit_minutes'] ?? false)) : ?>
|
||||
휴 가 신 청<br>
|
||||
<button type="button" id='vacation' style=background-color:<?= GameConst::$basecolor2 ?>;color:white;width:160px;height:30px;font-size:14px;>휴가 신청</button><br><br>
|
||||
@@ -177,7 +151,7 @@ $changeDefence999Atmos = $me->onCalcDomestic('changeDefenceTrain', "atmos999", $
|
||||
<a href="b_myPage.php?detachNPC=1"><button type="button" style=background-color:<?= GameConst::$basecolor2 ?>;color:white;width:160px;height:30px;font-size:14px;>빙의 해체 요청</button></a>-->
|
||||
|
||||
<?php if ($showDieOnPrestartBtn) : ?>
|
||||
가오픈 기간 내 장수 삭제 (<?= $targetTimeDisplay ?> 부터)<br>
|
||||
가오픈 기간 내 장수 삭제 (<?= substr($targetTime, 0, 19) ?> 부터)<br>
|
||||
<button type="button" id='dieOnPrestart' style=background-color:<?= GameConst::$basecolor2 ?>;color:white;width:160px;height:30px;font-size:14px;>장수 삭제</button><br><br>
|
||||
<?php endif; ?>
|
||||
|
||||
@@ -192,7 +166,7 @@ $changeDefence999Atmos = $me->onCalcDomestic('changeDefenceTrain', "atmos999", $
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($gameStor->npcmode == 2 && $me->getNPCType() == 0) : ?>
|
||||
다른 장수 선택 (<?= $nextChangeDisplay ?? '지금' ?>부터)<br>
|
||||
다른 장수 선택 (<?= substr($me->getAuxVar('next_change') ?? TimeUtil::now(), 0, 19) ?> 부터)<br>
|
||||
<a href="select_general_from_pool.php" id='select_general_from_pool'><button type="button" style=background-color:<?= GameConst::$basecolor2 ?>;color:white;width:160px;height:30px;font-size:14px;>다른 장수 선택</button></a><br><br>
|
||||
<?php endif; ?>
|
||||
|
||||
@@ -290,4 +264,4 @@ $changeDefence999Atmos = $me->onCalcDomestic('changeDefenceTrain', "atmos999", $
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
+57
-1
@@ -125,7 +125,63 @@ $globalBetTotal = array_sum($globalBet);
|
||||
</tr>
|
||||
</table>
|
||||
<table align=center class='tb_layout bg0'>
|
||||
<?php if ($me['no'] > 0 && $me['tournament'] == 0 && $admin['tournament'] == 1) : ?>
|
||||
<?php if ($session->userGrade >= 5) : ?>
|
||||
<form method=post action=c_tournament.php>
|
||||
<tr>
|
||||
<td colspan=8><input type=textarea size=150 style=color:white;background-color:black; name=msg><input type=submit name=btn value='메시지'></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan=8>
|
||||
<button type="button" class="btn btn-secondary" onclick='location.reload()'>갱신</button>
|
||||
<?php if ($admin['tournament'] == 0) : ?>
|
||||
<select name=trig size=1 style=color:white;background-color:black;>
|
||||
<option style=color:white; value=0 <?= !$admin['tnmt_trig'] ? 'selected' : '' ?>>수동진행</option>
|
||||
<option style=color:white; value=1 <?= $admin['tnmt_trig'] ? 'selected' : '' ?>>자동진행</option>
|
||||
</select>
|
||||
<input type=submit name=btn value='자동개최설정'>
|
||||
<?php else : ?>
|
||||
<input type=submit name=btn value='중단' onclick='return confirm("진짜 중단하시겠습니까?")'>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
<?php switch ($admin['tournament']) {
|
||||
case 1:
|
||||
echo "<input type=submit name=btn value='랜덤투입'>";
|
||||
echo "<input type=submit name=btn value='랜덤전부투입'>";
|
||||
break;
|
||||
case 2:
|
||||
echo "<input type=submit name=btn value='예선'><input type=submit name=btn value='예선전부'>";
|
||||
break;
|
||||
case 3:
|
||||
echo "<input type=submit name=btn value='추첨'><input type=submit name=btn value='추첨전부'>";
|
||||
break;
|
||||
case 4:
|
||||
echo "<input type=submit name=btn value='본선'><input type=submit name=btn value='본선전부'>";
|
||||
break;
|
||||
case 5:
|
||||
echo "<input type=submit name=btn value='배정'>";
|
||||
break;
|
||||
case 6:
|
||||
echo "<input type=submit name=btn value='베팅마감'>";
|
||||
break;
|
||||
case 7:
|
||||
echo "<input type=submit name=btn value='16강'>";
|
||||
break;
|
||||
case 8:
|
||||
echo "<input type=submit name=btn value='8강'>";
|
||||
break;
|
||||
case 9:
|
||||
echo "<input type=submit name=btn value='4강'>";
|
||||
break;
|
||||
case 10:
|
||||
echo "<input type=submit name=btn value='결승'>";
|
||||
break;
|
||||
} ?>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</form>
|
||||
<?php elseif ($me['no'] > 0 && $me['tournament'] == 0 && $admin['tournament'] == 1) : ?>
|
||||
<form method=post action=c_tournament.php>
|
||||
<tr>
|
||||
<td colspan=8><button type="button" class="btn btn-secondary" onclick='location.reload()'>갱신</button><button type="submit" class="btn btn-sammo-base2" onclick='return confirm("참가비 금<?= $admin['develcost'] ?>이 필요합니다. 참가하시겠습니까?")'>참가</button><input type='hidden' name='btn' value='참가'/></td>
|
||||
|
||||
@@ -228,10 +228,10 @@ if($btn == "자동개최설정") {
|
||||
$phase = 0;
|
||||
startBetting($admin['tnmt_type'], 720);
|
||||
} elseif($btn == "베팅마감") {
|
||||
$clock = GameClock::fromStorage($gameStor);
|
||||
$dt = date("Y-m-d H:i:s", time() + 60);
|
||||
$gameStor->tournament=7;
|
||||
$gameStor->phase=0;
|
||||
$gameStor->tnmt_time = $clock->nowTick() + $clock->ticksFromSeconds(60);
|
||||
$gameStor->tnmt_time = $dt;
|
||||
} elseif($btn == "16강") {
|
||||
finalFight($admin['tnmt_type'], $admin['tournament'], $admin['phase'], 16);
|
||||
} elseif($btn == "8강") {
|
||||
@@ -248,4 +248,4 @@ if($btn == "자동개최설정") {
|
||||
$gameStor->tnmt_msg = $msg;
|
||||
}
|
||||
|
||||
header('location:b_tournament.php');
|
||||
header('location:b_tournament.php');
|
||||
@@ -51,22 +51,6 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
.picture_choice {
|
||||
margin: 8px auto;
|
||||
}
|
||||
|
||||
.picture_choice label,
|
||||
.event_picture label {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
margin: 4px 8px;
|
||||
}
|
||||
|
||||
.picture_choice img {
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.custom_picture {
|
||||
display: none;
|
||||
}
|
||||
@@ -77,4 +61,4 @@
|
||||
|
||||
.custom_stat {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
+131
-132
@@ -9,7 +9,6 @@ use sammo\Enums\GeneralAccessLogColumn;
|
||||
use sammo\Enums\GeneralColumn;
|
||||
use sammo\Enums\GeneralQueryMode;
|
||||
use sammo\Enums\InheritanceKey;
|
||||
use sammo\Enums\PenaltyKey;
|
||||
use sammo\Enums\RankColumn;
|
||||
|
||||
require_once 'process_war.php';
|
||||
@@ -112,7 +111,7 @@ function GetImageURL($imgsvr, $filepath = '')
|
||||
function checkLimit($refreshScore = null)
|
||||
{
|
||||
$session = Session::getInstance();
|
||||
if ($session->userGrade >= 6) {
|
||||
if ($session->userGrade >= 4) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -377,11 +376,11 @@ function myNationInfo(General $generalObj)
|
||||
function checkSecretMaxPermission($penalty)
|
||||
{
|
||||
$secretMax = 4;
|
||||
if ($penalty[PenaltyKey::NoTopSecret->value] ?? false) {
|
||||
if ($penalty['noTopSecret'] ?? false) {
|
||||
$secretMax = 1;
|
||||
} else if ($penalty[PenaltyKey::NoChief->value] ?? false) {
|
||||
} else if ($penalty['noChief'] ?? false) {
|
||||
$secretMax = 1;
|
||||
} else if ($penalty[PenaltyKey::NoAmbassador->value] ?? false) {
|
||||
} else if ($penalty['noAmbassador'] ?? false) {
|
||||
$secretMax = 2;
|
||||
}
|
||||
return $secretMax;
|
||||
@@ -404,7 +403,7 @@ function checkSecretPermission(array $me, $checkSecretLimit = true)
|
||||
}
|
||||
|
||||
|
||||
if ($penalty[PenaltyKey::NoChief->value] ?? false) {
|
||||
if ($penalty['noSecret'] ?? false) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -630,11 +629,7 @@ function generalInfo(General $generalObj)
|
||||
$injury = "건강";
|
||||
}
|
||||
|
||||
$clock = GameClock::fromStorage(KVStorage::getStorage(DB::db(), 'game_env'));
|
||||
$remaining = max(0, intdiv(
|
||||
$generalObj->getTurnTick() - $clock->nowTick(),
|
||||
$clock->ticksFromMinutes(1),
|
||||
));
|
||||
$remaining = (new \DateTimeImmutable($generalObj->getTurnTime()))->diff(new \DateTimeImmutable())->i;
|
||||
|
||||
if ($nation['color'] == "") {
|
||||
$nation['color'] = "#000000";
|
||||
@@ -925,37 +920,45 @@ function banner()
|
||||
);
|
||||
}
|
||||
|
||||
function addTurn(int $tick, int $turnterm, int $turn = 1, bool $withFraction = true): int
|
||||
{
|
||||
return $tick + GameClock::TICKS_PER_TURN * $turn;
|
||||
}
|
||||
|
||||
function subTurn(int $tick, int $turnterm, int $turn = 1, bool $withFraction = true): int
|
||||
{
|
||||
return $tick - GameClock::TICKS_PER_TURN * $turn;
|
||||
}
|
||||
|
||||
function cutTurn(int $tick, int $turnterm, bool $withFraction = true): int
|
||||
{
|
||||
$remainder = $tick % GameClock::TICKS_PER_TURN;
|
||||
if ($remainder < 0) {
|
||||
$remainder += GameClock::TICKS_PER_TURN;
|
||||
}
|
||||
return $tick - $remainder;
|
||||
}
|
||||
|
||||
/** 시나리오 초기화 입력인 벽시계를 기존 01:00 기준 월 경계로 정렬합니다. */
|
||||
function cutTurnDateTime(string $date, int $turnterm, bool $withFraction = true): string
|
||||
{
|
||||
$dateObj = new \DateTime($date);
|
||||
$baseDate = new \DateTime($dateObj->format('Y-m-d'));
|
||||
$baseDate->sub(new \DateInterval('P1D'));
|
||||
$baseDate->add(new \DateInterval('PT1H'));
|
||||
$diffMin = intdiv($dateObj->getTimestamp() - $baseDate->getTimestamp(), 60);
|
||||
$diffMin -= $diffMin % $turnterm;
|
||||
$baseDate->add(new \DateInterval("PT{$diffMin}M"));
|
||||
return $baseDate->format($withFraction ? 'Y-m-d H:i:s.u' : 'Y-m-d H:i:s');
|
||||
}
|
||||
function addTurn($date, int $turnterm, int $turn = 1, bool $withFraction = true)
|
||||
{
|
||||
$date = new \DateTime($date);
|
||||
$target = $turnterm * $turn;
|
||||
$date->add(new \DateInterval("PT{$target}M"));
|
||||
if ($withFraction) {
|
||||
return $date->format('Y-m-d H:i:s.u');
|
||||
}
|
||||
return $date->format('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
function subTurn($date, int $turnterm, int $turn = 1, bool $withFraction = true)
|
||||
{
|
||||
$date = new \DateTime($date);
|
||||
$target = $turnterm * $turn;
|
||||
$date->sub(new \DateInterval("PT{$target}M"));
|
||||
if ($withFraction) {
|
||||
return $date->format('Y-m-d H:i:s.u');
|
||||
}
|
||||
return $date->format('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
function cutTurn($date, int $turnterm, bool $withFraction = true)
|
||||
{
|
||||
$date = new \DateTime($date);
|
||||
|
||||
$baseDate = new \DateTime($date->format('Y-m-d'));
|
||||
$baseDate->sub(new \DateInterval("P1D"));
|
||||
$baseDate->add(new \DateInterval("PT1H"));
|
||||
|
||||
$diffMin = intdiv($date->getTimeStamp() - $baseDate->getTimeStamp(), 60);
|
||||
$diffMin -= $diffMin % $turnterm;
|
||||
|
||||
$baseDate->add(new \DateInterval("PT{$diffMin}M"));
|
||||
if ($withFraction) {
|
||||
return $baseDate->format('Y-m-d H:i:s.u');
|
||||
}
|
||||
return $baseDate->format('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
function cutDay($date, int $turnterm, bool $withFraction = true)
|
||||
{
|
||||
@@ -997,13 +1000,15 @@ function increaseRefresh($type = "", $cnt = 1)
|
||||
$generalID = $session->generalID;
|
||||
$userGrade = $session->userGrade;
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$date = GameClock::fromStorage($gameStor)->nowTick();
|
||||
$dateObj = new \DateTimeImmutable();
|
||||
$date = TimeUtil::format($dateObj, false);
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$isunited = $gameStor->isunited;
|
||||
$opentime = $gameStor->opentime;
|
||||
|
||||
if ($userGrade >= 6) {
|
||||
if ($userGrade == 6) {
|
||||
return;
|
||||
}
|
||||
if ($isunited == 2) {
|
||||
@@ -1041,7 +1046,7 @@ function increaseRefresh($type = "", $cnt = 1)
|
||||
|
||||
$logDB = FileDB::db($logPath, $serverPath . '/../f_install/sql/api_log.sql');
|
||||
|
||||
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'] ?? 'local';
|
||||
$ip = $_SERVER['REMOTE_ADDR'] ?? 'local';
|
||||
$date = date('Y-m-d H:i:s');
|
||||
|
||||
$logDB->insert('api_log', [
|
||||
@@ -1082,12 +1087,12 @@ function updateTraffic()
|
||||
if(count($recentTraffic) >= 5){
|
||||
array_shift($recentTraffic);
|
||||
}
|
||||
$recentTraffic[] = [
|
||||
$recentTraffic[] = [
|
||||
'year'=>$admin['year'],
|
||||
'month' => $admin['month'],
|
||||
'refresh' => $admin['refresh'],
|
||||
'online' => $online,
|
||||
'date' => GameClock::fromStorage($gameStor)->formatNow(),
|
||||
'date' => TimeUtil::now(),
|
||||
];
|
||||
$gameStor->recentTraffic = $recentTraffic;
|
||||
|
||||
@@ -1101,7 +1106,7 @@ function CheckOverhead()
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
[$turnterm, $refreshLimit] = $gameStor->getValuesAsArray(['turnterm', 'refreshLimit']);
|
||||
|
||||
$nextRefreshLimit = Util::round(pow($turnterm, 0.6) * 3) * GameConst::$refreshLimitCoef;
|
||||
$nextRefreshLimit = Util::round(pow($turnterm, 0.6) * 3) * 10;
|
||||
|
||||
|
||||
if ($nextRefreshLimit != $refreshLimit) {
|
||||
@@ -1139,19 +1144,18 @@ function unlock(): bool
|
||||
return $db->affectedRows() > 0;
|
||||
}
|
||||
|
||||
function timeover(): bool
|
||||
function timeover(): bool
|
||||
{
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
list($turnterm, $turntime) = $gameStor->getValuesAsArray(['turnterm', 'turntime']);
|
||||
$clock = GameClock::fromStorage($gameStor);
|
||||
$diff = $clock->nowTick() - Util::toInt($turntime);
|
||||
list($turnterm, $turntime) = $gameStor->getValuesAsArray(['turnterm', 'turntime']);
|
||||
$diff = (new \DateTime())->getTimestamp() - (new \DateTime($turntime))->getTimestamp();
|
||||
|
||||
$t = min($turnterm, 5);
|
||||
|
||||
$term = $clock->ticksFromSeconds($t);
|
||||
if ($diff >= $term || $diff < 0) {
|
||||
$term = $diff;
|
||||
if ($term >= $t || $term < 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@@ -1164,8 +1168,9 @@ function checkDelay()
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
//서버정보
|
||||
$clock = GameClock::fromStorage($gameStor);
|
||||
$timeMinDiff = intdiv($clock->nowTick() - Util::toInt($gameStor->turntime), $clock->ticksFromMinutes(1));
|
||||
$now = new \DateTimeImmutable();
|
||||
$turntime = new \DateTimeImmutable($gameStor->turntime);
|
||||
$timeMinDiff = intdiv($now->getTimestamp() - $turntime->getTimestamp(), 60);
|
||||
|
||||
// 1턴이상 갱신 없었으면 서버 지연
|
||||
$term = $gameStor->turnterm;
|
||||
@@ -1179,17 +1184,20 @@ function checkDelay()
|
||||
//지연 해야할 밀린 턴 횟수
|
||||
$iter = intdiv($timeMinDiff, $term);
|
||||
if ($iter > $threshold) {
|
||||
$minute = $iter * $term;
|
||||
$delayTick = $clock->ticksFromMinutes($minute);
|
||||
$gameStor->turntime = Util::toInt($gameStor->turntime) + $delayTick;
|
||||
$gameStor->starttime = Util::toInt($gameStor->starttime) + $delayTick;
|
||||
|
||||
$db->update('general', [
|
||||
'turntime' => $db->sqleval('turntime + %i', $delayTick)
|
||||
], true);
|
||||
$db->update('ng_auction', [
|
||||
'close_tick' => $db->sqleval('close_tick + %i', $delayTick)
|
||||
], 'finished = 0');
|
||||
$minute = $iter * $term;
|
||||
$newTurntime = $turntime->add(new \DateInterval("PT{$minute}M"));
|
||||
$newNextTurntime = $turntime->add(new \DateInterval("PT{$term}M"));
|
||||
$gameStor->turntime = $newTurntime->format('Y-m-d H:i:s');
|
||||
$gameStor->starttime = (new \DateTimeImmutable($gameStor->starttime))
|
||||
->add(new \DateInterval("PT{$minute}M"))
|
||||
->format('Y-m-d H:i:s');
|
||||
|
||||
$db->update('general', [
|
||||
'turntime' => $db->sqleval('DATE_ADD(turntime, INTERVAL %i MINUTE)', $minute)
|
||||
], 'turntime<=DATE_ADD(turntime, INTERVAL %i MINUTE)', $term);
|
||||
$db->update('ng_auction', [
|
||||
'close_date' => $db->sqleval('DATE_ADD(close_date, INTERVAL %i MINUTE)', $minute)
|
||||
], 'finished = 0');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1238,15 +1246,17 @@ function updateOnline()
|
||||
$gameStor->online_nation = join(', ', $onlineNation);
|
||||
}
|
||||
|
||||
function turnDate($curtime)
|
||||
function turnDate($curtime)
|
||||
{
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$admin = $gameStor->getValues(['startyear', 'starttime', 'turnterm', 'year', 'month']);
|
||||
|
||||
$turn = $admin['starttime'];
|
||||
$curturn = cutTurn(Util::toInt($curtime), $admin['turnterm']);
|
||||
$num = intdiv($curturn - Util::toInt($turn), GameClock::TICKS_PER_TURN);
|
||||
$curturn = cutTurn($curtime, $admin['turnterm']);
|
||||
$term = $admin['turnterm'];
|
||||
|
||||
$num = intdiv((strtotime($curturn) - strtotime($turn)), $term * 60);
|
||||
|
||||
$date = $admin['startyear'] * 12;
|
||||
$date += $num;
|
||||
@@ -1376,14 +1386,12 @@ function CheckHall($no)
|
||||
return;
|
||||
}
|
||||
|
||||
$clock = GameClock::fromStorage($gameStor);
|
||||
$unitedDate = $clock->formatTick($clock->nowTick());
|
||||
$unitedDate = TimeUtil::now();
|
||||
$nation = $generalObj->getStaticNation();
|
||||
|
||||
$serverCnt = $db->queryFirstField('SELECT count(*) FROM ng_games');
|
||||
|
||||
[$scenarioIdx, $scenarioName, $startTick] = $gameStor->getValuesAsArray(['scenario', 'scenario_text', 'starttime']);
|
||||
$startTime = $clock->formatTick(Util::toInt($startTick));
|
||||
[$scenarioIdx, $scenarioName, $startTime] = $gameStor->getValuesAsArray(['scenario', 'scenario_text', 'starttime']);
|
||||
|
||||
$ownerName = $generalObj->getVar('owner_name');
|
||||
if ($generalObj->getVar('owner')) {
|
||||
@@ -1392,11 +1400,8 @@ function CheckHall($no)
|
||||
|
||||
foreach ($types as [$typeName, $valueType]) {
|
||||
|
||||
if ($valueType === 'natural') {
|
||||
$value = $generalObj->getVar($typeName);
|
||||
if (in_array($typeName, ['dex1', 'dex2', 'dex3', 'dex4', 'dex5'], true)) {
|
||||
$value = CentennialAllStarGrowthService::recordableValue($generalObj, $typeName);
|
||||
}
|
||||
if ($valueType === 'natural') {
|
||||
$value = $generalObj->getVar($typeName);
|
||||
} else if ($valueType === 'rank') {
|
||||
$value = $generalObj->getRankVar(RankColumn::from($typeName));
|
||||
} else if ($valueType === 'calc') {
|
||||
@@ -1663,6 +1668,8 @@ function tryUniqueItemLottery(RandUtil $rng, General $general, string $acquireTy
|
||||
$prob = 1 / ($genCount * $itemTypeCnt * 0.7 / 3); // 투표율 70%, 설문조사 한번에 2~3개 등장
|
||||
} else if ($acquireType == '랜덤 임관') {
|
||||
$prob = 1 / ($genCount * $itemTypeCnt / 10 / 2); // 랜임시 2개(10%) 등장(200명중 20명 랜임시도?)
|
||||
} else if ($acquireType == '건국') {
|
||||
$prob = 1 / ($genCount * $itemTypeCnt / 10 / 4); // 건국시 4개(20%) 등장(200명시 20국 정도 됨)
|
||||
}
|
||||
|
||||
$prob *= GameConst::$uniqueTrialCoef;
|
||||
@@ -1676,9 +1683,6 @@ function tryUniqueItemLottery(RandUtil $rng, General $general, string $acquireTy
|
||||
//포인트로 랜덤 유니크 획득
|
||||
$prob = 1;
|
||||
}
|
||||
else if ($acquireType == '건국') {
|
||||
$prob = 1; // 건국시 100%
|
||||
}
|
||||
|
||||
foreach (Util::range($maxCnt) as $_idx) {
|
||||
if ($rng->nextBool($prob)) {
|
||||
@@ -1696,21 +1700,12 @@ function tryUniqueItemLottery(RandUtil $rng, General $general, string $acquireTy
|
||||
return giveRandomUniqueItem($rng, $general, $acquireType);
|
||||
}
|
||||
|
||||
function getAdmin()
|
||||
{
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$admin = $gameStor->getAll();
|
||||
$clock = GameClock::fromStorage($gameStor);
|
||||
foreach (['turntime', 'starttime', 'opentime', 'tnmt_time'] as $key) {
|
||||
if (($admin[$key] ?? null) !== null) {
|
||||
$admin["{$key}_display"] = $clock->formatTick(Util::toInt($admin[$key]), true);
|
||||
}
|
||||
}
|
||||
$admin['clock_now_tick'] = $clock->nowTick();
|
||||
$admin['clock_now_display'] = $clock->formatTick($admin['clock_now_tick'], true);
|
||||
return $admin;
|
||||
}
|
||||
function getAdmin()
|
||||
{
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
return $gameStor->getAll();
|
||||
}
|
||||
|
||||
/** @return General[] */
|
||||
function deleteNation(General $lord, bool $applyDB): array
|
||||
@@ -1788,13 +1783,11 @@ function deleteNation(General $lord, bool $applyDB): array
|
||||
// 부대 삭제
|
||||
$db->delete('troop', 'nation=%i', $nationID);
|
||||
|
||||
// 국가 삭제
|
||||
$gameDate = GameClock::fromStorage(KVStorage::getStorage($db, 'game_env'))->formatNow();
|
||||
$db->insert('ng_old_nations', [
|
||||
'server_id' => UniqueConst::$serverID,
|
||||
'nation' => $nationID,
|
||||
'date' => $gameDate,
|
||||
'data' => Json::encode($nation)
|
||||
// 국가 삭제
|
||||
$db->insert('ng_old_nations', [
|
||||
'server_id' => UniqueConst::$serverID,
|
||||
'nation' => $nationID,
|
||||
'data' => Json::encode($nation)
|
||||
]);
|
||||
$db->delete('nation', 'nation=%i', $nationID);
|
||||
$db->delete('nation_turn', 'nation_id=%i', $nationID);
|
||||
@@ -2201,29 +2194,35 @@ function SabotageInjury(RandUtil $rng, array $cityGeneralList, string $reason):
|
||||
return $injuryCount;
|
||||
}
|
||||
|
||||
function getRandTurn(RandUtil $rng, int $term, ?int $baseTick = null): int
|
||||
{
|
||||
$db = DB::db();
|
||||
$clock = GameClock::fromStorage(KVStorage::getStorage($db, 'game_env'));
|
||||
$baseTick ??= $clock->nowTick();
|
||||
|
||||
$randSecond = $rng->nextRangeInt(0, 60 * $term - 1);
|
||||
$randMicrosecond = $rng->nextRangeInt(0, 999999); // 레거시 RNG 소비 6자리 유지
|
||||
|
||||
return $baseTick
|
||||
+ $clock->ticksFromSeconds($randSecond)
|
||||
+ intdiv($randMicrosecond * $clock->ticksPerSecond(), 1_000_000);
|
||||
}
|
||||
|
||||
function getRandTurn2(RandUtil $rng, int $term, ?int $baseTick = null): int
|
||||
{
|
||||
$db = DB::db();
|
||||
$clock = GameClock::fromStorage(KVStorage::getStorage($db, 'game_env'));
|
||||
$baseTick ??= $clock->nowTick();
|
||||
$randSecond = $rng->nextRangeInt(0, 60 * $term - 1);
|
||||
$randMicrosecond = $rng->nextRangeInt(0, 999999); // 레거시 RNG 소비 6자리 유지
|
||||
|
||||
return $baseTick
|
||||
- $clock->ticksFromSeconds($randSecond)
|
||||
- intdiv($randMicrosecond * $clock->ticksPerSecond(), 1_000_000);
|
||||
}
|
||||
function getRandTurn(RandUtil $rng, $term, ?\DateTimeInterface $baseDateTime = null)
|
||||
{
|
||||
if ($baseDateTime === null) {
|
||||
$baseDateTime = new \DateTimeImmutable();
|
||||
} else if ($baseDateTime instanceof \DateTime) {
|
||||
$baseDateTime = \DateTimeImmutable::createFromMutable($baseDateTime);
|
||||
} else if ($baseDateTime instanceof \DateTimeImmutable) {
|
||||
//do Nothing
|
||||
} else {
|
||||
throw new MustNotBeReachedException();
|
||||
}
|
||||
|
||||
$randSecond = $rng->nextRangeInt(0, 60 * $term - 1);
|
||||
$randFraction = $rng->nextRangeInt(0, 999999) / 1000000; //6자리 소수
|
||||
|
||||
return TimeUtil::format($baseDateTime->add(TimeUtil::secondsToDateInterval($randSecond + $randFraction)), true);
|
||||
}
|
||||
|
||||
function getRandTurn2(RandUtil $rng, $term, ?\DateTimeInterface $baseDateTime = null)
|
||||
{
|
||||
if ($baseDateTime === null) {
|
||||
$baseDateTime = new \DateTimeImmutable();
|
||||
} else if ($baseDateTime instanceof \DateTime) {
|
||||
$baseDateTime = \DateTimeImmutable::createFromMutable($baseDateTime);
|
||||
} else {
|
||||
throw new MustNotBeReachedException();
|
||||
}
|
||||
$randSecond = $rng->nextRangeInt(0, 60 * $term - 1);
|
||||
$randFraction = $rng->nextRangeInt(0, 999999) / 1000000; //6자리 소수
|
||||
|
||||
return $baseDateTime->sub(TimeUtil::secondsToDateInterval($randSecond + $randFraction))->format('Y-m-d H:i:s.u');
|
||||
}
|
||||
|
||||
@@ -62,12 +62,11 @@ function processAuction()
|
||||
{
|
||||
$db = DB::db();
|
||||
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$nowTick = GameClock::fromStorage($gameStor)->nowTick();
|
||||
$now = TimeUtil::now();
|
||||
|
||||
$auctionList = $db->queryAllLists(
|
||||
'SELECT id, `type` FROM ng_auction WHERE `close_tick` <= %i AND finished = 0',
|
||||
$nowTick
|
||||
'SELECT id, `type` FROM ng_auction WHERE `close_date` <= %s AND finished = 0',
|
||||
$now
|
||||
);
|
||||
|
||||
if (!$auctionList) {
|
||||
|
||||
+37
-80
@@ -3,7 +3,6 @@ namespace sammo;
|
||||
|
||||
use sammo\Command\GeneralCommand;
|
||||
use sammo\Command\NationCommand;
|
||||
use sammo\Enums\PenaltyKey;
|
||||
|
||||
function getGeneralTurnBrief(General $generalObj, array $turnList) {
|
||||
$result = [];
|
||||
@@ -42,21 +41,15 @@ function pushGeneralCommand(int $generalID, int $turnCnt=1){
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
$db->query(
|
||||
'UPDATE general_turn AS dst
|
||||
LEFT JOIN general_turn AS src
|
||||
ON src.general_id = dst.general_id
|
||||
AND src.turn_idx = dst.turn_idx - %i
|
||||
SET dst.action = IF(src.id IS NULL, %s, src.action),
|
||||
dst.arg = IF(src.id IS NULL, %s, src.arg),
|
||||
dst.brief = IF(src.id IS NULL, %s, src.brief)
|
||||
WHERE dst.general_id = %i',
|
||||
$turnCnt,
|
||||
'휴식',
|
||||
'{}',
|
||||
'휴식',
|
||||
$generalID
|
||||
);
|
||||
$db->update('general_turn', [
|
||||
'turn_idx'=>$db->sqleval('turn_idx + %i', $turnCnt)
|
||||
], 'general_id=%i ORDER BY turn_idx DESC', $generalID);
|
||||
$db->update('general_turn', [
|
||||
'turn_idx'=>$db->sqleval('turn_idx - %i', GameConst::$maxTurn),
|
||||
'action'=>'휴식',
|
||||
'arg'=>'{}',
|
||||
'brief'=>'휴식'
|
||||
], 'general_id=%i AND turn_idx >= %i', $generalID, GameConst::$maxTurn);
|
||||
}
|
||||
|
||||
function pullGeneralCommand(int $generalID, int $turnCnt=1){
|
||||
@@ -73,21 +66,15 @@ function pullGeneralCommand(int $generalID, int $turnCnt=1){
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
$db->query(
|
||||
'UPDATE general_turn AS dst
|
||||
LEFT JOIN general_turn AS src
|
||||
ON src.general_id = dst.general_id
|
||||
AND src.turn_idx = dst.turn_idx + %i
|
||||
SET dst.action = IF(src.id IS NULL, %s, src.action),
|
||||
dst.arg = IF(src.id IS NULL, %s, src.arg),
|
||||
dst.brief = IF(src.id IS NULL, %s, src.brief)
|
||||
WHERE dst.general_id = %i',
|
||||
$turnCnt,
|
||||
'휴식',
|
||||
'{}',
|
||||
'휴식',
|
||||
$generalID
|
||||
);
|
||||
$db->update('general_turn', [
|
||||
'turn_idx'=>$db->sqleval('turn_idx + %i', GameConst::$maxTurn),
|
||||
'action'=>'휴식',
|
||||
'arg'=>'{}',
|
||||
'brief'=>'휴식'
|
||||
], 'general_id=%i AND turn_idx < %i', $generalID, $turnCnt);
|
||||
$db->update('general_turn', [
|
||||
'turn_idx'=>$db->sqleval('turn_idx - %i', $turnCnt)
|
||||
], 'general_id=%i ORDER BY turn_idx ASC', $generalID);
|
||||
}
|
||||
|
||||
function repeatGeneralCommand(int $generalId, int $turnCnt){
|
||||
@@ -138,23 +125,15 @@ function pushNationCommand(int $nationID, int $officerLevel, int $turnCnt=1){
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
$db->query(
|
||||
'UPDATE nation_turn AS dst
|
||||
LEFT JOIN nation_turn AS src
|
||||
ON src.nation_id = dst.nation_id
|
||||
AND src.officer_level = dst.officer_level
|
||||
AND src.turn_idx = dst.turn_idx - %i
|
||||
SET dst.action = IF(src.id IS NULL, %s, src.action),
|
||||
dst.arg = IF(src.id IS NULL, %s, src.arg),
|
||||
dst.brief = IF(src.id IS NULL, %s, src.brief)
|
||||
WHERE dst.nation_id = %i AND dst.officer_level = %i',
|
||||
$turnCnt,
|
||||
'휴식',
|
||||
'{}',
|
||||
'휴식',
|
||||
$nationID,
|
||||
$officerLevel
|
||||
);
|
||||
$db->update('nation_turn', [
|
||||
'turn_idx'=>$db->sqleval('turn_idx + %i', $turnCnt)
|
||||
], 'nation_id=%i AND officer_level=%i ORDER BY turn_idx DESC', $nationID, $officerLevel);
|
||||
$db->update('nation_turn', [
|
||||
'turn_idx'=>$db->sqleval('turn_idx - %i', GameConst::$maxChiefTurn),
|
||||
'action'=>'휴식',
|
||||
'arg'=>'{}',
|
||||
'brief'=>'휴식'
|
||||
], 'nation_id=%i AND officer_level=%i AND turn_idx >= %i ORDER BY turn_idx ASC', $nationID, $officerLevel, GameConst::$maxChiefTurn);
|
||||
}
|
||||
|
||||
function pullNationCommand(int $nationID, int $officerLevel, int $turnCnt=1){
|
||||
@@ -177,23 +156,15 @@ function pullNationCommand(int $nationID, int $officerLevel, int $turnCnt=1){
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
$db->query(
|
||||
'UPDATE nation_turn AS dst
|
||||
LEFT JOIN nation_turn AS src
|
||||
ON src.nation_id = dst.nation_id
|
||||
AND src.officer_level = dst.officer_level
|
||||
AND src.turn_idx = dst.turn_idx + %i
|
||||
SET dst.action = IF(src.id IS NULL, %s, src.action),
|
||||
dst.arg = IF(src.id IS NULL, %s, src.arg),
|
||||
dst.brief = IF(src.id IS NULL, %s, src.brief)
|
||||
WHERE dst.nation_id = %i AND dst.officer_level = %i',
|
||||
$turnCnt,
|
||||
'휴식',
|
||||
'{}',
|
||||
'휴식',
|
||||
$nationID,
|
||||
$officerLevel
|
||||
);
|
||||
$db->update('nation_turn', [
|
||||
'turn_idx'=>$db->sqleval('turn_idx + %i', GameConst::$maxChiefTurn),
|
||||
'action'=>'휴식',
|
||||
'arg'=>'{}',
|
||||
'brief'=>'휴식',
|
||||
], 'nation_id=%i AND officer_level=%i AND turn_idx < %i', $nationID, $officerLevel, $turnCnt);
|
||||
$db->update('nation_turn', [
|
||||
'turn_idx'=>$db->sqleval('turn_idx - %i', $turnCnt)
|
||||
], 'nation_id=%i AND officer_level=%i ORDER BY turn_idx ASC', $nationID, $officerLevel);
|
||||
}
|
||||
|
||||
function repeatNationCommand(int $nationID, int $officerLevel, int $turnCnt){
|
||||
@@ -463,13 +434,6 @@ function setNationCommand(int $generalID, array $turnList, string $command, ?arr
|
||||
];
|
||||
}
|
||||
|
||||
if($general->hasPenalty(PenaltyKey::NoChiefTurnInput)){
|
||||
return [
|
||||
'result'=>false,
|
||||
'reason'=>'수뇌 턴 입력 불가능'
|
||||
];
|
||||
}
|
||||
|
||||
try{
|
||||
$commandObj = buildNationCommandClass($command, $general, $env, $general->getLastTurn(), $arg);
|
||||
}
|
||||
@@ -509,17 +473,10 @@ function setNationCommand(int $generalID, array $turnList, string $command, ?arr
|
||||
}
|
||||
|
||||
_setNationCommand($commandObj, $turnList);
|
||||
|
||||
if($general->getNPCType() < 2){
|
||||
//유저장인 경우에는 턴 리필
|
||||
$general->updateVarWithLimit('killturn', $env['killturn'], $general->getVar('killturn'));
|
||||
$general->applyDB($db);
|
||||
}
|
||||
|
||||
return [
|
||||
'result'=>true,
|
||||
'brief'=>$commandObj->getBrief(),
|
||||
'arg_test'=>true,
|
||||
'reason'=>'success'
|
||||
];
|
||||
}
|
||||
}
|
||||
+1
-24
@@ -457,29 +457,6 @@ function buildWarUnitTriggerClass(?string $type, WarUnit $unit, ?array $args = n
|
||||
return $class->newInstanceArgs(array_merge([$unit], $args));
|
||||
}
|
||||
|
||||
function getStaticEventClass(string $type){
|
||||
static $basePath = __NAMESPACE__.'\\StaticEvent\\';
|
||||
$classPath = ($basePath.$type);
|
||||
|
||||
if(class_exists($classPath)){
|
||||
return $classPath;
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException("{$type}은 StaticEvent가 아님");
|
||||
}
|
||||
|
||||
function buildStaticEventClass(?string $type):BaseStaticEvent{
|
||||
static $cache = [];
|
||||
if(key_exists($type, $cache)){
|
||||
return $cache[$type];
|
||||
}
|
||||
|
||||
$class = getStaticEventClass($type);
|
||||
$obj = new $class();
|
||||
$cache[$type] = $obj;
|
||||
return $obj;
|
||||
}
|
||||
|
||||
function getGeneralPoolClass(string $type){
|
||||
static $basePath = __NAMESPACE__.'\\GeneralPool\\';
|
||||
$classPath = ($basePath.$type);
|
||||
@@ -686,7 +663,7 @@ function TechLimit($startYear, $year, $tech) : bool {
|
||||
$relYear = $year - $startYear;
|
||||
|
||||
$relMaxTech = Util::valueFit(
|
||||
floor($relYear / GameConst::$techLevelIncYear) + GameConst::$initialAllowedTechLevel,
|
||||
floor($relYear / 5) + 1,
|
||||
1,
|
||||
GameConst::$maxTechLevel
|
||||
);
|
||||
|
||||
+19
-30
@@ -372,7 +372,7 @@ function postUpdateMonthly(RandUtil $rng)
|
||||
continue;
|
||||
}
|
||||
|
||||
//양측 기간 모두 0이 되는 상황이면 종전
|
||||
//양측 기간 모두 0이 되는 상황이면 휴전
|
||||
$nation1 = getNationStaticInfo($me);
|
||||
$name1 = $nation1['name'];
|
||||
$nation2 = getNationStaticInfo($you);
|
||||
@@ -381,7 +381,7 @@ function postUpdateMonthly(RandUtil $rng)
|
||||
$josaWa = JosaUtil::pick($name1, '와');
|
||||
$josaYi = JosaUtil::pick($name2, '이');
|
||||
|
||||
$globalLogger->pushGlobalHistoryLog("<R><b>【종전】</b></><D><b>$name1</b></>{$josaWa} <D><b>$name2</b></>{$josaYi} <S>종전</>합니다.");
|
||||
$globalLogger->pushGlobalHistoryLog("<R><b>【휴전】</b></><D><b>$name1</b></>{$josaWa} <D><b>$name2</b></>{$josaYi} <S>휴전</>합니다.");
|
||||
$db->update('diplomacy', [
|
||||
'state' => 2,
|
||||
'term' => 0,
|
||||
@@ -559,7 +559,7 @@ function checkStatistic()
|
||||
|
||||
$nationHist = '';
|
||||
foreach (GameConst::$availableNationType as $nationType) {
|
||||
if (!($nationHists[$nationType] ?? null)) {
|
||||
if (!Util::array_get($nationHists[$nationType])) {
|
||||
$nationHists[$nationType] = '-';
|
||||
}
|
||||
$nationHist .= getNationType($nationType) . "({$nationHists[$nationType]}), ";
|
||||
@@ -651,24 +651,16 @@ function checkStatistic()
|
||||
}
|
||||
|
||||
|
||||
function convForOldGeneral(array $general, int $year, int $month)
|
||||
{
|
||||
$general['history'] = getGeneralHistoryLogAll($general['no']);
|
||||
$clock = GameClock::fromStorage(KVStorage::getStorage(DB::db(), 'game_env'));
|
||||
$turnTimeDisplay = $clock->formatTick(Util::toInt($general['turntime']), true);
|
||||
$general['turntime_tick'] = Util::toInt($general['turntime']);
|
||||
$general['turntime'] = $turnTimeDisplay;
|
||||
if ($general['recent_war'] !== null) {
|
||||
$general['recent_war_tick'] = Util::toInt($general['recent_war']);
|
||||
$general['recent_war'] = $clock->formatTick(Util::toInt($general['recent_war']), true);
|
||||
}
|
||||
return [
|
||||
function convForOldGeneral(array $general, int $year, int $month)
|
||||
{
|
||||
$general['history'] = getGeneralHistoryLogAll($general['no']);
|
||||
return [
|
||||
'server_id' => UniqueConst::$serverID,
|
||||
'general_no' => $general['no'],
|
||||
'owner' => $general['owner'],
|
||||
'name' => $general['name'],
|
||||
'last_yearmonth' => $year * 100 + $month,
|
||||
'turntime' => $turnTimeDisplay,
|
||||
'turntime' => $general['turntime'],
|
||||
'data' => Json::encode($general)
|
||||
];
|
||||
}
|
||||
@@ -742,7 +734,7 @@ function checkEmperior()
|
||||
|
||||
/** @var int[] */
|
||||
$auctionList = $db->queryFirstColumn(
|
||||
'SELECT `id` FROM `ng_auction` WHERE `type` = %s AND `finished` = 0 ORDER BY `close_tick` ASC',
|
||||
'SELECT `id` FROM `ng_auction` WHERE `type` = %s AND `finished` = 0 ORDER BY `close_date` ASC',
|
||||
AuctionType::UniqueItem->value
|
||||
);
|
||||
foreach($auctionList as $auctionID){
|
||||
@@ -838,23 +830,20 @@ function checkEmperior()
|
||||
$nation['aux'] += $nationStor->max_power ?? [];
|
||||
$nation['history'] = getNationHistoryLogAll($nation['nation']);
|
||||
|
||||
storeOldGenerals(0, $admin['year'], $admin['month']);
|
||||
storeOldGenerals($nation['nation'], $admin['year'], $admin['month']);
|
||||
$gameDate = GameClock::fromStorage($gameStor)->formatNow();
|
||||
|
||||
$db->insert('ng_old_nations', [
|
||||
'server_id' => UniqueConst::$serverID,
|
||||
'nation' => $nation['nation'],
|
||||
'date' => $gameDate,
|
||||
'data' => Json::encode($nation)
|
||||
storeOldGenerals(0, $admin['year'], $admin['month']);
|
||||
storeOldGenerals($nation['nation'], $admin['year'], $admin['month']);
|
||||
|
||||
$db->insert('ng_old_nations', [
|
||||
'server_id' => UniqueConst::$serverID,
|
||||
'nation' => $nation['nation'],
|
||||
'data' => Json::encode($nation)
|
||||
]);
|
||||
|
||||
$noNationGeneral = $db->queryFirstColumn('SELECT `no` FROM general WHERE nation=0');
|
||||
$db->insert('ng_old_nations', [
|
||||
'server_id' => UniqueConst::$serverID,
|
||||
'nation' => 0,
|
||||
'date' => $gameDate,
|
||||
'data' => Json::encode([
|
||||
'server_id' => UniqueConst::$serverID,
|
||||
'nation' => 0,
|
||||
'data' => Json::encode([
|
||||
'nation' => 0,
|
||||
'name' => '재야',
|
||||
'generals' => $noNationGeneral
|
||||
|
||||
+2
-6
@@ -4,10 +4,6 @@ namespace sammo;
|
||||
|
||||
function printLimitMsg($turntime)
|
||||
{
|
||||
if (is_int($turntime) || (is_string($turntime) && ctype_digit(ltrim($turntime, '-')))) {
|
||||
$gameStor = KVStorage::getStorage(DB::db(), 'game_env');
|
||||
$turntime = GameClock::fromStorage($gameStor)->formatTick(Util::toInt($turntime), true);
|
||||
}
|
||||
//FIXME: template로 이동.
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
@@ -142,7 +138,7 @@ function JSCitiesBasedOnDistance(int $cityNo, int $maxDistance = 1): array{
|
||||
$distanceList = searchDistance($cityNo, $maxDistance, true);
|
||||
$result = [];
|
||||
for ($dist = 1; $dist <= $maxDistance; $dist++) {
|
||||
$result[$dist] = $distanceList[$dist] ?? [];
|
||||
$result[$dist] = Util::array_get($distanceList[$dist], []);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
@@ -156,7 +152,7 @@ function printCitiesBasedOnDistance(int $cityNo, int $maxDistance = 1): string
|
||||
for ($dist = 1; $dist <= $maxDistance; $dist++) {
|
||||
$cityList = array_map(function ($cityID) {
|
||||
return CityConst::byID($cityID)->name;
|
||||
}, $distanceList[$dist] ?? []);
|
||||
}, Util::array_get($distanceList[$dist], []));
|
||||
|
||||
$cityStr = join(', ', $cityList);
|
||||
|
||||
|
||||
@@ -61,12 +61,8 @@ function chiefTurnTable()
|
||||
";
|
||||
}
|
||||
|
||||
function templateLimitMsg(string $turntime): string
|
||||
{
|
||||
if (ctype_digit(ltrim($turntime, '-'))) {
|
||||
$gameStor = KVStorage::getStorage(DB::db(), 'game_env');
|
||||
$turntime = GameClock::fromStorage($gameStor)->formatTick(Util::toInt($turntime), true);
|
||||
}
|
||||
function templateLimitMsg(string $turntime): string
|
||||
{
|
||||
return "이미 너무 많은 접속을 하셨습니다. 다음 턴에 다시 시도해주세요. (턴시간: {$turntime})";
|
||||
}
|
||||
|
||||
|
||||
+10
-17
@@ -17,10 +17,10 @@ function processTournament()
|
||||
{
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$clock = GameClock::fromStorage($gameStor);
|
||||
|
||||
$admin = $gameStor->getValues(['tournament', 'phase', 'tnmt_type', 'tnmt_auto', 'tnmt_time', 'turnterm', 'last_tournament_betting_id']);
|
||||
$offset = intdiv($clock->nowTick() - Util::toInt($admin['tnmt_time']), $clock->ticksPerSecond());
|
||||
$now = new \DateTime();
|
||||
$offset = $now->getTimestamp() - (new \DateTime($admin['tnmt_time']))->getTimestamp();
|
||||
|
||||
//수동일땐 무시
|
||||
if (!$admin['tnmt_auto']) {
|
||||
@@ -122,10 +122,10 @@ function processTournament()
|
||||
if ($tnmt == 6) {
|
||||
$betTerm = Util::valueFit($unit * 60, null, 3600);
|
||||
//처리 초 더한 날짜
|
||||
$dt = date("Y-m-d H:i:s", strtotime($admin['tnmt_time']) + $unit * $i + $betTerm);
|
||||
$gameStor->tournament = $tnmt;
|
||||
$gameStor->phase = $phase;
|
||||
$gameStor->tnmt_time = Util::toInt($admin['tnmt_time'])
|
||||
+ $clock->ticksFromSeconds($unit * $i + $betTerm);
|
||||
$gameStor->tnmt_time = $dt;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -133,7 +133,7 @@ function processTournament()
|
||||
$second = $unit * $iter;
|
||||
$gameStor->tournament = $tnmt;
|
||||
$gameStor->phase = $phase;
|
||||
$gameStor->tnmt_time = Util::toInt($admin['tnmt_time']) + $clock->ticksFromSeconds($second);
|
||||
$gameStor->tnmt_time = (new \DateTimeImmutable($admin['tnmt_time']))->add(new \DateInterval("PT{$second}S"))->format('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
function getTournamentTermText(int $turnTerm)
|
||||
@@ -160,8 +160,7 @@ function getTournamentTime()
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
list($tnmt, $tnmt_time) = $gameStor->getValuesAsArray(['tournament', 'tnmt_time']);
|
||||
$clock = GameClock::fromStorage($gameStor);
|
||||
$dt = substr($clock->formatTick(Util::toInt($tnmt_time)), 11, 5);
|
||||
$dt = substr($tnmt_time, 11, 5);
|
||||
switch ($tnmt) {
|
||||
case 1:
|
||||
$tnmt = "개막시간 {$dt}";
|
||||
@@ -285,11 +284,9 @@ function startTournament($type)
|
||||
$admin = $gameStor->getValues(['year', 'month', 'turnterm']);
|
||||
$turnTerm = $admin['turnterm'];
|
||||
$unit = calcTournamentTerm($turnTerm);
|
||||
$clock = GameClock::fromStorage($gameStor);
|
||||
|
||||
$gameStor->tnmt_auto = true;
|
||||
// 기존 startTournament은 unit을 분으로 더하므로 그 계약을 유지합니다.
|
||||
$gameStor->tnmt_time = $clock->nowTick() + $clock->ticksFromMinutes($unit);
|
||||
$gameStor->tnmt_time = (new \DateTimeImmutable())->add(new \DateInterval("PT{$unit}M"))->format('Y-m-d H:i:s');
|
||||
$gameStor->tournament = 1;
|
||||
$gameStor->tnmt_type = $type;
|
||||
$gameStor->last_tournament_betting_id = 0;
|
||||
@@ -1156,25 +1153,21 @@ function fight($tnmt_type, $tnmt, $phs, $group, $g1, $g2, $type)
|
||||
];
|
||||
|
||||
//막판 분노
|
||||
$factor1 = 1.0;
|
||||
$factor2 = 1.0;
|
||||
$ratio = rand() % 300;
|
||||
if ($e1 / 5 > $energy1 && $damage1 > $damage2 && $gen1[$tp] >= $ratio) {
|
||||
$factor2 = Util::round((rand() % 301 + 200) / 100); // 200 ~ 500%
|
||||
$damage2 *= Util::round((rand() % 301 + 200) / 100); // 200 ~ 500%
|
||||
$critical1 = 1;
|
||||
$str = Util::choiceRandom($crticialSkillMap[$tnmt_type]);
|
||||
$log[] = "<S>●</> <Y>{$gen1['name']}</>의 분노의 <M>{$str}</> 공격!";
|
||||
}
|
||||
$ratio = rand() % 300;
|
||||
if ($e2 / 5 > $energy2 && $damage2 > $damage1 && $gen2[$tp] >= $ratio) {
|
||||
$factor1 = Util::round((rand() % 301 + 200) / 100); // 200 ~ 500%
|
||||
$damage1 *= Util::round((rand() % 301 + 200) / 100); // 200 ~ 500%
|
||||
$critical2 = 1;
|
||||
|
||||
$str = Util::choiceRandom($crticialSkillMap[$tnmt_type]);
|
||||
$log[] = "<S>●</> <Y>{$gen2['name']}</>의 분노의 <M>{$str}</> 공격!";
|
||||
}
|
||||
$damage1 *= $factor1;
|
||||
$damage2 *= $factor2;
|
||||
|
||||
//1합 승부
|
||||
if ($phase == 1) {
|
||||
|
||||
|
||||
+2
-3
@@ -7,7 +7,6 @@ include "func.php";
|
||||
Session::requireLogin()->loginGame()->setReadOnly();
|
||||
|
||||
$mapName = GameConst::$mapName;
|
||||
$frontClock = GameClock::fromStorage(KVStorage::getStorage(DB::db(), 'game_env'));
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
@@ -29,7 +28,7 @@ $frontClock = GameClock::fromStorage(KVStorage::getStorage(DB::db(), 'game_env')
|
||||
|
||||
'maxTurn' => GameConst::$maxTurn,
|
||||
'maxPushTurn' => 12,
|
||||
'serverNow' => $frontClock->formatTick($frontClock->nowTick()),
|
||||
'serverNow' => TimeUtil::now(false),
|
||||
]
|
||||
], false) ?>
|
||||
<?= WebUtil::printJS('../d_shared/common_path.js') ?>
|
||||
@@ -43,4 +42,4 @@ $frontClock = GameClock::fromStorage(KVStorage::getStorage(DB::db(), 'game_env')
|
||||
<div id="app"></div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
+2
-2
@@ -7,10 +7,10 @@ include "func.php";
|
||||
|
||||
$session = Session::requireLogin();
|
||||
|
||||
if ($session->userGrade < 6) {
|
||||
if ($session->userGrade < 5) {
|
||||
die('관리자 아님');
|
||||
}
|
||||
if ($session->userGrade == 6) {
|
||||
if ($session->userGrade == 5) {
|
||||
die('DB 리셋 권한을 가지고 있지 않습니다.');
|
||||
}
|
||||
|
||||
|
||||
+12
-15
@@ -25,24 +25,21 @@ if(!$reserved){
|
||||
]);
|
||||
}
|
||||
|
||||
$reservedDate = new \DateTimeImmutable($reserved['date']);
|
||||
$now = GameClock::readWallTime();
|
||||
$reservedDate = new \DateTime($reserved['date']);
|
||||
$now = new \DateTime();
|
||||
|
||||
|
||||
$status = 'not_yet';
|
||||
|
||||
list($isUnited, $unitedWallAnchor) = $gameStor->getValuesAsArray(['isunited', 'autoreset_united_wall_anchor']);
|
||||
if($isUnited === null){
|
||||
$isUnited = 2;
|
||||
}
|
||||
$lastTurn = null;
|
||||
if($isUnited > 0){
|
||||
if(!is_string($unitedWallAnchor) || $unitedWallAnchor === ''){
|
||||
$unitedWallAnchor = TimeUtil::format($now, true);
|
||||
$gameStor->autoreset_united_wall_anchor = $unitedWallAnchor;
|
||||
}
|
||||
$lastTurn = new \DateTimeImmutable($unitedWallAnchor);
|
||||
}
|
||||
list($isUnited, $lastTurn) = $gameStor->getValuesAsArray(['isunited', 'turntime']);
|
||||
if($isUnited === null || $lastTurn === null){
|
||||
$isUnited = 2;
|
||||
$lastTurn = '2000-01-01';
|
||||
}
|
||||
|
||||
if($lastTurn !== null){
|
||||
$lastTurn = new \DateTime($lastTurn);
|
||||
}
|
||||
|
||||
if($lastTurn === null){
|
||||
//이미 리셋된 상태임
|
||||
@@ -102,4 +99,4 @@ $result['affected']=1;
|
||||
$prefix = DB::prefix();
|
||||
ServConfig::getServerList()[$prefix]->openServer();
|
||||
|
||||
Json::die($result);
|
||||
Json::die($result);
|
||||
@@ -10,7 +10,6 @@ $session = Session::requireGameLogin()->setReadOnly();
|
||||
$userID = Session::getUserID();
|
||||
|
||||
$db = DB::db();
|
||||
$clock = GameClock::fromStorage(KVStorage::getStorage($db, 'game_env'));
|
||||
|
||||
$isSecretBoard = Util::getPost('isSecret', 'bool', false);
|
||||
$title = Util::getPost('title');
|
||||
@@ -68,7 +67,7 @@ $icon = GetImageURL($me['imgsvr'], $me['picture']);
|
||||
$db->insert('board', [
|
||||
'nation_no'=>$me['nation'],
|
||||
'is_secret'=>$isSecretBoard,
|
||||
'date'=>$clock->formatNow(),
|
||||
'date'=>TimeUtil::now(),
|
||||
'general_no'=>$me['no'],
|
||||
'author'=>$me['name'],
|
||||
'author_icon'=>$icon,
|
||||
@@ -80,4 +79,4 @@ Json::die([
|
||||
'result'=>true,
|
||||
'reason'=>'success',
|
||||
'row_id'=>$db->insertId()
|
||||
]);
|
||||
]);
|
||||
@@ -10,7 +10,6 @@ $session = Session::requireGameLogin()->setReadOnly();
|
||||
$userID = Session::getUserID();
|
||||
|
||||
$db = DB::db();
|
||||
$clock = GameClock::fromStorage(KVStorage::getStorage($db, 'game_env'));
|
||||
|
||||
$articleNo = Util::getPost('articleNo', 'int');
|
||||
$text = Util::getPost('text');
|
||||
@@ -74,7 +73,7 @@ else if ($isSecretBoard && $permission < 2) {
|
||||
$db->insert('comment', [
|
||||
'nation_no'=>$me['nation'],
|
||||
'is_secret'=>$isSecretBoard,
|
||||
'date'=>$clock->formatNow(),
|
||||
'date'=>TimeUtil::now(),
|
||||
'document_no'=>$articleNo,
|
||||
'general_no'=>$me['no'],
|
||||
'author'=>$me['name'],
|
||||
@@ -85,4 +84,4 @@ Json::die([
|
||||
'result'=>true,
|
||||
'reason'=>'success',
|
||||
'row_id'=>$db->insertId()
|
||||
]);
|
||||
]);
|
||||
@@ -83,7 +83,7 @@ else{
|
||||
}
|
||||
|
||||
|
||||
$now = Message::gameNow();
|
||||
$now = new \DateTime();
|
||||
$unlimited = new \DateTime('9999-12-31');
|
||||
|
||||
if(in_array($stateOpt, ['try_destroy_src', 'try_destroy_dest'])){
|
||||
@@ -138,4 +138,4 @@ Json::die([
|
||||
'result'=>true,
|
||||
'reason'=>'success',
|
||||
'state'=>$lastState
|
||||
]);
|
||||
]);
|
||||
@@ -69,7 +69,7 @@ $destNation = getNationStaticInfo($letter['dest_nation_id']);
|
||||
$src = new MessageTarget($me['no'], $me['name'], $destNation['nation'], $destNation['name'], $destNation['color'], $me['icon']);
|
||||
$dest = new MessageTarget(0, '', $srcNation['nation'], $srcNation['name'], $srcNation['color']);
|
||||
|
||||
$now = Message::gameNow();
|
||||
$now = new \DateTime();
|
||||
$unlimited = new \DateTime('9999-12-31');
|
||||
|
||||
if($isAgree){
|
||||
@@ -133,4 +133,4 @@ $msgID = $msg->send();
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'reason'=>'success'
|
||||
]);
|
||||
]);
|
||||
@@ -63,7 +63,7 @@ $destNation = getNationStaticInfo($letter['dest_nation_id']);
|
||||
$src = new MessageTarget($me['no'], $me['name'], $srcNation['nation'], $srcNation['name'], $srcNation['color'], $me['icon']);
|
||||
$dest = new MessageTarget(0, '', $destNation['nation'], $destNation['name'], $destNation['color']);
|
||||
|
||||
$now = Message::gameNow();
|
||||
$now = new \DateTime();
|
||||
$unlimited = new \DateTime('9999-12-31');
|
||||
|
||||
$aux['reason'] = [
|
||||
@@ -91,4 +91,4 @@ $msgID = $msg->send();
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'reason'=>'success'
|
||||
]);
|
||||
]);
|
||||
@@ -140,8 +140,6 @@ else{
|
||||
|
||||
$me['icon'] = GetImageURL($me['imgsvr'], $me['picture']);
|
||||
|
||||
$clock = GameClock::fromStorage($gameStor);
|
||||
$gameNow = $clock->nowDateTime();
|
||||
$db->insert('ng_diplomacy', [
|
||||
'src_nation_id'=>$srcNation['nation'],
|
||||
'dest_nation_id'=>$destNation['nation'],
|
||||
@@ -149,7 +147,7 @@ $db->insert('ng_diplomacy', [
|
||||
'state'=>'proposed',
|
||||
'text_brief'=>$textBrief,
|
||||
'text_detail'=>$textDetail,
|
||||
'date'=>TimeUtil::format($gameNow),
|
||||
'date'=>TimeUtil::now(),
|
||||
'src_signer'=>$me['no'],
|
||||
'dest_signer'=>null,
|
||||
'aux'=>Json::encode([
|
||||
@@ -170,7 +168,7 @@ $newLetterNo = $db->insertId();
|
||||
$src = new MessageTarget($me['no'], $me['name'], $srcNation['nation'], $srcNation['name'], $srcNation['color'], $me['icon']);
|
||||
$dest = new MessageTarget(0, '', $destNation['nation'], $destNation['name'], $destNation['color']);
|
||||
|
||||
$now = \DateTime::createFromImmutable($gameNow);
|
||||
$now = new \DateTime();
|
||||
$unlimited = new \DateTime('9999-12-31');
|
||||
|
||||
$josaYi = JosaUtil::pick($newLetterNo, '이');
|
||||
@@ -197,4 +195,4 @@ Json::die([
|
||||
'result'=>true,
|
||||
'reason'=>'success',
|
||||
'row_id'=>$db->insertId()
|
||||
]);
|
||||
]);
|
||||
@@ -18,7 +18,7 @@ else{
|
||||
$availableNextCall = $session->availableNextCallGetCityList??'2000-01-01 00:00:00';
|
||||
$now = new \DateTimeImmutable();
|
||||
|
||||
if($now <= new \DateTimeImmutable($availableNextCall) && $session->userGrade < 6){
|
||||
if($now <= new \DateTimeImmutable($availableNextCall) && $session->userGrade < 5){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>"도시 목록은 10초에 한번 갱신 가능합니다.\n다음 시간 : ".$availableNextCall
|
||||
|
||||
@@ -16,10 +16,12 @@ $session = Session::requireLogin([])->setReadOnly();
|
||||
$userID = Session::getUserID();
|
||||
|
||||
|
||||
$oNow = new \DateTimeImmutable();
|
||||
|
||||
$now = $oNow->format('Y-m-d H:i:s');
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$clock = GameClock::fromStorage($gameStor);
|
||||
$now = $clock->nowTick();
|
||||
|
||||
$oldGeneral = $db->queryFirstField('SELECT `no` FROM general WHERE `owner`=%i', $userID);
|
||||
if($oldGeneral !== null){
|
||||
@@ -42,14 +44,15 @@ if($npcmode!=1){
|
||||
]);
|
||||
}
|
||||
|
||||
$token = $db->queryFirstRow('SELECT * FROM select_npc_token WHERE `owner`=%i AND `valid_until`>=%i', $userID, $now);
|
||||
$token = $db->queryFirstRow('SELECT * FROM select_npc_token WHERE `owner`=%i AND `valid_until`>=%s', $userID, $now);
|
||||
$pickResult = [];
|
||||
|
||||
|
||||
if($token && $refresh){
|
||||
$pickMoreFrom = Util::toInt($token['pick_more_from']);
|
||||
$pickMoreFrom = (new \DateTime($token['pick_more_from']))->getTimestamp();
|
||||
$nowT = $oNow->getTimestamp();
|
||||
|
||||
if($now >= $pickMoreFrom){
|
||||
if($nowT >= $pickMoreFrom){
|
||||
$oldPickResult = Json::decode($token['pick_result']);
|
||||
|
||||
foreach($keepResult as $keepId){
|
||||
@@ -72,16 +75,15 @@ if($token && $refresh){
|
||||
}
|
||||
|
||||
if($token && !$refresh){
|
||||
$pickMoreFrom = Util::toInt($token['pick_more_from']);
|
||||
$pickMoreFrom = (new \DateTime($token['pick_more_from']))->getTimestamp();
|
||||
$nowT = $oNow->getTimestamp();
|
||||
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'pick'=>Json::decode($token['pick_result']),
|
||||
'pickMoreFrom'=>$clock->formatTick($pickMoreFrom),
|
||||
'pickMoreSeconds'=>intdiv($pickMoreFrom - $now, $clock->ticksPerSecond()),
|
||||
'validUntil'=>$clock->formatTick(Util::toInt($token['valid_until'])),
|
||||
'validForSeconds'=>max(0, intdiv(Util::toInt($token['valid_until']) - $now, $clock->ticksPerSecond())),
|
||||
'clockMode'=>$clock->getMode(),
|
||||
'pickMoreFrom'=>$token['pick_more_from'],
|
||||
'pickMoreSeconds'=>$pickMoreFrom-$nowT,
|
||||
'validUntil'=>$token['valid_until']
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -98,7 +100,7 @@ foreach($db->query('SELECT `no`, `name`, leadership, strength, intel, nation, im
|
||||
$weight[$general['no']] = pow($allStat, 1.5);
|
||||
}
|
||||
|
||||
foreach($db->queryFirstColumn('SELECT pick_result FROM select_npc_token WHERE `owner`!=%i AND valid_until >=%i', $userID, $now) as $reserved){
|
||||
foreach($db->queryFirstColumn('SELECT pick_result FROM select_npc_token WHERE `owner`!=%i AND valid_until >=%s', $userID, $now) as $reserved){
|
||||
$reserved = Json::decode($reserved);
|
||||
foreach(array_keys($reserved) as $reservedNPC){
|
||||
if(key_exists($reservedNPC, $weight)){
|
||||
@@ -129,8 +131,8 @@ $newNonce = random_int(0, 0xfffffff);
|
||||
$validSecond = max(VALID_SECOND, $turnterm*40);
|
||||
$pickMoreSecond = max(PICK_MORE_SECOND, Util::round(pow($turnterm, 0.672)*8));
|
||||
|
||||
$validUntil = $now + $clock->ticksFromSeconds($validSecond);
|
||||
$pickMoreFrom = $now + $clock->ticksFromSeconds($pickMoreSecond);
|
||||
$validUntil = $oNow->add(new \DateInterval(sprintf('PT%dS', $validSecond)));
|
||||
$pickMoreFrom = $oNow->add(new \DateInterval(sprintf('PT%dS', $pickMoreSecond)));
|
||||
|
||||
$db->delete('select_npc_token', 'valid_until < %s', $now);
|
||||
|
||||
@@ -138,8 +140,8 @@ $inserted = 0;
|
||||
|
||||
if($token){
|
||||
$db->update('select_npc_token', [
|
||||
'valid_until'=>$validUntil,
|
||||
'pick_more_from'=>$pickMoreFrom,
|
||||
'valid_until'=>$validUntil->format('Y-m-d H:i:s'),
|
||||
'pick_more_from'=>$pickMoreFrom->format('Y-m-d H:i:s'),
|
||||
'pick_result'=>Json::encode($pickResult),
|
||||
'nonce'=>$newNonce
|
||||
], 'owner = %i AND nonce = %i', $userID, $token['nonce']);
|
||||
@@ -150,8 +152,8 @@ if($token){
|
||||
else{
|
||||
$db->insertIgnore('select_npc_token', [
|
||||
'owner'=>$userID,
|
||||
'valid_until'=>$validUntil,
|
||||
'pick_more_from'=>$now,
|
||||
'valid_until'=>$validUntil->format('Y-m-d H:i:s'),
|
||||
'pick_more_from'=>'2000-01-01 01:00:00',
|
||||
'pick_result'=>Json::encode($pickResult),
|
||||
'nonce'=>$newNonce
|
||||
]);
|
||||
@@ -171,9 +173,7 @@ if($inserted === 0){
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'pick'=>$pickResult,
|
||||
'pickMoreFrom'=>$clock->formatTick(($inserted===-1)?$pickMoreFrom:$now),
|
||||
'pickMoreFrom'=>($inserted===-1)?$pickMoreFrom->format('Y-m-d H:i:s'):'2000-01-01 01:00:00',
|
||||
'pickMoreSeconds'=>($inserted===-1)?$pickMoreSecond:0,
|
||||
'validUntil'=>$clock->formatTick($validUntil),
|
||||
'validForSeconds'=>max(0, intdiv($validUntil - $now, $clock->ticksPerSecond())),
|
||||
'clockMode'=>$clock->getMode(),
|
||||
]);
|
||||
'validUntil'=>$validUntil->format('Y-m-d H:i:s')
|
||||
]);
|
||||
+14
-34
@@ -10,23 +10,7 @@ function sortTokens(&$tokens){
|
||||
});
|
||||
}
|
||||
|
||||
function putInfoText(&$info, ?array $currentTargetEnv){
|
||||
if (($info['event100Growth'] ?? false) === true) {
|
||||
if ($currentTargetEnv === null) {
|
||||
$displayStats = CentennialAllStarGrowthService::calculateUserInitialStats($info);
|
||||
$info['selectionStatLabel'] = '시작 능력치';
|
||||
} else {
|
||||
$displayStats = CentennialAllStarGrowthService::calculateUserCurrentTargetStats(
|
||||
$info,
|
||||
$currentTargetEnv
|
||||
);
|
||||
$info['selectionStatLabel'] = '현재 변경 기준 능력치';
|
||||
}
|
||||
$info['selectionLeadership'] = $displayStats['leadership'];
|
||||
$info['selectionStrength'] = $displayStats['strength'];
|
||||
$info['selectionIntel'] = $displayStats['intel'];
|
||||
}
|
||||
|
||||
function putInfoText(&$info){
|
||||
if(key_exists('specialDomestic', $info)){
|
||||
$class = buildGeneralSpecialDomesticClass($info['specialDomestic']);
|
||||
$info['specialDomesticName'] = $class->getName();
|
||||
@@ -43,13 +27,14 @@ function putInfoText(&$info, ?array $currentTargetEnv){
|
||||
$session = Session::requireLogin([])->setReadOnly();
|
||||
$userID = Session::getUserID();
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$clock = GameClock::fromStorage($gameStor);
|
||||
$now = $clock->nowTick();
|
||||
$oNow = new \DateTimeImmutable();
|
||||
|
||||
$eventEnv = $gameStor->getValues(['npcmode', 'startyear', 'year', 'month']);
|
||||
$npcmode = $eventEnv['npcmode'];
|
||||
$now = $oNow->format('Y-m-d H:i:s');
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
$npcmode = $gameStor->getValue('npcmode');
|
||||
if($npcmode!=2){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
@@ -57,8 +42,7 @@ if($npcmode!=2){
|
||||
]);
|
||||
}
|
||||
|
||||
$rawGeneral = $db->queryFirstRow('SELECT no, aux FROM general WHERE `owner` = %i', $userID);
|
||||
$currentTargetEnv = $rawGeneral ? $eventEnv : null;
|
||||
$rawGeneral = $db->queryFirstRow('SELECT no, aux FROM general WHERE `owner` = %i', $userID);
|
||||
if($rawGeneral){
|
||||
$generalAux = Json::decode($rawGeneral['aux']);
|
||||
if(key_exists('next_change', $generalAux)&& $generalAux['next_change'] > $now){
|
||||
@@ -78,7 +62,7 @@ if($tokens){
|
||||
foreach($tokens as $token){
|
||||
$valid_until = $token['reserved_until'];
|
||||
$info = Json::decode($token['info']);
|
||||
putInfoText($info, $currentTargetEnv);
|
||||
putInfoText($info);
|
||||
$info['uniqueName'] = $token['unique_name'];
|
||||
$pick[] = $info;
|
||||
}
|
||||
@@ -86,9 +70,7 @@ if($tokens){
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'pick'=>$pick,
|
||||
'validUntil'=>$clock->formatTick(Util::toInt($valid_until)),
|
||||
'validForSeconds'=>max(0, intdiv(Util::toInt($valid_until) - $now, $clock->ticksPerSecond())),
|
||||
'clockMode'=>$clock->getMode(),
|
||||
'validUntil'=>$valid_until
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -101,14 +83,12 @@ $valid_until = null;
|
||||
foreach(pickGeneralFromPool($db, $rng, $userID, 14) as $pickObj){
|
||||
$valid_until = $pickObj->getValidUntil();
|
||||
$info = $pickObj->getInfo();
|
||||
putInfoText($info, $currentTargetEnv);
|
||||
putInfoText($info);
|
||||
$pick[] = $info;
|
||||
}
|
||||
sortTokens($pick);//좀 무식하지만..
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'pick'=>$pick,
|
||||
'validUntil'=>$valid_until === null ? null : $clock->formatTick(Util::toInt($valid_until)),
|
||||
'validForSeconds'=>$valid_until === null ? 0 : max(0, intdiv(Util::toInt($valid_until) - $now, $clock->ticksPerSecond())),
|
||||
'clockMode'=>$clock->getMode(),
|
||||
]);
|
||||
'validUntil'=>$valid_until
|
||||
]);
|
||||
+2
-2
@@ -211,7 +211,7 @@ try{
|
||||
$show_img_level,
|
||||
!!$tournament_trig,
|
||||
$join_mode,
|
||||
TimeUtil::format(GameClock::readWallTime(), false),
|
||||
TimeUtil::now(),
|
||||
$autorun_user
|
||||
));
|
||||
}
|
||||
@@ -220,4 +220,4 @@ catch(\Exception $e){
|
||||
'result'=>false,
|
||||
'reason'=>$e->getMessage()
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -19,15 +19,7 @@ if(!prepareDir('data/file_cache')){
|
||||
]);
|
||||
}
|
||||
|
||||
$absolutePath = realpath('data/file_cache');
|
||||
if(!$absolutePath){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'cache 불가'
|
||||
]);
|
||||
}
|
||||
|
||||
$storage = new \Nette\Caching\Storages\FileStorage($absolutePath);
|
||||
$storage = new \Nette\Caching\Storages\FileStorage('data/file_cache');
|
||||
$cache = new Cache($storage);
|
||||
$serverID = UniqueConst::$serverID;
|
||||
|
||||
|
||||
+99
-130
@@ -1,12 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace sammo;
|
||||
|
||||
use sammo\Enums\GeneralColumn;
|
||||
use sammo\Enums\GeneralLiteQueryMode;
|
||||
use sammo\Enums\GeneralQueryMode;
|
||||
use sammo\Enums\MessageType;
|
||||
use sammo\Enums\PenaltyKey;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
@@ -24,99 +21,92 @@ $userID = Session::getUserID();
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$gameStor->cacheValues(['startyear', 'year', 'month', 'scenario', 'killturn']);
|
||||
$gameStor->cacheValues(['startyear','year','month','scenario']);
|
||||
|
||||
$me = $db->queryFirstRow('SELECT no,npc,nation,officer_level,penalty from general where owner=%i', $userID);
|
||||
$me = $db->queryFirstRow('SELECT no,nation,officer_level from general where owner=%i', $userID);
|
||||
$myOfficerLevel = $me['officer_level'];
|
||||
$nationID = $me['nation'];
|
||||
$myPenalty = Json::decode($me['penalty'] ?? '{}');
|
||||
|
||||
//수뇌가 아니면 아무것도 할 수 없음
|
||||
if ($myOfficerLevel < 5) {
|
||||
if($myOfficerLevel < 5){
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => '수뇌가 아닙니다.'
|
||||
'result'=>false,
|
||||
'reason'=>'수뇌가 아닙니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
if ($action === '추방' && $destGeneralID == 0) {
|
||||
if($action === '추방' && $destGeneralID==0){
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => '장수가 지정되지 않았습니다.'
|
||||
'result'=>false,
|
||||
'reason'=>'장수가 지정되지 않았습니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
if ($destGeneralID == 0) {
|
||||
if($destGeneralID==0){
|
||||
$general = new DummyGeneral(true);
|
||||
$general->setVar('nation', $nationID);
|
||||
} else {
|
||||
}
|
||||
else{
|
||||
$general = General::createObjFromDB($destGeneralID);
|
||||
|
||||
if ($general instanceof DummyGeneral) {
|
||||
if($general instanceof DummyGeneral){
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => '올바르지 않은 장수입니다.'
|
||||
'result'=>false,
|
||||
'reason'=>'올바르지 않은 장수입니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
if ($nationID != $general->getNationID()) {
|
||||
if($nationID != $general->getNationID()){
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => '아국 장수가 아닙니다'
|
||||
'result'=>false,
|
||||
'reason'=>'아국 장수가 아닙니다'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($officerLevel == 12) {
|
||||
if($officerLevel == 12){
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => '군주를 대상으로 할 수 없습니다.'
|
||||
'result'=>false,
|
||||
'reason'=>'군주를 대상으로 할 수 없습니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
function do수뇌임명(General $general, int $targetOfficerLevel): ?string
|
||||
{
|
||||
global $myPenalty;
|
||||
|
||||
if ($myPenalty[PenaltyKey::NoChiefChange->value] ?? false) {
|
||||
return '수뇌를 임명할 수 없는 상태입니다.';
|
||||
}
|
||||
|
||||
function do수뇌임명(General $general, int $targetOfficerLevel):?string{
|
||||
$generalID = $general->getID();
|
||||
$nationID = $general->getNationID();
|
||||
|
||||
if($general->hasPenalty(PenaltyKey::NoChief)){
|
||||
return '수뇌가 될 수 없는 상태입니다.';
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
[$chiefSet, $nationLevel] = $db->queryFirstList('SELECT chief_set,level FROM nation WHERE nation = %i', $nationID);
|
||||
[$chiefSet, $nationLevel] = $db->queryFirstList('SELECT chief_set,level FROM nation WHERE nation = %i',$nationID);
|
||||
|
||||
// 임명가능 레벨
|
||||
// 임명가능 레벨
|
||||
$lv = getNationChiefLevel($nationLevel);
|
||||
|
||||
if ($targetOfficerLevel < $lv) {
|
||||
if($targetOfficerLevel < $lv){
|
||||
return '임명불가능한 관직입니다.';
|
||||
}
|
||||
|
||||
if (isOfficerSet($chiefSet, $targetOfficerLevel)) {
|
||||
if(isOfficerSet($chiefSet, $targetOfficerLevel)){
|
||||
return '지금은 임명할 수 없습니다.';
|
||||
}
|
||||
|
||||
//기존 장수 일반으로
|
||||
$db->update('general', [
|
||||
'officer_level' => 1,
|
||||
'officer_city' => 0,
|
||||
'officer_level'=>1,
|
||||
'officer_city'=>0,
|
||||
], 'nation=%i AND officer_level=%i AND no!=%i', $nationID, $targetOfficerLevel, $generalID);
|
||||
|
||||
if ($targetOfficerLevel === 11) {
|
||||
} else if ($targetOfficerLevel % 2 == 0) {
|
||||
if ($general->getVar('strength') < GameConst::$chiefStatMin) {
|
||||
if($targetOfficerLevel === 11){
|
||||
|
||||
}
|
||||
else if($targetOfficerLevel % 2 == 0){
|
||||
if($general->getVar('strength') < GameConst::$chiefStatMin){
|
||||
return '무력이 부족합니다.';
|
||||
}
|
||||
} else {
|
||||
if ($general->getVar('intel') < GameConst::$chiefStatMin) {
|
||||
|
||||
}
|
||||
else{
|
||||
if($general->getVar('intel') < GameConst::$chiefStatMin){
|
||||
return '지력이 부족합니다.';
|
||||
}
|
||||
}
|
||||
@@ -125,59 +115,52 @@ function do수뇌임명(General $general, int $targetOfficerLevel): ?string
|
||||
$general->setVar('officer_level', $targetOfficerLevel);
|
||||
$general->setVar('officer_city', 0);
|
||||
$db->update('nation', [
|
||||
'chief_set' => $db->sqleval('chief_set | %i', doOfficerSet(0, $targetOfficerLevel)),
|
||||
'chief_set'=> $db->sqleval('chief_set | %i', doOfficerSet(0, $targetOfficerLevel)),
|
||||
], 'nation=%i', $nationID);
|
||||
$general->applyDB($db);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function do도시임명(General $general, int $cityID, int $targetOfficerLevel): ?string
|
||||
{
|
||||
global $myPenalty;
|
||||
|
||||
function do도시임명(General $general, int $cityID, int $targetOfficerLevel):?string{
|
||||
$nationID = $general->getNationID();
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
if (CityConst::byID($cityID) === null) {
|
||||
if(CityConst::byID($cityID) === null){
|
||||
return '올바르지 않은 도시입니다';
|
||||
}
|
||||
|
||||
if ($general->getVar(GeneralColumn::officer_level) >= 4 && ($myPenalty[PenaltyKey::NoChiefChange->value] ?? false)) {
|
||||
return '수뇌인 장수를 변경할 수 없는 상태입니다.';
|
||||
}
|
||||
|
||||
$officerSet = $db->queryFirstField('SELECT officer_set FROM city WHERE nation=%i AND city=%i', $nationID, $cityID);
|
||||
if ($officerSet === null) {
|
||||
if($officerSet === null){
|
||||
return '아국 도시가 아닙니다';
|
||||
}
|
||||
|
||||
if (isOfficerSet($officerSet, $targetOfficerLevel)) {
|
||||
if(isOfficerSet($officerSet, $targetOfficerLevel)){
|
||||
return '이미 다른 장수가 임명되어있습니다';
|
||||
}
|
||||
|
||||
//기존 장수 일반으로
|
||||
$db->update('general', [
|
||||
'officer_level' => 1,
|
||||
'officer_city' => 0,
|
||||
'officer_level'=>1,
|
||||
'officer_city'=>0,
|
||||
], 'officer_level=%i AND officer_city=%i AND no!=%i', $targetOfficerLevel, $cityID, $general->getID());
|
||||
|
||||
if ($general instanceof DummyGeneral) {
|
||||
if($general instanceof DummyGeneral){
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($targetOfficerLevel === 4 && $general->getVar('strength') < GameConst::$chiefStatMin) {
|
||||
if($targetOfficerLevel === 4 && $general->getVar('strength') < GameConst::$chiefStatMin){
|
||||
return '무력이 부족합니다.';
|
||||
}
|
||||
|
||||
if ($targetOfficerLevel === 3 && $general->getVar('intel') < GameConst::$chiefStatMin) {
|
||||
if($targetOfficerLevel === 3 && $general->getVar('intel') < GameConst::$chiefStatMin){
|
||||
return '지력이 부족합니다.';
|
||||
}
|
||||
|
||||
//신임 장수
|
||||
$db->update('city', [
|
||||
'officer_set' => $db->sqleval('officer_set | %i', doOfficerSet(0, $targetOfficerLevel)),
|
||||
'officer_set'=>$db->sqleval('officer_set | %i', doOfficerSet(0, $targetOfficerLevel)),
|
||||
], 'city=%i AND nation=%i', $cityID, $nationID);
|
||||
$general->setVar('officer_level', $targetOfficerLevel);
|
||||
$general->setVar('officer_city', $cityID);
|
||||
@@ -186,25 +169,22 @@ function do도시임명(General $general, int $cityID, int $targetOfficerLevel):
|
||||
return null;
|
||||
}
|
||||
|
||||
function do추방(General $general, int $myOfficerLevel): ?string
|
||||
{
|
||||
function do추방(General $general, int $myOfficerLevel):?string{
|
||||
$generalID = $general->getID();
|
||||
$generalName = $general->getVar('name');
|
||||
$nationID = $general->getNationID();
|
||||
|
||||
if ($myPenalty[PenaltyKey::NoBanGeneral->value] ?? false) {
|
||||
return '추방할 수 없는 상태입니다.';
|
||||
}
|
||||
|
||||
|
||||
//추방할사람이 외교권자이면 불가
|
||||
$permission = checkSecretPermission($general->getRaw());
|
||||
if ($permission == 4) {
|
||||
if($permission == 4){
|
||||
return '외교권자는 추방할 수 없습니다.';
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$env = $gameStor->getValues(['startyear', 'year', 'month', 'scenario']);
|
||||
$env = $gameStor->getValues(['startyear','year','month','scenario']);
|
||||
|
||||
$nation = $db->queryFirstRow('SELECT name,chief_set,color FROM nation WHERE nation=%i', $nationID);
|
||||
$nationName = $nation['name'];
|
||||
@@ -212,17 +192,17 @@ function do추방(General $general, int $myOfficerLevel): ?string
|
||||
$logger = $general->getLogger();
|
||||
|
||||
//이미 지정했다면 무시
|
||||
if (isOfficerSet($nation['chief_set'], $myOfficerLevel) || ($myOfficerLevel == 0 && $myOfficerLevel == 12)) {
|
||||
if(isOfficerSet($nation['chief_set'], $myOfficerLevel) || ($myOfficerLevel == 0 && $myOfficerLevel == 12)) {
|
||||
return '이미 추방 권한을 사용했습니다.';
|
||||
}
|
||||
$gold = 0;
|
||||
$rice = 0;
|
||||
// 금쌀1000이상은 남김
|
||||
if ($general->getVar('gold') > GameConst::$defaultGold) {
|
||||
if($general->getVar('gold') > GameConst::$defaultGold) {
|
||||
$gold = $general->getVar('gold') - GameConst::$defaultGold;
|
||||
$general->setVar('gold', GameConst::$defaultGold);
|
||||
}
|
||||
if ($general->getVar('rice') > GameConst::$defaultRice) {
|
||||
if($general->getVar('rice') > GameConst::$defaultRice) {
|
||||
$rice = $general->getVar('rice') - GameConst::$defaultRice;
|
||||
$general->setVar('rice', GameConst::$defaultRice);
|
||||
}
|
||||
@@ -240,26 +220,27 @@ function do추방(General $general, int $myOfficerLevel): ?string
|
||||
$logger->pushGeneralActionLog("<D><b>{$nationName}</b></>에서 <R>추방</>당했습니다.", ActionLogger::PLAIN);
|
||||
|
||||
// 명성/공헌 N*10%감소
|
||||
if ($env['year'] <= $env['startyear'] && $general->getNPCType() < 2) {
|
||||
if($env['year'] <= $env['startyear'] && $general->getNPCType() < 2){
|
||||
$general->setVar('makelimit', $oldMakeLimit);
|
||||
} else {
|
||||
}
|
||||
else{
|
||||
$betrayCnt = $general->getVar('betray');
|
||||
$general->addExperience(-$general->getVar('experience') * 0.15 * $betrayCnt);
|
||||
$general->addDedication(-$general->getVar('dedication') * 0.15 * $betrayCnt);
|
||||
$general->addExperience(-$general->getVar('experience')*0.15*$betrayCnt);
|
||||
$general->addDedication(-$general->getVar('dedication')*0.15*$betrayCnt);
|
||||
$general->increaseVarWithLimit('betray', 1, null, GameConst::$maxBetrayCnt);
|
||||
}
|
||||
|
||||
//부대장일 경우
|
||||
if ($general->getVar('troop') == $generalID) {
|
||||
if($general->getVar('troop') == $generalID){
|
||||
// 모두 탈퇴
|
||||
$db->update('general', [
|
||||
'troop' => 0,
|
||||
'troop'=>0,
|
||||
], 'troop = %i', $generalID);
|
||||
$db->delete('troop', 'troop_leader=%i', $generalID);
|
||||
}
|
||||
$general->setVar('troop', 0);
|
||||
|
||||
if ($general->getNPCType() >= 2) {
|
||||
if($general->getNPCType() >= 2){
|
||||
$rng = new RandUtil(new LiteHashDRBG(Util::simpleSerialize(
|
||||
UniqueConst::$hiddenSeed,
|
||||
'BanNPC',
|
||||
@@ -290,7 +271,7 @@ function do추방(General $general, int $myOfficerLevel): ?string
|
||||
$src,
|
||||
$src,
|
||||
$str,
|
||||
Message::gameNow(),
|
||||
new \DateTime(),
|
||||
new \DateTime('9999-12-31'),
|
||||
[]
|
||||
);
|
||||
@@ -298,24 +279,24 @@ function do추방(General $general, int $myOfficerLevel): ?string
|
||||
}
|
||||
}
|
||||
|
||||
if ($env['year'] < $env['startyear'] + 3) {
|
||||
if($env['year'] < $env['startyear']+3) {
|
||||
//초반엔 군주 부상 증가(엔장 임관지양)
|
||||
$db->update('general', [
|
||||
'injury' => $db->sqleval('least(injury + 1, %i)', 80),
|
||||
'injury'=>$db->sqleval('least(injury + 1, %i)', 80),
|
||||
], 'nation=%i AND officer_level=12', $nationID);
|
||||
|
||||
$db->update('nation', [
|
||||
'gennum' => $db->sqleval('gennum - %i', $general->getNPCType() != 5 ? 1 : 0),
|
||||
'gold' => $db->sqleval('gold + %i', $gold),
|
||||
'rice' => $db->sqleval('rice + %i', $rice),
|
||||
'gennum'=>$db->sqleval('gennum - %i', $general->getNPCType()!=5?1:0),
|
||||
'gold'=>$db->sqleval('gold + %i', $gold),
|
||||
'rice'=>$db->sqleval('rice + %i', $rice),
|
||||
], 'nation = %i', $nationID);
|
||||
} else {
|
||||
//이번분기는 추방불가(초반 제외)
|
||||
$db->update('nation', [
|
||||
'chief_set' => $db->sqleval('chief_set | %i', doOfficerSet(0, $myOfficerLevel)),
|
||||
'gennum' => $db->sqleval('gennum - %i', $general->getNPCType() != 5 ? 1 : 0),
|
||||
'gold' => $db->sqleval('gold + %i', $gold),
|
||||
'rice' => $db->sqleval('rice + %i', $rice),
|
||||
'chief_set'=>$db->sqleval('chief_set | %i', doOfficerSet(0, $myOfficerLevel)),
|
||||
'gennum'=>$db->sqleval('gennum - %i', $general->getNPCType()!=5?1:0),
|
||||
'gold'=>$db->sqleval('gold + %i', $gold),
|
||||
'rice'=>$db->sqleval('rice + %i', $rice),
|
||||
], 'nation = %i', $nationID);
|
||||
}
|
||||
|
||||
@@ -327,74 +308,62 @@ function do추방(General $general, int $myOfficerLevel): ?string
|
||||
|
||||
|
||||
|
||||
if ($action == "임명") {
|
||||
if (2 <= $officerLevel && $officerLevel <= 4) {
|
||||
if (!$destCityID) {
|
||||
if($action == "임명") {
|
||||
if(2 <= $officerLevel && $officerLevel <= 4){
|
||||
if(!$destCityID){
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => '도시가 지정되지 않았습니다.'
|
||||
'result'=>false,
|
||||
'reason'=>'도시가 지정되지 않았습니다.'
|
||||
]);
|
||||
}
|
||||
$result = do도시임명($general, $destCityID, $officerLevel);
|
||||
if ($result !== null) {
|
||||
if($result !== null){
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => $result
|
||||
'result'=>false,
|
||||
'reason'=>$result
|
||||
]);
|
||||
}
|
||||
//수뇌의 삭턴 리필
|
||||
$db->update('general', [
|
||||
'killturn' => $db->sqleval('GREATEST(%b, %i)', 'killturn', $gameStor->getValue('killturn')),
|
||||
], 'no=%i', $me['no']);
|
||||
Json::die([
|
||||
'result' => true,
|
||||
'reason' => 'success'
|
||||
'result'=>true,
|
||||
'reason'=>'success'
|
||||
]);
|
||||
}
|
||||
|
||||
if (5 <= $officerLevel && $officerLevel < 12) {
|
||||
if(5 <= $officerLevel && $officerLevel < 12){
|
||||
$result = do수뇌임명($general, $officerLevel);
|
||||
if ($result !== null) {
|
||||
if($result !== null){
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => $result
|
||||
'result'=>false,
|
||||
'reason'=>$result
|
||||
]);
|
||||
}
|
||||
//수뇌의 삭턴 리필
|
||||
$db->update('general', [
|
||||
'killturn' => $db->sqleval('GREATEST(%b, %i)', 'killturn', $gameStor->getValue('killturn')),
|
||||
], 'no=%i', $me['no']);
|
||||
Json::die([
|
||||
'result' => true,
|
||||
'reason' => 'success'
|
||||
'result'=>true,
|
||||
'reason'=>'success'
|
||||
]);
|
||||
}
|
||||
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => '올바르지 않은 지정입니다.'
|
||||
'result'=>false,
|
||||
'reason'=>'올바르지 않은 지정입니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
if ($action == "추방") {
|
||||
if($action == "추방") {
|
||||
$result = do추방($general, $myOfficerLevel);
|
||||
if ($result !== null) {
|
||||
if($result !== null){
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => $result
|
||||
'result'=>false,
|
||||
'reason'=>$result
|
||||
]);
|
||||
}
|
||||
//수뇌의 삭턴 리필
|
||||
$db->update('general', [
|
||||
'killturn' => $db->sqleval('GREATEST(%b, %i)', 'killturn', $gameStor->getValue('killturn')),
|
||||
], 'no=%i', $me['no']);
|
||||
Json::die([
|
||||
'result' => true,
|
||||
'reason' => 'success'
|
||||
'result'=>true,
|
||||
'reason'=>'success'
|
||||
]);
|
||||
}
|
||||
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => '올바르지 않은 명령입니다.'
|
||||
]);
|
||||
'result'=>false,
|
||||
'reason'=>'올바르지 않은 명령입니다.'
|
||||
]);
|
||||
@@ -8,7 +8,7 @@ include('func.php');
|
||||
|
||||
$session = Session::requireLogin([])->setReadOnly();
|
||||
|
||||
if(Session::getInstance()->userGrade < 6){
|
||||
if(Session::getInstance()->userGrade < 5){
|
||||
Json::die([
|
||||
'reason'=>'권한이 부족합니다.'
|
||||
]);
|
||||
|
||||
@@ -24,8 +24,8 @@ $db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$rootDB = RootDB::db();
|
||||
|
||||
$clock = GameClock::fromStorage($gameStor);
|
||||
$now = $clock->nowTick();
|
||||
$oNow = new \DateTimeImmutable();
|
||||
$now = $oNow->format('Y-m-d H:i:s');
|
||||
|
||||
$member = $rootDB->queryFirstRow('SELECT `name`, `penalty` FROM member WHERE `NO`=%i', $userID);
|
||||
if(!$member){
|
||||
@@ -41,7 +41,7 @@ $penaltyInfo = array_merge($memberPenalty['any'] ?? [], $memberPenalty[DB::prefi
|
||||
|
||||
$penalty = [];
|
||||
foreach($penaltyInfo as $penaltyKey => $penaltyValue){
|
||||
if(($penaltyValue['expire'] ?? 0) > TimeUtil::now()){
|
||||
if($penaltyValue['expire'] ?? 0 > TimeUtil::now()){
|
||||
$penalty[$penaltyKey] = $penaltyValue['value'];
|
||||
}
|
||||
}
|
||||
@@ -139,4 +139,4 @@ $rootDB->insert('member_log', [
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'reason'=>'success'
|
||||
]);
|
||||
]);
|
||||
@@ -8,20 +8,10 @@ WebUtil::requireAJAX();
|
||||
|
||||
$pick = Util::getPost('pick');
|
||||
$leadership = Util::getPost('leadership', 'int', GameConst::$defaultStatMin);
|
||||
$isCentennialAllStar = CentennialAllStarGrowthService::isActive();
|
||||
$strength = Util::getPost(
|
||||
$isCentennialAllStar ? 'strength' : 'leadership',
|
||||
'int',
|
||||
GameConst::$defaultStatMin
|
||||
);
|
||||
$intel = Util::getPost(
|
||||
$isCentennialAllStar ? 'intel' : 'leadership',
|
||||
'int',
|
||||
GameConst::$defaultStatMin
|
||||
);
|
||||
$strength = Util::getPost('leadership', 'int', GameConst::$defaultStatMin);
|
||||
$intel = Util::getPost('leadership', 'int', GameConst::$defaultStatMin);
|
||||
$personal = Util::getPost('personal', 'string', null);
|
||||
$use_own_picture = Util::getPost('use_own_picture', 'bool', false);
|
||||
$pictureSource = Util::getPost('picture_source', 'string', 'selected');
|
||||
|
||||
|
||||
if(!$pick){
|
||||
@@ -37,8 +27,8 @@ $db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
$rootDB = RootDB::db();
|
||||
$clock = GameClock::fromStorage($gameStor);
|
||||
$now = $clock->nowTick();
|
||||
$oNow = new \DateTimeImmutable();
|
||||
$now = $oNow->format('Y-m-d H:i:s');
|
||||
|
||||
$hasGeneralID = $db->queryFirstField('SELECT no FROM general WHERE owner = %i', $userID);
|
||||
if($hasGeneralID){
|
||||
@@ -70,39 +60,16 @@ if(!$selectInfo){
|
||||
}
|
||||
$selectInfo = Json::decode($selectInfo);
|
||||
|
||||
$ownerInfo = RootDB::db()->queryFirstRow(
|
||||
'SELECT `name`,`picture`,`imgsvr`,`grade` FROM member WHERE `NO`=%i',
|
||||
$userID
|
||||
);
|
||||
if(!$ownerInfo){
|
||||
$ownerInfo = RootDB::db()->queryFirstRow('SELECT `name`,`picture`,`imgsvr` FROM member WHERE `NO`=%i',$userID);
|
||||
if(!$ownerInfo){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'멤버 정보를 가져오지 못했습니다.'
|
||||
]);
|
||||
}
|
||||
if ($isCentennialAllStar) {
|
||||
if (!in_array($pictureSource, ['selected', 'own'], true)) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => '올바르지 않은 전콘 선택입니다.',
|
||||
]);
|
||||
}
|
||||
if ($pictureSource === 'own') {
|
||||
$canUseOwnPicture = in_array('picture', GameConst::$generalPoolAllowOption, true)
|
||||
&& $env['show_img_level'] >= 1
|
||||
&& $ownerInfo['grade'] >= 1
|
||||
&& $ownerInfo['picture'] !== '';
|
||||
if (!$canUseOwnPicture) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => '사용할 수 있는 내 전콘이 없습니다.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$gencount = $db->queryFirstField('SELECT count(`no`) FROM general WHERE npc<2');
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
$gencount = $db->queryFirstField('SELECT count(`no`) FROM general WHERE npc<2');
|
||||
|
||||
if ($gencount >= $maxgeneral) {
|
||||
Json::die([
|
||||
@@ -113,25 +80,12 @@ if ($gencount >= $maxgeneral) {
|
||||
|
||||
$poolClass = getGeneralPoolClass(GameConst::$targetGeneralPool);
|
||||
/** @var AbsGeneralPool */
|
||||
if ($isCentennialAllStar) {
|
||||
$rng = new RandUtil(new LiteHashDRBG(Util::simpleSerialize(
|
||||
UniqueConst::$hiddenSeed,
|
||||
'selectPickedGeneral',
|
||||
$userID,
|
||||
$pick
|
||||
)));
|
||||
$pickedGeneral = new $poolClass($db, $rng, $selectInfo, $now);
|
||||
} else {
|
||||
$pickedGeneral = new $poolClass($db, $selectInfo, $now);
|
||||
}
|
||||
$pickedGeneral = new $poolClass($db, $selectInfo, $now);
|
||||
|
||||
$builder = $pickedGeneral->getGeneralBuilder();
|
||||
if ($isCentennialAllStar) {
|
||||
CentennialAllStarGrowthService::prepareInitialUser($builder, $selectInfo);
|
||||
}
|
||||
|
||||
foreach(GameConst::$generalPoolAllowOption as $allowOption){
|
||||
if($allowOption == 'stat' && !$isCentennialAllStar){
|
||||
if($allowOption == 'stat'){
|
||||
$leadership = Util::valueFit($leadership, GameConst::$defaultStatMin, GameConst::$defaultStatMax);
|
||||
$strength = Util::valueFit($strength, GameConst::$defaultStatMin, GameConst::$defaultStatMax);
|
||||
$intel = Util::valueFit($intel, GameConst::$defaultStatMin, GameConst::$defaultStatMax);
|
||||
@@ -144,23 +98,14 @@ foreach(GameConst::$generalPoolAllowOption as $allowOption){
|
||||
}
|
||||
$builder->setStat($leadership, $strength, $intel);
|
||||
}
|
||||
else if(
|
||||
$allowOption == 'picture'
|
||||
&& (
|
||||
(!$isCentennialAllStar && $use_own_picture)
|
||||
|| ($isCentennialAllStar && $pictureSource === 'own')
|
||||
)
|
||||
){
|
||||
$builder->setPicture($ownerInfo['imgsvr'], $ownerInfo['picture']);
|
||||
else if($allowOption == 'picture' && $use_own_picture){
|
||||
$builder->setPicture($ownerInfo['imgsvr'], $ownerInfo['picture']);
|
||||
}
|
||||
else if($allowOption == 'ego'){
|
||||
if(!$personal || $personal == 'Random'){
|
||||
$personal = Util::choiceRandom(GameConst::$availablePersonality);
|
||||
}
|
||||
$invalidPersonal = $isCentennialAllStar
|
||||
? !in_array($personal, GameConst::$availablePersonality, true)
|
||||
: !array_search($personal, GameConst::$availablePersonality);
|
||||
if($invalidPersonal){
|
||||
if(!array_search($personal, GameConst::$availablePersonality)){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'올바르지 않은 성격입니다.'
|
||||
@@ -168,7 +113,7 @@ foreach(GameConst::$generalPoolAllowOption as $allowOption){
|
||||
}
|
||||
$builder->setEgo($personal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$userNick = $ownerInfo['name'];
|
||||
|
||||
@@ -176,29 +121,8 @@ $builder->setOwner($userID);
|
||||
$builder->setOwnerName($userNick);
|
||||
$builder->setKillturn(5);
|
||||
$builder->setNPCType(0);
|
||||
$builder->setAuxVar('next_change', $now + GameClock::TICKS_PER_TURN * 12);
|
||||
$builder->setAuxVar(
|
||||
'prestart_delete_after',
|
||||
addTurn($now, $env['turnterm'], GameConst::$minTurnDieOnPrestart)
|
||||
);
|
||||
$builder->setAuxVar('next_change', TimeUtil::nowAddMinutes(12 * $env['turnterm']));
|
||||
$builder->fillRemainSpecAsZero($env);
|
||||
if ($isCentennialAllStar) {
|
||||
$candidateCities = $db->queryFirstColumn(
|
||||
'SELECT city FROM city WHERE level >= 5 AND level <= 6 AND nation = 0'
|
||||
);
|
||||
if (!$candidateCities) {
|
||||
$candidateCities = $db->queryFirstColumn(
|
||||
'SELECT city FROM city WHERE level >= 5 AND level <= 6'
|
||||
);
|
||||
}
|
||||
if (!$candidateCities) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => '장수를 생성할 소·중성이 없습니다.',
|
||||
]);
|
||||
}
|
||||
$builder->setCityID($rng->choice($candidateCities));
|
||||
}
|
||||
$builder->build($env);
|
||||
$generalID = $builder->getGeneralID();
|
||||
if(!$generalID){
|
||||
@@ -243,4 +167,4 @@ $rootDB->insert('member_log', [
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'reason'=>'success'
|
||||
]);
|
||||
]);
|
||||
@@ -19,7 +19,6 @@ if(!class_exists('\\sammo\\DB')){
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$clock = GameClock::fromStorage($gameStor);
|
||||
|
||||
if(file_exists(__DIR__.'/.htaccess')){
|
||||
$reserved = $db->queryFirstRow(
|
||||
@@ -76,9 +75,8 @@ $admin['maxUserCnt'] = $admin['maxgeneral'];
|
||||
$admin['npcMode'] = $admin['npcmode'];
|
||||
$admin['turnTerm'] = $admin['turnterm'];
|
||||
$admin['isUnited'] = $admin['isunited'];
|
||||
$admin['isOpen'] = $clock->nowTick() >= Util::toInt($admin['opentime']);
|
||||
$admin['starttime'] = substr($clock->formatTick(Util::toInt($admin['opentime'])), 5, 11);
|
||||
$admin['turntime'] = substr($clock->formatTick(Util::toInt($admin['turntime'])), 5, 11);
|
||||
$admin['starttime'] = substr($admin['opentime'], 5, 11);
|
||||
$admin['turntime'] = substr($admin['turntime'], 5, 11);
|
||||
unset($admin['npcmode']);
|
||||
unset($admin['maxgeneral']);
|
||||
unset($admin['turnterm']);
|
||||
@@ -133,4 +131,4 @@ if($general){
|
||||
Json::die([
|
||||
'game'=>$admin,
|
||||
'me'=>$me?:null
|
||||
]);
|
||||
]);
|
||||
+15
-37
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
namespace sammo;
|
||||
|
||||
include "lib.php";
|
||||
@@ -25,13 +24,14 @@ if ($defence_train <= 40) {
|
||||
$defence_train = 40;
|
||||
}
|
||||
|
||||
if ($defence_train <= 90) {
|
||||
if($defence_train <= 90){
|
||||
$defence_train = Util::round($defence_train, -1);
|
||||
} else {
|
||||
}
|
||||
else{
|
||||
$defence_train = 999;
|
||||
}
|
||||
|
||||
if ($tnmt < 0 || $tnmt > 1) {
|
||||
if($tnmt < 0 || $tnmt > 1){
|
||||
$tnmt = 1;
|
||||
}
|
||||
|
||||
@@ -39,8 +39,8 @@ $db = DB::db();
|
||||
$me = General::createObjFromDB($generalID);
|
||||
|
||||
|
||||
if ($defence_train !== $me->getVar('defence_train')) {
|
||||
if ($defence_train == 999) {
|
||||
if($defence_train !== $me->getVar('defence_train')){
|
||||
if($defence_train == 999){
|
||||
$me->increaseVar('myset', -1);
|
||||
$me->setVar('defence_train', $defence_train);
|
||||
$affectedTrain = -3;
|
||||
@@ -49,7 +49,8 @@ if ($defence_train !== $me->getVar('defence_train')) {
|
||||
$affectedAtmos = $me->onCalcDomestic('changeDefenceTrain', "atmos{$defence_train}", $affectedAtmos);
|
||||
$me->increaseVarWithLimit('train', $affectedTrain, 20, GameConst::$maxTrainByWar);
|
||||
$me->increaseVarWithLimit('atmos', $affectedAtmos, 20, GameConst::$maxAtmosByWar);
|
||||
} else {
|
||||
}
|
||||
else{
|
||||
$me->increaseVar('myset', -1);
|
||||
$me->setVar('defence_train', $defence_train);
|
||||
}
|
||||
@@ -59,44 +60,21 @@ $me->setAuxVar('use_treatment', Util::valueFit($use_treatment, 10, 100));
|
||||
$me->setAuxVar('use_auto_nation_turn', $use_auto_nation_turn);
|
||||
$me->setVar('tnmt', $tnmt);
|
||||
|
||||
if ($me->getNPCType() == 1 && $detachNPC) {
|
||||
if($me->getNPCType() == 1 && $detachNPC){
|
||||
$turnterm = $gameStor->turnterm;
|
||||
|
||||
if ($turnterm < 10) {
|
||||
if($turnterm < 10){
|
||||
$targetKillTurn = 30 / $turnterm;
|
||||
} else {
|
||||
}
|
||||
else{
|
||||
$targetKillTurn = 60 / $turnterm;
|
||||
}
|
||||
$me->setVar('killturn', $targetKillTurn);
|
||||
}
|
||||
|
||||
$rootDB = RootDB::db();
|
||||
//회원 테이블에서 정보확인
|
||||
$member = $rootDB->queryFirstRow('SELECT `no`, id, picture, grade, `name`, imgsvr, `penalty` FROM member WHERE no=%i', $userID);
|
||||
|
||||
if (!$member) {
|
||||
//이런 경우가 있나?
|
||||
//TODO: 로그 남겨둘 것
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => '회원 정보를 찾을 수 없습니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
$memberPenalty = Json::decode($member['penalty'] ?? "{}");
|
||||
$penaltyInfo = array_merge($memberPenalty['any'] ?? [], $memberPenalty[DB::prefix()] ?? []);
|
||||
|
||||
$penalty = [];
|
||||
foreach ($penaltyInfo as $penaltyKey => $penaltyValue) {
|
||||
if (($penaltyValue['expire'] ?? 0) > TimeUtil::now()) {
|
||||
$penalty[$penaltyKey] = $penaltyValue['value'];
|
||||
}
|
||||
}
|
||||
$me->setVar('penalty', Json::encode($penalty));
|
||||
|
||||
$me->applyDB($db);
|
||||
|
||||
Json::die([
|
||||
'result' => true,
|
||||
'reason' => 'success'
|
||||
]);
|
||||
'result'=>true,
|
||||
'reason'=>'success'
|
||||
]);
|
||||
@@ -64,7 +64,6 @@ if ($permission < 3) {
|
||||
function applyNationPolicy($policy, $nationID, $generalName): ?string
|
||||
{
|
||||
$db = DB::db();
|
||||
$gameNow = GameClock::fromStorage(KVStorage::getStorage($db, 'game_env'))->formatNow();
|
||||
$nationStor = KVStorage::getStorage($db, $nationID, 'nation_env');
|
||||
|
||||
$defaultPolicy = AutorunNationPolicy::$defaultPolicy;
|
||||
@@ -140,7 +139,7 @@ function applyNationPolicy($policy, $nationID, $generalName): ?string
|
||||
|
||||
$nationPolicyRoot['values'] = $nationPolicy;
|
||||
$nationPolicyRoot['valueSetter'] = $generalName;
|
||||
$nationPolicyRoot['valueSetTime'] = $gameNow;
|
||||
$nationPolicyRoot['valueSetTime'] = TimeUtil::now();
|
||||
$nationStor->npc_nation_policy = $nationPolicyRoot;
|
||||
return null;
|
||||
}
|
||||
@@ -148,7 +147,6 @@ function applyNationPolicy($policy, $nationID, $generalName): ?string
|
||||
function applyNationPriority($priority, $nationID, $generalName): ?string
|
||||
{
|
||||
$db = DB::db();
|
||||
$gameNow = GameClock::fromStorage(KVStorage::getStorage($db, 'game_env'))->formatNow();
|
||||
$nationStor = KVStorage::getStorage($db, $nationID, 'nation_env');
|
||||
$nationPolicyRoot = $nationStor->npc_nation_policy;
|
||||
|
||||
@@ -160,7 +158,7 @@ function applyNationPriority($priority, $nationID, $generalName): ?string
|
||||
}
|
||||
$nationPolicyRoot['priority'] = $priority;
|
||||
$nationPolicyRoot['prioritySetter'] = $generalName;
|
||||
$nationPolicyRoot['prioritySetTime'] = $gameNow;
|
||||
$nationPolicyRoot['prioritySetTime'] = TimeUtil::now();
|
||||
$nationStor->npc_nation_policy = $nationPolicyRoot;
|
||||
return null;
|
||||
}
|
||||
@@ -168,7 +166,6 @@ function applyNationPriority($priority, $nationID, $generalName): ?string
|
||||
function applyGeneralPriority($priority, $nationID, $generalName): ?string
|
||||
{
|
||||
$db = DB::db();
|
||||
$gameNow = GameClock::fromStorage(KVStorage::getStorage($db, 'game_env'))->formatNow();
|
||||
$nationStor = KVStorage::getStorage($db, $nationID, 'nation_env');
|
||||
$generalPolicyRoot = $nationStor->npc_general_policy;
|
||||
|
||||
@@ -209,7 +206,7 @@ function applyGeneralPriority($priority, $nationID, $generalName): ?string
|
||||
|
||||
$generalPolicyRoot['priority'] = $priority;
|
||||
$generalPolicyRoot['prioritySetter'] = $generalName;
|
||||
$generalPolicyRoot['prioritySetTime'] = $gameNow;
|
||||
$generalPolicyRoot['prioritySetTime'] = TimeUtil::now();
|
||||
$nationStor->npc_general_policy = $generalPolicyRoot;
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -77,8 +77,7 @@ $month = $query['month'];
|
||||
$repeatCnt = $query['repeatCnt'];
|
||||
|
||||
$rawAttacker = $query['attackerGeneral'];
|
||||
$battleClock = GameClock::fromStorage(KVStorage::getStorage(DB::db(), 'game_env'));
|
||||
$rawAttacker['turntime'] = $battleClock->formatTick($battleClock->nowTick());
|
||||
$rawAttacker['turntime'] = TimeUtil::now();
|
||||
$rawAttackerCity = $query['attackerCity'];
|
||||
$rawAttackerNation = $query['attackerNation'];
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ include "func.php";
|
||||
WebUtil::requireAJAX();
|
||||
|
||||
$pick = Util::getPost('pick');
|
||||
$pictureSource = Util::getPost('picture_source', 'string', 'selected');
|
||||
|
||||
if(!$pick){
|
||||
Json::die([
|
||||
@@ -22,8 +21,8 @@ $db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
$rootDB = RootDB::db();
|
||||
$clock = GameClock::fromStorage($gameStor);
|
||||
$now = $clock->nowTick();
|
||||
$oNow = new \DateTimeImmutable();
|
||||
$now = $oNow->format('Y-m-d H:i:s');
|
||||
|
||||
$generalID = $db->queryFirstField('SELECT no FROM general WHERE owner = %i', $userID);
|
||||
if(!$generalID){
|
||||
@@ -36,20 +35,10 @@ if(!$generalID){
|
||||
list(
|
||||
$year,
|
||||
$month,
|
||||
$startYear,
|
||||
$maxgeneral,
|
||||
$npcmode,
|
||||
$turnterm,
|
||||
$showImgLevel
|
||||
) = $gameStor->getValuesAsArray([
|
||||
'year',
|
||||
'month',
|
||||
'startyear',
|
||||
'maxgeneral',
|
||||
'npcmode',
|
||||
'turnterm',
|
||||
'show_img_level',
|
||||
]);
|
||||
$turnterm
|
||||
) = $gameStor->getValuesAsArray(['year', 'month', 'maxgeneral', 'npcmode', 'turnterm']);
|
||||
|
||||
if($npcmode!=2){
|
||||
Json::die([
|
||||
@@ -66,10 +55,7 @@ if(!$info){
|
||||
]);
|
||||
}
|
||||
|
||||
$ownerInfo = RootDB::db()->queryFirstRow(
|
||||
'SELECT `name`,`picture`,`imgsvr`,`grade` FROM member WHERE `NO`=%i',
|
||||
$userID
|
||||
);
|
||||
$ownerInfo = RootDB::db()->queryFirstRow('SELECT `name`,`picture`,`imgsvr` FROM member WHERE `NO`=%i',$userID);
|
||||
if(!$ownerInfo){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
@@ -78,27 +64,6 @@ if(!$ownerInfo){
|
||||
}
|
||||
|
||||
$info = Json::decode($info);
|
||||
$isCentennialAllStar = CentennialAllStarGrowthService::isActive();
|
||||
if ($isCentennialAllStar) {
|
||||
if (!in_array($pictureSource, ['current', 'own', 'selected'], true)) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => '올바르지 않은 전콘 선택입니다.',
|
||||
]);
|
||||
}
|
||||
if ($pictureSource === 'own') {
|
||||
$canUseOwnPicture = in_array('picture', GameConst::$generalPoolAllowOption, true)
|
||||
&& $showImgLevel >= 1
|
||||
&& $ownerInfo['grade'] >= 1
|
||||
&& $ownerInfo['picture'] !== '';
|
||||
if (!$canUseOwnPicture) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => '사용할 수 있는 내 전콘이 없습니다.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$generalObj = General::createObjFromDB($generalID);
|
||||
@@ -136,52 +101,35 @@ $db->update('select_pool',[
|
||||
'reserved_until'=>null,
|
||||
], '(owner=%i or reserved_until < %s) AND general_id is NULL', $userID, $now);
|
||||
|
||||
if ($isCentennialAllStar) {
|
||||
CentennialAllStarGrowthService::prepareLegacyUserReselection($generalObj);
|
||||
CentennialAllStarGrowthService::applyTarget($generalObj, $info, [
|
||||
'startyear' => $startYear,
|
||||
'year' => $year,
|
||||
'month' => $month,
|
||||
]);
|
||||
} else {
|
||||
if(key_exists('leadership', $info)){
|
||||
$generalObj->updateVar('leadership', $info['leadership']);
|
||||
$generalObj->updateVar('strength', $info['strength']);
|
||||
$generalObj->updateVar('intel', $info['intel']);
|
||||
}
|
||||
if(key_exists('dex', $info)){
|
||||
$generalObj->updateVar('dex1', $info['dex'][0]);
|
||||
$generalObj->updateVar('dex2', $info['dex'][1]);
|
||||
$generalObj->updateVar('dex3', $info['dex'][2]);
|
||||
$generalObj->updateVar('dex4', $info['dex'][3]);
|
||||
$generalObj->updateVar('dex5', $info['dex'][4]);
|
||||
}
|
||||
if(key_exists('ego', $info)){
|
||||
$generalObj->updateVar('personal', $info['ego']);
|
||||
}
|
||||
if(key_exists('specialDomestic', $info)){
|
||||
$generalObj->updateVar('special', $info['specialDomestic']);
|
||||
}
|
||||
if(key_exists('specialWar', $info)){
|
||||
$generalObj->updateVar('special2', $info['specialWar']);
|
||||
}
|
||||
if(key_exists('leadership', $info)){
|
||||
$generalObj->updateVar('leadership', $info['leadership']);
|
||||
$generalObj->updateVar('strength', $info['strength']);
|
||||
$generalObj->updateVar('intel', $info['intel']);
|
||||
}
|
||||
if ($isCentennialAllStar) {
|
||||
if ($pictureSource === 'own') {
|
||||
$generalObj->updateVar('imgsvr', $ownerInfo['imgsvr']);
|
||||
$generalObj->updateVar('picture', $ownerInfo['picture']);
|
||||
} elseif ($pictureSource === 'selected' && key_exists('picture', $info)) {
|
||||
$generalObj->updateVar('imgsvr', $info['imgsvr']);
|
||||
$generalObj->updateVar('picture', $info['picture']);
|
||||
}
|
||||
} elseif(key_exists('picture', $info)){
|
||||
if(key_exists('picture', $info)){
|
||||
$generalObj->updateVar('imgsvr', $info['imgsvr']);
|
||||
$generalObj->updateVar('picture', $info['picture']);
|
||||
}
|
||||
if(key_exists('generalName', $info)){
|
||||
$generalObj->updateVar('name', $info['generalName']);
|
||||
}
|
||||
$generalObj->setAuxVar('next_change', $now + GameClock::TICKS_PER_TURN * 12);
|
||||
if(key_exists('dex', $info)){
|
||||
$generalObj->updateVar('dex1', $info['dex'][0]);
|
||||
$generalObj->updateVar('dex2', $info['dex'][1]);
|
||||
$generalObj->updateVar('dex3', $info['dex'][2]);
|
||||
$generalObj->updateVar('dex4', $info['dex'][3]);
|
||||
$generalObj->updateVar('dex5', $info['dex'][4]);
|
||||
}
|
||||
if(key_exists('ego', $info)){
|
||||
$generalObj->updateVar('personal', $info['ego']);
|
||||
}
|
||||
if(key_exists('specialDomestic', $info)){
|
||||
$generalObj->updateVar('special', $info['specialDomestic']);
|
||||
}
|
||||
if(key_exists('specialWar', $info)){
|
||||
$generalObj->updateVar('special2', $info['specialWar']);
|
||||
}
|
||||
$generalObj->setAuxVar('next_change', TimeUtil::nowAddMinutes(12 * $turnterm));
|
||||
|
||||
$userNick = $ownerInfo['name'];
|
||||
$generalObj->setVar('owner_name', $userNick);
|
||||
@@ -200,4 +148,4 @@ $generalObj->applyDB($db);
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'reason'=>'success'
|
||||
]);
|
||||
]);
|
||||
+2
-3
@@ -51,9 +51,8 @@ function MessageBox($str)
|
||||
|
||||
function LogText($prefix, $variable)
|
||||
{
|
||||
return;
|
||||
//$text = sprintf('%s : %s'."\r\n", $prefix, TVarDumper::dump($variable));
|
||||
//file_put_contents(ROOT.'/d_log/'.UniqueConst::$serverName.'_dbg_logs.txt', $text, FILE_APPEND);
|
||||
$text = sprintf('%s : %s'."\r\n", $prefix, TVarDumper::dump($variable));
|
||||
file_put_contents(ROOT.'/d_log/'.UniqueConst::$serverName.'_dbg_logs.txt', $text, FILE_APPEND);
|
||||
}
|
||||
|
||||
function prepareDir(string $dirPath, bool $forceCreate=true):bool{
|
||||
|
||||
@@ -0,0 +1,430 @@
|
||||
<?php
|
||||
|
||||
namespace sammo;
|
||||
|
||||
use sammo\DTO\VoteInfo;
|
||||
use sammo\Enums\GeneralQueryMode;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
$session = Session::requireLogin()->loginGame()->setReadOnly();
|
||||
$userID = Session::getUserID();
|
||||
|
||||
increaseRefresh("메인", 1);
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
if (!$userID) {
|
||||
header('Location:..');
|
||||
die();
|
||||
}
|
||||
|
||||
//턴 실행.
|
||||
TurnExecutionHelper::executeAllCommand();
|
||||
|
||||
if (!$session->isGameLoggedIn()) {
|
||||
header('Location:..');
|
||||
die();
|
||||
}
|
||||
|
||||
$me = $db->queryFirstRow(
|
||||
'SELECT no,refresh_score,turntime,newmsg,newvote,`officer_level` FROM `general`
|
||||
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner = %i',
|
||||
$userID
|
||||
);
|
||||
|
||||
//그새 사망이면
|
||||
if ($me === null) {
|
||||
$session->logoutGame();
|
||||
header('Location: ../');
|
||||
die();
|
||||
}
|
||||
|
||||
$gameStor->cacheAll(true);
|
||||
|
||||
if ($me['newmsg'] == 1 || $me['newvote'] == 1) {
|
||||
$db->update('general', [
|
||||
'newmsg' => 0,
|
||||
'newvote' => 0
|
||||
], 'owner=%i', $userID);
|
||||
}
|
||||
|
||||
$plock = boolval($db->queryFirstField('SELECT plock FROM plock WHERE `type`="GAME" LIMIT 1'));
|
||||
|
||||
$limitState = checkLimit($me['refresh_score']);
|
||||
if ($limitState >= 2) {
|
||||
printLimitMsg($me['turntime']);
|
||||
exit();
|
||||
}
|
||||
|
||||
$generalObj = General::createObjFromDB($me['no'], null, GeneralQueryMode::FullWithAccessLog);
|
||||
$generalObj->setRawCity($db->queryFirstRow('SELECT * FROM city WHERE city = %i', $generalObj->getCityID()));
|
||||
$scenario = $gameStor->scenario_text;
|
||||
|
||||
$nationID = $generalObj->getNationID();
|
||||
if ($nationID) {
|
||||
$nationStor = KVStorage::getStorage($db, $nationID, 'nation_env');
|
||||
$nationStor->cacheAll();
|
||||
}
|
||||
|
||||
if ($gameStor->extended_general == 0) {
|
||||
$extend = "표준";
|
||||
} else {
|
||||
$extend = "확장";
|
||||
}
|
||||
if ($gameStor->fiction == 0) {
|
||||
$fiction = "사실";
|
||||
} else {
|
||||
$fiction = "가상";
|
||||
}
|
||||
if ($gameStor->npcmode == 0) {
|
||||
$npcmode = "불가능";
|
||||
} else if ($gameStor->npcmode == 1) {
|
||||
$npcmode = "가능";
|
||||
} else {
|
||||
$npcmode = "선택 생성";
|
||||
}
|
||||
$color = "cyan";
|
||||
$serverName = UniqueConst::$serverName;
|
||||
$serverCnt = $gameStor->server_cnt;
|
||||
|
||||
$auctionCount = $db->queryFirstField('SELECT count(*) FROM ng_auction WHERE finished = 0');
|
||||
$isTournamentActive = $gameStor->tournament > 0;
|
||||
$isTournamentApplicationOpen = $gameStor->tournament == 1;
|
||||
$isBettingActive = $gameStor->tournament == 6;
|
||||
|
||||
$myNationStatic = getNationStaticInfo($generalObj->getNationID());
|
||||
$nationColorType = substr($myNationStatic['color'] ?? '#000000', 1);
|
||||
|
||||
$autorunUser = ($gameStor->autorun_user) ?? [];
|
||||
$otherTextInfo = [];
|
||||
|
||||
if ($gameStor->join_mode == 'onlyRandom') {
|
||||
$otherTextInfo[] = '랜덤 임관 전용';
|
||||
}
|
||||
if ($autorunUser['limit_minutes'] ?? false) {
|
||||
$otherTextInfo[] = getAutorunInfo($autorunUser);
|
||||
}
|
||||
|
||||
if (!$otherTextInfo) {
|
||||
$otherTextInfo = '표준';
|
||||
} else {
|
||||
$otherTextInfo = join(', ', $otherTextInfo);
|
||||
}
|
||||
|
||||
$lastVoteID = $gameStor->lastVote;
|
||||
$lastVote = null;
|
||||
if ($lastVoteID) {
|
||||
$voteStor = KVStorage::getStorage($db, 'vote');
|
||||
$lastVote = VoteInfo::fromArray($voteStor->getValue("vote_{$lastVoteID}"));
|
||||
if ($lastVote->endDate && $lastVote->endDate < TimeUtil::now()) {
|
||||
$lastVote = null;
|
||||
}
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title><?= $serverName ?>: 메인</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=500" />
|
||||
<?= WebUtil::printJS('../d_shared/common_path.js') ?>
|
||||
<?= WebUtil::printJS('d_shared/base_map.js') ?>
|
||||
<?= WebUtil::printCSS('../d_shared/common.css') ?>
|
||||
<?= WebUtil::printDist('vue', 'v_main', true) ?>
|
||||
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
|
||||
<?= WebUtil::printCSS('css/map.css') ?>
|
||||
<?= WebUtil::printStaticValues([
|
||||
//deprecated, staticValues를 이용할 것
|
||||
'serverName' => $serverName,
|
||||
'serverCnt' => $serverCnt,
|
||||
'serverNick' => DB::prefix(),
|
||||
'serverID' => UniqueConst::$serverID,
|
||||
'maxTurn' => GameConst::$maxTurn,
|
||||
'maxPushTurn' => 12,
|
||||
'serverNow' => TimeUtil::now(false),
|
||||
'lastExecuted' => $gameStor->turntime,
|
||||
'isLocked' => $plock,
|
||||
'isTournamentActive' => $isTournamentActive,
|
||||
'isBettingActive' => $isBettingActive,
|
||||
'staticValues' => [
|
||||
'serverName' => $serverName,
|
||||
'serverCnt' => $serverCnt,
|
||||
'serverNick' => DB::prefix(),
|
||||
'serverID' => UniqueConst::$serverID,
|
||||
'maxTurn' => GameConst::$maxTurn,
|
||||
'maxPushTurn' => 12,
|
||||
'serverNow' => TimeUtil::now(false),
|
||||
'lastExecuted' => $gameStor->turntime,
|
||||
'isLocked' => $plock,
|
||||
'isTournamentActive' => $isTournamentActive,
|
||||
'isBettingActive' => $isBettingActive,
|
||||
'mapName' => GameConst::$mapName,
|
||||
'unitSet' => GameConst::$unitSet,
|
||||
]
|
||||
]) ?>
|
||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
|
||||
</head>
|
||||
|
||||
<body class="img_back sam-color-<?= $nationColorType ?>">
|
||||
<div id="container" class="bg0">
|
||||
<div class="row toolbars gx-0">
|
||||
<div class="buttonPlate"><?= allButton($gameStor->npcmode == 1) ?></button></div>
|
||||
</div>
|
||||
<div class="tb_layout row gx-0">
|
||||
<div id="server_title" class="row py-2 center">
|
||||
<h3>삼국지 모의전투 HiDCHe <?= $serverName . $serverCnt ?>기 <span class="avoid-wrap">(<font color=cyan><?= $scenario ?></font>)</span></h3>
|
||||
</div>
|
||||
|
||||
<div class="row center gx-0">
|
||||
<div class="s-border-t col py-2 col-8 col-lg-4" style="color:<?= $color ?>;">
|
||||
<?= $scenario ?>
|
||||
</div>
|
||||
<div class="s-border-t col py-2 col-4 col-lg-2" style="color:<?= $color ?>;">
|
||||
NPC 수, 상성 : <?= $extend ?>,<?= $fiction ?>
|
||||
</div>
|
||||
<div class="s-border-t col py-2 col-4 col-lg-2" style="color:<?= $color ?>;">
|
||||
NPC선택 : <?= $npcmode ?>
|
||||
</div>
|
||||
<div class="s-border-t col py-2 col-4 col-lg-2" style="color:<?= $color ?>;">
|
||||
토너먼트 : <?= getTournamentTermText($gameStor->turnterm) ?>
|
||||
</div>
|
||||
<div class="s-border-t col py-2 col-4 col-lg-2" style="color:<?= $color ?>;">
|
||||
기타 설정: <?= $otherTextInfo ?>
|
||||
</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-4 col-lg-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-8 col-lg-4"><?= info(3) ?></div>
|
||||
<div class="s-border-t py-2 col col-6 col-lg-4">
|
||||
<?php if ($isTournamentActive) : ?>
|
||||
↑<span style='color:cyan'><?= (['전력전', '통솔전', '일기토', '설전',])[$gameStor->tnmt_type] ?? '' ?> <?= getTournament($gameStor->tournament) ?> <?= getTournamentTime() ?></span>↑
|
||||
<?php else : ?>
|
||||
<span style='color:magenta'>현재 토너먼트 경기 없음</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="s-border-t py-2 col col-6 col-lg-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>
|
||||
<div class="s-border-t py-2 col col-6 col-lg-2">
|
||||
<?php if ($auctionCount > 0) : ?>
|
||||
<span style='color:cyan'><?= $auctionCount ?>건</span> 거래 진행중
|
||||
<?php else : ?>
|
||||
<span style='color:magenta'>진행중 거래 없음</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="s-border-t py-2 col col-6 col-lg-4 vote-cell">
|
||||
<?php
|
||||
?>
|
||||
<?php if ($lastVote === null) : ?>
|
||||
<span style='color:magenta'>진행중 설문 없음</span>
|
||||
<?php else : ?>
|
||||
<span style='color:cyan'>설문 진행중</span> : <span><?= $lastVote->title ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row gx-0">
|
||||
<div class="col s-border-t px-2 py-2">접속중인 국가: <?= $gameStor->online_nation ?></div>
|
||||
</div>
|
||||
<div class="row gx-0">
|
||||
<div class="col s-border-t px-2 py-2">운영자 메세지 : <span style='color:yellow;'><?= $gameStor->msg ?></span></div>
|
||||
</div>
|
||||
<div class="row gx-0">
|
||||
<div class="col s-border-t py-2" id="nation-msg-position">
|
||||
<div class="px-2">【 국가방침 】</div>
|
||||
<div id='nation-msg-box'>
|
||||
<div id='nation-msg'><?= nationMsg($generalObj) ?></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row gx-0">
|
||||
<div class="col s-border-t px-2 py-2">
|
||||
【 접속자 】<?= onlinegen($generalObj) ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php if ($session->userGrade >= 5) : ?>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<a href='_admin1.php' target='_blank'><button type='button'>게임관리</button></a>
|
||||
<a href='_admin2.php' target='_blank'><button type='button'>회원관리</button></a>
|
||||
<a href='_admin4.php' target='_blank'><button type='button'>멀티관리</button></a>
|
||||
<a href='_admin5.php' target='_blank'><button type='button'>일제정보</button></a>
|
||||
<a href='_admin7.php' target='_blank'><button type='button'>로그정보</button></a>
|
||||
<a href='_admin8.php' target='_blank'><button type='button'>외교정보</button></a>
|
||||
<a href='_119.php' target='_blank'><button type='button'>119</button></a>
|
||||
</div>
|
||||
</div>
|
||||
<?php elseif ($session->userGrade == 4) : ?>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<a href='_119.php' target='_blank'><button type='button'>119</button></a>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div id="map_view" class="gx-0">
|
||||
<div id="mapZone" class="view-item"><?= getMapHtml() ?></div>
|
||||
<div class="view-item" id="reservedCommandZone">
|
||||
<div id="reservedCommandList"></div>
|
||||
<div id="actionMiniPlate" class="gx-0 row">
|
||||
<div class="col">
|
||||
<div class="gx-1 row">
|
||||
<div class="col-8 d-grid"><button type='button' class='btn btn-sammo-base2 refreshPage'>갱 신</button></div>
|
||||
<div class="col-4 d-grid"><button type='button' class='btn btn-sammo-base2' onclick="location.replace('../')">로비로</button></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="cityInfo" class="view-item" style="border:none;text-align:center;"><?= cityInfo($generalObj) ?></div>
|
||||
<div id="nation-position"><?php myNationInfo($generalObj); ?></div>
|
||||
<div id="general-position"><?php generalInfo($generalObj); ?></div>
|
||||
<div id="generalCommandButton" class="row gx-0">
|
||||
<div class="buttonPlate bg2">
|
||||
?></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="actionMiniPlateSub" class="gx-0 row">
|
||||
<div class="col">
|
||||
<div class="gx-1 row">
|
||||
<div class="col-3 d-grid"><button type='button' class="btn btn-dark" onclick="scrollHardTo('reservedCommandList')">명령으로</button></div>
|
||||
<div class="col-5 d-grid"><button type='button' class='btn btn-sammo-base2 refreshPage'>갱 신</button></div>
|
||||
<div class="col-4 d-grid"><button type='button' class='btn btn-sammo-base2' onclick="location.replace('../')">로비로</button></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row gx-0">
|
||||
<div class="col-lg-6" id="general_public_record-position">
|
||||
<div class="bg1 center s-border-tb"><b>장수 동향</b></div>
|
||||
<div id="general_public_record" style="text-align:left;"><?= formatHistoryToHTML(getGlobalActionLogRecent(15)) ?></div>
|
||||
</div>
|
||||
<div class="col-lg-6" id="general_log-position">
|
||||
<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>
|
||||
<div class="col-12" id="world_history-position">
|
||||
<div class="bg1 center s-border-tb"><b>중원 정세</b></div>
|
||||
<div id="world_history" colspan=2 style="text-align:left;"><?= formatHistoryToHTML(getGlobalHistoryLogRecent(15)) ?></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row toolbars gx-0">
|
||||
<div class="buttonPlate"><?= allButton($gameStor->npcmode == 1) ?></div>
|
||||
|
||||
<div id="message_board" class="row gx-0">
|
||||
<div class="message_input_form bg0 gx-0 row">
|
||||
<div id="mailbox_list-col" class="col-6 col-lg-2 d-grid">
|
||||
<select id="mailbox_list" size="1" class="form-control bg-dark text-white">
|
||||
</select>
|
||||
</div>
|
||||
<div id="msg_input-col" class="col-12 col-lg-8 d-grid">
|
||||
<input type="text" id="msg_input" maxlength="99" class="form-control">
|
||||
</div>
|
||||
<div id="msg_submit-col" class="col-6 col-lg-2 d-grid"><button id="msg_submit" class="btn btn-primary">서신전달&갱신</button></div>
|
||||
</div>
|
||||
<div class="col-lg-6 board_side bg0"><a id="public_talk_position"></a>
|
||||
<div class="board_header bg0">전체 메시지(최고99자)</div>
|
||||
<section class="public_message">
|
||||
<div class="d-grid"><button type="button" class="load_old_message btn btn-secondary" data-msg_type="public">이전 메시지 불러오기</button></div>
|
||||
</section>
|
||||
</div>
|
||||
<div class="col-lg-6 board_side bg0"><a id="national_talk_position"></a>
|
||||
<div class="board_header bg0">국가 메시지(최고99자)</div>
|
||||
<section class="national_message">
|
||||
<div class="d-grid"><button type="button" class="load_old_message btn btn-secondary" data-msg_type="national">이전 메시지 불러오기</button></div>
|
||||
</section>
|
||||
</div>
|
||||
<div class="col-lg-6 board_side bg0"><a id="private_talk_position"></a>
|
||||
<div class="board_header bg0">개인 메시지(최고99자)</div>
|
||||
<section class="private_message">
|
||||
<div class="d-grid"><button type="button" class="load_old_message btn btn-secondary" data-msg_type="private">이전 메시지 불러오기</button></div>
|
||||
</section>
|
||||
</div>
|
||||
<div class="col-lg-6 board_side bg0"><a id="diplomacy_talk_position"></a>
|
||||
<div class="board_header bg0">외교 메시지(최고99자)</div>
|
||||
<section class="diplomacy_message">
|
||||
<div class="d-grid"><button type="button" class="load_old_message btn btn-secondary" data-msg_type="diplomacy">이전 메시지 불러오기</button></div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row toolbars gx-0">
|
||||
<div class="buttonPlate"><?= allButton($gameStor->npcmode == 1) ?></div><?= banner() ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
if ($limitState == 1) {
|
||||
MessageBox("접속제한이 얼마 남지 않았습니다!");
|
||||
}
|
||||
if ($me['newmsg'] == 1) {
|
||||
MessageBox("새로운 서신이 도착했습니다!");
|
||||
}
|
||||
if ($me['newvote'] == 1) {
|
||||
$develcost = $gameStor->develcost * 5;
|
||||
MessageBox("설문조사에 참여하시면 금{$develcost}과 유니크템을 드립니다! (우측 상단 설문조사 메뉴)");
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<nav class="navbar navbar-expand fixed-bottom navbar-dark bg-dark d-sm-block d-lg-none p-0" id="navbar500">
|
||||
<div class="container-fluid px-0">
|
||||
<div class="collapse navbar-collapse">
|
||||
<ul class="navbar-nav me-auto mx-auto">
|
||||
<li class="nav-item dropup">
|
||||
<div class="dropdown-toggle text-white btn btn-sammo-base2" id="navbarGlobal" role="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
외부 메뉴
|
||||
</div>
|
||||
<ul class="dropdown-menu dropdown-menu-start" aria-labelledby="navbarGlobal" id="navbarGlobalItems">
|
||||
<?= allButton($gameStor->npcmode == 1, ['btnBegin' => '<li>', 'btnEnd' => '</li>', 'btnClass' => 'dropdown-item']) ?>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="nav-item dropup">
|
||||
<div class="dropdown-toggle btn btn-sammo-nation" id="navbarNation" role="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
국가 메뉴
|
||||
</div>
|
||||
<ul class="dropdown-menu" aria-labelledby="navbarNation" id="navbarNationItems">
|
||||
</ul>
|
||||
</li>
|
||||
<li class="nav-item dropup">
|
||||
<div class="dropdown-toggle text-white btn btn-dark" id="navbarQuick" role="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
빠른 이동
|
||||
</div>
|
||||
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown" id="navbarQuickItems">
|
||||
<li><a class="dropdown-item disabled">국가 정보</a></button></li>
|
||||
<hr class="dropdown-divider">
|
||||
</hr>
|
||||
<li><button type="button" onclick="scrollHardTo('nation-msg-position')" class="dropdown-item">방침</button></li>
|
||||
<li><button type="button" onclick="scrollHardTo('reservedCommandList')" class="dropdown-item">명령</button></li>
|
||||
<li><button type="button" onclick="scrollHardTo('nation-position')" class="dropdown-item">국가</button></li>
|
||||
<li><button type="button" onclick="scrollHardTo('general-position')" class="dropdown-item">장수</button></li>
|
||||
<li><button type="button" onclick="scrollHardTo('cityInfo')" class="dropdown-item">도시</button></li>
|
||||
<li><a class="dropdown-item disabled">동향 정보</a></button></li>
|
||||
<hr class="dropdown-divider">
|
||||
</hr>
|
||||
<li><button type="button" onclick="scrollHardTo('mapZone')" class="dropdown-item">지도</button></li>
|
||||
<li><button type="button" onclick="scrollHardTo('general_public_record-position')" class="dropdown-item">동향</button></li>
|
||||
<li><button type="button" onclick="scrollHardTo('general_log-position')" class="dropdown-item">개인</button></li>
|
||||
<li><button type="button" onclick="scrollHardTo('world_history-position')" class="dropdown-item">정세</button></li>
|
||||
<li><span> </span></li>
|
||||
<li><a class="dropdown-item disabled">메시지</a></button></li>
|
||||
<hr class="dropdown-divider">
|
||||
</hr>
|
||||
<li><button type="button" onclick="scrollHardTo('public_talk_position')" class="dropdown-item">전체</button></li>
|
||||
<li><button type="button" onclick="scrollHardTo('national_talk_position')" class="dropdown-item">국가</button></li>
|
||||
<li><button type="button" onclick="scrollHardTo('private_talk_position')" class="dropdown-item">개인</button></li>
|
||||
<li><button type="button" onclick="scrollHardTo('diplomacy_talk_position')" class="dropdown-item">외교</button></li>
|
||||
<li><button type='button' class='btn btn-sammo-base2' onclick="location.replace('../')">로비로</button></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="refreshPage btn btn-sammo-base2 text-white" role="button">갱신</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
+1
-11
@@ -8,14 +8,4 @@ $session = Session::getInstance()->setReadOnly();
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
$updated = false;
|
||||
$locked = false;
|
||||
$lastExecuted = TurnExecutionHelper::executeAllCommand($updated, $locked);
|
||||
$clock = GameClock::fromStorage(KVStorage::getStorage($db, 'game_env'));
|
||||
Json::die([
|
||||
'result' => true,
|
||||
'updated' => $updated,
|
||||
'locked' => $locked,
|
||||
'lastExecutedTick' => $lastExecuted,
|
||||
'lastExecuted' => $clock->formatTick($lastExecuted, true),
|
||||
]);
|
||||
TurnExecutionHelper::executeAllCommand();
|
||||
|
||||
+10
-13
@@ -526,7 +526,7 @@ function DeleteConflict($nation)
|
||||
function getConquerNation($city): int
|
||||
{
|
||||
$conflict = Json::decode($city['conflict']);
|
||||
return array_key_first($conflict);
|
||||
return Util::array_first_key($conflict);
|
||||
}
|
||||
|
||||
function ConquerCity(array $admin, General $general, array $city, array $defenderCityGeneralList)
|
||||
@@ -718,17 +718,14 @@ function ConquerCity(array $admin, General $general, array $city, array $defende
|
||||
$attackerLogger->pushGlobalHistoryLog("<M><b>【긴급천도】</b></><D><b>{$defenderNationName}</b></>{$josaYi} 수도가 함락되어 <G><b>$minCityName</b></>{$josaRo} 긴급천도하였습니다.");
|
||||
|
||||
$moveLog = "수도가 함락되어 <G><b>$minCityName</b></>{$josaRo} <M>긴급천도</>합니다.";
|
||||
foreach ($db->queryAllLists(
|
||||
'SELECT no, officer_level FROM general WHERE nation=%i',
|
||||
//아국 수뇌부에게 로그 전달
|
||||
foreach ($db->queryFirstColumn(
|
||||
'SELECT no FROM general WHERE nation=%i AND officer_level>=5',
|
||||
$defenderNationID
|
||||
) as [$defenderGeneralID, $defenderGeneralChiefLevel]) {
|
||||
$defenderLogger = new ActionLogger($defenderGeneralID, $defenderNationID, $year, $month);
|
||||
$defenderLogger->pushGeneralActionLog($moveLog, ActionLogger::PLAIN);
|
||||
if($defenderGeneralChiefLevel >= 5){
|
||||
$defenderLogger->pushGeneralActionLog("수뇌는 <G><b>{$minCityName}</b></>{$josaRo} 집합되었습니다.");
|
||||
}
|
||||
|
||||
$defenderLogger->flush();
|
||||
) as $defenderChiefID) {
|
||||
$chiefLogger = new ActionLogger($defenderChiefID, $defenderNationID, $year, $month);
|
||||
$chiefLogger->pushGeneralActionLog($moveLog, ActionLogger::PLAIN);
|
||||
$chiefLogger->flush();
|
||||
}
|
||||
|
||||
//천도
|
||||
@@ -785,8 +782,8 @@ function ConquerCity(array $admin, General $general, array $city, array $defende
|
||||
'officer_set' => 0,
|
||||
];
|
||||
if ($city['level'] > 3) {
|
||||
$query['def'] = GameConst::$defaultCityWall;
|
||||
$query['wall'] = GameConst::$defaultCityWall;
|
||||
$query['def'] = 1000;
|
||||
$query['wall'] = 1000;
|
||||
} else {
|
||||
$query['def'] = $db->sqleval('def_max/2');
|
||||
$query['wall'] = $db->sqleval('wall_max/2');
|
||||
|
||||
@@ -21,7 +21,7 @@ class BidUniqueAuction extends \sammo\BaseAPI
|
||||
])
|
||||
->rule('int', 'amount')
|
||||
->rule('int', 'auctionID')
|
||||
->rule('boolean', 'extendCloseTick');
|
||||
->rule('boolean', 'extendCloseDate');
|
||||
|
||||
if (!$v->validate()) {
|
||||
return $v->errorStr();
|
||||
@@ -38,7 +38,7 @@ class BidUniqueAuction extends \sammo\BaseAPI
|
||||
{
|
||||
$auctionID = $this->args['auctionID'];
|
||||
$amount = $this->args['amount'];
|
||||
$tryExtendCloseDate = $this->args['extendCloseTick'] ?? false;
|
||||
$tryExtendCloseDate = $this->args['extendCloseDate'] ?? false;
|
||||
|
||||
$generalID = $session->generalID;
|
||||
$general = General::createObjFromDB($generalID);
|
||||
|
||||
@@ -15,8 +15,6 @@ use sammo\General;
|
||||
use sammo\Json;
|
||||
use sammo\TimeUtil;
|
||||
use sammo\Util;
|
||||
use sammo\GameClock;
|
||||
use sammo\KVStorage;
|
||||
|
||||
use function sammo\getAuctionLogRecent;
|
||||
|
||||
@@ -35,13 +33,12 @@ class GetActiveResourceAuctionList extends \sammo\BaseAPI
|
||||
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag): null | string | array | APIRecoveryType
|
||||
{
|
||||
$db = DB::db();
|
||||
$clock = GameClock::fromStorage(KVStorage::getStorage($db, 'game_env'));
|
||||
|
||||
$buyRiceList = [];
|
||||
$sellRiceList = [];
|
||||
/** @var AuctionInfo[] */
|
||||
$auctions = array_map(fn ($raw) => AuctionInfo::fromArray($raw), $db->query(
|
||||
'SELECT * FROM `ng_auction` WHERE `type` IN %ls AND `finished` = 0 ORDER BY `close_tick` ASC',
|
||||
'SELECT * FROM `ng_auction` WHERE `type` IN %ls AND `finished` = 0 ORDER BY `close_date` ASC',
|
||||
[
|
||||
AuctionType::BuyRice->value,
|
||||
AuctionType::SellRice->value,
|
||||
@@ -90,8 +87,8 @@ class GetActiveResourceAuctionList extends \sammo\BaseAPI
|
||||
'type' => $auction->type->value,
|
||||
'hostGeneralID' => $auction->hostGeneralID,
|
||||
'hostName' => $auction->detail->hostName,
|
||||
'openDate' => $clock->formatTick($auction->openTick),
|
||||
'closeDate' => $clock->formatTick($auction->closeTick),
|
||||
'openDate' => TimeUtil::format($auction->openDate, false),
|
||||
'closeDate' => TimeUtil::format($auction->closeDate, false),
|
||||
'amount' => $auction->detail->amount,
|
||||
'startBidAmount' => $auction->detail->startBidAmount,
|
||||
'finishBidAmount' => $auction->detail->finishBidAmount,
|
||||
|
||||
@@ -14,8 +14,6 @@ use sammo\Enums\GeneralQueryMode;
|
||||
use sammo\Enums\InheritanceKey;
|
||||
use sammo\InheritancePointManager;
|
||||
use sammo\TimeUtil;
|
||||
use sammo\GameClock;
|
||||
use sammo\KVStorage;
|
||||
use sammo\Validator;
|
||||
use sammo\General;
|
||||
|
||||
@@ -44,7 +42,6 @@ class GetUniqueItemAuctionDetail extends \sammo\BaseAPI
|
||||
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag): null | string | array | APIRecoveryType
|
||||
{
|
||||
$db = DB::db();
|
||||
$clock = GameClock::fromStorage(KVStorage::getStorage($db, 'game_env'));
|
||||
|
||||
$generalID = $session->generalID;
|
||||
$auctionID = $this->args['auctionID'];
|
||||
@@ -95,11 +92,9 @@ class GetUniqueItemAuctionDetail extends \sammo\BaseAPI
|
||||
'target' => $auction->target,
|
||||
'isCallerHost' => $auction->hostGeneralID === $generalID,
|
||||
'hostName' => $auction->detail->hostName,
|
||||
'closeDate' => $clock->formatTick($auction->closeTick),
|
||||
'closeDate' => TimeUtil::format($auction->closeDate, false),
|
||||
'remainCloseDateExtensionCnt' => $auction->detail->remainCloseDateExtensionCnt,
|
||||
'availableLatestBidCloseDate' => $auction->detail->availableLatestBidCloseTick === null
|
||||
? null
|
||||
: $clock->formatTick($auction->detail->availableLatestBidCloseTick),
|
||||
'availableLatestBidCloseDate' => TimeUtil::format($auction->detail->availableLatestBidCloseDate, false),
|
||||
],
|
||||
'bidList' => $responseBid,
|
||||
'obfuscatedName' => $obfuscatedName,
|
||||
|
||||
@@ -12,8 +12,6 @@ use sammo\Enums\APIRecoveryType;
|
||||
use sammo\Enums\AuctionType;
|
||||
use sammo\TimeUtil;
|
||||
use sammo\Util;
|
||||
use sammo\GameClock;
|
||||
use sammo\KVStorage;
|
||||
|
||||
class GetUniqueItemAuctionList extends \sammo\BaseAPI
|
||||
{
|
||||
@@ -30,13 +28,12 @@ class GetUniqueItemAuctionList extends \sammo\BaseAPI
|
||||
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag): null | string | array | APIRecoveryType
|
||||
{
|
||||
$db = DB::db();
|
||||
$clock = GameClock::fromStorage(KVStorage::getStorage($db, 'game_env'));
|
||||
|
||||
$generalID = $session->generalID;
|
||||
|
||||
/** @var AuctionInfo[] */
|
||||
$auctions = array_map(fn($raw)=>AuctionInfo::fromArray($raw), $db->query(
|
||||
'SELECT * FROM `ng_auction` WHERE `type` = %s ORDER BY `close_tick` ASC',
|
||||
'SELECT * FROM `ng_auction` WHERE `type` = %s ORDER BY `close_date` ASC',
|
||||
AuctionType::UniqueItem->value
|
||||
) ?? []);
|
||||
|
||||
@@ -88,11 +85,9 @@ class GetUniqueItemAuctionList extends \sammo\BaseAPI
|
||||
'target' => $auction->target,
|
||||
'isCallerHost' => $auction->hostGeneralID === $generalID,
|
||||
'hostName' => $auction->detail->hostName,
|
||||
'closeDate' => $clock->formatTick($auction->closeTick),
|
||||
'closeDate' => TimeUtil::format($auction->closeDate, false),
|
||||
'remainCloseDateExtensionCnt' => $auction->detail->remainCloseDateExtensionCnt,
|
||||
'availableLatestBidCloseDate' => $auction->detail->availableLatestBidCloseTick === null
|
||||
? null
|
||||
: $clock->formatTick($auction->detail->availableLatestBidCloseTick),
|
||||
'availableLatestBidCloseDate' => TimeUtil::format($auction->detail->availableLatestBidCloseDate, false),
|
||||
'highestBid' => [
|
||||
'generalName' => $highestBid->aux->generalName,
|
||||
'amount' => $highestBid->amount,
|
||||
|
||||
@@ -7,10 +7,9 @@ use DateTimeInterface;
|
||||
use sammo\DB;
|
||||
use sammo\Enums\APIRecoveryType;
|
||||
use sammo\GameConst;
|
||||
use sammo\GameClock;
|
||||
use sammo\Json;
|
||||
use sammo\KVStorage;
|
||||
use sammo\Util;
|
||||
use sammo\TimeUtil;
|
||||
|
||||
use function sammo\cutTurn;
|
||||
|
||||
@@ -32,7 +31,6 @@ class GetReservedCommand extends \sammo\BaseAPI
|
||||
|
||||
$commandList = [];
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$clock = GameClock::fromStorage($gameStor);
|
||||
$generalID = $session->generalID;
|
||||
|
||||
$invalidTurnList = 0;
|
||||
@@ -84,13 +82,11 @@ class GetReservedCommand extends \sammo\BaseAPI
|
||||
|
||||
return [
|
||||
'result' => true,
|
||||
'turnTimeTick' => Util::toInt($turnTime),
|
||||
'turnTime' => $clock->formatTick(Util::toInt($turnTime)),
|
||||
'turnTime' => $turnTime,
|
||||
'turnTerm' => $turnTerm,
|
||||
'year' => $year,
|
||||
'month' => $month,
|
||||
'date' => $clock->formatTick($clock->nowTick(), true),
|
||||
'clockMode' => $clock->getMode(),
|
||||
'date' => TimeUtil::now(true),
|
||||
'turn' => $commandList,
|
||||
'autorun_limit' => $generalAux['autorun_limit'] ?? null,
|
||||
];
|
||||
|
||||
@@ -11,8 +11,7 @@ use sammo\Session;
|
||||
use sammo\General;
|
||||
use sammo\JosaUtil;
|
||||
use sammo\KVStorage;
|
||||
use sammo\GameClock;
|
||||
use sammo\Util;
|
||||
use sammo\TimeUtil;
|
||||
|
||||
use function sammo\addTurn;
|
||||
use function sammo\increaseRefresh;
|
||||
@@ -38,14 +37,8 @@ class DieOnPrestart extends \sammo\BaseAPI
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$gameStor->cacheValues(['turnterm', 'opentime', 'turntime', 'year', 'month']);
|
||||
$clock = GameClock::fromStorage($gameStor);
|
||||
$nowTick = $clock->nowTick();
|
||||
|
||||
$general = $db->queryFirstRow('SELECT no,name,nation,owner_name,npc FROM general WHERE owner=%i AND npc = 0', $userID);
|
||||
if (!$general) {
|
||||
return '장수가 없습니다';
|
||||
}
|
||||
|
||||
$lastRefresh = $db->queryFirstField(
|
||||
'SELECT %b FROM general_access_log WHERE %b = %i',
|
||||
GeneralAccessLogColumn::lastRefresh->value,
|
||||
@@ -53,9 +46,8 @@ class DieOnPrestart extends \sammo\BaseAPI
|
||||
$general['no']
|
||||
);
|
||||
|
||||
$generalObj = General::createObjFromDB($general['no']);
|
||||
if ($generalObj instanceof DummyGeneral) {
|
||||
trigger_error("올바르지 않은 삭제 프로세스 $userID", E_USER_WARNING);
|
||||
if (!$general) {
|
||||
return '장수가 없습니다';
|
||||
}
|
||||
|
||||
increaseRefresh("장수 삭제", 1);
|
||||
@@ -69,21 +61,16 @@ class DieOnPrestart extends \sammo\BaseAPI
|
||||
return '이미 국가에 소속되어있습니다.';
|
||||
}
|
||||
|
||||
$targetTime = $generalObj->getAuxVar('prestart_delete_after');
|
||||
if (!is_int($targetTime)) {
|
||||
$targetTime = addTurn(
|
||||
$lastRefresh === null ? $nowTick : Util::toInt($lastRefresh),
|
||||
$gameStor->turnterm,
|
||||
GameConst::$minTurnDieOnPrestart
|
||||
);
|
||||
$generalObj->setAuxVar('prestart_delete_after', $targetTime);
|
||||
$generalObj->applyDB($db);
|
||||
//서버 가오픈시 할 수 있는 행동
|
||||
$targetTime = addTurn($lastRefresh, $gameStor->turnterm, GameConst::$minTurnDieOnPrestart);
|
||||
if ($targetTime > TimeUtil::now()) {
|
||||
$targetTimeShort = substr($targetTime, 0, 19);
|
||||
return "아직 삭제할 수 없습니다. {$targetTimeShort} 부터 가능합니다.";
|
||||
}
|
||||
|
||||
//서버 가오픈시 할 수 있는 행동
|
||||
if ($targetTime > $nowTick) {
|
||||
$targetTimeShort = $clock->formatTick($targetTime);
|
||||
return "아직 삭제할 수 없습니다. {$targetTimeShort} 부터 가능합니다.";
|
||||
$generalObj = General::createObjFromDB($general['no']);
|
||||
if ($generalObj instanceof DummyGeneral) {
|
||||
trigger_error("올바르지 않은 삭제 프로세스 $userID", E_USER_WARNING);
|
||||
}
|
||||
|
||||
$generalName = $generalObj->getName();
|
||||
|
||||
@@ -14,13 +14,13 @@ use sammo\Enums\GeneralColumn;
|
||||
use sammo\Enums\GeneralQueryMode;
|
||||
use sammo\Enums\RankColumn;
|
||||
use sammo\GameConst;
|
||||
use sammo\GameClock;
|
||||
use sammo\General;
|
||||
use sammo\KVStorage;
|
||||
use sammo\LastTurn;
|
||||
use sammo\Validator;
|
||||
|
||||
use sammo\Session;
|
||||
use sammo\TimeUtil;
|
||||
use sammo\Util;
|
||||
|
||||
use function sammo\buildNationCommandClass;
|
||||
@@ -105,7 +105,6 @@ class GetFrontInfo extends \sammo\BaseAPI
|
||||
$db = DB::db();
|
||||
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$clock = GameClock::fromStorage($gameStor);
|
||||
$gameStor->cacheValues(['isunited', 'opentime', 'refresh']);
|
||||
|
||||
$lastHistoryID = $this->args['lastWorldHistoryID'];
|
||||
@@ -159,7 +158,6 @@ class GetFrontInfo extends \sammo\BaseAPI
|
||||
private function generateGlobalInfo(MeekroDB $db): array
|
||||
{
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$clock = GameClock::fromStorage($gameStor);
|
||||
|
||||
[
|
||||
$scenarioText, $extendedGeneral, $isFiction, $npcMode,
|
||||
@@ -184,9 +182,8 @@ class GetFrontInfo extends \sammo\BaseAPI
|
||||
$lastVote = null;
|
||||
if ($lastVoteID) {
|
||||
$voteStor = KVStorage::getStorage($db, 'vote');
|
||||
$rawLastVote = VoteInfo::normalizeGameStorage($voteStor->getValue("vote_{$lastVoteID}"), $clock);
|
||||
$lastVote = VoteInfo::fromGameStorage($rawLastVote, $clock);
|
||||
if ($rawLastVote['endTick'] !== null && $rawLastVote['endTick'] < $clock->nowTick()) {
|
||||
$lastVote = VoteInfo::fromArray($voteStor->getValue("vote_{$lastVoteID}"));
|
||||
if ($lastVote->endDate && $lastVote->endDate < TimeUtil::now()) {
|
||||
$lastVote = null;
|
||||
}
|
||||
}
|
||||
@@ -213,8 +210,7 @@ class GetFrontInfo extends \sammo\BaseAPI
|
||||
'month' => $month,
|
||||
'autorunUser' => $autorunUser,
|
||||
'turnterm' => $turnterm,
|
||||
'lastExecutedTick' => $lastExecuted,
|
||||
'lastExecuted' => $clock->formatTick(Util::toInt($lastExecuted), true),
|
||||
'lastExecuted' => $lastExecuted,
|
||||
'lastVoteID' => $lastVoteID,
|
||||
'develCost' => $develCost,
|
||||
'noticeMsg' => $noticeMsg,
|
||||
@@ -228,8 +224,7 @@ class GetFrontInfo extends \sammo\BaseAPI
|
||||
'isLocked' => $isLocked,
|
||||
'tournamentType' => $tournamentType,
|
||||
'tournamentState' => $tournamentState,
|
||||
'tournamentTimeTick' => $tournamentTime,
|
||||
'tournamentTime' => $tournamentTime === null ? null : $clock->formatTick(Util::toInt($tournamentTime)),
|
||||
'tournamentTime' => $tournamentTime,
|
||||
'genCount' => $globalGenCount,
|
||||
'generalCntLimit' => $generalCntLimit,
|
||||
'serverCnt' => $serverCnt,
|
||||
@@ -366,7 +361,6 @@ class GetFrontInfo extends \sammo\BaseAPI
|
||||
|
||||
public function generateGeneralInfo(MeekroDB $db, General $general, array $rawNation): array
|
||||
{
|
||||
$clock = GameClock::fromStorage(KVStorage::getStorage($db, 'game_env'));
|
||||
|
||||
$permission = checkSecretPermission($general->getRaw());
|
||||
|
||||
@@ -431,12 +425,8 @@ class GetFrontInfo extends \sammo\BaseAPI
|
||||
'crew' => $general->getVar(GeneralColumn::crew), // number;
|
||||
'train' => $general->getVar(GeneralColumn::train), // number;
|
||||
'atmos' => $general->getVar(GeneralColumn::atmos), // number;
|
||||
'turntimeTick' => $general->getTurnTick(), // number;
|
||||
'turntime' => $general->getTurnTime(), // string;
|
||||
'recent_war_tick' => $general->getVar(GeneralColumn::recent_war), // number|null;
|
||||
'recent_war' => $general->getVar(GeneralColumn::recent_war) === null
|
||||
? null
|
||||
: $clock->formatTick(Util::toInt($general->getVar(GeneralColumn::recent_war)), true), // string|null;
|
||||
'turntime' => $general->getVar(GeneralColumn::turntime), // string;
|
||||
'recent_war' => $general->getVar(GeneralColumn::recent_war), // string;
|
||||
'horse' => $general->getVar(GeneralColumn::horse), // GameObjClassKey;
|
||||
'weapon' => $general->getVar(GeneralColumn::weapon), // GameObjClassKey;
|
||||
'book' => $general->getVar(GeneralColumn::book), // GameObjClassKey;
|
||||
@@ -554,7 +544,7 @@ class GetFrontInfo extends \sammo\BaseAPI
|
||||
'result' => false,
|
||||
'reason' => '접속 제한중입니다.',
|
||||
'recovery' => APIRecoveryType::GameQuota,
|
||||
'recovery_arg' => $general->getTurnTime(),
|
||||
'recovery_arg' => $general->getVar('turntime'),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ use sammo\Enums\APIRecoveryType;
|
||||
use sammo\Enums\GeneralAccessLogColumn;
|
||||
use sammo\Enums\RankColumn;
|
||||
use sammo\GameConst;
|
||||
use sammo\GameClock;
|
||||
use sammo\GameUnitConst;
|
||||
use sammo\General;
|
||||
use sammo\InheritancePointManager;
|
||||
@@ -100,7 +99,7 @@ class Join extends \sammo\BaseAPI
|
||||
}
|
||||
|
||||
$gameID = UniqueConst::$serverID;
|
||||
$alreadyJoined = $db->queryFirstField('SELECT COUNT(*) FROM `inheritance_result` WHERE `server_id` = %s AND `owner` = %i', $gameID, $userID);
|
||||
$alreadyJoined = $db->queryFirstField('SELECT count(*) FROM `storage` WHERE `namespace` = %s AND `key` LIKE %s', 'inheritance_result', "{$gameID}_{$userID}_%");
|
||||
if ($alreadyJoined) {
|
||||
//이미 받았음
|
||||
return 0;
|
||||
@@ -158,7 +157,7 @@ class Join extends \sammo\BaseAPI
|
||||
|
||||
$penalty = [];
|
||||
foreach($penaltyInfo as $penaltyKey => $penaltyValue){
|
||||
if(($penaltyValue['expire'] ?? 0) > TimeUtil::now()){
|
||||
if($penaltyValue['expire'] ?? 0 > TimeUtil::now()){
|
||||
$penalty[$penaltyKey] = $penaltyValue['value'];
|
||||
}
|
||||
}
|
||||
@@ -166,7 +165,6 @@ class Join extends \sammo\BaseAPI
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$gameStor->cacheValues(['year', 'month', 'maxgeneral', 'scenario', 'show_img_level', 'block_general_create', 'turnterm', 'turntime', 'genius', 'npcmode']);
|
||||
$clock = GameClock::fromStorage($gameStor);
|
||||
########## 동일 정보 존재여부 확인. ##########
|
||||
|
||||
$block_general_create = $gameStor->getValue('block_general_create');
|
||||
@@ -224,7 +222,7 @@ class Join extends \sammo\BaseAPI
|
||||
|
||||
$userLogger = new UserLogger($userID, $admin['year'], $admin['month'], false);
|
||||
|
||||
$now = $clock->nowTick();
|
||||
$now = TimeUtil::now(false);
|
||||
$rng = new RandUtil(new LiteHashDRBG(Util::simpleSerialize(
|
||||
UniqueConst::$hiddenSeed,
|
||||
'MakeGeneral',
|
||||
@@ -362,14 +360,17 @@ class Join extends \sammo\BaseAPI
|
||||
|
||||
$userLogger->push(sprintf("턴 시간 %02d:%02d 로 지정", intdiv($inheritTurntime, 60), $inheritTurntime % 60), "inheritPoint");
|
||||
|
||||
$inheritTurnMicrosecond = $rng->nextRangeInt(0, 999999);
|
||||
$turntime = cutTurn(Util::toInt($admin['turntime']), $admin['turnterm'])
|
||||
+ $clock->ticksFromSeconds($inheritTurntime)
|
||||
+ intdiv($inheritTurnMicrosecond * $clock->ticksPerSecond(), 1_000_000);
|
||||
$inheritTurntime += $rng->nextRangeInt(0, 999999) / 1000000;
|
||||
|
||||
$turntime = new \DateTimeImmutable(cutTurn($admin['turntime'], $admin['turnterm']));
|
||||
$turntime = $turntime->add(TimeUtil::secondsToDateInterval($inheritTurntime));
|
||||
$turntime = TimeUtil::format($turntime, true);
|
||||
} else {
|
||||
$turntime = getRandTurn($rng, $admin['turnterm'], Util::toInt($admin['turntime']));
|
||||
$turntime = getRandTurn($rng, $admin['turnterm'], new \DateTimeImmutable($admin['turntime']));
|
||||
}
|
||||
|
||||
|
||||
$now = TimeUtil::now(true);
|
||||
if ($now >= $turntime) {
|
||||
$turntime = addTurn($turntime, $admin['turnterm']);
|
||||
}
|
||||
@@ -434,13 +435,6 @@ class Join extends \sammo\BaseAPI
|
||||
'specage2' => $specage2,
|
||||
'special2' => $special2,
|
||||
'penalty' => Json::encode($penalty),
|
||||
'aux' => Json::encode([
|
||||
'prestart_delete_after' => addTurn(
|
||||
$now,
|
||||
$admin['turnterm'],
|
||||
GameConst::$minTurnDieOnPrestart
|
||||
),
|
||||
]),
|
||||
]);
|
||||
$generalID = $db->insertId();
|
||||
$db->insert('general_access_log', [
|
||||
|
||||
@@ -8,8 +8,6 @@ use DateTimeInterface;
|
||||
use sammo\Enums\APIRecoveryType;
|
||||
use sammo\TurnExecutionHelper;
|
||||
use sammo\UniqueConst;
|
||||
use sammo\GameClock;
|
||||
use sammo\KVStorage;
|
||||
|
||||
class ExecuteEngine extends \sammo\BaseAPI
|
||||
{
|
||||
@@ -37,13 +35,11 @@ class ExecuteEngine extends \sammo\BaseAPI
|
||||
$updated = false;
|
||||
$locked = false;
|
||||
$lastExecuted = TurnExecutionHelper::executeAllCommand($updated, $locked);
|
||||
$clock = GameClock::fromStorage(KVStorage::getStorage(DB::db(), 'game_env'));
|
||||
return [
|
||||
'result' => true,
|
||||
'updated' => $updated,
|
||||
'locked' => $locked,
|
||||
'lastExecutedTick' => $lastExecuted,
|
||||
'lastExecuted' => $clock->formatTick($lastExecuted, true),
|
||||
'lastExecuted' => $lastExecuted,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace sammo\API\Global;
|
||||
|
||||
use sammo\DB;
|
||||
use sammo\GameClock;
|
||||
use sammo\Enums\APIRecoveryType;
|
||||
use sammo\Json;
|
||||
use sammo\KVStorage;
|
||||
@@ -55,7 +54,7 @@ class GeneralList extends \sammo\BaseAPI
|
||||
$availableNextCall = $session->availableNextCallGetGeneralList ?? '2000-01-01 00:00:00';
|
||||
$now = new \DateTimeImmutable();
|
||||
|
||||
if ($now <= new \DateTimeImmutable($availableNextCall) && $session->userGrade < 6) {
|
||||
if ($now <= new \DateTimeImmutable($availableNextCall) && $session->userGrade < 5) {
|
||||
return "장수 리스트는 10초에 한번 갱신 가능합니다.\n다음 시간 : " . $availableNextCall;
|
||||
}
|
||||
|
||||
@@ -146,8 +145,7 @@ class GeneralList extends \sammo\BaseAPI
|
||||
|
||||
|
||||
if (static::$withToken) {
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$now = GameClock::fromStorage($gameStor)->nowTick();
|
||||
$now = (new \DateTimeImmutable())->format('Y-m-d H:i:s');
|
||||
$tokens = [];
|
||||
foreach ($db->query('SELECT * FROM select_npc_token WHERE `valid_until`>=%s', $now) as $token) {
|
||||
$validUntil = $token['valid_until'];
|
||||
|
||||
@@ -55,11 +55,7 @@ class GetCachedMap extends \sammo\BaseAPI
|
||||
return 'cache 불가';
|
||||
}
|
||||
|
||||
$absolutePath = realpath('data/file_cache');
|
||||
if (!$absolutePath) {
|
||||
return 'cache 불가';
|
||||
}
|
||||
$storage = new \Nette\Caching\Storages\FileStorage($absolutePath);
|
||||
$storage = new \Nette\Caching\Storages\FileStorage('data/file_cache');
|
||||
$cache = new Cache($storage);
|
||||
|
||||
$now = TimeUtil::nowDateTimeImmutable();
|
||||
|
||||
@@ -288,10 +288,6 @@ class GetConst extends \sammo\BaseAPI
|
||||
if (!prepareDir($cacheDir)) {
|
||||
throw new RuntimeException('cache 폴더 없음');
|
||||
}
|
||||
$absolutePath = realpath($cacheDir);
|
||||
if (!$absolutePath) {
|
||||
throw new RuntimeException('cache 폴더 없음');
|
||||
}
|
||||
$storage = new \Nette\Caching\Storages\FileStorage($cacheDir);
|
||||
$cache = new Cache($storage);
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ use sammo\Enums\RankColumn;
|
||||
use sammo\GameConst;
|
||||
use sammo\General;
|
||||
use sammo\KVStorage;
|
||||
use sammo\TimeUtil;
|
||||
use sammo\UserLogger;
|
||||
|
||||
class BuyRandomUnique extends \sammo\BaseAPI
|
||||
@@ -55,7 +56,7 @@ class BuyRandomUnique extends \sammo\BaseAPI
|
||||
$userLogger->push("{$reqAmount} 포인트로 랜덤 유니크 구입", "inheritPoint");
|
||||
$userLogger->flush();
|
||||
|
||||
$general->setAuxVar('inheritRandomUnique', true);
|
||||
$general->setAuxVar('inheritRandomUnique', TimeUtil::now());
|
||||
$inheritStor->setValue('previous', [$previousPoint - $reqAmount, null]);
|
||||
$general->increaseRankVar(RankColumn::inherit_point_spent_dynamic, $reqAmount);
|
||||
$general->applyDB($db);
|
||||
|
||||
@@ -1,154 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace sammo\API\InheritAction;
|
||||
|
||||
use sammo\Session;
|
||||
use DateTimeInterface;
|
||||
use sammo\DB;
|
||||
use sammo\Enums\APIRecoveryType;
|
||||
use sammo\Enums\MessageType;
|
||||
use sammo\Enums\RankColumn;
|
||||
use sammo\GameConst;
|
||||
use sammo\General;
|
||||
use sammo\KVStorage;
|
||||
use sammo\Message;
|
||||
use sammo\MessageTarget;
|
||||
use sammo\RootDB;
|
||||
use sammo\TimeUtil;
|
||||
use sammo\UserLogger;
|
||||
use sammo\Validator;
|
||||
|
||||
use function sammo\GetImageURL;
|
||||
use function sammo\getNationStaticInfo;
|
||||
|
||||
/**
|
||||
*
|
||||
* 유산 포인트 1000 포인트를 사용하면 지정한 상대의 본래 유저명을 확인 가능.
|
||||
* 개인 메시지로 전달되며, 이 기능이 사용되었음을 상대에게도 알림.
|
||||
*/
|
||||
class CheckOwner extends \sammo\BaseAPI
|
||||
{
|
||||
public function validateArgs(): ?string
|
||||
{
|
||||
$v = new Validator($this->args);
|
||||
$v->rule('required', [
|
||||
'destGeneralID',
|
||||
])
|
||||
->rule('int', 'destGeneralID')
|
||||
->rule('min', 'destGeneralID', 1);
|
||||
|
||||
if (!$v->validate()) {
|
||||
return $v->errorStr();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getRequiredSessionMode(): int
|
||||
{
|
||||
return static::REQ_GAME_LOGIN;
|
||||
}
|
||||
|
||||
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag): null|string|array|APIRecoveryType
|
||||
{
|
||||
$userID = $session->userID;
|
||||
$generalID = $session->generalID;
|
||||
|
||||
$destGeneralID = $this->args['destGeneralID'];
|
||||
if ($generalID == $destGeneralID) {
|
||||
return '자신의 정보는 확인할 수 없습니다.';
|
||||
}
|
||||
|
||||
$general = General::createObjFromDB($generalID);
|
||||
if ($userID != $general->getVar('owner')) {
|
||||
return '로그인 상태가 이상합니다. 다시 로그인해 주세요.';
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
$destRawGeneral = $db->queryFirstRow('SELECT no,name,nation,owner,owner_name,imgsvr,picture FROM general WHERE no = %i', $destGeneralID);
|
||||
|
||||
if (!$destRawGeneral) {
|
||||
return '대상 장수가 존재하지 않습니다.';
|
||||
}
|
||||
|
||||
if (!$destRawGeneral['owner']) {
|
||||
return '대상 장수는 NPC입니다.';
|
||||
}
|
||||
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
if ($gameStor->isunited) {
|
||||
return '이미 천하가 통일되었습니다.';
|
||||
}
|
||||
|
||||
$reqPoint = GameConst::$inheritCheckOwnerPoint;
|
||||
|
||||
$inheritStor = KVStorage::getStorage($db, "inheritance_{$userID}");
|
||||
$previousPoint = ($inheritStor->getValue('previous') ?? [0, 0])[0];
|
||||
if ($previousPoint < $reqPoint) {
|
||||
return '충분한 유산 포인트를 가지고 있지 않습니다.';
|
||||
}
|
||||
|
||||
$userLogger = new UserLogger($userID);
|
||||
$userLogger->push("{$reqPoint} 포인트로 장수 소유자 확인", "inheritPoint");
|
||||
$userLogger->flush();
|
||||
|
||||
$destGeneralName = $destRawGeneral['name'];
|
||||
$destGeneralOwnerName = $destRawGeneral['owner_name'];
|
||||
if (!$destGeneralOwnerName) {
|
||||
$rootDB = RootDB::db();
|
||||
$destGeneralOwnerName = $rootDB->queryFirstField('SELECT name FROM member WHERE no = %i', $destRawGeneral['owner']) ?? '알수없음';
|
||||
}
|
||||
|
||||
$src = new MessageTarget(0, '', 0, 'System', '#000000');
|
||||
|
||||
if (true) {
|
||||
$staticNation = $general->getStaticNation();
|
||||
$dest = new MessageTarget(
|
||||
$generalID,
|
||||
$general->getName(),
|
||||
$general->getNationID(),
|
||||
$staticNation['name'],
|
||||
$staticNation['color'],
|
||||
GetImageURL($general->getVar('imgsvr'), $general->getVar('picture'))
|
||||
);
|
||||
$msg = new Message(
|
||||
MessageType::private,
|
||||
$src,
|
||||
$dest,
|
||||
"{$destGeneralName}의 소유자는 {$destGeneralOwnerName} 입니다.",
|
||||
Message::gameNow(),
|
||||
new \DateTime('9999-12-31'),
|
||||
[]
|
||||
);
|
||||
$msg->send(true);
|
||||
}
|
||||
|
||||
$inheritStor->setValue('previous', [$previousPoint - $reqPoint, null]);
|
||||
$general->increaseRankVar(RankColumn::inherit_point_spent_dynamic, $reqPoint);
|
||||
$general->applyDB($db);
|
||||
|
||||
if(true){
|
||||
$destStaticNation = getNationStaticInfo($destRawGeneral['nation']);
|
||||
$dest = new MessageTarget(
|
||||
$destGeneralID,
|
||||
$destGeneralName,
|
||||
$destRawGeneral['nation'],
|
||||
$destStaticNation['name'],
|
||||
$destStaticNation['color'],
|
||||
GetImageURL($destRawGeneral['imgsvr'], $destRawGeneral['picture'])
|
||||
);
|
||||
$msg = new Message(
|
||||
MessageType::private,
|
||||
$src,
|
||||
$dest,
|
||||
"소유자명이 누군가에 의해 확인되었습니다.",
|
||||
Message::gameNow(),
|
||||
new \DateTime('9999-12-31'),
|
||||
[]
|
||||
);
|
||||
$msg->send(true);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,188 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace sammo\API\InheritAction;
|
||||
|
||||
use sammo\Session;
|
||||
use DateTimeInterface;
|
||||
use sammo\CentennialAllStarGrowthService;
|
||||
use sammo\DB;
|
||||
use sammo\Enums\APIRecoveryType;
|
||||
use sammo\Enums\RankColumn;
|
||||
use sammo\GameConst;
|
||||
use sammo\General;
|
||||
use sammo\KVStorage;
|
||||
use sammo\LiteHashDRBG;
|
||||
use sammo\RandUtil;
|
||||
use sammo\UniqueConst;
|
||||
use sammo\UserLogger;
|
||||
use sammo\Util;
|
||||
use sammo\Validator;
|
||||
|
||||
class ResetStat extends \sammo\BaseAPI
|
||||
{
|
||||
public function validateArgs(): ?string
|
||||
{
|
||||
$v = new Validator($this->args);
|
||||
$v->rule('required', [
|
||||
'leadership',
|
||||
'strength',
|
||||
'intel',
|
||||
])
|
||||
->rule('int', [
|
||||
'leadership',
|
||||
'strength',
|
||||
'intel',
|
||||
])
|
||||
->rule('min', [
|
||||
'leadership',
|
||||
'strength',
|
||||
'intel'
|
||||
], GameConst::$defaultStatMin)
|
||||
->rule('max', [
|
||||
'leadership',
|
||||
'strength',
|
||||
'intel'
|
||||
], GameConst::$defaultStatMax)
|
||||
->rule('integerArray', 'inheritBonusStat');
|
||||
|
||||
if (!$v->validate()) {
|
||||
return $v->errorStr();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getRequiredSessionMode(): int
|
||||
{
|
||||
//General.aux 쓰므로 lock;
|
||||
return static::REQ_GAME_LOGIN;
|
||||
}
|
||||
|
||||
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag): null | string | array | APIRecoveryType
|
||||
{
|
||||
$userID = $session->userID;
|
||||
$generalID = $session->generalID;
|
||||
|
||||
|
||||
$leadership = $this->args['leadership'];
|
||||
$strength = $this->args['strength'];
|
||||
$intel = $this->args['intel'];
|
||||
$inheritBonusStat = $this->args['inheritBonusStat'] ?? null;
|
||||
|
||||
if ($leadership + $strength + $intel != GameConst::$defaultStatTotal) {
|
||||
return "능력치 총합이 " . GameConst::$defaultStatTotal . "이 아닙니다. 다시 입력해주세요!";
|
||||
}
|
||||
|
||||
if ($inheritBonusStat) {
|
||||
if (count($inheritBonusStat) != 3) {
|
||||
return "보너스 능력치가 잘못 지정되었습니다. 다시 입력해주세요!";
|
||||
}
|
||||
foreach ($inheritBonusStat as $stat) {
|
||||
if ($stat < 0) {
|
||||
return "보너스 능력치가 음수입니다. 다시 입력해주세요!";
|
||||
}
|
||||
}
|
||||
$sum = array_sum($inheritBonusStat);
|
||||
if ($sum == 0) {
|
||||
$inheritBonusStat = null;
|
||||
} else if ($sum < 3 || $sum > 5) {
|
||||
return "보너스 능력치 합이 잘못 지정되었습니다. 다시 입력해주세요!";
|
||||
}
|
||||
}
|
||||
|
||||
$general = General::createObjFromDB($generalID);
|
||||
if ($userID != $general->getVar('owner')) {
|
||||
return '로그인 상태가 이상합니다. 다시 로그인해 주세요.';
|
||||
}
|
||||
$userLogger = new UserLogger($userID);
|
||||
|
||||
if($general->getNPCType() != 0){
|
||||
return 'NPC는 능력치 초기화를 할 수 없습니다.';
|
||||
}
|
||||
|
||||
if (!CentennialAllStarGrowthService::isStatResetAllowed()) {
|
||||
return '100기 올스타 장수는 능력치 초기화를 사용할 수 없습니다.';
|
||||
}
|
||||
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$gameStor->cacheValues([
|
||||
'isunited',
|
||||
'season',
|
||||
]);
|
||||
if ($gameStor->isunited) {
|
||||
return '이미 천하가 통일되었습니다.';
|
||||
}
|
||||
$userStor = KVStorage::getStorage($db, "user_{$userID}");
|
||||
|
||||
$lastUserStatReset = $userStor->getValue('last_stat_reset') ?? [];
|
||||
$gameSeason = $gameStor->getValue('season');
|
||||
|
||||
if (array_search($gameSeason, $lastUserStatReset) !== false) {
|
||||
return '이번 시즌에 이미 능력치를 초기화하셨습니다.';
|
||||
}
|
||||
|
||||
|
||||
$inheritStor = KVStorage::getStorage($db, "inheritance_{$userID}");
|
||||
$previousPoint = ($inheritStor->getValue('previous') ?? [0, 0])[0];
|
||||
$reqAmount = 0;
|
||||
if ($inheritBonusStat !== null) {
|
||||
$reqAmount += GameConst::$inheritBornStatPoint;
|
||||
}
|
||||
|
||||
if ($previousPoint < $reqAmount) {
|
||||
return '충분한 유산 포인트를 가지고 있지 않습니다.';
|
||||
}
|
||||
|
||||
$userLogger->push("통솔 {$leadership}, 무력 {$strength}, 지력 {$intel} 스탯 재설정", "inheritPoint");
|
||||
|
||||
if ($inheritBonusStat) {
|
||||
$pleadership = $inheritBonusStat[0] ?? 0;
|
||||
$pstrength = $inheritBonusStat[1] ?? 0;
|
||||
$pintel = $inheritBonusStat[2] ?? 0;
|
||||
$userLogger->push("{$reqAmount}로 통솔 {$pleadership}, 무력 {$pstrength}, 지력 {$pintel} 보너스 능력치 적용", "inheritPoint");
|
||||
} else {
|
||||
$rng = new RandUtil(new LiteHashDRBG(Util::simpleSerialize(
|
||||
UniqueConst::$hiddenSeed,
|
||||
'ResetStat',
|
||||
$userID,
|
||||
)));
|
||||
$pleadership = 0;
|
||||
$pstrength = 0;
|
||||
$pintel = 0;
|
||||
foreach (Util::range($rng->nextRangeInt(3, 5)) as $statIdx) {
|
||||
switch ($rng->choiceUsingWeight([$leadership, $strength, $intel])) {
|
||||
case 0:
|
||||
$pleadership++;
|
||||
break;
|
||||
case 1:
|
||||
$pstrength++;
|
||||
break;
|
||||
case 2:
|
||||
$pintel++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$userLogger->push("통솔 {$pleadership}, 무력 {$pstrength}, 지력 {$pintel} 보너스 능력치 적용", "inheritPoint");
|
||||
}
|
||||
|
||||
$leadership += $pleadership;
|
||||
$strength += $pstrength;
|
||||
$intel += $pintel;
|
||||
|
||||
$lastUserStatReset[] = $gameSeason;
|
||||
|
||||
|
||||
$general->setVar('leadership', $leadership);
|
||||
$general->setVar('strength', $strength);
|
||||
$general->setVar('intel', $intel);
|
||||
|
||||
$userLogger->flush();
|
||||
|
||||
$inheritStor->setValue('previous', [$previousPoint - $reqAmount, null]);
|
||||
$userStor->setValue('last_stat_reset', $lastUserStatReset);
|
||||
$general->increaseRankVar(RankColumn::inherit_point_spent_dynamic, $reqAmount);
|
||||
$general->applyDB($db);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -64,11 +64,13 @@ class ResetTurnTime extends \sammo\BaseAPI
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$turnTerm = $gameStor->getValue('turnterm');
|
||||
|
||||
$currTurnTime = new DateTimeImmutable($general->getTurnTime());
|
||||
|
||||
$rng = new RandUtil(new LiteHashDRBG(Util::simpleSerialize(
|
||||
UniqueConst::$hiddenSeed,
|
||||
'ResetTurnTime',
|
||||
$userID,
|
||||
$general->getAuxVar('nextTurnTimeBase') ?? $general->getTurnTick()
|
||||
$general->getAuxVar('nextTurnTimeBase') ?? $general->getTurnTime()
|
||||
)));
|
||||
|
||||
$afterTurn = $rng->nextFloat1() * $turnTerm * 60;
|
||||
|
||||
@@ -7,7 +7,6 @@ use DateTimeInterface;
|
||||
use sammo\DB;
|
||||
use sammo\Enums\APIRecoveryType;
|
||||
use sammo\Enums\MessageType;
|
||||
use sammo\Enums\PenaltyKey;
|
||||
use sammo\Json;
|
||||
use sammo\Message;
|
||||
use sammo\MessageTarget;
|
||||
@@ -44,7 +43,7 @@ class SendMessage extends \sammo\BaseAPI
|
||||
|
||||
private function genPublicMessage(MessageTarget $src, string $text): Message
|
||||
{
|
||||
$now = Message::gameNow();
|
||||
$now = new \DateTime();
|
||||
$unlimited = new \DateTime('9999-12-31');
|
||||
|
||||
$msg = new Message(
|
||||
@@ -62,7 +61,7 @@ class SendMessage extends \sammo\BaseAPI
|
||||
|
||||
private function genNationalMessage(MessageTarget $src, string $text): Message
|
||||
{
|
||||
$now = Message::gameNow();
|
||||
$now = new \DateTime();
|
||||
$unlimited = new \DateTime('9999-12-31');
|
||||
|
||||
$dest = new MessageTarget(0, '', $src->nationID, $src->nationName, $src->color);
|
||||
@@ -82,7 +81,7 @@ class SendMessage extends \sammo\BaseAPI
|
||||
|
||||
private function genDiplomacyMessage(MessageTarget $src, int $destNationID, string $text): Message|string
|
||||
{
|
||||
$now = Message::gameNow();
|
||||
$now = new \DateTime();
|
||||
$unlimited = new \DateTime('9999-12-31');
|
||||
|
||||
$destNation = getNationStaticInfo($destNationID);
|
||||
@@ -107,7 +106,7 @@ class SendMessage extends \sammo\BaseAPI
|
||||
|
||||
private function genPrivateMessage(MessageTarget $src, int $destGeneralID, int $permission, string $text): Message|string
|
||||
{
|
||||
$now = Message::gameNow();
|
||||
$now = new \DateTime();
|
||||
$unlimited = new \DateTime('9999-12-31');
|
||||
|
||||
$db = DB::db();
|
||||
@@ -192,9 +191,6 @@ class SendMessage extends \sammo\BaseAPI
|
||||
|
||||
// 전체 메세지
|
||||
if ($mailbox === Message::MAILBOX_PUBLIC) {
|
||||
if($penalty[PenaltyKey::NoSendPublicMsg->value] ?? 0) {
|
||||
return '공개 메세지를 보낼 수 없습니다.';
|
||||
}
|
||||
$msgID = $this->genPublicMessage($src, $text)->send();
|
||||
return [
|
||||
'msgType' => 'public',
|
||||
@@ -235,11 +231,7 @@ class SendMessage extends \sammo\BaseAPI
|
||||
$lastMsg = new \DateTime($session->lastMsg ?? '0000-00-00');
|
||||
$msg_interval = $now->getTimestamp() - $lastMsg->getTimestamp();
|
||||
|
||||
if($penalty[PenaltyKey::NoSendPrivateMsg->value] ?? 0) {
|
||||
return '개인 메세지를 보낼 수 없습니다.';
|
||||
}
|
||||
|
||||
$msg_min_interval = $penalty[PenaltyKey::SendPrivateMsgDelay->value] ?? 2;
|
||||
$msg_min_interval = $penalty['sendPrivateMsgDelay'] ?? 2;
|
||||
if ($msg_interval < $msg_min_interval) {
|
||||
return "개인메세지는 {$msg_min_interval}초당 1건만 보낼 수 있습니다!";
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ class UploadImage extends \sammo\BaseAPI
|
||||
}
|
||||
|
||||
$extension = ltrim($contentType, 'image/');
|
||||
$validExtensions = ['png', 'jpeg', 'jpg', 'gif', 'webp', 'avif'];
|
||||
$validExtensions = ['png', 'jpeg', 'jpg', 'gif', 'webp'];
|
||||
if (!in_array(strtolower($extension), $validExtensions)) {
|
||||
return '지원하지 않는 이미지 파일입니다: ' . $contentType;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ use sammo\Enums\APIRecoveryType;
|
||||
use sammo\Enums\GeneralLiteQueryMode;
|
||||
use sammo\Enums\GeneralQueryMode;
|
||||
use sammo\General;
|
||||
use sammo\GameClock;
|
||||
use sammo\GeneralLite;
|
||||
use sammo\Session;
|
||||
use sammo\Util;
|
||||
@@ -265,11 +264,8 @@ class GeneralList extends \sammo\BaseAPI
|
||||
'honorText' => fn ($rawGeneral) => getHonor($rawGeneral['experience']),
|
||||
'dedLevelText' => fn ($rawGeneral) => getDedLevelText($rawGeneral['dedlevel']),
|
||||
//'0000-00-00 11:23';
|
||||
'turntime' => fn ($rawGeneral) => GameClock::fromStorage($gameStor)
|
||||
->formatTick(Util::toInt($rawGeneral['turntime'])),
|
||||
'recent_war' => fn ($rawGeneral) => $rawGeneral['recent_war'] === null
|
||||
? null
|
||||
: GameClock::fromStorage($gameStor)->formatTick(Util::toInt($rawGeneral['recent_war'])),
|
||||
'turntime' => fn ($rawGeneral) => substr($rawGeneral['turntime'], 0, 19),
|
||||
'recent_war' => fn ($rawGeneral) => substr($rawGeneral['recent_war'], 0, 19),
|
||||
'bill' => fn ($rawGeneral) => getBillByLevel($rawGeneral['dedlevel']),
|
||||
'reservedCommand' => fn ($rawGeneral) => $reservedCommand[$rawGeneral['no']] ?? null,
|
||||
'autorun_limit' => fn ($rawGeneral) => ($rawGeneral['aux'] ?? [])['autorun_limit'] ?? 0,
|
||||
|
||||
@@ -6,8 +6,8 @@ use sammo\Session;
|
||||
use DateTimeInterface;
|
||||
use sammo\DB;
|
||||
use sammo\Enums\APIRecoveryType;
|
||||
use sammo\GameClock;
|
||||
use sammo\KVStorage;
|
||||
use sammo\TimeUtil;
|
||||
use sammo\Validator;
|
||||
use sammo\WebUtil;
|
||||
|
||||
@@ -51,9 +51,8 @@ class SetNotice extends \sammo\BaseAPI
|
||||
$nationID = $me['nation'];
|
||||
|
||||
$nationStor = KVStorage::getStorage($db, $nationID, 'nation_env');
|
||||
$gameNow = GameClock::fromStorage(KVStorage::getStorage($db, 'game_env'))->formatNow();
|
||||
$nationStor->nationNotice = [
|
||||
'date'=>$gameNow,
|
||||
'date'=>TimeUtil::now(),
|
||||
'msg'=>WebUtil::htmlPurify($msg),
|
||||
'author'=>$me['name'],
|
||||
'authorID'=>$me['no'],
|
||||
|
||||
@@ -8,10 +8,10 @@ use sammo\DB;
|
||||
use sammo\Enums\APIRecoveryType;
|
||||
use sammo\Enums\GeneralQueryMode;
|
||||
use sammo\GameConst;
|
||||
use sammo\GameClock;
|
||||
use sammo\General;
|
||||
use sammo\Json;
|
||||
use sammo\KVStorage;
|
||||
use sammo\TimeUtil;
|
||||
use sammo\Util;
|
||||
|
||||
use function sammo\checkLimit;
|
||||
@@ -39,7 +39,6 @@ class GetReservedCommand extends \sammo\BaseAPI
|
||||
increaseRefresh("사령부", 1);
|
||||
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$clock = GameClock::fromStorage($gameStor);
|
||||
$userID = $session->userID;
|
||||
|
||||
$me = $db->queryFirstRow(
|
||||
@@ -52,8 +51,7 @@ class GetReservedCommand extends \sammo\BaseAPI
|
||||
$nationID = $me['nation'];
|
||||
$limitState = checkLimit($me['refresh_score']);
|
||||
if ($limitState >= 2) {
|
||||
$limitTime = GameClock::fromStorage($gameStor)->formatTick(Util::toInt($me['turntime']), true);
|
||||
return "접속 제한중입니다. 1턴 이내에 너무 많은 갱신을 하셨습니다. (다음 갱신 가능 시각 : {$limitTime})";
|
||||
return "접속 제한중입니다. 1턴 이내에 너무 많은 갱신을 하셨습니다. (다음 갱신 가능 시각 : {$me['turntime']})";
|
||||
}
|
||||
|
||||
$permission = checkSecretPermission($me);
|
||||
@@ -158,8 +156,7 @@ class GetReservedCommand extends \sammo\BaseAPI
|
||||
'year' => $year,
|
||||
'month' => $month,
|
||||
'turnTerm' => $turnTerm,
|
||||
'date' => $clock->formatTick($clock->nowTick(), true),
|
||||
'clockMode' => $clock->getMode(),
|
||||
'date' => TimeUtil::now(true),
|
||||
'chiefList' => $nationChiefList,
|
||||
'troopList' => $troopList,
|
||||
'isChief' => ($me['officer_level'] > 4),
|
||||
|
||||
@@ -6,9 +6,6 @@ use sammo\Session;
|
||||
use DateTimeInterface;
|
||||
use sammo\DB;
|
||||
use sammo\Enums\APIRecoveryType;
|
||||
use sammo\Enums\GeneralLiteQueryMode;
|
||||
use sammo\GeneralLite;
|
||||
use sammo\StaticEventHandler;
|
||||
|
||||
class ExitTroop extends \sammo\BaseAPI
|
||||
{
|
||||
@@ -27,35 +24,23 @@ class ExitTroop extends \sammo\BaseAPI
|
||||
$generalID = $session->generalID;
|
||||
$db = DB::db();
|
||||
|
||||
$me = GeneralLite::createObjFromDB($generalID, ['troop'], GeneralLiteQueryMode::Lite);
|
||||
if (!$me) {
|
||||
return '장수 정보를 불러올 수 없습니다.';
|
||||
}
|
||||
|
||||
$troopID = $me->getVar('troop');
|
||||
$troopID = $db->queryFirstField('SELECT troop FROM general WHERE no = %i', $generalID);
|
||||
if($troopID == 0){
|
||||
return '부대에 소속되어 있지 않습니다.';
|
||||
}
|
||||
|
||||
if($troopID != $generalID){
|
||||
StaticEventHandler::handleEvent($me, null, $this::class, [
|
||||
"isTroopLeader" => false,
|
||||
], $this->args);
|
||||
$me->setVar('troop', 0);
|
||||
$me->applyDB($db);
|
||||
if($generalID != $troopID){
|
||||
$db->update('general', [
|
||||
'troop' => 0,
|
||||
], '`no` = %i', $generalID);
|
||||
return null;
|
||||
}
|
||||
|
||||
//부대장이다.
|
||||
StaticEventHandler::handleEvent($me, null, $this::class, [
|
||||
"isTroopLeader" => true,
|
||||
], $this->args);
|
||||
$db->update('general', [
|
||||
'troop' => 0,
|
||||
], '`troop` = %i', $troopID);
|
||||
$db->delete('troop', 'troop_leader = %i', $troopID);
|
||||
$me->setVar('troop', 0);
|
||||
$me->applyDB($db);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -6,9 +6,6 @@ use sammo\Session;
|
||||
use DateTimeInterface;
|
||||
use sammo\DB;
|
||||
use sammo\Enums\APIRecoveryType;
|
||||
use sammo\Enums\GeneralLiteQueryMode;
|
||||
use sammo\GeneralLite;
|
||||
use sammo\StaticEventHandler;
|
||||
use sammo\StringUtil;
|
||||
use sammo\Validator;
|
||||
|
||||
@@ -35,22 +32,16 @@ class JoinTroop extends \sammo\BaseAPI
|
||||
|
||||
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag): null | string | array | APIRecoveryType
|
||||
{
|
||||
$generalID = $session->generalID;
|
||||
$userID = $session->userID;
|
||||
$troopID = $this->args['troopID'];
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
$me = GeneralLite::createObjFromDB($generalID, ['troop'], GeneralLiteQueryMode::Lite);
|
||||
if(!$me){
|
||||
return '장수 정보를 불러올 수 없습니다.';
|
||||
}
|
||||
|
||||
if($me->getVar('troop') != 0){
|
||||
$me = $db->queryFirstRow('SELECT `no`,nation,`troop`,`officer_level`,permission,penalty FROM general WHERE `owner`=%i', $userID);
|
||||
if ($me['troop'] != 0) {
|
||||
return '이미 부대에 소속되어 있습니다.';
|
||||
}
|
||||
|
||||
$nationID = $me->getNationID();
|
||||
if($nationID == 0){
|
||||
$nationID = $me['nation'];
|
||||
if ($nationID == 0) {
|
||||
return '국가에 소속되어 있지 않습니다.';
|
||||
}
|
||||
|
||||
@@ -58,10 +49,11 @@ class JoinTroop extends \sammo\BaseAPI
|
||||
if (!$troopExists) {
|
||||
return '부대가 올바르지 않습니다.';
|
||||
}
|
||||
$generalID = $me['no'];
|
||||
|
||||
$me->setVar('troop', $troopID);
|
||||
StaticEventHandler::handleEvent($me, null, $this::class, [], $this->args);
|
||||
$me->applyDB($db);
|
||||
$db->update('general', [
|
||||
'troop' => $troopID,
|
||||
], '`no` = %i AND `troop` = %i', $generalID, 0);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -6,9 +6,6 @@ use sammo\Session;
|
||||
use DateTimeInterface;
|
||||
use sammo\DB;
|
||||
use sammo\Enums\APIRecoveryType;
|
||||
use sammo\Enums\GeneralLiteQueryMode;
|
||||
use sammo\GeneralLite;
|
||||
use sammo\StaticEventHandler;
|
||||
use sammo\Validator;
|
||||
|
||||
class KickFromTroop extends \sammo\BaseAPI
|
||||
@@ -40,8 +37,7 @@ class KickFromTroop extends \sammo\BaseAPI
|
||||
$generalID = $this->args['generalID'];
|
||||
$db = DB::db();
|
||||
|
||||
$destGeneral = GeneralLite::createObjFromDB($generalID, ['troop'], GeneralLiteQueryMode::Lite);
|
||||
$troopID = $destGeneral->getVar('troop');
|
||||
$troopID = $db->queryFirstField('SELECT troop FROM general WHERE no = %i', $generalID);
|
||||
if($troopID == 0){
|
||||
return '부대에 소속되어 있지 않습니다.';
|
||||
}
|
||||
@@ -54,10 +50,9 @@ class KickFromTroop extends \sammo\BaseAPI
|
||||
return '부대장을 추방할 수 없습니다.';
|
||||
}
|
||||
|
||||
StaticEventHandler::handleEvent($destGeneral, null, $this::class, [], $this->args);
|
||||
$destGeneral->setVar('troop', 0);
|
||||
$destGeneral->applyDB($db);
|
||||
|
||||
$db->update('general', [
|
||||
'troop' => 0,
|
||||
], '`no` = %i AND `troop` = %i', $generalID, $troopID);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,6 @@ use sammo\Session;
|
||||
use DateTimeInterface;
|
||||
use sammo\DB;
|
||||
use sammo\Enums\APIRecoveryType;
|
||||
use sammo\Enums\GeneralLiteQueryMode;
|
||||
use sammo\GeneralLite;
|
||||
use sammo\StaticEventHandler;
|
||||
use sammo\StringUtil;
|
||||
use sammo\Validator;
|
||||
|
||||
@@ -35,23 +32,24 @@ class NewTroop extends \sammo\BaseAPI
|
||||
|
||||
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag): null | string | array | APIRecoveryType
|
||||
{
|
||||
$generalID = $session->generalID;
|
||||
$userID = $session->userID;
|
||||
$troopName = StringUtil::neutralize($this->args['troopName']);
|
||||
if(!$troopName){
|
||||
return '부대 이름이 없습니다.';
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
$me = GeneralLite::createObjFromDB($generalID, ['troop'], GeneralLiteQueryMode::Lite);
|
||||
$troopID = $me->getVar('troop');
|
||||
if($troopID != 0){
|
||||
$me = $db->queryFirstRow('SELECT `no`,nation,`troop`,`officer_level`,permission,penalty FROM general WHERE `owner`=%i', $userID);
|
||||
if($me['troop'] != 0){
|
||||
return '이미 부대에 소속되어 있습니다.';
|
||||
}
|
||||
$nationID = $me->getNationID();
|
||||
$nationID = $me['nation'];
|
||||
if($nationID == 0){
|
||||
return '국가에 소속되어 있지 않습니다.';
|
||||
}
|
||||
|
||||
$generalID = $me['no'];
|
||||
|
||||
$db->insert('troop', [
|
||||
'name'=>$troopName,
|
||||
'troop_leader'=>$generalID,
|
||||
@@ -62,9 +60,9 @@ class NewTroop extends \sammo\BaseAPI
|
||||
return '부대가 생성되지 않았습니다. 버그일 수 있습니다.';
|
||||
}
|
||||
|
||||
$me->setVar('troop', $generalID);
|
||||
StaticEventHandler::handleEvent($me, null, $this::class, [], $this->args);
|
||||
$me->applyDB($db);
|
||||
$db->update('general', [
|
||||
'troop'=>$generalID
|
||||
], '`no` = %i', $generalID);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -6,9 +6,6 @@ use sammo\Session;
|
||||
use DateTimeInterface;
|
||||
use sammo\DB;
|
||||
use sammo\Enums\APIRecoveryType;
|
||||
use sammo\Enums\GeneralLiteQueryMode;
|
||||
use sammo\GeneralLite;
|
||||
use sammo\StaticEventHandler;
|
||||
use sammo\StringUtil;
|
||||
use sammo\Validator;
|
||||
|
||||
@@ -39,12 +36,13 @@ class SetTroopName extends \sammo\BaseAPI
|
||||
|
||||
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag): null | string | array | APIRecoveryType
|
||||
{
|
||||
$generalID = $session->generalID;
|
||||
$userID = $session->userID;
|
||||
$db = DB::db();
|
||||
$me = GeneralLite::createObjFromDB($generalID, ['troop', 'permission', 'penalty'], GeneralLiteQueryMode::Lite);
|
||||
$permission = checkSecretPermission($me->getRaw(), false);
|
||||
$me = $db->queryFirstRow('SELECT `no`,nation,`officer_level`,permission,penalty FROM general WHERE `owner`=%i', $userID);
|
||||
$permission = checkSecretPermission($me, false);
|
||||
$troopID = $this->args['troopID'];
|
||||
|
||||
$generalID = $me['no'];
|
||||
if($generalID != $troopID && $permission < 4){
|
||||
return "권한이 부족합니다.";
|
||||
}
|
||||
@@ -54,7 +52,7 @@ class SetTroopName extends \sammo\BaseAPI
|
||||
return '부대 이름이 없습니다.';
|
||||
}
|
||||
|
||||
$nationID = $me->getNationID();
|
||||
$nationID = $me['nation'];
|
||||
$db->update('troop', [
|
||||
'name'=>$troopName
|
||||
], 'troop_leader=%i AND `nation`=%i',$troopID, $nationID);
|
||||
@@ -62,7 +60,6 @@ class SetTroopName extends \sammo\BaseAPI
|
||||
if($db->affectedRows() == 0){
|
||||
return '부대가 없습니다.';
|
||||
}
|
||||
StaticEventHandler::handleEvent($me, null, $this::class, [], $this->args);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -10,9 +10,8 @@ use sammo\Enums\GeneralLiteQueryMode;
|
||||
use sammo\Enums\GeneralQueryMode;
|
||||
use sammo\General;
|
||||
use sammo\GeneralLite;
|
||||
use sammo\GameClock;
|
||||
use sammo\KVStorage;
|
||||
use sammo\Session;
|
||||
use sammo\TimeUtil;
|
||||
use sammo\Validator;
|
||||
|
||||
class AddComment extends \sammo\BaseAPI
|
||||
@@ -48,8 +47,7 @@ class AddComment extends \sammo\BaseAPI
|
||||
$generalName = $general->getName();
|
||||
$nationID = $general->getNationID();
|
||||
$nationName = $general->getStaticNation()['name'];
|
||||
$db = DB::db();
|
||||
$date = GameClock::fromStorage(KVStorage::getStorage($db, 'game_env'))->formatNow();
|
||||
$date = TimeUtil::now();
|
||||
|
||||
|
||||
$comment = new VoteComment(
|
||||
@@ -63,6 +61,7 @@ class AddComment extends \sammo\BaseAPI
|
||||
date: $date
|
||||
);
|
||||
|
||||
$db = DB::db();
|
||||
$db->insert('vote_comment', $comment->toArray());
|
||||
|
||||
return null;
|
||||
|
||||
@@ -8,7 +8,6 @@ use sammo\DB;
|
||||
use sammo\DTO\VoteComment;
|
||||
use sammo\DTO\VoteInfo;
|
||||
use sammo\Enums\APIRecoveryType;
|
||||
use sammo\GameClock;
|
||||
use sammo\Json;
|
||||
use sammo\KVStorage;
|
||||
use sammo\Validator;
|
||||
@@ -36,16 +35,13 @@ class GetVoteDetail extends \sammo\BaseAPI
|
||||
{
|
||||
$voteID = $this->args['voteID'];
|
||||
$db = DB::db();
|
||||
$clock = GameClock::fromStorage(KVStorage::getStorage($db, 'game_env'));
|
||||
|
||||
$voteStor = KVStorage::getStorage($db, 'vote');
|
||||
$rawVote = $voteStor->getValue("vote_{$voteID}");
|
||||
if (!$rawVote) {
|
||||
return '설문조사가 없습니다.';
|
||||
}
|
||||
$rawVote = VoteInfo::normalizeGameStorage($rawVote, $clock);
|
||||
$voteInfo = VoteInfo::fromGameStorage($rawVote, $clock);
|
||||
$isOpen = $rawVote['endTick'] === null || $rawVote['endTick'] >= $clock->nowTick();
|
||||
$voteInfo = VoteInfo::fromArray($rawVote);
|
||||
|
||||
|
||||
$votes = array_map(fn ($arr) => [Json::decode($arr[0]), $arr[1]], $db->queryAllLists(
|
||||
@@ -74,7 +70,6 @@ class GetVoteDetail extends \sammo\BaseAPI
|
||||
'comments' => $comments,
|
||||
'myVote' => $myVote,
|
||||
'userCnt' => $userCnt,
|
||||
'isOpen' => $isOpen,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ use DateTimeInterface;
|
||||
use sammo\DB;
|
||||
use sammo\DTO\VoteInfo;
|
||||
use sammo\Enums\APIRecoveryType;
|
||||
use sammo\GameClock;
|
||||
use sammo\KVStorage;
|
||||
use sammo\Session;
|
||||
|
||||
@@ -26,17 +25,16 @@ class GetVoteList extends \sammo\BaseAPI
|
||||
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag): null | string | array | APIRecoveryType
|
||||
{
|
||||
$db = DB::db();
|
||||
$clock = GameClock::fromStorage(KVStorage::getStorage($db, 'game_env'));
|
||||
|
||||
$voteStor = KVStorage::getStorage($db, 'vote');
|
||||
|
||||
$votes = [];
|
||||
foreach($voteStor->getAll() as $voteKey => $rawVote){
|
||||
if(preg_match('/^vote_(\d+)$/D', $voteKey, $matches) !== 1){
|
||||
if(!str_starts_with($voteKey, 'vote_')){
|
||||
continue;
|
||||
}
|
||||
$voteID = (int)$matches[1];
|
||||
$votes[$voteID] = VoteInfo::fromGameStorage($rawVote, $clock);
|
||||
$voteID = (int)substr($voteKey, 5);
|
||||
$votes[$voteID] = VoteInfo::fromArray($rawVote);
|
||||
}
|
||||
|
||||
return [
|
||||
|
||||
@@ -7,9 +7,8 @@ use sammo\DB;
|
||||
use sammo\DTO\VoteInfo;
|
||||
use sammo\Enums\APIRecoveryType;
|
||||
use sammo\KVStorage;
|
||||
use sammo\RootDB;
|
||||
use sammo\Session;
|
||||
use sammo\GameClock;
|
||||
use sammo\TimeUtil;
|
||||
use sammo\Util;
|
||||
use sammo\Validator;
|
||||
|
||||
@@ -37,7 +36,7 @@ class NewVote extends \sammo\BaseAPI
|
||||
return null;
|
||||
}
|
||||
|
||||
function closeOldVote(int $voteID, KVStorage $voteStor, GameClock $clock)
|
||||
function closeOldVote(int $voteID, KVStorage $voteStor)
|
||||
{
|
||||
$db = DB::db();
|
||||
$voteStor = KVStorage::getStorage($db, 'vote');
|
||||
@@ -45,14 +44,13 @@ class NewVote extends \sammo\BaseAPI
|
||||
if (!$rawLastVoteInfo) {
|
||||
return;
|
||||
}
|
||||
$rawLastVoteInfo = VoteInfo::normalizeGameStorage($rawLastVoteInfo, $clock);
|
||||
if ($rawLastVoteInfo['endTick'] !== null) {
|
||||
$lastVoteInfo = VoteInfo::fromArray($rawLastVoteInfo);
|
||||
if ($lastVoteInfo->endDate) {
|
||||
return;
|
||||
}
|
||||
|
||||
$rawLastVoteInfo['endTick'] = $clock->nowTick();
|
||||
$rawLastVoteInfo['endDate'] = $clock->formatTick($rawLastVoteInfo['endTick']);
|
||||
$voteStor->setValue("vote_{$voteID}", $rawLastVoteInfo);
|
||||
$lastVoteInfo->endDate = TimeUtil::now();
|
||||
$voteStor->setValue("vote_{$voteID}", $lastVoteInfo->toArray());
|
||||
}
|
||||
|
||||
function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag): null | string | array | APIRecoveryType
|
||||
@@ -72,11 +70,7 @@ class NewVote extends \sammo\BaseAPI
|
||||
$multipleOptions = 0;
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$clock = GameClock::fromStorage($gameStor);
|
||||
$nowTick = $clock->nowTick();
|
||||
$now = $clock->formatTick($nowTick);
|
||||
$now = TimeUtil::now();
|
||||
/** @var ?string */
|
||||
$endDate = $this->args['endDate'] ?? null;
|
||||
/** @var string[] */
|
||||
@@ -88,9 +82,9 @@ class NewVote extends \sammo\BaseAPI
|
||||
|
||||
if($endDate !== null){
|
||||
try{
|
||||
$oNow = new \DateTimeImmutable($now);
|
||||
$oEndDate = new \DateTimeImmutable($endDate);
|
||||
$endTick = $clock->dateTimeToTick($oEndDate);
|
||||
if($endTick < $nowTick){
|
||||
if($oEndDate < $oNow){
|
||||
return '종료일이 이미 지났습니다.';
|
||||
}
|
||||
}
|
||||
@@ -99,7 +93,9 @@ class NewVote extends \sammo\BaseAPI
|
||||
}
|
||||
}
|
||||
|
||||
$userName = $session->userName;
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
|
||||
$lastVote = $gameStor->getValue('lastVote') ?? 0;
|
||||
$voteID = $lastVote + 1;
|
||||
@@ -107,26 +103,21 @@ class NewVote extends \sammo\BaseAPI
|
||||
$voteStor = KVStorage::getStorage($db, 'vote');
|
||||
|
||||
if (!($this->args['keepOldVote'] ?? false)) {
|
||||
$this->closeOldVote($lastVote, $voteStor, $clock);
|
||||
$this->closeOldVote($lastVote, $voteStor);
|
||||
}
|
||||
|
||||
$multipleOptions = Util::valueFit($multipleOptions, 0, count($options));
|
||||
|
||||
|
||||
$voteInfo = new VoteInfo(
|
||||
id: $voteID,
|
||||
title: $title,
|
||||
opener: $userName ?? '[SYSTEM]',
|
||||
multipleOptions: $multipleOptions,
|
||||
startDate: $now,
|
||||
endDate: $endDate,
|
||||
options: $options,
|
||||
);
|
||||
|
||||
$voteStor->setValue("vote_{$voteID}", $voteInfo->toArray() + [
|
||||
'startTick' => $nowTick,
|
||||
'endTick' => $endDate === null ? null : $clock->dateTimeToTick(new \DateTimeImmutable($endDate)),
|
||||
]);
|
||||
$voteStor->setValue("vote_{$voteID}", $voteInfo->toArray());
|
||||
$gameStor->setValue('lastVote', $voteID);
|
||||
|
||||
$db->update('general', [
|
||||
|
||||
@@ -8,7 +8,6 @@ use sammo\DTO\VoteInfo;
|
||||
use sammo\Enums\APIRecoveryType;
|
||||
use sammo\Enums\GeneralQueryMode;
|
||||
use sammo\General;
|
||||
use sammo\GameClock;
|
||||
use sammo\Json;
|
||||
use sammo\KVStorage;
|
||||
use sammo\LiteHashDRBG;
|
||||
@@ -55,17 +54,15 @@ class Vote extends \sammo\BaseAPI
|
||||
return '선택한 항목이 없습니다.';
|
||||
}
|
||||
$db = DB::db();
|
||||
$clock = GameClock::fromStorage(KVStorage::getStorage($db, 'game_env'));
|
||||
$voteStor = KVStorage::getStorage($db, 'vote');
|
||||
|
||||
$rawVoteInfo = $voteStor->getValue("vote_{$voteID}");
|
||||
if (!$rawVoteInfo) {
|
||||
return '설문조사가 없습니다.';
|
||||
}
|
||||
$rawVoteInfo = VoteInfo::normalizeGameStorage($rawVoteInfo, $clock);
|
||||
$voteInfo = VoteInfo::fromGameStorage($rawVoteInfo, $clock);
|
||||
$voteInfo = VoteInfo::fromArray($rawVoteInfo);
|
||||
|
||||
if ($rawVoteInfo['endTick'] !== null && $rawVoteInfo['endTick'] < $clock->nowTick()) {
|
||||
if ($voteInfo->endDate && $voteInfo->endDate < new \DateTimeImmutable()) {
|
||||
return '설문조사가 종료되었습니다.';
|
||||
}
|
||||
|
||||
|
||||
@@ -8,11 +8,6 @@ use sammo\Util;
|
||||
|
||||
abstract class AbsFromUserPool extends AbsGeneralPool{
|
||||
|
||||
protected static function getCandidateWeight(array $info, int $owner): int|float
|
||||
{
|
||||
return array_sum($info['dex'] ?? []);
|
||||
}
|
||||
|
||||
public function occupyGeneralName(): bool
|
||||
{
|
||||
$generalID = $this->getGeneralBuilder()->getGeneralID();
|
||||
@@ -30,9 +25,8 @@ abstract class AbsFromUserPool extends AbsGeneralPool{
|
||||
}
|
||||
|
||||
static public function pickGeneralFromPool(\MeekroDB $db, RandUtil $rng, int $owner, int $pickCnt, ?string $prefix=null):array{
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$clock = GameClock::fromStorage($gameStor);
|
||||
$now = $clock->nowTick();
|
||||
$oNow = new \DateTimeImmutable();
|
||||
$now = $oNow->format('Y-m-d H:i:s');
|
||||
|
||||
$db->update('select_pool', [
|
||||
'reserved_until'=>null,
|
||||
@@ -42,15 +36,17 @@ abstract class AbsFromUserPool extends AbsGeneralPool{
|
||||
$pool = [];
|
||||
foreach($db->query('SELECT id, unique_name, info FROM select_pool WHERE reserved_until IS NULL AND general_id IS NULL', $pickCnt) as $cand){
|
||||
$cand['info'] = Json::decode($cand['info']);
|
||||
$pool[] = [$cand, static::getCandidateWeight($cand['info'], $owner)];
|
||||
$dexTotal = array_sum($cand['info']['dex']);
|
||||
$pool[] = [$cand, $dexTotal];
|
||||
}
|
||||
|
||||
if(count($pool) < $pickCnt){
|
||||
throw new \RuntimeException('pool 부족');
|
||||
}
|
||||
|
||||
$result = [];
|
||||
$validUntil = $now + GameClock::TICKS_PER_TURN * 2;
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$result = [];
|
||||
$validUntil = TimeUtil::nowAddMinutes(2 * $gameStor->turnterm);
|
||||
while(count($result) < $pickCnt){
|
||||
$cand = $rng->choiceUsingWeightPair($pool);
|
||||
$poolID = $cand['id'];
|
||||
@@ -73,4 +69,4 @@ abstract class AbsFromUserPool extends AbsGeneralPool{
|
||||
|
||||
return array_values($result);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,7 +34,7 @@ abstract class AbsGeneralPool{
|
||||
* specialWar
|
||||
*/
|
||||
|
||||
public function __construct(\MeekroDB $db, RandUtil $rng, array $info, int $validUntil)
|
||||
public function __construct(\MeekroDB $db, RandUtil $rng, array $info, string $validUntil)
|
||||
{
|
||||
$this->db = $db;
|
||||
$this->info = $info;
|
||||
@@ -92,7 +92,7 @@ abstract class AbsGeneralPool{
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
public function getValidUntil():int{
|
||||
public function getValidUntil():string{
|
||||
return $this->validUntil;
|
||||
}
|
||||
|
||||
@@ -109,4 +109,4 @@ abstract class AbsGeneralPool{
|
||||
|
||||
abstract public static function getPoolName():string;
|
||||
abstract public static function initPool(\MeekroDB $db);
|
||||
}
|
||||
}
|
||||
@@ -19,14 +19,10 @@ class che_저지_삼황내문 extends \sammo\BaseItem{
|
||||
if($unit->isAttacker()){
|
||||
return null;
|
||||
}
|
||||
|
||||
if($unit->getPhase() > 0){
|
||||
if($unit->getPhase() >= 2){
|
||||
return null;
|
||||
}
|
||||
if($unit->hasActivatedSkillOnLog('저지') >= 2){
|
||||
return null;
|
||||
}
|
||||
if($unit->hasActivatedSkillOnLog('저지') == 1 && $unit->getPhase() == 0 && $unit->rng->nextBool(0.5)){
|
||||
if($unit->getPhase() == 1 && $unit->rng->nextBool(0.5)){
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ class che_척사_오악진형도 extends \sammo\BaseItem{
|
||||
|
||||
public function getWarPowerMultiplier(WarUnit $unit):array{
|
||||
$opposeCrewType = $unit->getOppose()->getCrewType();
|
||||
if($opposeCrewType->reqCities() || $opposeCrewType->reqRegions()){
|
||||
if($opposeCrewType->reqCities || $opposeCrewType->reqRegions){
|
||||
return [1.15, 0.85];
|
||||
}
|
||||
return [1, 1];
|
||||
|
||||
@@ -33,7 +33,7 @@ class event_전투특기_공성 extends \sammo\BaseItem{
|
||||
}
|
||||
|
||||
public function onCalcStat(General $general, string $statName, $value, $aux=null){
|
||||
if(str_starts_with($statName, 'dex')){
|
||||
if(\sammo\Util::starts_with($statName, 'dex')){
|
||||
$myArmType = 'dex'.GameUnitConst::T_SIEGE;
|
||||
$opposeArmType = 'dex'.$aux['opposeType']->armType;;
|
||||
if($aux['isAttacker'] && $opposeArmType === $statName){
|
||||
|
||||
@@ -28,7 +28,7 @@ class event_전투특기_궁병 extends \sammo\BaseItem{
|
||||
if($statName === 'warAvoidRatio'){
|
||||
return $value + 0.2;
|
||||
}
|
||||
if(str_starts_with($statName, 'dex')){
|
||||
if(\sammo\Util::starts_with($statName, 'dex')){
|
||||
$myArmType = 'dex'.GameUnitConst::T_ARCHER;
|
||||
$opposeArmType = 'dex'.$aux['opposeType']->armType;;
|
||||
if($aux['isAttacker'] && $opposeArmType === $statName){
|
||||
|
||||
@@ -28,7 +28,7 @@ class event_전투특기_귀병 extends \sammo\BaseItem{
|
||||
if($statName === 'warMagicSuccessProb'){
|
||||
return $value + 0.2;
|
||||
}
|
||||
if(str_starts_with($statName, 'dex')){
|
||||
if(\sammo\Util::starts_with($statName, 'dex')){
|
||||
$myArmType = 'dex'.GameUnitConst::T_WIZARD;
|
||||
$opposeArmType = 'dex'.$aux['opposeType']->armType;;
|
||||
if($aux['isAttacker'] && $opposeArmType === $statName){
|
||||
|
||||
@@ -32,7 +32,7 @@ class event_전투특기_기병 extends \sammo\BaseItem{
|
||||
}
|
||||
|
||||
public function onCalcStat(General $general, string $statName, $value, $aux=null){
|
||||
if(str_starts_with($statName, 'dex')){
|
||||
if(\sammo\Util::starts_with($statName, 'dex')){
|
||||
$myArmType = 'dex'.GameUnitConst::T_CAVALRY;
|
||||
$opposeArmType = 'dex'.$aux['opposeType']->armType;;
|
||||
if($aux['isAttacker'] && $opposeArmType === $statName){
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user