Compare commits

...
44 Commits
Author SHA1 Message Date
Hide_D 1ca07286a4 Revert "game: 국가 임관 시, 기존 등용장 무효화"
This reverts commit 376aed9787.
2023-07-12 20:19:59 +10:00
Hide_D 376aed9787 game: 국가 임관 시, 기존 등용장 무효화 2023-07-11 22:47:24 +10:00
Hide_D 246751b4dd feat: 등용장 일괄 무효화 추가 2023-07-11 22:43:09 +10:00
Hide_D 7f3a9d69ca misc: FIXME 2023-07-11 22:11:01 +10:00
Hide_D a4106f6242 game: 등용장 수락은 재야 상태에서만 가능 2023-07-11 22:02:07 +10:00
Hide_DandGitea f233e8241e Merge pull request 'feat,refac: General 테이블의 벌점(갱신) 항목을 별도 테이블로 분리' (#232) from general_access_log into devel 2023-07-08 09:10:53 +00:00
Hide_D 79dedea47c fix: 물자원조 조사 2023-07-08 02:04:17 +00:00
Hide_D e106a6a3cf fix: queryMode 조회 문제
- 아니 PHP야 enum에 ->value 좀..
2023-07-07 18:44:36 +00:00
Hide_D ee3d84d7b0 refac: General 객체 생성을 GeneralQueryMode를 활용
- 기존 $constructMode
- 버그 있음..?
2023-07-07 18:39:23 +00:00
Hide_D b4f197b7d8 feat: GeneralQueryMode Enum 추가
- mergeQueryColumn, createGeneralObjListFromDB, createGeneralObjFromDB 호출시
 column 특수 모드 지정
2023-07-07 18:14:55 +00:00
Hide_D e3c89a37aa fix: 구 내정보 페이지 변수 조회 문제 2023-07-07 17:29:03 +00:00
Hide_D ad0770d1be fix: 접속량 정보 변수명 2023-07-07 17:20:24 +00:00
Hide_D 161ed97a34 fix: GeneralAccessLogColumn 인자 값 문제
- PHP 제발 반성 좀... 왜 ->value가 필요해..?
2023-07-07 17:12:15 +00:00
Hide_D f66008da56 refac, fix: General 객체 생성 과정에서 accessLog 분리
- 생성자 인수 1개 추가,
- mergeQueryColumn에서 $accessLogColumn에 정상적으로 enum[] 반영
- createGeneralObjListFromDB를 쿼리 1회 분리
- General에 getAccessLogVar() 추가
  - 변경 기능 제공 예정 '없음'
- 변경된 생성자에 맞게 호출 부 변경
- NPC인 경우 accessLog 조회값이 null일 수 있으므로 반영
2023-07-07 17:08:05 +00:00
Hide_D 6b400f76cf fix: 오타 수정 2023-07-07 15:58:18 +00:00
Hide_D 758ae06fd9 refac, wip: con 삭제,생성 관련 2023-07-07 10:57:52 +00:00
Hide_D 49429e1e7e refac, wip: con -> refreshScore 2023-07-07 10:57:52 +00:00
Hide_D c9dd873019 refac, wip: 벌점(connect, con) 변경
- 벌점: refreshScoreTotal
- 순간벌점: refreshScore
2023-07-07 10:57:52 +00:00
Hide_D 3ae49456b1 fix: general_access_log에 벌점 관련 데이터 누락 2023-07-07 10:57:52 +00:00
Hide_D 9bf7bd0fda refac,wip: refresh 수치를 이전 중
- connect, con을 잊었음!
2023-07-07 10:57:51 +00:00
Hide_D a9b51977d4 refac: lastrefresh를 general_access_log로 이전
- last_refresh에 index를 걸 것인지는 고려 필요
  - 안 거는게 차라리 나을 수도 있음
- 불필요해보이는 값 확인: nation_id,
2023-07-07 10:57:51 +00:00
Hide_D 50408ed516 feat: TableName Enum 2023-07-07 10:57:51 +00:00
Hide_D b0cdf3ccb5 refac: General::lastconnect 삭제
- 안쓰는데..?
- api_log로 어느새 이전된건가?
2023-07-07 10:57:51 +00:00
Hide_D ea80b85b33 refac: 갱신 시 refresh를 general_access_log로 이동 2023-07-07 10:57:51 +00:00
Hide_D 39ca3e2bb9 feat: GeneralAccessLog 구조 변경
- 기본값 최대한 많이 사용
2023-07-07 10:57:51 +00:00
Hide_D f8cc0c9c92 feat: GeneralAccessLog table 준비
- general 테이블에서 유저 접속과 관련한 로그만 분리
- ip 정보는 api 접속부에서 기록하므로 제외
2023-07-07 10:57:51 +00:00
Hide_D 7a9ef6454c fix: 정체불명의 ts type error fix
- 이 변경이 없어도 잘 되어야함. type에 undefined로 놓는게 어딨어?
2023-07-07 10:57:50 +00:00
Hide_D d48c27dccb misc: 관리자5번 도구에서 벌점 정보 제거 2023-07-07 10:57:50 +00:00
Hide_D 5a565c2678 feat: formatListOfBackticks에서 인자로 BackedEnum 사용 가능 2023-07-07 10:57:50 +00:00
Hide_D 1e0875ae73 game: 국력 계산식에 '벌점' 제거 2023-07-07 10:57:50 +00:00
Hide_D 33759d24e5 refac: 접속 로그를 날짜_refresh.txt에서 api_log로 통일
- path가 refresh로 고정
2023-07-07 10:57:50 +00:00
Hide_D 033e75de5c refac: 구 멀티 검사 페이지 삭제
- IP로만 구분하던 방식
- IP를 general에서 없애므로 삭제
2023-07-07 10:57:45 +00:00
Hide_D f2f8374fd4 fix: 쉼표를 주의하시오 2023-07-04 10:24:32 +09:00
Hide_D e891525d56 refac: general_turn, nation_turn 불필요한 인덱스 제거 2023-07-03 17:04:38 +00:00
Hide_D 93bc8304ce misc: 몇 가지 눈에 보이는 오타 수정 (#231)
Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/231
2023-07-03 22:32:42 +09:00
Jinhyun Kim d4218f409c 몇 가지 눈에 보이는 오타 수정 2023-07-03 20:59:05 +09:00
Hide_D 462de95866 misc: php xdebug profiler ignore 2023-07-02 17:42:56 +00:00
Hide_D dad477ed14 misc: 불필요산 #app css 제거
- 필요하다면 vue page에서 직접 요구하여야 함.
2023-07-02 17:06:01 +00:00
Hide_D 660258f715 refac: 메인 페이지 바 표시 형식 변경
- 상 하단 분리 대신 하단의 position:fixed bar로 변경
- iPhone에서 좌우 스크롤이 유도되는 것은 완전 해결되지 않음
- 모든 컨텐츠가 viewport 밖을 넘어서지 않도록 않도록 해야 할 것으로
- 예: 500px viewport, 498px content
2023-07-02 17:05:14 +00:00
Hide_D 9f6c7d9489 fix: 누락된 php breakpoint 수정 2023-06-30 16:34:14 +00:00
Hide_D de17d87f47 fix: 비일관적인 breakpoint 정정
- md가 아니라 lg를 기준으로 잡아야 함
- lg의 기준 breakpoint를 940으로 변경
- is100pxMode의 기준 역시 lg breakpoint와 일치
2023-06-30 16:30:44 +00:00
Hide_D f8ebcf91b1 fix: 삼성 브라우저 draggable workaround 2023-06-28 14:50:52 +00:00
Hide_D d25d414057 dep: vuedraggable-es 2023-06-28 14:50:37 +00:00
Hide_D 96a9254bf8 misc: tabSize 4 2023-06-28 13:45:24 +00:00
163 changed files with 1557 additions and 1329 deletions
+2
View File
@@ -69,3 +69,5 @@ gateway/js/*
gateway/css/* gateway/css/*
*.db-journal *.db-journal
d_log/cachegrind.*
+1 -1
View File
@@ -29,5 +29,5 @@
"josa", "josa",
"sammo" "sammo"
], ],
"editor.tabSize": 2 "editor.tabSize": 4
} }
+3 -3
View File
@@ -30,10 +30,10 @@ require(__DIR__ . '/../vendor/autoload.php');
<body> <body>
<div class="container"> <div class="container">
<h1 class="row justify-content-md-center">삼국지 모의전투 HiDCHe 설치</h1> <h1 class="row justify-content-lg-center">삼국지 모의전투 HiDCHe 설치</h1>
<div class="row justify-content-md-center"> <div class="row justify-content-lg-center">
<div class="col col-12 col-md-10 col-lg-7"> <div class="col col-12 col-lg-10 col-lg-7">
<div class="card" id="db_form_card" style="display:none"> <div class="card" id="db_form_card" style="display:none">
<h3 class="card-header"> <h3 class="card-header">
설치(DB 설정) 설치(DB 설정)
+10 -10
View File
@@ -38,13 +38,13 @@ if ($genlist) {
} }
switch ($btn) { switch ($btn) {
case "전체 접속허용": case "전체 접속허용":
$db->update('general', [ $db->update('general_access_log', [
'con' => 0 'refresh_score' => 0
], true); ], true);
break; break;
case "전체 접속제한": case "전체 접속제한":
$db->update('general', [ $db->update('general_access_log', [
'con' => 1000 'refresh_score' => 1000
], true); ], true);
break; break;
case "블럭 해제": case "블럭 해제":
@@ -186,14 +186,14 @@ switch ($btn) {
], '`no` IN %li', $genlist); ], '`no` IN %li', $genlist);
break; break;
case "접속 허용": case "접속 허용":
$db->update('general', [ $db->update('general_access_log', [
'con' => 0 'refresh_score' => 0
], '`no` IN %li', $genlist); ], '`general_id` IN %li', $genlist);
break; break;
case "접속 제한": case "접속 제한":
$db->update('general', [ $db->update('general_access_log', [
'con' => 1000 'refresh_score' => 1000
], '`no` IN %li', $genlist); ], '`general_id` IN %li', $genlist);
break; break;
case "메세지 전달": case "메세지 전달":
$text = $msg ?? ''; $text = $msg ?? '';
-125
View File
@@ -1,125 +0,0 @@
<?php
namespace sammo;
include "lib.php";
include "func.php";
//로그인 검사
$session = Session::requireGameLogin()->setReadOnly();
if ($session->userGrade < 5) {
die(requireAdminPermissionHTML());
}
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$conlimit = $gameStor->conlimit;
$ipGroupList = Util::arrayGroupBy(
$db->query(
'SELECT name,ip,lastconnect,owner,block,substring_index(ip,".",3) as ip_c from general WHERE ip!="" and npc<2'
),
'ip_c'
);
?>
<!DOCTYPE html>
<html>
<head>
<title>멀티관리</title>
<meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" />
<?= WebUtil::printCSS('../d_shared/common.css') ?>
<?= WebUtil::printDist('ts', 'common', true) ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
</head>
<body>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td>멀 티 관 리<br><?= backButton() ?></td>
</tr>
</table>
<form name=form1 method=post action=_admin4_submit.php>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td width=80 align=center rowspan=3>회원선택<br><br>
<font color=cyan>NPC</font><br>
<font color=skyblue>NPC유저</font><br>
<font color=red>접속제한</font><br><b style=background-color:red;>블럭회원</b>
</td>
<td width=105 rowspan=3>
<?php
echo "
<select name=genlist[] size=20 multiple style='color:white;background-color:black;font-size:14px'>";
foreach ($db->query('SELECT no,name,npc,block,con from general where ip!=\'\' order by npc,ip') as $general) {
$style = "style=;";
if ($general['block'] > 0) {
$style .= "background-color:red;";
}
$npcColor = getNPCColor($general['npc']);
if($npcColor !== null){
$style .= "color:{$npcColor};";
}
echo "
<option value={$general['no']} $style>{$general['name']}</option>";
}
echo "
</select>";
?>
</td>
<td width=100 align=center>블럭</td>
<td width=504>
<input type=submit name=btn value='블럭 해제'><input type=submit name=btn value='1단계 블럭'><input type=submit name=btn value='2단계 블럭'><input type=submit name=btn value='3단계 블럭'><input type=submit name=btn value='무한삭턴'><br>
1단계:발언권, 2단계:턴블럭
</td>
</tr>
<tr>
<td align=center>강제 사망</td>
<td><input type=submit name=btn value='강제 사망'></td>
</tr>
<tr>
<td align=center>메세지 전달</td>
<td><input type=textarea size=60 maxlength=255 name=msg style=background-color:black;color:white;><input type=submit name=btn value='메세지 전달'></td>
</tr>
</table>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td align=center width=100>장수명</td>
<td align=center width=180>최근로그인</td>
<td align=center width=129>IP</td>
<td align=center width=100>ID</td>
</tr>
<?php foreach ($ipGroupList as $ipGroupC => $users) : ?>
<tr>
<td><?= join('<br>', array_column($users, 'name')) ?></td>
<td><?= join('<br>', array_column($users, 'lastconnect')) ?></td>
<td><?= join('<br>', array_column($users, 'ip')) ?></td>
<td><?= join('<br>', array_column($users, 'owner')) ?></td>
</tr>
<?php endforeach; ?>
</table>
<?php
//NOTE: password의 md5 해시가 같은지 확인하는 방식으로는 앞으로 잡아낼 수 없다. 폐기
?>
</form>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td><?= backButton() ?></td>
</tr>
<tr>
<td><?= banner() ?> </td>
</tr>
</table>
</body>
</html>
-86
View File
@@ -1,86 +0,0 @@
<?php
namespace sammo;
use sammo\Enums\MessageType;
include "lib.php";
include "func.php";
//로그인 검사
$session = Session::requireGameLogin()->setReadOnly();
if ($session->userGrade < 5) {
header('location:_admin4.php');
die();
}
$btn = Util::getPost('btn');
$genlist = Util::getPost('genlist', 'array_int');
$msg = Util::getPost('msg', 'string', '메시지');
$db = DB::db();
//NOTE: 왜 기능이 admin2와 admin4가 같이 있는가?
//NOTE: 왜 블럭 시 admin4에선 금쌀을 없애지 않는가?
switch ($btn) {
case "블럭 해제":
DB::db()->query('update general set block=0 where no IN %li', $genlist);
break;
case "1단계 블럭":
$date = TimeUtil::now();
$db = DB::db();
$db->query('update general set block=1,killturn=24 where no IN %li', $genlist);
//FIXME: subquery로 하는게 더 빠를 듯.
$uid = $db->queryFirstColumn('select owner from general where no IN %li', $genlist);
RootDB::db()->query('update member set block_num=block_num+1,block_date=%s where id IN %ls', $date, $uid);
break;
case "2단계 블럭":
$date = TimeUtil::now();
$db = DB::db();
$db->query('update general set block=2,killturn=24 where no IN %li', $genlist);
$uid = $db->queryFirstColumn('select owner from general where no IN %li', $genlist);
RootDB::db()->query('update member set block_num=block_num+1,block_date=%s where id IN %ls', $date, $uid);
break;
case "3단계 블럭":
$date = TimeUtil::now();
$db = DB::db();
$db->query('update general set block=3,killturn=24 where no IN %li', $genlist);
$uid = $db->queryFirstColumn('select owner from general where no IN %li', $genlist);
RootDB::db()->query('update member set block_num=block_num+1,block_date=%s where id IN %ls', $date, $uid);
break;
case "무한삭턴":
DB::db()->query('update general set killturn=8000 where no IN %li', $genlist);
break;
case "강제 사망":
$date = TimeUtil::now(true);
$db->update('general', [
'killturn' => 0,
'turntime' => $date,
], '`no` IN %li', $genlist);
$db->update('general_turn', [
'action' => '휴식',
'arg' => '{}',
'brief' => '휴식'
], 'general_id IN %li AND turn_idx = 0', $genlist);
break;
case "메세지 전달":
$date = TimeUtil::now();
$src = MessageTarget::buildQuick($session->generalID);
foreach($genlist as $generalID){
$msgObj = new Message(
MessageType::private,
$src,
MessageTarget::buildQuick($generalID),
$msg,
new \DateTime(),
new \DateTime('9999-12-31'),
[]
);
if ($msgObj) {
$msgObj->send(true);
}
}
break;
}
header('location:_admin4.php');
-14
View File
@@ -66,8 +66,6 @@ $sel2[$type2] = "selected";
<option <?= $sel[8] ?? '' ?> value=8>평무</option> <option <?= $sel[8] ?? '' ?> value=8>평무</option>
<option <?= $sel[9] ?? '' ?> value=9>평지</option> <option <?= $sel[9] ?? '' ?> value=9>평지</option>
<option <?= $sel[10] ?? '' ?> value=10>평Lv</option> <option <?= $sel[10] ?? '' ?> value=10>평Lv</option>
<option <?= $sel[11] ?? '' ?> value=11>접속률</option>
<option <?= $sel[12] ?? '' ?> value=12>단기접</option>
<option <?= $sel[13] ?? '' ?> value=13>보숙</option> <option <?= $sel[13] ?? '' ?> value=13>보숙</option>
<option <?= $sel[14] ?? '' ?> value=14>궁숙</option> <option <?= $sel[14] ?? '' ?> value=14>궁숙</option>
<option <?= $sel[15] ?? '' ?> value=15>기숙</option> <option <?= $sel[15] ?? '' ?> value=15>기숙</option>
@@ -105,8 +103,6 @@ $sel2[$type2] = "selected";
<table align=center width=1600 class="tb_layout bg0"> <table align=center width=1600 class="tb_layout bg0">
<tr class='bg1'> <tr class='bg1'>
<td align=center>국명</td> <td align=center>국명</td>
<td align=center>접률</td>
<td align=center>단접</td>
<td align=center>국력</td> <td align=center>국력</td>
<td align=center>장수</td> <td align=center>장수</td>
<td align=center>속령</td> <td align=center>속령</td>
@@ -147,8 +143,6 @@ SELECT
A.gold, A.gold,
A.rice, A.rice,
COUNT(B.nation) AS gennum, COUNT(B.nation) AS gennum,
ROUND(AVG(B.connect), 1) AS connect,
ROUND(AVG(B.con), 1) AS con,
ROUND(AVG(B.dex1)) AS dex1, ROUND(AVG(B.dex1)) AS dex1,
ROUND(AVG(B.dex2)) AS dex2, ROUND(AVG(B.dex2)) AS dex2,
ROUND(AVG(B.dex3)) AS dex3, ROUND(AVG(B.dex3)) AS dex3,
@@ -193,12 +187,6 @@ GROUP BY B.nation
case 10: case 10:
$query .= " order by avg(B.explevel) desc"; $query .= " order by avg(B.explevel) desc";
break; break;
case 11:
$query .= " order by avg(B.connect) desc";
break;
case 12:
$query .= " order by avg(B.con) desc";
break;
case 13: case 13:
$query .= " order by avg(B.dex1) desc"; $query .= " order by avg(B.dex1) desc";
break; break;
@@ -240,8 +228,6 @@ from city where nation=%i', $nation['nation']);
echo " echo "
<tr> <tr>
<td align=center style=background-color:{$nation['color']};color:" . newColor($nation['color']) . ";>{$nation['name']}</td> <td align=center style=background-color:{$nation['color']};color:" . newColor($nation['color']) . ";>{$nation['name']}</td>
<td align=center>&nbsp;{$nation['connect']}&nbsp;</td>
<td align=center>&nbsp;{$nation['con']}&nbsp;</td>
<td align=center>&nbsp;{$nation['power']}&nbsp;</td> <td align=center>&nbsp;{$nation['power']}&nbsp;</td>
<td align=center>&nbsp;{$gen['cnt']}&nbsp;</td> <td align=center>&nbsp;{$gen['cnt']}&nbsp;</td>
<td align=center>&nbsp;{$city['cnt']}&nbsp;</td> <td align=center>&nbsp;{$city['cnt']}&nbsp;</td>
+3 -1
View File
@@ -2,6 +2,8 @@
namespace sammo; namespace sammo;
use sammo\Enums\GeneralQueryMode;
include "lib.php"; include "lib.php";
include "func.php"; include "func.php";
@@ -74,7 +76,7 @@ if (!$gen) {
$gen = $generalBasicList[0]['no']; $gen = $generalBasicList[0]['no'];
} }
$generalObj = General::createGeneralObjFromDB($gen); $generalObj = General::createGeneralObjFromDB($gen, null, GeneralQueryMode::FullWithAccessLog);
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
+16 -8
View File
@@ -16,10 +16,13 @@ $gameStor = KVStorage::getStorage($db, 'game_env');
increaseRefresh("장수일람", 2); increaseRefresh("장수일람", 2);
$me = $db->queryFirstRow('SELECT con,turntime FROM general WHERE owner = %i', $userID); $me = $db->queryFirstRow(
'SELECT refresh_score,turntime FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner = %i', $userID
);
$con = checkLimit($me['con']); $limitState = checkLimit($me['refresh_score']);
if ($con >= 2) { if ($limitState >= 2) {
printLimitMsg($me['turntime']); printLimitMsg($me['turntime']);
exit(); exit();
} }
@@ -102,7 +105,7 @@ if ($gameStor->isunited) {
6 => ['dedication', true], 6 => ['dedication', true],
7 => ['officer_level', true], 7 => ['officer_level', true],
8 => ['killturn', false], 8 => ['killturn', false],
9 => ['connect', true], 9 => ['refresh_score_total', true],
10 => ['experience', true], 10 => ['experience', true],
11 => ['personal', true], 11 => ['personal', true],
12 => ['special', true], 12 => ['special', true],
@@ -111,7 +114,12 @@ if ($gameStor->isunited) {
15 => ['npc', true], 15 => ['npc', true],
][$type]; ][$type];
$generalList = $db->query('SELECT owner,no,picture,imgsvr,npc,age,nation,special,special2,personal,name,injury,leadership,strength,intel,experience,dedication,officer_level,killturn,connect from general order by %b %l', $orderKey, $orderDesc ? 'desc' : ''); $generalList = $db->query(
'SELECT owner,no,picture,imgsvr,npc,age,nation,special,special2,personal,name,injury,leadership,strength,intel,experience,dedication,officer_level,killturn,refresh_score_total
FROM `general` LEFT JOIN `general_access_log` ON general.no = general_access_log.general_id order by %b %l',
$orderKey,
$orderDesc ? 'desc' : ''
);
echo " echo "
<table align=center width=1000 class='tb_layout bg0'> <table align=center width=1000 class='tb_layout bg0'>
@@ -163,7 +171,7 @@ if ($gameStor->isunited) {
$name = $name . '<br><small>(' . $ownerNameList[$general['owner']] . ')</small>'; $name = $name . '<br><small>(' . $ownerNameList[$general['owner']] . ')</small>';
} }
$general['connect'] = Util::round($general['connect'], -1); $general['refresh_score_total'] = Util::round($general['refresh_score_total'], -1);
$imageTemp = GetImageURL($general['imgsvr']); $imageTemp = GetImageURL($general['imgsvr']);
echo " echo "
@@ -192,8 +200,8 @@ if ($gameStor->isunited) {
<td align=center>$strength</td> <td align=center>$strength</td>
<td align=center>$intel</td> <td align=center>$intel</td>
<td align=center>{$general['killturn']}</td> <td align=center>{$general['killturn']}</td>
<td align=center>{$general['connect']}"; <td align=center>" . $general['refresh_score_total'] ?? 0;
echo "<br>【" . getConnect($general['connect']) . "】</td> echo "<br>【" . getRefreshScoreText($general['refresh_score_total'] ?? 0) . "】</td>
</tr>"; </tr>";
} }
echo " echo "
+6 -3
View File
@@ -13,10 +13,13 @@ $gameStor = KVStorage::getStorage($db, 'game_env');
$gameStor->cacheValues(['killturn', 'autorun_user', 'turnterm']); $gameStor->cacheValues(['killturn', 'autorun_user', 'turnterm']);
increaseRefresh("세력일람", 2); increaseRefresh("세력일람", 2);
$me = $db->queryFirstRow('SELECT con, turntime FROM general WHERE owner=%i', $userID); $me = $db->queryFirstRow(
'SELECT refresh_score, turntime FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$con = checkLimit($me['con']); $limitState = checkLimit($me['refresh_score']);
if ($con >= 2) { if ($limitState >= 2) {
printLimitMsg($me['turntime']); printLimitMsg($me['turntime']);
exit(); exit();
} }
+15 -8
View File
@@ -2,6 +2,8 @@
namespace sammo; namespace sammo;
use sammo\Enums\GeneralAccessLogColumn;
include "lib.php"; include "lib.php";
include "func.php"; include "func.php";
@@ -23,10 +25,10 @@ $online = [];
$curonline = getOnlineNum(); $curonline = getOnlineNum();
foreach ($log as $i => $value) { foreach ($log as $i => $value) {
$parse = Json::decode($value); $parse = Json::decode($value);
if(is_array($parse) === false){ if (is_array($parse) === false) {
continue; continue;
} }
if(count($parse) < 5){ if (count($parse) < 5) {
continue; continue;
} }
$date[$i] = $parse[0]; $date[$i] = $parse[0];
@@ -193,19 +195,24 @@ if ($admin['maxonline'] < $curonline) {
</td> </td>
</tr> </tr>
<?php <?php
$max_refresh = $db->queryFirstRow('SELECT sum(refresh) as refresh, sum(`connect`) as `connect` from general'); $totalRefresh = [
$max_refresh['name'] = '접속자 총합'; ...$db->queryFirstRow('SELECT sum(`refresh`) as `refresh`, sum(`refresh_score_total`) as `refresh_score_total` from general_access_log'),
'name' => '접속자 총합'
];
$refresh_result = array_merge([$max_refresh], $db->query('SELECT `name`,refresh,`connect` FROM general ORDER BY refresh DESC LIMIT 5')); $top5Refresh = $db->query(
'SELECT `name`, `log`.`refresh`, `refresh_score_total` FROM `general_access_log` AS `log`
INNER JOIN `general` ON `log`.`general_id` = `general`.`no` ORDER BY `log`.`refresh` DESC LIMIT 5'
);
foreach ($refresh_result as $i => $user) { foreach (array_merge([$totalRefresh], $top5Refresh) as $i => $user) {
$w = round($user['refresh'] / max(1, $max_refresh['refresh']) * 100, 1); $w = round($user['refresh'] / max(1, $totalRefresh['refresh']) * 100, 1);
$w2 = round(100 - $w, 1); $w2 = round(100 - $w, 1);
$color = getTrafficColor($w); $color = getTrafficColor($w);
?> ?>
<tr> <tr>
<td width=98 align=center><?= $user['name'] ?></td> <td width=98 align=center><?= $user['name'] ?></td>
<td width=98 align=center><?= $user['connect'] ?>(<?= $user['refresh'] ?>)</td> <td width=98 align=center><?= $user['refresh_score_total'] ?>(<?= $user['refresh'] ?>)</td>
<td width=798> <td width=798>
<?php if ($w == 0) : ?> <?php if ($w == 0) : ?>
<?php elseif ($w < 10) : ?> <?php elseif ($w < 10) : ?>
+9 -5
View File
@@ -2,6 +2,7 @@
namespace sammo; namespace sammo;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\RankColumn; use sammo\Enums\RankColumn;
include "lib.php"; include "lib.php";
@@ -21,12 +22,15 @@ $generalID = $session->generalID;
$me = $db->queryFirstRow('SELECT no,tournament,con,turntime from general where owner=%i', $userID); $me = $db->queryFirstRow(
'SELECT no,tournament,refresh_score,turntime FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id where owner=%i', $userID
);
$admin = $gameStor->getValues(['tournament', 'phase', 'tnmt_type', 'turnterm', 'develcost']); $admin = $gameStor->getValues(['tournament', 'phase', 'tnmt_type', 'turnterm', 'develcost']);
$turnTerm = $admin['turnterm']; $turnTerm = $admin['turnterm'];
$con = checkLimit($me['con']); $limitState = checkLimit($me['refresh_score']);
if ($con >= 2) { if ($limitState >= 2) {
printLimitMsg($me['turntime']); printLimitMsg($me['turntime']);
exit(); exit();
} }
@@ -107,7 +111,7 @@ if ($str3) {
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<?php if ($con == 1) { <?php if ($limitState == 1) {
MessageBox("접속제한이 얼마 남지 않았습니다!"); MessageBox("접속제한이 얼마 남지 않았습니다!");
} ?> } ?>
@@ -563,7 +567,7 @@ if ($str3) {
$tournamentRankerList = General::createGeneralObjListFromDB( $tournamentRankerList = General::createGeneralObjListFromDB(
$db->queryFirstColumn('SELECT general_id FROM rank_data WHERE `type`= %s ORDER BY value DESC LIMIT 40', $gameColumn->value), $db->queryFirstColumn('SELECT general_id FROM rank_data WHERE `type`= %s ORDER BY value DESC LIMIT 40', $gameColumn->value),
[$prizeColumn->value, $gameColumn->value, $winColumn->value, $drawColumn->value, $loseColumn->value, 'leadership', 'strength', 'intel', 'no', 'npc', 'name'], [$prizeColumn->value, $gameColumn->value, $winColumn->value, $drawColumn->value, $loseColumn->value, 'leadership', 'strength', 'intel', 'no', 'npc', 'name'],
0 GeneralQueryMode::Core
); );
usort($tournamentRankerList, function (General $lhs, General $rhs) use ($gameColumn, $winColumn, $drawColumn, $loseColumn) { usort($tournamentRankerList, function (General $lhs, General $rhs) use ($gameColumn, $winColumn, $drawColumn, $loseColumn) {
$result = - ($lhs->getRankVar($gameColumn) <=> $rhs->getRankVar($gameColumn)); $result = - ($lhs->getRankVar($gameColumn) <=> $rhs->getRankVar($gameColumn));
+2 -2
View File
@@ -211,7 +211,7 @@ $templates = new \League\Plates\Engine('templates');
$city['trade'] = "- "; $city['trade'] = "- ";
} }
$dbColumns = General::mergeQueryColumn(['npc', 'defence_train', 'no', 'picture', 'imgsvr', 'name', 'injury', 'leadership', 'strength', 'intel', 'officer_level', 'nation', 'crewtype', 'crew', 'train', 'atmos'], 2)[0]; $dbColumns = General::mergeQueryColumn(['npc', 'defence_train', 'no', 'picture', 'imgsvr', 'name', 'injury', 'leadership', 'strength', 'intel', 'officer_level', 'nation', 'crewtype', 'crew', 'train', 'atmos'])[0];
if ($showDetailedInfo) { if ($showDetailedInfo) {
$generals = $db->query( $generals = $db->query(
'SELECT %l from general where city=%i order by turntime', 'SELECT %l from general where city=%i order by turntime',
@@ -327,7 +327,7 @@ $templates = new \League\Plates\Engine('templates');
if ($ourGeneral && !$isNPC) { if ($ourGeneral && !$isNPC) {
$turnText = []; $turnText = [];
$generalObj = new General($general, null, null, null, null, null, false); $generalObj = new General($general, null, null, null, null, null, null, false);
foreach ($generalTurnList[$generalObj->getID()] as $turnRawIdx => $turn) { foreach ($generalTurnList[$generalObj->getID()] as $turnRawIdx => $turn) {
$turnIdx = $turnRawIdx + 1; $turnIdx = $turnRawIdx + 1;
$turnText[] = "{$turnIdx} : $turn"; $turnText[] = "{$turnIdx} : $turn";
+7 -4
View File
@@ -19,12 +19,15 @@ $gameStor = KVStorage::getStorage($db, 'game_env');
increaseRefresh("암행부", 1); increaseRefresh("암행부", 1);
$me = $db->queryFirstRow('SELECT no,nation,officer_level,con,turntime,belong,permission,penalty from general where owner=%i', $userID); $me = $db->queryFirstRow(
'SELECT no,nation,officer_level,refresh_score,turntime,belong,permission,penalty FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$nationLevel = $db->queryFirstField('SELECT level FROM nation WHERE nation=%i', $me['nation']); $nationLevel = $db->queryFirstField('SELECT level FROM nation WHERE nation=%i', $me['nation']);
$con = checkLimit($me['con']); $limitState = checkLimit($me['refresh_score']);
if ($con >= 2) { if ($limitState >= 2) {
printLimitMsg($me['turntime']); printLimitMsg($me['turntime']);
exit(); exit();
} }
@@ -45,7 +48,7 @@ $templates = new \League\Plates\Engine('templates');
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<?php if ($con == 1) { <?php if ($limitState == 1) {
MessageBox("접속제한이 얼마 남지 않았습니다!"); MessageBox("접속제한이 얼마 남지 않았습니다!");
} ?> } ?>
+6 -4
View File
@@ -97,7 +97,7 @@ if ($gameStor->isunited) {
7 => ['gold', true], 7 => ['gold', true],
8 => ['rice', true], 8 => ['rice', true],
9 => ['crew', true], 9 => ['crew', true],
10 => ['connect', true], 10 => ['refresh_score_total', true],
11 => ['personal', true], 11 => ['personal', true],
12 => ['special', true], 12 => ['special', true],
13 => ['special2', true], 13 => ['special2', true],
@@ -105,7 +105,9 @@ if ($gameStor->isunited) {
15 => ['npc', true], 15 => ['npc', true],
][$type]; ][$type];
$generalList = $db->query('SELECT owner,no,picture,imgsvr,npc,age,nation,special,special2,personal,name,injury,leadership,strength,intel,experience,dedication,officer_level,killturn,connect,gold,rice,crew,belong from general where nation = %i order by %b %l', $me['nation'], $orderKey, $orderDesc ? 'desc' : ''); $generalList = $db->query(
'SELECT owner,no,picture,imgsvr,npc,age,nation,special,special2,personal,name,injury,leadership,strength,intel,experience,dedication,officer_level,killturn,refresh_score_total,gold,rice,crew,belong
FROM `general` LEFT JOIN `general_access_log` ON general.no = general_access_log.general_id where nation = %i order by %b %l', $me['nation'], $orderKey, $orderDesc ? 'desc' : '');
echo " echo "
<table align=center class='tb_layout bg0'> <table align=center class='tb_layout bg0'>
@@ -173,8 +175,8 @@ if ($gameStor->isunited) {
<td align=center>" . displayCharInfo($general['personal']) . "</td> <td align=center>" . displayCharInfo($general['personal']) . "</td>
<td align=center>" . displaySpecialDomesticInfo($general['special']) . " / " . displaySpecialWarInfo($general['special2']) . "</td> <td align=center>" . displaySpecialDomesticInfo($general['special']) . " / " . displaySpecialWarInfo($general['special2']) . "</td>
<td align=center>{$general['belong']}</td> <td align=center>{$general['belong']}</td>
<td align=center>{$general['connect']}"; <td align=center>". $general['refresh_score_total'] ?? 0;
echo "<br>(" . getConnect($general['connect']) . ")</td> echo "<br>(" . getRefreshScoreText($general['refresh_score_total'] ?? 0) . ")</td>
</tr>"; </tr>";
} }
echo " echo "
+19 -8
View File
@@ -2,6 +2,10 @@
namespace sammo; namespace sammo;
use sammo\Enums\GeneralAccessLogColumn;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\TableName;
include "lib.php"; include "lib.php";
include "func.php"; include "func.php";
@@ -20,7 +24,7 @@ $gameStor->cacheValues(['turntime', 'opentime', 'autorun_user', 'npcmode']);
increaseRefresh("내정보", 1); increaseRefresh("내정보", 1);
$me = General::createGeneralObjFromDB($generalID); $me = General::createGeneralObjFromDB($generalID, null, GeneralQueryMode::FullWithAccessLog);
$myset = $me->getVar('myset'); $myset = $me->getVar('myset');
if ($myset > 0) { if ($myset > 0) {
@@ -29,7 +33,14 @@ if ($myset > 0) {
$submit = 'hidden'; $submit = 'hidden';
} }
$targetTime = addTurn($me->getVar('lastrefresh'), $gameStor->turnterm, GameConst::$minTurnDieOnPrestart); $lastRefresh = $db->queryFirstField(
'SELECT %b FROM %b WHERE %b = %i',
GeneralAccessLogColumn::lastRefresh->value,
TableName::generalAccessLog->value,
GeneralAccessLogColumn::generalID->value, $generalID
);
$targetTime = addTurn($lastRefresh, $gameStor->turnterm, GameConst::$minTurnDieOnPrestart);
if ($gameStor->turntime <= $gameStor->opentime) { if ($gameStor->turntime <= $gameStor->opentime) {
//서버 가오픈시 할 수 있는 행동 //서버 가오픈시 할 수 있는 행동
if ($me->getNPCType() == 0 && $me->getNationID() == 0) { if ($me->getNPCType() == 0 && $me->getNationID() == 0) {
@@ -81,13 +92,13 @@ $use_auto_nation_turn = $me->getAuxVar('use_auto_nation_turn') ?? 1;
<div class="col">내 정 보<br><?= backButton() ?></div> <div class="col">내 정 보<br><?= backButton() ?></div>
</div> </div>
<div class="row gx-0"> <div class="row gx-0">
<div class="col col-12 col-md-6"> <div class="col col-12 col-lg-6">
<div class="row"> <div class="row">
<div class="col"><?php generalInfo($me); ?><?php generalInfo2($me); ?></div> <div class="col"><?php generalInfo($me); ?><?php generalInfo2($me); ?></div>
</div> </div>
</div> </div>
<div class="col col-12 col-md-6"> <div class="col col-12 col-lg-6">
<div class="row mx-0 gx-0"> <div class="row mx-0 gx-0">
<div class="col" style='padding-left:2ch;'> <div class="col" style='padding-left:2ch;'>
토너먼트 【 토너먼트 【
@@ -178,7 +189,7 @@ $use_auto_nation_turn = $me->getAuxVar('use_auto_nation_turn') ?? 1;
</div> </div>
</div> </div>
</div> </div>
<div class="col col-12 col-md-6"> <div class="col col-12 col-lg-6">
<div class="row gx-0"> <div class="row gx-0">
<div class="col bg1 text-center"> <div class="col bg1 text-center">
<h4 style='color:skyblue'>개인 기록</h4> <h4 style='color:skyblue'>개인 기록</h4>
@@ -191,7 +202,7 @@ $use_auto_nation_turn = $me->getAuxVar('use_auto_nation_turn') ?? 1;
<button type="button" class="load_old_log btn btn-secondary" data-log_type="generalAction">이전 로그 불러오기</button> <button type="button" class="load_old_log btn btn-secondary" data-log_type="generalAction">이전 로그 불러오기</button>
</div> </div>
</div> </div>
<div class="col col-12 col-md-6"> <div class="col col-12 col-lg-6">
<div class="row gx-0"> <div class="row gx-0">
<div class="col bg1 text-center"> <div class="col bg1 text-center">
<h4 style='color:orange'>전투 기록</h4> <h4 style='color:orange'>전투 기록</h4>
@@ -205,7 +216,7 @@ $use_auto_nation_turn = $me->getAuxVar('use_auto_nation_turn') ?? 1;
</div> </div>
</div> </div>
<div class="col col-12 col-md-6"> <div class="col col-12 col-lg-6">
<div class="row gx-0"> <div class="row gx-0">
<div class="col bg1 text-center"> <div class="col bg1 text-center">
<h4 style='color:skyblue'>장수 열전</h4> <h4 style='color:skyblue'>장수 열전</h4>
@@ -215,7 +226,7 @@ $use_auto_nation_turn = $me->getAuxVar('use_auto_nation_turn') ?? 1;
<?= formatHistoryToHTML(getGeneralHistoryLogAll($generalID)) ?> <?= formatHistoryToHTML(getGeneralHistoryLogAll($generalID)) ?>
</div> </div>
</div> </div>
<div class="col col-12 col-md-6"> <div class="col col-12 col-lg-6">
<div class="row gx-0"> <div class="row gx-0">
<div class="col bg1 text-center"> <div class="col bg1 text-center">
<h4 style='color:orange'>전투 결과</h4> <h4 style='color:orange'>전투 결과</h4>
+7 -5
View File
@@ -14,14 +14,16 @@ $gameStor = KVStorage::getStorage($db, 'game_env');
increaseRefresh("토너먼트", 1); increaseRefresh("토너먼트", 1);
TurnExecutionHelper::executeAllCommand(); TurnExecutionHelper::executeAllCommand();
$me = $db->queryFirstRow('select no,tournament,con,turntime from general where owner=%i', $userID); $me = $db->queryFirstRow(
$generalID = $session->generalID; 'SELECT no,tournament,refresh_score,turntime from `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id where owner=%i', $userID
);
$admin = $gameStor->getValues(['tournament', 'phase', 'turnterm', 'tnmt_msg', 'tnmt_type', 'develcost', 'tnmt_trig']); $admin = $gameStor->getValues(['tournament', 'phase', 'turnterm', 'tnmt_msg', 'tnmt_type', 'develcost', 'tnmt_trig']);
$turnTerm = $admin['turnterm']; $turnTerm = $admin['turnterm'];
$con = checkLimit($me['con']); $limitState = checkLimit($me['refresh_score']);
if ($con >= 2) { if ($limitState >= 2) {
printLimitMsg($me['turntime']); printLimitMsg($me['turntime']);
exit(); exit();
} }
@@ -100,7 +102,7 @@ $globalBetTotal = array_sum($globalBet);
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<?php if ($con == 1) { <?php if ($limitState == 1) {
MessageBox("접속제한이 얼마 남지 않았습니다! 제한량이 모자라다면 참여를 해보세요^^"); MessageBox("접속제한이 얼마 남지 않았습니다! 제한량이 모자라다면 참여를 해보세요^^");
} ?> } ?>
+75 -65
View File
@@ -5,6 +5,9 @@ namespace sammo;
use DateTime; use DateTime;
use Ds\Set; use Ds\Set;
use sammo\Enums\AuctionType; use sammo\Enums\AuctionType;
use sammo\Enums\GeneralAccessLogColumn;
use sammo\Enums\GeneralColumn;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\InheritanceKey; use sammo\Enums\InheritanceKey;
use sammo\Enums\RankColumn; use sammo\Enums\RankColumn;
@@ -103,10 +106,9 @@ function GetImageURL($imgsvr, $filepath = '')
} }
/** /**
* @param null|int $con 장수의 벌점 * @param null|int $refreshScore 장수의 벌점
* @param null|int $conlimit 최대 벌점
*/ */
function checkLimit($con = null) function checkLimit($refreshScore = null)
{ {
$session = Session::getInstance(); $session = Session::getInstance();
if ($session->userGrade >= 4) { if ($session->userGrade >= 4) {
@@ -116,15 +118,15 @@ function checkLimit($con = null)
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
if ($con === null) { if ($refreshScore === null) {
$con = $db->queryFirstField('SELECT con FROM general WHERE `owner`=%i', Session::getUserID()); $refreshScore = $db->queryFirstField('SELECT refresh_score FROM general_access_log WHERE `general_id`=%i', Session::getGeneralID());
} }
$conlimit = $gameStor->conlimit; $refreshLimit = $gameStor->refreshLimit;
if ($con > $conlimit) { if ($refreshScore > $refreshLimit) {
return 2; return 2;
//접속제한 90%이면 경고문구 //접속제한 90%이면 경고문구
} elseif ($con > $conlimit * 0.9) { } elseif ($refreshScore > $refreshLimit * 0.9) {
return 1; return 1;
} else { } else {
return 0; return 0;
@@ -642,7 +644,7 @@ function generalInfo(General $generalObj)
$age = "<font color=red>{$age} 세</font>"; $age = "<font color=red>{$age} 세</font>";
} }
$connectCnt = round($generalObj->getVar('connect'), -1); $refreshScoreTotal = round($generalObj->getAccessLogVar(GeneralAccessLogColumn::refreshScoreTotal) ?? 0, -1);
$specialDomestic = $generalObj->getVar('special') === GameConst::$defaultSpecialDomestic $specialDomestic = $generalObj->getVar('special') === GameConst::$defaultSpecialDomestic
? "{$generalObj->getVar('specage')}세" ? "{$generalObj->getVar('specage')}세"
: "<font color=limegreen>" . displayiActionObjInfo($generalObj->getSpecialDomestic()) . "</font>"; : "<font color=limegreen>" . displayiActionObjInfo($generalObj->getSpecialDomestic()) . "</font>";
@@ -751,7 +753,7 @@ function generalInfo(General $generalObj)
<td style='text-align:center;' class='bg1'><b>부대</b></td> <td style='text-align:center;' class='bg1'><b>부대</b></td>
<td style='text-align:center;' colspan=3>{$troopInfo}</td> <td style='text-align:center;' colspan=3>{$troopInfo}</td>
<td style='text-align:center;' class='bg1'><b>벌점</b></td> <td style='text-align:center;' class='bg1'><b>벌점</b></td>
<td style='text-align:center;' colspan=5>" . getConnect($connectCnt) . " {$connectCnt}({$generalObj->getVar('con')})</td> <td style='text-align:center;' colspan=5>" . getRefreshScoreText($refreshScoreTotal) . " {$refreshScoreTotal}({$generalObj->getAccessLogVar(GeneralAccessLogColumn::refreshScore)})</td>
</tr> </tr>
</table>"; </table>";
} }
@@ -998,52 +1000,69 @@ function increaseRefresh($type = "", $cnt = 1)
$generalID = $session->generalID; $generalID = $session->generalID;
$userGrade = $session->userGrade; $userGrade = $session->userGrade;
$date = TimeUtil::now(); $dateObj = new \DateTimeImmutable();
$date = TimeUtil::format($dateObj, false);
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
$isunited = $gameStor->isunited; $isunited = $gameStor->isunited;
$opentime = $gameStor->opentime; $opentime = $gameStor->opentime;
if($userGrade == 6){ if ($userGrade == 6) {
return; return;
} }
if($isunited == 2){ if ($isunited == 2) {
return; return;
} }
if(!$generalID){ if (!$generalID) {
return; return;
} }
if($opentime > $date){ if ($opentime > $date) {
return; return;
} }
$gameStor->refresh = $gameStor->refresh + $cnt; //TODO: +로 증가하는 값은 별도로 분리 $gameStor->refresh = $gameStor->refresh + $cnt; //TODO: +로 증가하는 값은 별도로 분리
$db->update('general', [ $db->insertUpdate('general_access_log', [
'lastrefresh' => $date, GeneralAccessLogColumn::generalID->value => $generalID,
'con' => $db->sqleval('con + %i', $cnt), GeneralAccessLogColumn::userID->value => $userID,
'connect' => $db->sqleval('connect + %i', $cnt), GeneralAccessLogColumn::lastRefresh->value => $date,
'refcnt' => $db->sqleval('refcnt + %i', $cnt), GeneralAccessLogColumn::refreshTotal->value => $cnt,
'refresh' => $db->sqleval('refresh + %i', $cnt) GeneralAccessLogColumn::refresh->value => $cnt,
], 'owner=%i', $userID); GeneralAccessLogColumn::refreshScore->value => $cnt,
GeneralAccessLogColumn::refreshScoreTotal->value => $cnt,
], [
GeneralAccessLogColumn::lastRefresh->value => $date,
GeneralAccessLogColumn::refreshTotal->value => $db->sqleval('%b + %i', GeneralAccessLogColumn::refreshTotal->value, $cnt),
GeneralAccessLogColumn::refresh->value => $db->sqleval('%b + %i', GeneralAccessLogColumn::refresh->value, $cnt),
GeneralAccessLogColumn::refreshScore->value => $db->sqleval('%b + %i', GeneralAccessLogColumn::refreshScore->value, $cnt),
GeneralAccessLogColumn::refreshScoreTotal->value => $db->sqleval('%b + %i', GeneralAccessLogColumn::refreshScoreTotal->value, $cnt),
]);
$date = date('Y_m_d H:i:s'); $serverPath = __DIR__;
$date2 = substr($date, 0, 10);
$online = getOnlineNum(); $serverID = UniqueConst::$serverID;
file_put_contents( $logPath = "{$serverPath}/logs/{$serverID}/api_log.db";
__DIR__ . "/logs/" . UniqueConst::$serverID . "/_{$date2}_refresh.txt",
sprintf( $logDB = FileDB::db($logPath, $serverPath . '/../f_install/sql/api_log.sql');
"%s, %s, %s, %s, %s, %d\n",
$date, $ip = $_SERVER['REMOTE_ADDR'] ?? 'local';
$session->userName, $date = date('Y-m-d H:i:s');
$session->generalName,
$session->ip, $logDB->insert('api_log', [
$type, 'user_id' => $session->userID,
$online 'ip' => $ip,
), 'date' => $date,
FILE_APPEND 'path' => "refresh",
); 'arg' => JSON::encode([
'type' => $type,
]),
'aux' => JSON::encode([
'generalID' => $generalID,
'generalName' => $session->generalName,
'userName' => $session->userName,
]),
]);
} }
function updateTraffic() function updateTraffic()
@@ -1054,9 +1073,6 @@ function updateTraffic()
$admin = $gameStor->getValues(['year', 'month', 'refresh', 'maxonline', 'maxrefresh']); $admin = $gameStor->getValues(['year', 'month', 'refresh', 'maxonline', 'maxrefresh']);
/** @var array{year:int,month:int,refresh:int,maxonline:int,maxrefresh:int} $admin */ /** @var array{year:int,month:int,refresh:int,maxonline:int,maxrefresh:int} $admin */
//최다갱신자
$user = $db->queryFirstRow('select name,refresh from general order by refresh desc limit 1');
if ($admin['maxrefresh'] < $admin['refresh']) { if ($admin['maxrefresh'] < $admin['refresh']) {
$admin['maxrefresh'] = $admin['refresh']; $admin['maxrefresh'] = $admin['refresh'];
} }
@@ -1067,22 +1083,7 @@ function updateTraffic()
$gameStor->maxrefresh = $admin['maxrefresh']; $gameStor->maxrefresh = $admin['maxrefresh'];
$gameStor->maxonline = $admin['maxonline']; $gameStor->maxonline = $admin['maxonline'];
$db->update('general', ['refresh' => 0], true); $db->update('general_access_log', ['refresh' => 0], true);
$date = TimeUtil::now();
//일시|년|월|총갱신|접속자|최다갱신자
file_put_contents(
__DIR__ . "/logs/" . UniqueConst::$serverID . "/_traffic.txt",
Json::encode([
$date,
$admin['year'],
$admin['month'],
$admin['refresh'],
$online,
$user['name'] . "(" . $user['refresh'] . ")"
]) . "\n",
FILE_APPEND
);
} }
function CheckOverhead() function CheckOverhead()
@@ -1090,13 +1091,13 @@ function CheckOverhead()
//서버정보 //서버정보
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
list($turnterm, $conlimit) = $gameStor->getValuesAsArray(['turnterm', 'conlimit']); [$turnterm, $refreshLimit] = $gameStor->getValuesAsArray(['turnterm', 'refreshLimit']);
$con = Util::round(pow($turnterm, 0.6) * 3) * 10; $nextRefreshLimit = Util::round(pow($turnterm, 0.6) * 3) * 10;
if ($con != $conlimit) { if ($nextRefreshLimit != $refreshLimit) {
$gameStor->conlimit = $con; $gameStor->refreshLimit = $nextRefreshLimit;
} }
} }
@@ -1200,7 +1201,16 @@ function updateOnline()
//동접수 //동접수
$startTurn = cutTurn($gameStor->turntime, $gameStor->turnterm, false); $startTurn = cutTurn($gameStor->turntime, $gameStor->turnterm, false);
$onlineUser = $db->query('SELECT no,name,nation FROM general WHERE lastrefresh >= %s AND npc < 2', $startTurn); $onlineUser = $db->query(
'SELECT %b, %b, %b FROM `general_access_log` as `log` INNER JOIN `general` ON `log`.%b = `general`.%b WHERE %b >= %s',
GeneralColumn::no->value,
GeneralColumn::name->value,
GeneralColumn::nation->value,
GeneralAccessLogColumn::generalID->value,
GeneralColumn::no->value,
GeneralAccessLogColumn::lastRefresh->value,
$startTurn
);
$onlineNum = count($onlineUser); $onlineNum = count($onlineUser);
$onlineNationUsers = Util::arrayGroupBy($onlineUser, 'nation'); $onlineNationUsers = Util::arrayGroupBy($onlineUser, 'nation');
@@ -1314,7 +1324,7 @@ function CheckHall($no)
["betrate", 'calc'], ["betrate", 'calc'],
]; ];
$generalObj = General::createGeneralObjFromDB($no, null, 2); $generalObj = General::createGeneralObjFromDB($no);
$ttw = $generalObj->getRankVar(RankColumn::ttw); $ttw = $generalObj->getRankVar(RankColumn::ttw);
$ttd = $generalObj->getRankVar(RankColumn::ttd); $ttd = $generalObj->getRankVar(RankColumn::ttd);
@@ -1711,7 +1721,7 @@ function deleteNation(General $lord, bool $applyDB): array
$lordID $lordID
), ),
['npc', 'owner', 'gold', 'rice', 'experience', 'explevel', 'dedication', 'dedlevel', 'belong', 'aux'], ['npc', 'owner', 'gold', 'rice', 'experience', 'explevel', 'dedication', 'dedlevel', 'belong', 'aux'],
1 GeneralQueryMode::Lite,
); );
$nationGeneralList[$lordID] = $lord; $nationGeneralList[$lordID] = $lord;
@@ -1728,7 +1738,7 @@ function deleteNation(General $lord, bool $applyDB): array
// 전 장수 재야로 // 전 장수 재야로
foreach ($nationGeneralList as $general) { foreach ($nationGeneralList as $general) {
if($general->getNPCType() < 2){ if ($general->getNPCType() < 2) {
$general->setAuxVar( $general->setAuxVar(
InheritanceKey::max_belong->value, InheritanceKey::max_belong->value,
max( max(
+12 -12
View File
@@ -133,19 +133,19 @@ function getNationType(?string $type) {
} }
function getConnect($con) { function getRefreshScoreText($score) {
if($con < 50) $conname = '안함'; if($score < 50) $scoreName = '안함';
elseif($con < 100) $conname = '무관심'; elseif($score < 100) $scoreName = '무관심';
elseif($con < 200) $conname = '가끔'; elseif($score < 200) $scoreName = '가끔';
elseif($con < 400) $conname = '보통'; elseif($score < 400) $scoreName = '보통';
elseif($con < 800) $conname = '자주'; elseif($score < 800) $scoreName = '자주';
elseif($con < 1600) $conname = '열심'; elseif($score < 1600) $scoreName = '열심';
elseif($con < 3200) $conname = '중독'; elseif($score < 3200) $scoreName = '중독';
elseif($con < 6400) $conname = '폐인'; elseif($score < 6400) $scoreName = '폐인';
elseif($con < 12800) $conname = '경고'; elseif($score < 12800) $scoreName = '경고';
else $conname = '헐...'; else $scoreName = '헐...';
return $conname; return $scoreName;
} }
function getNationType2(?string $type) { function getNationType2(?string $type) {
+5 -4
View File
@@ -202,8 +202,10 @@ function preUpdateMonthly()
$admin = $gameStor->getValues(['startyear', 'year', 'month']); $admin = $gameStor->getValues(['startyear', 'year', 'month']);
//접률감소, 건국제한-1 //접률감소, 건국제한-1
$db->update('general_access_log', [
'refresh_score_total' => $db->sqleval('floor(refresh_score_total*0.99)'),
], true);
$db->update('general', [ $db->update('general', [
'connect' => $db->sqleval('floor(connect*0.99)'),
'makelimit' => $db->sqleval('greatest(0, makelimit - 1)'), 'makelimit' => $db->sqleval('greatest(0, makelimit - 1)'),
], true); ], true);
//전략제한-1, 외교제한-1, 세율동기화 //전략제한-1, 외교제한-1, 세율동기화
@@ -301,7 +303,6 @@ function postUpdateMonthly(RandUtil $rng)
WHERE g.nation = A.nation) WHERE g.nation = A.nation)
+(select round(sum(dex1+dex2+dex3+dex4+dex5)/1000) from general where nation=A.nation) +(select round(sum(dex1+dex2+dex3+dex4+dex5)/1000) from general where nation=A.nation)
+(select round(sum(experience+dedication)/100) from general where nation=A.nation) +(select round(sum(experience+dedication)/100) from general where nation=A.nation)
+(select round(avg(connect)) from general where nation=A.nation)
)/10) )/10)
as power, as power,
(select sum(crew) from general where nation=A.nation) as totalCrew (select sum(crew) from general where nation=A.nation) as totalCrew
@@ -697,7 +698,7 @@ function checkEmperior()
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
$admin = $gameStor->getValues(['year', 'month', 'isunited', 'conlimit']); $admin = $gameStor->getValues(['year', 'month', 'isunited', 'refreshLimit']);
if ($admin['isunited'] != 0) { if ($admin['isunited'] != 0) {
return; return;
} }
@@ -759,7 +760,7 @@ function checkEmperior()
} }
$gameStor->isunited = 2; $gameStor->isunited = 2;
$gameStor->conlimit = $gameStor->conlimit * 100; $gameStor->refreshLimit = $gameStor->refreshLimit * 100;
foreach ($db->queryFirstColumn('SELECT no FROM general WHERE npc<2 AND age>=%i', GameConst::$minPushHallAge) as $hallGeneralNo) { foreach ($db->queryFirstColumn('SELECT no FROM general WHERE npc<2 AND age>=%i', GameConst::$minPushHallAge) as $hallGeneralNo) {
CheckHall($hallGeneralNo); CheckHall($hallGeneralNo);
+1 -1
View File
@@ -383,7 +383,7 @@ function disaster(RandUtil $rng) {
$generalList = array_map( $generalList = array_map(
function($rawGeneral) use ($city, $year, $month){ function($rawGeneral) use ($city, $year, $month){
return new General($rawGeneral, null, $city, null, $year, $month, false); return new General($rawGeneral, null, null, $city, null, $year, $month, false);
}, },
$generalListByCity[$city['city']]??[] $generalListByCity[$city['city']]??[]
); );
+2 -2
View File
@@ -39,8 +39,8 @@ if ($session->userGrade < 5 && !$allowReset) {
<body> <body>
<div class="container"> <div class="container">
<h1 class="row justify-content-md-center">삼국지 모의전투 HiDCHe 리셋</h1> <h1 class="row justify-content-lg-center">삼국지 모의전투 HiDCHe 리셋</h1>
<div class="row justify-content-md-center"> <div class="row justify-content-lg-center">
<div class="col col-lg-8"> <div class="col col-lg-8">
<div class="card" id="game_form_card"> <div class="card" id="game_form_card">
+2 -2
View File
@@ -32,8 +32,8 @@ if ($session->userGrade == 5) {
<body> <body>
<div class="container" style="min-width:720px;"> <div class="container" style="min-width:720px;">
<h1 class="row justify-content-md-center">삼국지 모의전투 HiDCHe 리셋</h1> <h1 class="row justify-content-lg-center">삼국지 모의전투 HiDCHe 리셋</h1>
<div class="row justify-content-md-center"> <div class="row justify-content-lg-center">
<div class="col col-lg-8"> <div class="col col-lg-8">
<div class="card" id="db_form_card"> <div class="card" id="db_form_card">
+7 -4
View File
@@ -17,10 +17,13 @@ $text = Util::getPost('text');
increaseRefresh("회의실", 1); increaseRefresh("회의실", 1);
$me = $db->queryFirstRow('SELECT no, nation, name, officer_level, permission, con, turntime, belong, penalty, `picture`,`imgsvr` FROM general WHERE owner=%i', $userID); $me = $db->queryFirstRow(
'SELECT no, nation, name, officer_level, permission, refresh_score, turntime, belong, penalty, `picture`,`imgsvr` FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$con = checkLimit($me['con']); $limitState = checkLimit($me['refresh_score']);
if ($con >= 2) { if ($limitState >= 2) {
Json::die([ Json::die([
'result'=>false, 'result'=>false,
'reason'=>'접속 제한입니다.' 'reason'=>'접속 제한입니다.'
@@ -50,7 +53,7 @@ if($permission < 0){
'result'=>false, 'result'=>false,
'reason'=>'국가에 소속되어있지 않습니다.' 'reason'=>'국가에 소속되어있지 않습니다.'
]); ]);
} }
else if ($isSecretBoard && $permission < 2) { else if ($isSecretBoard && $permission < 2) {
Json::die([ Json::die([
+7 -4
View File
@@ -16,10 +16,13 @@ $text = Util::getPost('text');
increaseRefresh("회의실", 1); increaseRefresh("회의실", 1);
$me = $db->queryFirstRow('SELECT no, nation, name, officer_level, permission, con, turntime, belong, penalty FROM general WHERE owner=%i', $userID); $me = $db->queryFirstRow(
'SELECT no, nation, name, officer_level, permission, refresh_score, turntime, belong, penalty FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$con = checkLimit($me['con']); $limitState = checkLimit($me['refresh_score']);
if ($con >= 2) { if ($limitState >= 2) {
Json::die([ Json::die([
'result'=>false, 'result'=>false,
'reason'=>'접속 제한입니다.' 'reason'=>'접속 제한입니다.'
@@ -58,7 +61,7 @@ if($permission < 0){
'result'=>false, 'result'=>false,
'reason'=>'국가에 소속되어있지 않습니다.' 'reason'=>'국가에 소속되어있지 않습니다.'
]); ]);
} }
else if ($isSecretBoard && $permission < 2) { else if ($isSecretBoard && $permission < 2) {
Json::die([ Json::die([
+7 -5
View File
@@ -16,11 +16,14 @@ $isSecretBoard = Util::getPost('isSecret', 'bool', false);
increaseRefresh("회의실", 1); increaseRefresh("회의실", 1);
$me = $db->queryFirstRow('SELECT no, nation, officer_level, permission, con, turntime, belong, penalty FROM general WHERE owner=%i', $userID); $me = $db->queryFirstRow(
'SELECT no, nation, officer_level, permission, refresh_score, turntime, belong, penalty FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$con = checkLimit($me['con']); $limitState = checkLimit($me['refresh_score']);
if ($con >= 2) { if ($limitState >= 2) {
Json::die([ Json::die([
'result'=>false, 'result'=>false,
'reason'=>'접속 제한입니다.' 'reason'=>'접속 제한입니다.'
@@ -33,7 +36,7 @@ if($permission < 0){
'result'=>false, 'result'=>false,
'reason'=>'국가에 소속되어있지 않습니다.' 'reason'=>'국가에 소속되어있지 않습니다.'
]); ]);
} }
else if ($isSecretBoard && $permission < 2) { else if ($isSecretBoard && $permission < 2) {
Json::die([ Json::die([
@@ -72,4 +75,3 @@ Json::die([
'articles'=>$articles, 'articles'=>$articles,
'reason'=>'success' 'reason'=>'success'
]); ]);
+6 -3
View File
@@ -17,10 +17,13 @@ $letterNo = Util::getPost('letterNo', 'int');
increaseRefresh("외교부", 1); increaseRefresh("외교부", 1);
$me = $db->queryFirstRow('SELECT no, name, nation, officer_level, permission, con, turntime, belong, penalty, picture, imgsvr FROM general WHERE owner=%i', $userID); $me = $db->queryFirstRow(
'SELECT no, name, nation, officer_level, permission, refresh_score, turntime, belong, penalty, picture, imgsvr FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$con = checkLimit($me['con']); $limitState = checkLimit($me['refresh_score']);
if ($con >= 2) { if ($limitState >= 2) {
Json::die([ Json::die([
'result'=>false, 'result'=>false,
'reason'=>'접속 제한입니다.' 'reason'=>'접속 제한입니다.'
+7 -5
View File
@@ -16,11 +16,14 @@ $isSecretBoard = Util::getPost('isSecret', 'bool', false);
increaseRefresh("외교부", 1); increaseRefresh("외교부", 1);
$me = $db->queryFirstRow('SELECT no, nation, officer_level, permission, con, turntime, belong, penalty FROM general WHERE owner=%i', $userID); $me = $db->queryFirstRow(
'SELECT no, nation, officer_level, permission, refresh_score, turntime, belong, penalty FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$con = checkLimit($me['con']); $limitState = checkLimit($me['refresh_score']);
if ($con >= 2) { if ($limitState >= 2) {
Json::die([ Json::die([
'result'=>false, 'result'=>false,
'reason'=>'접속 제한입니다.' 'reason'=>'접속 제한입니다.'
@@ -33,7 +36,7 @@ if($permission < 0){
'result'=>false, 'result'=>false,
'reason'=>'국가에 소속되어있지 않습니다.' 'reason'=>'국가에 소속되어있지 않습니다.'
]); ]);
} }
$letters = []; $letters = [];
@@ -83,4 +86,3 @@ Json::die([
'myNationID'=>$me['nation'], 'myNationID'=>$me['nation'],
'reason'=>'success' 'reason'=>'success'
]); ]);
+6 -3
View File
@@ -22,10 +22,13 @@ $reason = Util::getPost('reason', 'string', '');
increaseRefresh("외교부", 1); increaseRefresh("외교부", 1);
$me = $db->queryFirstRow('SELECT no, name, nation, officer_level, permission, con, turntime, belong, penalty, picture, imgsvr FROM general WHERE owner=%i', $userID); $me = $db->queryFirstRow(
'SELECT no, name, nation, officer_level, permission, refresh_score, turntime, belong, penalty, picture, imgsvr FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$con = checkLimit($me['con']); $limitState = checkLimit($me['refresh_score']);
if ($con >= 2) { if ($limitState >= 2) {
Json::die([ Json::die([
'result'=>false, 'result'=>false,
'reason'=>'접속 제한입니다.' 'reason'=>'접속 제한입니다.'
+6 -3
View File
@@ -17,10 +17,13 @@ $letterNo = Util::getPost('letterNo', 'int');
increaseRefresh("외교부", 1); increaseRefresh("외교부", 1);
$me = $db->queryFirstRow('SELECT no, name, nation, officer_level, permission, con, turntime, belong, penalty, picture, imgsvr FROM general WHERE owner=%i', $userID); $me = $db->queryFirstRow(
'SELECT no, name, nation, officer_level, permission, refresh_score, turntime, belong, penalty, picture, imgsvr FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$con = checkLimit($me['con']); $limitState = checkLimit($me['refresh_score']);
if ($con >= 2) { if ($limitState >= 2) {
Json::die([ Json::die([
'result'=>false, 'result'=>false,
'reason'=>'접속 제한입니다.' 'reason'=>'접속 제한입니다.'
+6 -3
View File
@@ -24,10 +24,13 @@ if($prevNo < 1){
$prevNo = null; $prevNo = null;
} }
$me = $db->queryFirstRow('SELECT no, name, nation, officer_level, permission, con, turntime, belong, penalty, picture, imgsvr FROM general WHERE owner=%i', $userID); $me = $db->queryFirstRow(
'SELECT no, name, nation, officer_level, permission, refresh_score, turntime, belong, penalty, picture, imgsvr FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$con = checkLimit($me['con']); $limitState = checkLimit($me['refresh_score']);
if ($con >= 2) { if ($limitState >= 2) {
Json::die([ Json::die([
'result'=>false, 'result'=>false,
'reason'=>'접속 제한입니다.' 'reason'=>'접속 제한입니다.'
+7 -4
View File
@@ -33,12 +33,15 @@ if($generalID <= 0 || $reqTo <= 0){
$db = DB::db(); $db = DB::db();
$me = $db->queryFirstRow('SELECT no,nation,officer_level,con,turntime,belong,permission,penalty from general where owner=%i', $userID); $me = $db->queryFirstRow(
'SELECT no,nation,officer_level,refresh_score,turntime,belong,permission,penalty FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$nationID = $me['nation']; $nationID = $me['nation'];
$con = checkLimit($me['con']); $limitState = checkLimit($me['refresh_score']);
if ($con >= 2) { if ($limitState >= 2) {
Json::die([ Json::die([
'result'=>false, 'result'=>false,
'reason'=>'접속 제한입니다.' 'reason'=>'접속 제한입니다.'
@@ -61,7 +64,7 @@ if($generalID !== $targetID){
'reason'=>'권한이 부족합니다. 수뇌부가 아니거나 사관년도가 부족합니다.' 'reason'=>'권한이 부족합니다. 수뇌부가 아니거나 사관년도가 부족합니다.'
]); ]);
} }
if($testGeneralNationID !== $nationID){ if($testGeneralNationID !== $nationID){
Json::die([ Json::die([
'result'=>false, 'result'=>false,
+2 -1
View File
@@ -1,6 +1,7 @@
<?php <?php
namespace sammo; namespace sammo;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\MessageType; use sammo\Enums\MessageType;
include "lib.php"; include "lib.php";
@@ -50,7 +51,7 @@ else{
'troop','officer_level','npc','picture','imgsvr', 'troop','officer_level','npc','picture','imgsvr',
'permission','penalty','belong', 'crewtype', 'permission','penalty','belong', 'crewtype',
'experience', 'dedication', 'betray', 'dedlevel', 'explevel', 'makelimit', 'aux', 'experience', 'dedication', 'betray', 'dedlevel', 'explevel', 'makelimit', 'aux',
], 1); ], GeneralQueryMode::Lite);
if($general instanceof DummyGeneral){ if($general instanceof DummyGeneral){
Json::die([ Json::die([
+7
View File
@@ -1,6 +1,8 @@
<?php <?php
namespace sammo; namespace sammo;
use sammo\Enums\GeneralAccessLogColumn;
include "lib.php"; include "lib.php";
include "func.php"; include "func.php";
@@ -86,6 +88,11 @@ $db->update('general', [
'owner'=>$userID, 'owner'=>$userID,
'aux'=>Json::encode($genAux) 'aux'=>Json::encode($genAux)
], 'owner <= 0 AND npc = 2 AND no = %i', $pick); ], 'owner <= 0 AND npc = 2 AND no = %i', $pick);
$db->insertIgnore('general_access_log', [
GeneralAccessLogColumn::generalID->value => $generalID,
GeneralAccessLogColumn::userID->value => $userID,
GeneralAccessLogColumn::lastRefresh->value => $now,
]);
if(!$db->affectedRows()){ if(!$db->affectedRows()){
Json::die([ Json::die([
+4 -1
View File
@@ -39,7 +39,10 @@ if (!$data || !is_array($data)) {
$db = DB::db(); $db = DB::db();
$me = $db->queryFirstRow('SELECT no, name, npc, nation, city, officer_level, con, turntime, belong, permission, penalty FROM general WHERE owner=%i', $userID); $me = $db->queryFirstRow(
'SELECT no, name, npc, nation, city, officer_level, refresh_score, turntime, belong, permission, penalty FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$nationID = $me['nation']; $nationID = $me['nation'];
+4 -4
View File
@@ -270,7 +270,7 @@ if (key_exists('inheritBuff', $rawAttacker)) {
} }
$rawAttacker['aux'] = Json::encode($rawAttacker['aux']); $rawAttacker['aux'] = Json::encode($rawAttacker['aux']);
$rawAttacker['owner'] = 0; $rawAttacker['owner'] = 0;
$attackerGeneral = new General($rawAttacker, extractRankVar($rawAttacker), $rawAttackerCity, $rawAttackerNation, $year, $month); $attackerGeneral = new General($rawAttacker, extractRankVar($rawAttacker), null, $rawAttackerCity, $rawAttackerNation, $year, $month);
$attacker = new WarUnitGeneral( $attacker = new WarUnitGeneral(
$tmpRNG, $tmpRNG,
$attackerGeneral, $attackerGeneral,
@@ -308,7 +308,7 @@ foreach ($rawDefenderList as $idx => $rawDefenderGeneral) {
$rawDefenderGeneral['aux'] = Json::encode($rawDefenderGeneral['aux']); $rawDefenderGeneral['aux'] = Json::encode($rawDefenderGeneral['aux']);
$rawDefenderGeneral['owner'] = 0; $rawDefenderGeneral['owner'] = 0;
$defenderGeneral = new General($rawDefenderGeneral, extractRankVar($rawDefenderGeneral), $rawDefenderCity, $rawAttackerNation, $year, $month, true); $defenderGeneral = new General($rawDefenderGeneral, extractRankVar($rawDefenderGeneral), null, $rawDefenderCity, $rawAttackerNation, $year, $month, true);
$defenderList[] = new WarUnitGeneral( $defenderList[] = new WarUnitGeneral(
$tmpRNG, $tmpRNG,
@@ -382,7 +382,7 @@ function simulateBattle(
$warRng = new RandUtil(new LiteHashDRBG($warSeed)); $warRng = new RandUtil(new LiteHashDRBG($warSeed));
$attackerGeneral = new General($rawAttacker, extractRankVar($rawAttacker), $rawAttackerCity, $rawAttackerNation, $year, $month); $attackerGeneral = new General($rawAttacker, extractRankVar($rawAttacker), null, $rawAttackerCity, $rawAttackerNation, $year, $month);
$attacker = new WarUnitGeneral( $attacker = new WarUnitGeneral(
$warRng, $warRng,
$attackerGeneral, $attackerGeneral,
@@ -395,7 +395,7 @@ function simulateBattle(
$defenderList = []; $defenderList = [];
foreach ($rawDefenderList as $rawDefenderGeneral) { foreach ($rawDefenderList as $rawDefenderGeneral) {
$defenderGeneral = new General($rawDefenderGeneral, extractRankVar($rawDefenderGeneral), $rawDefenderCity, $rawAttackerNation, $year, $month, true); $defenderGeneral = new General($rawDefenderGeneral, extractRankVar($rawDefenderGeneral), null, $rawDefenderCity, $rawAttackerNation, $year, $month, true);
$defenderList[] = new WarUnitGeneral( $defenderList[] = new WarUnitGeneral(
$warRng, $warRng,
+30 -28
View File
@@ -3,6 +3,7 @@
namespace sammo; namespace sammo;
use sammo\DTO\VoteInfo; use sammo\DTO\VoteInfo;
use sammo\Enums\GeneralQueryMode;
include "lib.php"; include "lib.php";
include "func.php"; include "func.php";
@@ -29,7 +30,8 @@ if (!$session->isGameLoggedIn()) {
} }
$me = $db->queryFirstRow( $me = $db->queryFirstRow(
'SELECT no,con,turntime,newmsg,newvote,`officer_level` from general where owner = %i', '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 $userID
); );
@@ -51,13 +53,13 @@ if ($me['newmsg'] == 1 || $me['newvote'] == 1) {
$plock = boolval($db->queryFirstField('SELECT plock FROM plock WHERE `type`="GAME" LIMIT 1')); $plock = boolval($db->queryFirstField('SELECT plock FROM plock WHERE `type`="GAME" LIMIT 1'));
$con = checkLimit($me['con']); $limitState = checkLimit($me['refresh_score']);
if ($con >= 2) { if ($limitState >= 2) {
printLimitMsg($me['turntime']); printLimitMsg($me['turntime']);
exit(); exit();
} }
$generalObj = General::createGeneralObjFromDB($me['no']); $generalObj = General::createGeneralObjFromDB($me['no'], null, GeneralQueryMode::FullWithAccessLog);
$generalObj->setRawCity($db->queryFirstRow('SELECT * FROM city WHERE city = %i', $generalObj->getCityID())); $generalObj->setRawCity($db->queryFirstRow('SELECT * FROM city WHERE city = %i', $generalObj->getCityID()));
$scenario = $gameStor->scenario_text; $scenario = $gameStor->scenario_text;
@@ -180,44 +182,44 @@ if ($lastVoteID) {
</div> </div>
<div class="row center gx-0"> <div class="row center gx-0">
<div class="s-border-t col py-2 col-8 col-md-4" style="color:<?= $color ?>;"> <div class="s-border-t col py-2 col-8 col-lg-4" style="color:<?= $color ?>;">
<?= $scenario ?> <?= $scenario ?>
</div> </div>
<div class="s-border-t col py-2 col-4 col-md-2" style="color:<?= $color ?>;"> <div class="s-border-t col py-2 col-4 col-lg-2" style="color:<?= $color ?>;">
NPC 수, 상성 : <?= $extend ?>,<?= $fiction ?> NPC 수, 상성 : <?= $extend ?>,<?= $fiction ?>
</div> </div>
<div class="s-border-t col py-2 col-4 col-md-2" style="color:<?= $color ?>;"> <div class="s-border-t col py-2 col-4 col-lg-2" style="color:<?= $color ?>;">
NPC선택 : <?= $npcmode ?> NPC선택 : <?= $npcmode ?>
</div> </div>
<div class="s-border-t col py-2 col-4 col-md-2" style="color:<?= $color ?>;"> <div class="s-border-t col py-2 col-4 col-lg-2" style="color:<?= $color ?>;">
토너먼트 : <?= getTournamentTermText($gameStor->turnterm) ?> 토너먼트 : <?= getTournamentTermText($gameStor->turnterm) ?>
</div> </div>
<div class="s-border-t col py-2 col-4 col-md-2" style="color:<?= $color ?>;"> <div class="s-border-t col py-2 col-4 col-lg-2" style="color:<?= $color ?>;">
기타 설정: <?= $otherTextInfo ?> 기타 설정: <?= $otherTextInfo ?>
</div> </div>
<div class="s-border-t col py-2 col-8 col-md-4"><?= info(2) ?></div> <div class="s-border-t col py-2 col-8 col-lg-4"><?= info(2) ?></div>
<div class="s-border-t col py-2 col-4 col-md-2">전체 접속자 수 : <?= $gameStor->online_user_cnt ?> 명</div> <div class="s-border-t col py-2 col-4 col-lg-2">전체 접속자 수 : <?= $gameStor->online_user_cnt ?> 명</div>
<div class="s-border-t col py-2 col-4 col-md-2">턴당 갱신횟수 : <?= $gameStor->conlimit ?>회</div> <div class="s-border-t col py-2 col-4 col-lg-2">턴당 갱신횟수 : <?= $gameStor->refreshLimit ?>회</div>
<div class="s-border-t col py-2 col-8 col-md-4"><?= info(3) ?></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-md-4"> <div class="s-border-t py-2 col col-6 col-lg-4">
<?php if ($isTournamentActive) : ?> <?php if ($isTournamentActive) : ?>
↑<span style='color:cyan'><?= (['전력전', '통솔전', '일기토', '설전',])[$gameStor->tnmt_type] ?? '' ?> <?= getTournament($gameStor->tournament) ?> <?= getTournamentTime() ?></span>↑ ↑<span style='color:cyan'><?= (['전력전', '통솔전', '일기토', '설전',])[$gameStor->tnmt_type] ?? '' ?> <?= getTournament($gameStor->tournament) ?> <?= getTournamentTime() ?></span>↑
<?php else : ?> <?php else : ?>
<span style='color:magenta'>현재 토너먼트 경기 없음</span> <span style='color:magenta'>현재 토너먼트 경기 없음</span>
<?php endif; ?> <?php endif; ?>
</div> </div>
<div class="s-border-t py-2 col col-6 col-md-2"> <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 style="display:inline-block;"><?= $plock ? ("<span style='color:magenta;'>동작 시각: " . substr($gameStor->turntime, 5, 14) . "</span>") : ("<span style='color:cyan;'>동작 시각: " . substr($gameStor->turntime, 5, 14) . "</span>") ?></div>
</div> </div>
<div class="s-border-t py-2 col col-6 col-md-2"> <div class="s-border-t py-2 col col-6 col-lg-2">
<?php if ($auctionCount > 0) : ?> <?php if ($auctionCount > 0) : ?>
<span style='color:cyan'><?= $auctionCount ?>건</span> 거래 진행중 <span style='color:cyan'><?= $auctionCount ?>건</span> 거래 진행중
<?php else : ?> <?php else : ?>
<span style='color:magenta'>진행중 거래 없음</span> <span style='color:magenta'>진행중 거래 없음</span>
<?php endif; ?> <?php endif; ?>
</div> </div>
<div class="s-border-t py-2 col col-6 col-md-4 vote-cell"> <div class="s-border-t py-2 col col-6 col-lg-4 vote-cell">
<?php <?php
?> ?>
<?php if ($lastVote === null) : ?> <?php if ($lastVote === null) : ?>
@@ -310,11 +312,11 @@ if ($lastVoteID) {
</div> </div>
</div> </div>
<div class="row gx-0"> <div class="row gx-0">
<div class="col-md-6" id="general_public_record-position"> <div class="col-lg-6" id="general_public_record-position">
<div class="bg1 center s-border-tb"><b>장수 동향</b></div> <div class="bg1 center s-border-tb"><b>장수 동향</b></div>
<div id="general_public_record" style="text-align:left;"><?= formatHistoryToHTML(getGlobalActionLogRecent(15)) ?></div> <div id="general_public_record" style="text-align:left;"><?= formatHistoryToHTML(getGlobalActionLogRecent(15)) ?></div>
</div> </div>
<div class="col-md-6" id="general_log-position"> <div class="col-lg-6" id="general_log-position">
<div class="bg1 center s-border-tb"><b>개인 기록</b></div> <div class="bg1 center s-border-tb"><b>개인 기록</b></div>
<div id="general_log" style="text-align:left;"><?= formatHistoryToHTML(getGeneralActionLogRecent($me['no'], 15)) ?></div> <div id="general_log" style="text-align:left;"><?= formatHistoryToHTML(getGeneralActionLogRecent($me['no'], 15)) ?></div>
</div> </div>
@@ -328,34 +330,34 @@ if ($lastVoteID) {
<div id="message_board" class="row gx-0"> <div id="message_board" class="row gx-0">
<div class="message_input_form bg0 gx-0 row"> <div class="message_input_form bg0 gx-0 row">
<div id="mailbox_list-col" class="col-6 col-md-2 d-grid"> <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 id="mailbox_list" size="1" class="form-control bg-dark text-white">
</select> </select>
</div> </div>
<div id="msg_input-col" class="col-12 col-md-8 d-grid"> <div id="msg_input-col" class="col-12 col-lg-8 d-grid">
<input type="text" id="msg_input" maxlength="99" class="form-control"> <input type="text" id="msg_input" maxlength="99" class="form-control">
</div> </div>
<div id="msg_submit-col" class="col-6 col-md-2 d-grid"><button id="msg_submit" class="btn btn-primary">서신전달&amp;갱신</button></div> <div id="msg_submit-col" class="col-6 col-lg-2 d-grid"><button id="msg_submit" class="btn btn-primary">서신전달&amp;갱신</button></div>
</div> </div>
<div class="col-md-6 board_side bg0"><a id="public_talk_position"></a> <div class="col-lg-6 board_side bg0"><a id="public_talk_position"></a>
<div class="board_header bg0">전체 메시지(최고99자)</div> <div class="board_header bg0">전체 메시지(최고99자)</div>
<section class="public_message"> <section class="public_message">
<div class="d-grid"><button type="button" class="load_old_message btn btn-secondary" data-msg_type="public">이전 메시지 불러오기</button></div> <div class="d-grid"><button type="button" class="load_old_message btn btn-secondary" data-msg_type="public">이전 메시지 불러오기</button></div>
</section> </section>
</div> </div>
<div class="col-md-6 board_side bg0"><a id="national_talk_position"></a> <div class="col-lg-6 board_side bg0"><a id="national_talk_position"></a>
<div class="board_header bg0">국가 메시지(최고99자)</div> <div class="board_header bg0">국가 메시지(최고99자)</div>
<section class="national_message"> <section class="national_message">
<div class="d-grid"><button type="button" class="load_old_message btn btn-secondary" data-msg_type="national">이전 메시지 불러오기</button></div> <div class="d-grid"><button type="button" class="load_old_message btn btn-secondary" data-msg_type="national">이전 메시지 불러오기</button></div>
</section> </section>
</div> </div>
<div class="col-md-6 board_side bg0"><a id="private_talk_position"></a> <div class="col-lg-6 board_side bg0"><a id="private_talk_position"></a>
<div class="board_header bg0">개인 메시지(최고99자)</div> <div class="board_header bg0">개인 메시지(최고99자)</div>
<section class="private_message"> <section class="private_message">
<div class="d-grid"><button type="button" class="load_old_message btn btn-secondary" data-msg_type="private">이전 메시지 불러오기</button></div> <div class="d-grid"><button type="button" class="load_old_message btn btn-secondary" data-msg_type="private">이전 메시지 불러오기</button></div>
</section> </section>
</div> </div>
<div class="col-md-6 board_side bg0"><a id="diplomacy_talk_position"></a> <div class="col-lg-6 board_side bg0"><a id="diplomacy_talk_position"></a>
<div class="board_header bg0">외교 메시지(최고99자)</div> <div class="board_header bg0">외교 메시지(최고99자)</div>
<section class="diplomacy_message"> <section class="diplomacy_message">
<div class="d-grid"><button type="button" class="load_old_message btn btn-secondary" data-msg_type="diplomacy">이전 메시지 불러오기</button></div> <div class="d-grid"><button type="button" class="load_old_message btn btn-secondary" data-msg_type="diplomacy">이전 메시지 불러오기</button></div>
@@ -367,7 +369,7 @@ if ($lastVoteID) {
</div> </div>
</div> </div>
<?php <?php
if ($con == 1) { if ($limitState == 1) {
MessageBox("접속제한이 얼마 남지 않았습니다!"); MessageBox("접속제한이 얼마 남지 않았습니다!");
} }
if ($me['newmsg'] == 1) { if ($me['newmsg'] == 1) {
@@ -379,7 +381,7 @@ if ($lastVoteID) {
} }
?> ?>
</div> </div>
<nav class="navbar navbar-expand fixed-bottom navbar-dark bg-dark d-sm-block d-md-none p-0" id="navbar500"> <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="container-fluid px-0">
<div class="collapse navbar-collapse"> <div class="collapse navbar-collapse">
<ul class="navbar-nav me-auto mx-auto"> <ul class="navbar-nav me-auto mx-auto">
+4 -3
View File
@@ -3,6 +3,7 @@
namespace sammo; namespace sammo;
use sammo\Enums\EventTarget; use sammo\Enums\EventTarget;
use sammo\Enums\GeneralQueryMode;
function processWar(string $warSeed, General $attackerGeneral, array $rawAttackerNation, array $rawDefenderCity) function processWar(string $warSeed, General $attackerGeneral, array $rawAttackerNation, array $rawDefenderCity)
{ {
@@ -37,7 +38,7 @@ function processWar(string $warSeed, General $attackerGeneral, array $rawAttacke
$city = new WarUnitCity($rng, $rawDefenderCity, $rawDefenderNation, $year, $month, $startYear); $city = new WarUnitCity($rng, $rawDefenderCity, $rawDefenderNation, $year, $month, $startYear);
$defenderIDList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND city=%i AND nation!=0 and crew > 0 and rice>(crew/100) and train>=defence_train and atmos>=defence_train', $city->getVar('nation'), $city->getVar('city')); $defenderIDList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND city=%i AND nation!=0 and crew > 0 and rice>(crew/100) and train>=defence_train and atmos>=defence_train', $city->getVar('nation'), $city->getVar('city'));
$defenderGeneralList = General::createGeneralObjListFromDB($defenderIDList, null, 2); $defenderGeneralList = General::createGeneralObjListFromDB($defenderIDList, null);
/** @var WarUnit[] */ /** @var WarUnit[] */
$defenderList = []; $defenderList = [];
@@ -595,10 +596,10 @@ function ConquerCity(array $admin, General $general, array $city)
$lord = new General($db->queryFirstRow( $lord = new General($db->queryFirstRow(
'SELECT %l FROM general WHERE nation = %i AND officer_level = %i LIMIT 1', 'SELECT %l FROM general WHERE nation = %i AND officer_level = %i LIMIT 1',
Util::formatListOfBackticks(General::mergeQueryColumn(['npc', 'gold', 'rice', 'experience', 'explevel', 'belong', 'dedication', 'dedlevel', 'aux'], 1)[0]), Util::formatListOfBackticks(General::mergeQueryColumn(['npc', 'gold', 'rice', 'experience', 'explevel', 'belong', 'dedication', 'dedlevel', 'aux'], GeneralQueryMode::Lite)[0]),
$defenderNationID, $defenderNationID,
12 12
), null, $city, $loseNation, $year, $month, false); ), null, null, $city, $loseNation, $year, $month, false);
$josaUl = JosaUtil::pick($defenderNationName, '을'); $josaUl = JosaUtil::pick($defenderNationName, '을');
$attackerLogger->pushNationalHistoryLog("<D><b>{$defenderNationName}</b></>{$josaUl} 정복"); $attackerLogger->pushNationalHistoryLog("<D><b>{$defenderNationName}</b></>{$josaUl} 정복");
@@ -10,6 +10,7 @@ use sammo\DTO\AuctionBidItem;
use sammo\DTO\AuctionInfo; use sammo\DTO\AuctionInfo;
use sammo\Enums\APIRecoveryType; use sammo\Enums\APIRecoveryType;
use sammo\Enums\AuctionType; use sammo\Enums\AuctionType;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\InheritanceKey; use sammo\Enums\InheritanceKey;
use sammo\InheritancePointManager; use sammo\InheritancePointManager;
use sammo\TimeUtil; use sammo\TimeUtil;
@@ -76,7 +77,7 @@ class GetUniqueItemAuctionDetail extends \sammo\BaseAPI
$inheritMgr = InheritancePointManager::getInstance(); $inheritMgr = InheritancePointManager::getInstance();
//preveious라서 column을 최대한 비울 수 있다. //preveious라서 column을 최대한 비울 수 있다.
$remainPoint = $inheritMgr->getInheritancePoint( $remainPoint = $inheritMgr->getInheritancePoint(
General::createGeneralObjFromDB($generalID, ['owner'], 0), General::createGeneralObjFromDB($generalID, ['owner'], GeneralQueryMode::Core),
InheritanceKey::previous InheritanceKey::previous
); );
+6 -3
View File
@@ -42,9 +42,12 @@ class GetBettingList extends \sammo\BaseAPI
$bettingStor = KVStorage::getStorage($db, 'betting'); $bettingStor = KVStorage::getStorage($db, 'betting');
$userID = $session->userID; $userID = $session->userID;
$me = $db->queryFirstRow('SELECT no,nation,officer_level,con,turntime,belong,penalty,permission FROM general WHERE owner=%i', $userID); $me = $db->queryFirstRow(
$con = checkLimit($me['con']); 'SELECT no,nation,officer_level,refresh_score,turntime,belong,penalty,permission FROM `general`
if ($con >= 2) { LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$limitState = checkLimit($me['refresh_score']);
if ($limitState >= 2) {
return "접속 제한중입니다."; return "접속 제한중입니다.";
} }
@@ -39,7 +39,7 @@ class BuildNationCandidate extends \sammo\BaseAPI
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
$gameStor->cacheValues(['opentime', 'turntime']); $gameStor->cacheValues(['opentime', 'turntime']);
$general = $db->queryFirstRow('SELECT no,name,nation,owner_name,npc,lastrefresh FROM general WHERE owner=%i', $userID); $general = $db->queryFirstRow('SELECT no,name,nation,owner_name,npc FROM general WHERE owner=%i', $userID);
if (!$general) { if (!$general) {
return '장수가 없습니다'; return '장수가 없습니다';
+9 -2
View File
@@ -5,6 +5,7 @@ namespace sammo\API\General;
use sammo\DB; use sammo\DB;
use sammo\DummyGeneral; use sammo\DummyGeneral;
use sammo\Enums\APIRecoveryType; use sammo\Enums\APIRecoveryType;
use sammo\Enums\GeneralAccessLogColumn;
use sammo\GameConst; use sammo\GameConst;
use sammo\Session; use sammo\Session;
use sammo\General; use sammo\General;
@@ -37,7 +38,13 @@ class DieOnPrestart extends \sammo\BaseAPI
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
$gameStor->cacheValues(['turnterm', 'opentime', 'turntime', 'year', 'month']); $gameStor->cacheValues(['turnterm', 'opentime', 'turntime', 'year', 'month']);
$general = $db->queryFirstRow('SELECT no,name,nation,owner_name,npc,lastrefresh FROM general WHERE owner=%i AND npc = 0', $userID); $general = $db->queryFirstRow('SELECT no,name,nation,owner_name,npc FROM general WHERE owner=%i AND npc = 0', $userID);
$lastRefresh = $db->queryFirstField(
'SELECT %b FROM general_access_log WHERE %b = %i',
GeneralAccessLogColumn::lastRefresh->value,
GeneralAccessLogColumn::generalID->value,
$general['no']
);
if (!$general) { if (!$general) {
return '장수가 없습니다'; return '장수가 없습니다';
@@ -55,7 +62,7 @@ class DieOnPrestart extends \sammo\BaseAPI
} }
//서버 가오픈시 할 수 있는 행동 //서버 가오픈시 할 수 있는 행동
$targetTime = addTurn($general['lastrefresh'], $gameStor->turnterm, GameConst::$minTurnDieOnPrestart); $targetTime = addTurn($lastRefresh, $gameStor->turnterm, GameConst::$minTurnDieOnPrestart);
if ($targetTime > TimeUtil::now()) { if ($targetTime > TimeUtil::now()) {
$targetTimeShort = substr($targetTime, 0, 19); $targetTimeShort = substr($targetTime, 0, 19);
return "아직 삭제할 수 없습니다. {$targetTimeShort} 부터 가능합니다."; return "아직 삭제할 수 없습니다. {$targetTimeShort} 부터 가능합니다.";
+9 -6
View File
@@ -9,7 +9,9 @@ use sammo\DB;
use sammo\DTO\VoteInfo; use sammo\DTO\VoteInfo;
use sammo\Enums\APIRecoveryType; use sammo\Enums\APIRecoveryType;
use sammo\Enums\CityColumn; use sammo\Enums\CityColumn;
use sammo\Enums\GeneralAccessLogColumn;
use sammo\Enums\GeneralColumn; use sammo\Enums\GeneralColumn;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\RankColumn; use sammo\Enums\RankColumn;
use sammo\GameConst; use sammo\GameConst;
use sammo\General; use sammo\General;
@@ -173,7 +175,7 @@ class GetFrontInfo extends \sammo\BaseAPI
'online_nation', 'online_user_cnt', 'online_nation', 'online_user_cnt',
'year', 'month', 'startyear', 'year', 'month', 'startyear',
'maxgeneral', 'maxgeneral',
'conlimit', 'refreshLimit',
'server_cnt', 'server_cnt',
]); ]);
@@ -383,7 +385,8 @@ class GetFrontInfo extends \sammo\BaseAPI
'specialWar' => $general->getVar(GeneralColumn::special2), // GameObjClassKey; 'specialWar' => $general->getVar(GeneralColumn::special2), // GameObjClassKey;
'personal' => $general->getVar(GeneralColumn::personal), // GameObjClassKey; 'personal' => $general->getVar(GeneralColumn::personal), // GameObjClassKey;
'belong' => $general->getVar(GeneralColumn::belong), // number; 'belong' => $general->getVar(GeneralColumn::belong), // number;
'connect' => $general->getVar(GeneralColumn::connect), // number;
'refreshScoreTotal' => $general->getAccessLogVar(GeneralAccessLogColumn::refreshScoreTotal, 0), // number;
'officerLevel' => $general->getVar(GeneralColumn::officer_level), // number; 'officerLevel' => $general->getVar(GeneralColumn::officer_level), // number;
'officerLevelText' => getOfficerLevelText($general->getVar(GeneralColumn::officer_level), $rawNation['level']), // string; 'officerLevelText' => getOfficerLevelText($general->getVar(GeneralColumn::officer_level), $rawNation['level']), // string;
@@ -400,7 +403,7 @@ class GetFrontInfo extends \sammo\BaseAPI
'troop' => $general->getVar(GeneralColumn::troop), // number; 'troop' => $general->getVar(GeneralColumn::troop), // number;
//P0 End //P0 End
'con' => $general->getVar(GeneralColumn::con), // number; 'refreshScore' => $general->getAccessLogVar(GeneralAccessLogColumn::refreshScore, 0), // number;
'specage' => $general->getVar(GeneralColumn::specage), // number; 'specage' => $general->getVar(GeneralColumn::specage), // number;
'specage2' => $general->getVar(GeneralColumn::specage2), // number; 'specage2' => $general->getVar(GeneralColumn::specage2), // number;
'leadership_exp' => $general->getVar(GeneralColumn::leadership_exp), // number; 'leadership_exp' => $general->getVar(GeneralColumn::leadership_exp), // number;
@@ -531,12 +534,12 @@ class GetFrontInfo extends \sammo\BaseAPI
{ {
$generalID = $session->generalID; $generalID = $session->generalID;
//NOTE: 이 경우 staticNation 정보를 조회한다. //NOTE: 이 경우 staticNation 정보를 조회한다.
$general = General::createGeneralObjFromDB($generalID); $general = General::createGeneralObjFromDB($generalID, null, GeneralQueryMode::FullWithAccessLog);
$nationID = $general->getNationID(); $nationID = $general->getNationID();
$cityID = $general->getCityID(); $cityID = $general->getCityID();
$con = checkLimit($general->getVar('con')); $limitState = checkLimit($general->getAccessLogVar(GeneralAccessLogColumn::refreshScore, 0));
if ($con >= 2) { if ($limitState >= 2) {
return [ return [
'result' => false, 'result' => false,
'reason' => '접속 제한중입니다.', 'reason' => '접속 제한중입니다.',
+6 -2
View File
@@ -8,6 +8,7 @@ use sammo\Auction;
use sammo\CityConst; use sammo\CityConst;
use sammo\DB; use sammo\DB;
use sammo\Enums\APIRecoveryType; use sammo\Enums\APIRecoveryType;
use sammo\Enums\GeneralAccessLogColumn;
use sammo\Enums\RankColumn; use sammo\Enums\RankColumn;
use sammo\GameConst; use sammo\GameConst;
use sammo\GameUnitConst; use sammo\GameUnitConst;
@@ -414,8 +415,6 @@ class Join extends \sammo\BaseAPI
'officer_level' => 0, 'officer_level' => 0,
'turntime' => $turntime, 'turntime' => $turntime,
'killturn' => 6, 'killturn' => 6,
'lastconnect' => $now,
'lastrefresh' => $now,
'crewtype' => GameUnitConst::DEFAULT_CREWTYPE, 'crewtype' => GameUnitConst::DEFAULT_CREWTYPE,
'makelimit' => 0, 'makelimit' => 0,
'betray' => $betray, 'betray' => $betray,
@@ -428,6 +427,11 @@ class Join extends \sammo\BaseAPI
'special2' => $special2 'special2' => $special2
]); ]);
$generalID = $db->insertId(); $generalID = $db->insertId();
$db->insert('general_access_log', [
GeneralAccessLogColumn::generalID->value => $generalID,
GeneralAccessLogColumn::userID->value => $userID,
GeneralAccessLogColumn::lastRefresh->value => $now,
]);
if($blockCustomGeneralName){ if($blockCustomGeneralName){
//XXX: 클래스가 이게 맞나? //XXX: 클래스가 이게 맞나?
+12 -6
View File
@@ -42,9 +42,12 @@ class GeneralList extends \sammo\BaseAPI
$userID = $session->userID; $userID = $session->userID;
if ($session->isGameLoggedIn()) { if ($session->isGameLoggedIn()) {
increaseRefresh("장수일람", 2); increaseRefresh("장수일람", 2);
$me = $db->queryFirstRow('SELECT con, turntime FROM general WHERE owner=%i', $userID); $me = $db->queryFirstRow(
$con = checkLimit($me['con']); 'SELECT refresh_score, turntime FROM `general`
if ($con >= 2) { LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$limitState = checkLimit($me['refresh_score']);
if ($limitState >= 2) {
return '접속 제한중입니다. 1턴 이내에 너무 많은 갱신을 하셨습니다.'; return '접속 제한중입니다. 1턴 이내에 너무 많은 갱신을 하셨습니다.';
} }
} else { } else {
@@ -62,7 +65,8 @@ class GeneralList extends \sammo\BaseAPI
$session->setReadOnly(); $session->setReadOnly();
$rawGeneralList = $db->queryAllLists('SELECT owner,no,picture,imgsvr,npc,age,nation,special,special2,personal,name,owner_name as ownerName,injury,leadership,strength,intel,experience,dedication,officer_level,killturn,connect from general'); $rawGeneralList = $db->queryAllLists(
'SELECT owner,no,picture,imgsvr,npc,age,nation,special,special2,personal,name,owner_name as ownerName,injury,leadership,strength,intel,experience,dedication,officer_level,killturn,refresh_score_total from `general` LEFT JOIN `general_access_log` ON general.no = general_access_log.general_id');
$ownerNameList = []; $ownerNameList = [];
if ($gameStor->isunited) { if ($gameStor->isunited) {
@@ -73,7 +77,7 @@ class GeneralList extends \sammo\BaseAPI
$generalList = []; $generalList = [];
foreach ($rawGeneralList as $rawGeneral) { foreach ($rawGeneralList as $rawGeneral) {
[$owner, $no, $picture, $imgsvr, $npc, $age, $nation, $special, $special2, $personal, $name, $ownerName, $injury, $leadership, $strength, $intel, $experience, $dedication, $officerLevel, $killturn, $connectCnt] = $rawGeneral; [$owner, $no, $picture, $imgsvr, $npc, $age, $nation, $special, $special2, $personal, $name, $ownerName, $injury, $leadership, $strength, $intel, $experience, $dedication, $officerLevel, $killturn, $refreshScoreTotal] = $rawGeneral;
if (key_exists($owner, $ownerNameList)) { if (key_exists($owner, $ownerNameList)) {
$ownerName = $ownerNameList[$owner]; $ownerName = $ownerNameList[$owner];
@@ -104,7 +108,7 @@ class GeneralList extends \sammo\BaseAPI
getDed($dedication), getDed($dedication),
getOfficerLevelText($officerLevel, $nationArr['level']), getOfficerLevelText($officerLevel, $nationArr['level']),
$killturn, $killturn,
$connectCnt $refreshScoreTotal ?: 0,
]; ];
} }
@@ -129,6 +133,8 @@ class GeneralList extends \sammo\BaseAPI
'honorText', 'honorText',
'dedLevelText', 'dedLevelText',
'officerLevelText', 'officerLevelText',
'killturn',
'refreshScoreTotal',
]; ];
$result = [ $result = [
+6 -3
View File
@@ -148,13 +148,16 @@ class GetHistory extends \sammo\BaseAPI
} }
increaseRefresh("연감", 1); increaseRefresh("연감", 1);
$me = $db->queryFirstRow('SELECT con, turntime FROM general WHERE owner = %i', $session->userID); $me = $db->queryFirstRow(
'SELECT refresh_score, turntime FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner = %i', $session->userID
);
if (!$me) { if (!$me) {
return '장수가 사망했습니다.'; return '장수가 사망했습니다.';
} }
$con = checkLimit($me['con']); $limitState = checkLimit($me['refresh_score']);
if ($con >= 2) { if ($limitState >= 2) {
return templateLimitMsg($me['turntime']); return templateLimitMsg($me['turntime']);
} }
} }
+1 -1
View File
@@ -75,7 +75,7 @@ class GetOldMessage extends \sammo\BaseAPI
$db = DB::db(); $db = DB::db();
$me = $db->queryFirstRow('SELECT `no`,`name`,`nation`,`officer_level`,`con`,`picture`,`imgsvr`,penalty,permission FROM general WHERE `owner`=%i', $userID); $me = $db->queryFirstRow('SELECT `no`,`name`,`nation`,`officer_level`,`picture`,`imgsvr`,penalty,permission FROM general WHERE `owner`=%i', $userID);
if ($me === null) { if ($me === null) {
return '장수가 사망했습니다.'; return '장수가 사망했습니다.';
+1 -1
View File
@@ -73,7 +73,7 @@ class GetRecentMessage extends \sammo\BaseAPI
$db = DB::db(); $db = DB::db();
$me = $db->queryFirstRow('SELECT `no`,`name`,`nation`,`officer_level`,`con`,`picture`,`imgsvr`,penalty,permission FROM general WHERE `owner`=%i', $userID); $me = $db->queryFirstRow('SELECT `no`,`name`,`nation`,`officer_level`,`picture`,`imgsvr`,penalty,permission FROM general WHERE `owner`=%i', $userID);
if ($me === null) { if ($me === null) {
return '장수가 사망했습니다.'; return '장수가 사망했습니다.';
+7 -4
View File
@@ -108,7 +108,7 @@ class SendMessage extends \sammo\BaseAPI
$unlimited = new \DateTime('9999-12-31'); $unlimited = new \DateTime('9999-12-31');
$db = DB::db(); $db = DB::db();
$destUser = $db->queryFirstRow('SELECT `no`,`name`,`nation`,`officer_level`,`con`,`picture`,`imgsvr`,permission,penalty FROM general WHERE `no`=%i', $destGeneralID); $destUser = $db->queryFirstRow('SELECT `no`,`name`,`nation`,`officer_level`,`picture`,`imgsvr`,permission,penalty FROM general WHERE `no`=%i', $destGeneralID);
if (!$destUser) { if (!$destUser) {
return '존재하지 않는 유저입니다.'; return '존재하지 않는 유저입니다.';
@@ -160,15 +160,18 @@ class SendMessage extends \sammo\BaseAPI
} }
$db = DB::db(); $db = DB::db();
$me = $db->queryFirstRow('SELECT `no`,`name`,`nation`,`officer_level`,`con`,`picture`,`imgsvr`,penalty,permission,belong FROM general WHERE `owner`=%i', $userID); $me = $db->queryFirstRow(
'SELECT `no`,`name`,`nation`,`officer_level`,`refresh_score`,`picture`,`imgsvr`,penalty,permission,belong FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE `owner`=%i', $userID
);
if (!$me) { if (!$me) {
$session->logoutGame(); $session->logoutGame();
return '장수가 없습니다.'; return '장수가 없습니다.';
} }
$con = checkLimit($me['con']); $limitState = checkLimit($me['refresh_score']);
if ($con >= 2) { if ($limitState >= 2) {
return '접속 제한입니다.'; return '접속 제한입니다.';
} }
+31 -13
View File
@@ -5,6 +5,7 @@ namespace sammo\API\Nation;
use ArrayObject; use ArrayObject;
use sammo\DB; use sammo\DB;
use sammo\Enums\APIRecoveryType; use sammo\Enums\APIRecoveryType;
use sammo\Enums\GeneralQueryMode;
use sammo\General; use sammo\General;
use sammo\Session; use sammo\Session;
use sammo\Util; use sammo\Util;
@@ -44,12 +45,10 @@ class GeneralList extends \sammo\BaseAPI
'special2' => 0, 'special2' => 0,
'personal' => 0, 'personal' => 0,
'belong' => 0, 'belong' => 0,
'connect' => 0,
'troop' => 0, 'troop' => 0,
'city' => 0, 'city' => 0,
'con' => 1,
'specage' => 0, 'specage' => 0,
'specage2' => 0, 'specage2' => 0,
'leadership_exp' => 1, 'leadership_exp' => 1,
@@ -83,6 +82,11 @@ class GeneralList extends \sammo\BaseAPI
'owner_name' => 9, //안씀. 'owner_name' => 9, //안씀.
//accessLog
'refresh_score_total' => 0,
'refresh_score' => 1,
//RANK //RANK
'warnum' => 1, 'warnum' => 1,
'killnum' => 1, 'killnum' => 1,
@@ -95,6 +99,8 @@ class GeneralList extends \sammo\BaseAPI
static $columnRemap = [ static $columnRemap = [
'special' => 'specialDomestic', 'special' => 'specialDomestic',
'special2' => 'specialWar', 'special2' => 'specialWar',
'refresh_score_total' => 'refreshScoreTotal',
'refresh_score' => 'refreshScore',
'aux' => null, 'aux' => null,
]; ];
@@ -143,9 +149,12 @@ class GeneralList extends \sammo\BaseAPI
$gameStor = \sammo\KVStorage::getStorage($db, 'game_env'); $gameStor = \sammo\KVStorage::getStorage($db, 'game_env');
$env = $gameStor->getValues(['year', 'month', 'turntime', 'turnterm', 'autorun_user', 'killturn']); $env = $gameStor->getValues(['year', 'month', 'turntime', 'turnterm', 'autorun_user', 'killturn']);
$me = $db->queryFirstRow('SELECT con, turntime, belong, nation, officer_level, permission, penalty FROM general WHERE owner=%i', $session->getUserID()); $me = $db->queryFirstRow(
$con = checkLimit($me['con']); 'SELECT refresh_score, turntime, belong, nation, officer_level, permission, penalty FROM `general`
if ($con >= 2) { LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $session->getUserID()
);
$limitState = checkLimit($me['refresh_score']);
if ($limitState >= 2) {
return '접속 제한중입니다. 1턴 이내에 너무 많은 갱신을 하셨습니다.'; return '접속 제한중입니다. 1턴 이내에 너무 많은 갱신을 하셨습니다.';
} }
@@ -156,9 +165,18 @@ class GeneralList extends \sammo\BaseAPI
[$queryColumns, $rankColumns] = General::mergeQueryColumn(array_keys(static::$viewColumns), 1); [$queryColumns, $rankColumns, $accessLogColumns] = General::mergeQueryColumn(array_keys(static::$viewColumns), GeneralQueryMode::Lite);
$rawGeneralList = Util::convertArrayToDict($db->query('SELECT %l from general WHERE nation = %i ORDER BY turntime ASC', Util::formatListOfBackticks($queryColumns), $nationID), 'no'); $rawGeneralList = Util::convertArrayToDict(
$db->query(
'SELECT %l, %l from `general` LEFT JOIN general_access_log
ON `general`.`no` = general_access_log.general_id WHERE nation = %i ORDER BY turntime ASC',
Util::formatListOfBackticks($queryColumns),
Util::formatListOfBackticks($accessLogColumns),
$nationID
),
'no'
);
/** @var ArrayObject[] */ /** @var ArrayObject[] */
$troops = []; $troops = [];
@@ -179,19 +197,19 @@ class GeneralList extends \sammo\BaseAPI
if ($this->permission >= 1 || count($troops)) { if ($this->permission >= 1 || count($troops)) {
$reservedCommandTargetGeneralIDList = []; $reservedCommandTargetGeneralIDList = [];
if($this->permission >= 1){ if ($this->permission >= 1) {
foreach ($rawGeneralList as $rawGeneral) { foreach ($rawGeneralList as $rawGeneral) {
if ($rawGeneral['npc'] < 2) { if ($rawGeneral['npc'] < 2) {
$reservedCommandTargetGeneralIDList[$rawGeneral['no']] = $rawGeneral['no']; $reservedCommandTargetGeneralIDList[$rawGeneral['no']] = $rawGeneral['no'];
} }
} }
} }
foreach($troops as $troop){ foreach ($troops as $troop) {
$reservedCommandTargetGeneralIDList[$troop['id']] = $troop['id']; $reservedCommandTargetGeneralIDList[$troop['id']] = $troop['id'];
} }
if($reservedCommandTargetGeneralIDList){ if ($reservedCommandTargetGeneralIDList) {
$rawTurnList = $db->query( $rawTurnList = $db->query(
'SELECT general_id, turn_idx, action, arg, brief FROM general_turn WHERE general_id IN %li AND turn_idx < 5 ORDER BY general_id asc, turn_idx asc', 'SELECT general_id, turn_idx, action, arg, brief FROM general_turn WHERE general_id IN %li AND turn_idx < 5 ORDER BY general_id asc, turn_idx asc',
array_values($reservedCommandTargetGeneralIDList) array_values($reservedCommandTargetGeneralIDList)
@@ -278,11 +296,11 @@ class GeneralList extends \sammo\BaseAPI
$resultColumns[$column] = $column; $resultColumns[$column] = $column;
} }
foreach ($troops as $troop){ foreach ($troops as $troop) {
$troopLeaderID = $troop['id']; $troopLeaderID = $troop['id'];
$troop['reservedCommand'] = array_map(function($turnObj){ $troop['reservedCommand'] = array_map(function ($turnObj) {
$brief = $turnObj['brief']; $brief = $turnObj['brief'];
if($brief == '집합'){ if ($brief == '집합') {
return $brief; return $brief;
} }
return '-'; return '-';
+5 -3
View File
@@ -109,10 +109,12 @@ class GetGeneralLog extends \sammo\BaseAPI
$reqTo = $this->args['reqTo'] ?? null; $reqTo = $this->args['reqTo'] ?? null;
$db = DB::db(); $db = DB::db();
$me = $db->queryFirstRow('SELECT no,nation,officer_level,con,turntime,belong,permission,penalty from general where owner=%i', $userID); $me = $db->queryFirstRow(
'SELECT no,nation,officer_level,refresh_score,turntime,belong,permission,penalty FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID);
$con = checkLimit($me['con']); $limitState = checkLimit($me['refresh_score']);
if ($con >= 2) { if ($limitState >= 2) {
return '접속 제한입니다.'; return '접속 제한입니다.';
} }
+2 -1
View File
@@ -4,6 +4,7 @@ namespace sammo\API\Nation;
use sammo\DB; use sammo\DB;
use sammo\Enums\APIRecoveryType; use sammo\Enums\APIRecoveryType;
use sammo\Enums\GeneralQueryMode;
use sammo\GameConst; use sammo\GameConst;
use sammo\General; use sammo\General;
use sammo\KVStorage; use sammo\KVStorage;
@@ -65,7 +66,7 @@ class GetNationInfo extends \sammo\BaseAPI
]; ];
} }
$generalObj = General::createGeneralObjFromDB($session->generalID, null, 1); $generalObj = General::createGeneralObjFromDB($session->generalID, null, GeneralQueryMode::FullWithoutIAction);
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
$gameEnv = $gameStor->getValues(['year', 'month', 'startyear']); $gameEnv = $gameStor->getValues(['year', 'month', 'startyear']);
@@ -6,6 +6,7 @@ use sammo\Session;
use DateTimeInterface; use DateTimeInterface;
use sammo\DB; use sammo\DB;
use sammo\Enums\APIRecoveryType; use sammo\Enums\APIRecoveryType;
use sammo\Enums\GeneralQueryMode;
use sammo\GameConst; use sammo\GameConst;
use sammo\General; use sammo\General;
use sammo\Json; use sammo\Json;
@@ -39,12 +40,15 @@ class GetReservedCommand extends \sammo\BaseAPI
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
$userID = $session->userID; $userID = $session->userID;
$me = $db->queryFirstRow('SELECT no,nation,officer_level,con,turntime,belong,penalty,permission FROM general WHERE owner=%i', $userID); $me = $db->queryFirstRow(
'SELECT no,nation,officer_level,refresh_score,turntime,belong,penalty,permission FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$nationLevel = $db->queryFirstField('SELECT level FROM nation WHERE nation = %i', $me['nation']); $nationLevel = $db->queryFirstField('SELECT level FROM nation WHERE nation = %i', $me['nation']);
$nationID = $me['nation']; $nationID = $me['nation'];
$con = checkLimit($me['con']); $limitState = checkLimit($me['refresh_score']);
if ($con >= 2) { if ($limitState >= 2) {
return "접속 제한중입니다. 1턴 이내에 너무 많은 갱신을 하셨습니다. (다음 갱신 가능 시각 : {$me['turntime']})"; return "접속 제한중입니다. 1턴 이내에 너무 많은 갱신을 하셨습니다. (다음 갱신 가능 시각 : {$me['turntime']})";
} }
@@ -59,7 +63,7 @@ class GetReservedCommand extends \sammo\BaseAPI
$generals = []; $generals = [];
foreach ($db->query('SELECT no,name,turntime,npc,city,nation,officer_level FROM general WHERE nation = %i AND officer_level >= 5', $nationID) as $rawGeneral) { foreach ($db->query('SELECT no,name,turntime,npc,city,nation,officer_level FROM general WHERE nation = %i AND officer_level >= 5', $nationID) as $rawGeneral) {
$generals[$rawGeneral['officer_level']] = new General($rawGeneral, null, null, null, $year, $month, false); $generals[$rawGeneral['officer_level']] = new General($rawGeneral, null, null, null, null, $year, $month, false);
} }
$nationTurnList = []; $nationTurnList = [];
@@ -109,7 +113,7 @@ class GetReservedCommand extends \sammo\BaseAPI
]; ];
} }
$generalObj = General::createGeneralObjFromDB($session->generalID); $generalObj = General::createGeneralObjFromDB($session->generalID, null, GeneralQueryMode::FullWithoutIAction);
return [ return [
+2 -1
View File
@@ -6,6 +6,7 @@ use DateTimeInterface;
use sammo\DB; use sammo\DB;
use sammo\DTO\VoteComment; use sammo\DTO\VoteComment;
use sammo\Enums\APIRecoveryType; use sammo\Enums\APIRecoveryType;
use sammo\Enums\GeneralQueryMode;
use sammo\General; use sammo\General;
use sammo\Session; use sammo\Session;
use sammo\TimeUtil; use sammo\TimeUtil;
@@ -40,7 +41,7 @@ class AddComment extends \sammo\BaseAPI
$text = mb_substr($this->args['text'], 0, 200); $text = mb_substr($this->args['text'], 0, 200);
$generalID = $session->generalID; $generalID = $session->generalID;
$general = General::createGeneralObjFromDB($generalID, [], 0); $general = General::createGeneralObjFromDB($generalID, null, GeneralQueryMode::Core);
$generalName = $general->getName(); $generalName = $general->getName();
$nationID = $general->getNationID(); $nationID = $general->getNationID();
$nationName = $general->getStaticNation()['name']; $nationName = $general->getStaticNation()['name'];
+2 -1
View File
@@ -6,6 +6,7 @@ use DateTimeInterface;
use sammo\DB; use sammo\DB;
use sammo\DTO\VoteInfo; use sammo\DTO\VoteInfo;
use sammo\Enums\APIRecoveryType; use sammo\Enums\APIRecoveryType;
use sammo\Enums\GeneralQueryMode;
use sammo\General; use sammo\General;
use sammo\Json; use sammo\Json;
use sammo\KVStorage; use sammo\KVStorage;
@@ -105,7 +106,7 @@ class Vote extends \sammo\BaseAPI
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
$voteReward = $gameStor->getValue('develcost') * 5; $voteReward = $gameStor->getValue('develcost') * 5;
$general = General::createGeneralObjFromDB($generalID, ['gold', 'horse', 'weapon', 'book', 'item', 'npc', 'imgsvr', 'picture', 'aux'], 2); $general = General::createGeneralObjFromDB($generalID, ['gold', 'horse', 'weapon', 'book', 'item', 'npc', 'imgsvr', 'picture', 'aux'], GeneralQueryMode::Lite);
$general->increaseVar('gold', $voteReward); $general->increaseVar('gold', $voteReward);
$uniqueRng = new RandUtil(new LiteHashDRBG(Util::simpleSerialize( $uniqueRng = new RandUtil(new LiteHashDRBG(Util::simpleSerialize(
UniqueConst::$hiddenSeed, UniqueConst::$hiddenSeed,
+2 -1
View File
@@ -5,6 +5,7 @@ namespace sammo;
use Ds\Map; use Ds\Map;
use sammo\DTO\BettingInfo; use sammo\DTO\BettingInfo;
use sammo\DTO\BettingItem; use sammo\DTO\BettingItem;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\RankColumn; use sammo\Enums\RankColumn;
class Betting class Betting
@@ -401,7 +402,7 @@ class Betting
$userLogger->flush(); $userLogger->flush();
} }
} else { } else {
$generalList = General::createGeneralObjListFromDB(array_unique(Util::squeezeFromArray($rewardList, 'generalID')), ['gold', 'npc', 'betgold'], 1); $generalList = General::createGeneralObjListFromDB(array_unique(Util::squeezeFromArray($rewardList, 'generalID')), ['gold', 'npc', 'betgold'], GeneralQueryMode::Lite);
foreach ($rewardList as $rewardItem) { foreach ($rewardList as $rewardItem) {
$gambler = $generalList[$rewardItem['generalID']]; $gambler = $generalList[$rewardItem['generalID']];
$reward = Util::round($rewardItem['amount']); $reward = Util::round($rewardItem['amount']);
+2 -2
View File
@@ -21,7 +21,7 @@ use function \sammo\getNationStaticInfo;
use function sammo\tryUniqueItemLottery; use function sammo\tryUniqueItemLottery;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\GeneralQueryMode;
class che_등용 extends Command\GeneralCommand class che_등용 extends Command\GeneralCommand
{ {
@@ -77,7 +77,7 @@ class che_등용 extends Command\GeneralCommand
protected function initWithArg() protected function initWithArg()
{ {
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['nation', 'experience', 'dedication'], 0); $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['nation', 'experience', 'dedication'], GeneralQueryMode::Lite);
$this->setDestGeneral($destGeneral); $this->setDestGeneral($destGeneral);
[$reqGold, $reqRice] = $this->getCost(); [$reqGold, $reqRice] = $this->getCost();
@@ -68,7 +68,7 @@ class che_등용수락 extends Command\GeneralCommand{
protected function initWithArg() protected function initWithArg()
{ {
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], null, 2); $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], null);
$this->setDestGeneral($destGeneral); $this->setDestGeneral($destGeneral);
$this->setDestNation($this->arg['destNationID'], ['gennum', 'scout']); $this->setDestNation($this->arg['destNationID'], ['gennum', 'scout']);
@@ -77,6 +77,7 @@ class che_등용수락 extends Command\GeneralCommand{
$this->fullConditionConstraints=[ $this->fullConditionConstraints=[
ConstraintHelper::ReqEnvValue('join_mode', '!=', 'onlyRandom', '랜덤 임관만 가능합니다'), ConstraintHelper::ReqEnvValue('join_mode', '!=', 'onlyRandom', '랜덤 임관만 가능합니다'),
ConstraintHelper::ExistsDestNation(), ConstraintHelper::ExistsDestNation(),
ConstraintHelper::BeNeutral(),
ConstraintHelper::AllowJoinDestNation($relYear), ConstraintHelper::AllowJoinDestNation($relYear),
ConstraintHelper::ReqDestNationValue('level', '국가규모', '>', 0, '방랑군에는 임관할 수 없습니다.'), ConstraintHelper::ReqDestNationValue('level', '국가규모', '>', 0, '방랑군에는 임관할 수 없습니다.'),
ConstraintHelper::DifferentDestNation(), ConstraintHelper::DifferentDestNation(),
+2 -1
View File
@@ -19,6 +19,7 @@ use function\sammo\tryUniqueItemLottery;
use \sammo\Constraint\Constraint; use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\InheritanceKey; use sammo\Enums\InheritanceKey;
class che_선양 extends Command\GeneralCommand class che_선양 extends Command\GeneralCommand
@@ -65,7 +66,7 @@ class che_선양 extends Command\GeneralCommand
protected function initWithArg() protected function initWithArg()
{ {
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['gold', 'nation'], 1); $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['gold', 'nation'], GeneralQueryMode::Lite);
$this->setDestGeneral($destGeneral); $this->setDestGeneral($destGeneral);
$this->fullConditionConstraints = [ $this->fullConditionConstraints = [
@@ -17,6 +17,7 @@ use function \sammo\tryUniqueItemLottery;
use function \sammo\getNationStaticInfo; use function \sammo\getNationStaticInfo;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\InheritanceKey; use sammo\Enums\InheritanceKey;
class che_장수대상임관 extends Command\GeneralCommand{ class che_장수대상임관 extends Command\GeneralCommand{
@@ -83,7 +84,7 @@ class che_장수대상임관 extends Command\GeneralCommand{
protected function initWithArg() protected function initWithArg()
{ {
$destGeneralID = $this->arg['destGeneralID']; $destGeneralID = $this->arg['destGeneralID'];
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['nation'], 0); $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['nation'], GeneralQueryMode::Lite);
$this->setDestGeneral($destGeneral); $this->setDestGeneral($destGeneral);
$this->setDestNation($this->destGeneralObj->getVar('nation'), ['gennum', 'scout']); $this->setDestNation($this->destGeneralObj->getVar('nation'), ['gennum', 'scout']);
+2 -1
View File
@@ -15,6 +15,7 @@ use \sammo\Command;
use \sammo\Constraint\Constraint; use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\GeneralQueryMode;
use function sammo\tryUniqueItemLottery; use function sammo\tryUniqueItemLottery;
@@ -86,7 +87,7 @@ class che_증여 extends Command\GeneralCommand
protected function initWithArg() protected function initWithArg()
{ {
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['gold', 'rice', 'nation'], 1); $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['gold', 'rice', 'nation'], GeneralQueryMode::Lite);
$this->setDestGeneral($destGeneral); $this->setDestGeneral($destGeneral);
$this->fullConditionConstraints = [ $this->fullConditionConstraints = [
+2 -1
View File
@@ -15,6 +15,7 @@ use function \sammo\searchDistance;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
use sammo\CityConst; use sammo\CityConst;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\RankColumn; use sammo\Enums\RankColumn;
use sammo\RandUtil; use sammo\RandUtil;
@@ -268,7 +269,7 @@ class che_화계 extends Command\GeneralCommand
$destCityGeneralList = []; $destCityGeneralList = [];
$cityGeneralID = $db->queryFirstColumn('SELECT no FROM general WHERE city = %i AND nation = %i', $destCityID, $destNationID); $cityGeneralID = $db->queryFirstColumn('SELECT no FROM general WHERE city = %i AND nation = %i', $destCityID, $destNationID);
$destCityGeneralList = General::createGeneralObjListFromDB($cityGeneralID, ['name', 'city', 'nation', 'officer_level', 'leadership', 'horse', 'strength', 'weapon', 'intel', 'book', 'item', 'last_turn', 'injury', 'special', 'special2', 'injury', 'crewtype', 'crew', 'atmos', 'train'], 2); $destCityGeneralList = General::createGeneralObjListFromDB($cityGeneralID, ['name', 'city', 'nation', 'officer_level', 'leadership', 'horse', 'strength', 'weapon', 'intel', 'book', 'item', 'last_turn', 'injury', 'special', 'special2', 'injury', 'crewtype', 'crew', 'atmos', 'train']);
foreach ($destCityGeneralList as &$destCityGeneral) { foreach ($destCityGeneralList as &$destCityGeneral) {
$destCityGeneral->setRawCity($this->destCity); $destCityGeneral->setRawCity($this->destCity);
unset($destCityGeneral); unset($destCityGeneral);
+7 -4
View File
@@ -19,6 +19,7 @@ use function \sammo\GetImageURL;
use \sammo\Constraint\Constraint; use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\MessageType; use sammo\Enums\MessageType;
class che_몰수 extends Command\NationCommand class che_몰수 extends Command\NationCommand
@@ -91,7 +92,7 @@ class che_몰수 extends Command\NationCommand
protected function initWithArg() protected function initWithArg()
{ {
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['gold', 'rice', 'npc', 'nation', 'imgsvr', 'picture'], 1); $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['gold', 'rice', 'npc', 'nation', 'imgsvr', 'picture'], GeneralQueryMode::Lite);
$this->setDestGeneral($destGeneral); $this->setDestGeneral($destGeneral);
$env = $this->env; $env = $this->env;
@@ -173,7 +174,7 @@ class che_몰수 extends Command\NationCommand
$npcTexts = [ $npcTexts = [
'몰수를 하다니... 이것이 윗사람이 할 짓이란 말입니까...', '몰수를 하다니... 이것이 윗사람이 할 짓이란 말입니까...',
'사유재산까지 몰수해가면서 이 나라가 잘 될거라 믿습니까? 정말 이해할 수가 없군요...', '사유재산까지 몰수해가면서 이 나라가 잘 될거라 믿습니까? 정말 이해할 수가 없군요...',
'내 돈 내놔라! 내 돈! 몰수가 말이냐!', '내 돈 내놔라! 내 돈! 몰수가 말이냐!',
'몰수해간 내 자금... 언젠가 몰래 다시 빼내올 것이다...', '몰수해간 내 자금... 언젠가 몰래 다시 빼내올 것이다...',
'몰수로 인한 사기 저하는 몰수로 얻은 물자보다 더 손해란걸 모른단 말인가!' '몰수로 인한 사기 저하는 몰수로 얻은 물자보다 더 손해란걸 모른단 말인가!'
]; ];
@@ -205,8 +206,10 @@ class che_몰수 extends Command\NationCommand
$resKey => $db->sqleval('%b + %i', $resKey, $amount) $resKey => $db->sqleval('%b + %i', $resKey, $amount)
], 'nation=%i', $nationID); ], 'nation=%i', $nationID);
$destGeneral->getLogger()->pushGeneralActionLog("{$resName} {$amountText}을 몰수 당했습니다.", ActionLogger::PLAIN); $josaUl = JosaUtil::pick($amountText, '을');
$logger->pushGeneralActionLog("<Y>{$destGeneral->getName()}</>에게서 {$resName} <C>$amountText</>을 몰수했습니다. <1>$date</>");
$destGeneral->getLogger()->pushGeneralActionLog("{$resName} {$amountText}{$josaUl} 몰수 당했습니다.", ActionLogger::PLAIN);
$logger->pushGeneralActionLog("<Y>{$destGeneral->getName()}</>에게서 {$resName} <C>$amountText</>{$josaUl} 몰수했습니다. <1>$date</>");
$this->setResultTurn(new LastTurn(static::getName(), $this->arg)); $this->setResultTurn(new LastTurn(static::getName(), $this->arg));
$general->applyDB($db); $general->applyDB($db);
@@ -215,14 +215,16 @@ class che_물자원조 extends Command\NationCommand
$chiefLogger->flush(); $chiefLogger->flush();
} }
$logger->pushGeneralHistoryLog("<D><b>{$destNationName}</b></>{$josaRo} 금<C>{$goldAmountText}</> 쌀<C>{$riceAmountText}</>을 지원"); $josaUlRiceAmount = JosaUtil::pick($riceAmountText, '을');
$logger->pushNationalHistoryLog("<D><b>{$destNationName}</b></>{$josaRo} 금<C>{$goldAmountText}</> 쌀<C>{$riceAmountText}</>을 지원");
$logger->pushGeneralHistoryLog("<D><b>{$destNationName}</b></>{$josaRo} 금<C>{$goldAmountText}</> 쌀<C>{$riceAmountText}</>{$josaUlRiceAmount} 지원");
$logger->pushNationalHistoryLog("<D><b>{$destNationName}</b></>{$josaRo} 금<C>{$goldAmountText}</> 쌀<C>{$riceAmountText}</>{$josaUlRiceAmount} 지원");
$logger->pushGlobalHistoryLog("<Y><b>【원조】</b></><D><b>{$nationName}</b></>에서 <D><b>{$destNationName}</b></>{$josaRo} 물자를 지원합니다"); $logger->pushGlobalHistoryLog("<Y><b>【원조】</b></><D><b>{$nationName}</b></>에서 <D><b>{$destNationName}</b></>{$josaRo} 물자를 지원합니다");
$logger->pushGeneralActionLog($broadcastMessage); $logger->pushGeneralActionLog($broadcastMessage);
$logger->pushGeneralActionLog("<D><b>{$destNationName}</b></>{$josaRo} 물자를 지원합니다. <1>$date</>", ActionLogger::PLAIN); $logger->pushGeneralActionLog("<D><b>{$destNationName}</b></>{$josaRo} 물자를 지원합니다. <1>$date</>", ActionLogger::PLAIN);
$destBroadcastMessage = $broadcastMessage = "<D><b>{$nationName}</b></>에서 금<C>{$goldAmountText}</> 쌀<C>{$riceAmountText}</> 원조했습니다."; $destBroadcastMessage = $broadcastMessage = "<D><b>{$nationName}</b></>에서 금<C>{$goldAmountText}</> 쌀<C>{$riceAmountText}</>{$josaUlRiceAmount} 원조했습니다.";
$destChiefList = $db->queryFirstColumn('SELECT no FROM general WHERE officer_level >= 5 AND nation = %i', $destNationID); $destChiefList = $db->queryFirstColumn('SELECT no FROM general WHERE officer_level >= 5 AND nation = %i', $destNationID);
foreach ($destChiefList as $destChiefID) { foreach ($destChiefList as $destChiefID) {
$destChiefLogger = new ActionLogger($destChiefID, $nationID, $year, $month); $destChiefLogger = new ActionLogger($destChiefID, $nationID, $year, $month);
@@ -232,7 +234,7 @@ class che_물자원조 extends Command\NationCommand
$josaRoSrc = JosaUtil::pick($nationName, '로'); $josaRoSrc = JosaUtil::pick($nationName, '로');
$destNationLogger = new ActionLogger(0, $destNationID, $year, $month); $destNationLogger = new ActionLogger(0, $destNationID, $year, $month);
$destNationLogger->pushNationalHistoryLog("<D><b>{$nationName}</b></>{$josaRoSrc}부터 금<C>{$goldAmountText}</> 쌀<C>{$riceAmountText}</> 지원 받음"); $destNationLogger->pushNationalHistoryLog("<D><b>{$nationName}</b></>{$josaRoSrc}부터 금<C>{$goldAmountText}</> 쌀<C>{$riceAmountText}</>{$josaUlRiceAmount} 지원 받음");
$destNationStor = KVStorage::getStorage(DB::db(), $destNationID, 'nation_env'); $destNationStor = KVStorage::getStorage(DB::db(), $destNationID, 'nation_env');
$destRecvAssist = $destNationStor->getValue('recv_assist') ?? []; $destRecvAssist = $destNationStor->getValue('recv_assist') ?? [];
+2 -1
View File
@@ -21,6 +21,7 @@ use function \sammo\cutTurn;
use \sammo\Constraint\Constraint; use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\GeneralQueryMode;
class che_발령 extends Command\NationCommand class che_발령 extends Command\NationCommand
{ {
@@ -71,7 +72,7 @@ class che_발령 extends Command\NationCommand
{ {
$this->setDestCity($this->arg['destCityID']); $this->setDestCity($this->arg['destCityID']);
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], null, 1); $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], null, GeneralQueryMode::Lite);
$this->setDestGeneral($destGeneral); $this->setDestGeneral($destGeneral);
if ($this->arg['destGeneralID'] == $this->getGeneral()->getID()) { if ($this->arg['destGeneralID'] == $this->getGeneral()->getID()) {
@@ -20,6 +20,7 @@ use function \sammo\getNationStaticInfo;
use \sammo\Constraint\Constraint; use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\GeneralQueryMode;
use sammo\Json; use sammo\Json;
use sammo\KVStorage; use sammo\KVStorage;
use sammo\RandUtil; use sammo\RandUtil;
@@ -103,7 +104,7 @@ class che_불가침수락 extends Command\NationCommand
$env = $this->env; $env = $this->env;
$relYear = $env['year'] - $env['startyear']; $relYear = $env['year'] - $env['startyear'];
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], [], 1); $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], null, GeneralQueryMode::Lite);
$this->setDestGeneral($destGeneral); $this->setDestGeneral($destGeneral);
$this->setDestNation($this->arg['destNationID']); $this->setDestNation($this->arg['destNationID']);
@@ -20,6 +20,7 @@ use function \sammo\getNationStaticInfo;
use \sammo\Constraint\Constraint; use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\GeneralQueryMode;
use sammo\RandUtil; use sammo\RandUtil;
class che_불가침파기수락 extends Command\NationCommand class che_불가침파기수락 extends Command\NationCommand
@@ -77,7 +78,7 @@ class che_불가침파기수락 extends Command\NationCommand
protected function initWithArg() protected function initWithArg()
{ {
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], [], 1); $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], null, GeneralQueryMode::Lite);
$this->setDestGeneral($destGeneral); $this->setDestGeneral($destGeneral);
$this->setDestNation($this->arg['destNationID']); $this->setDestNation($this->arg['destNationID']);
@@ -22,6 +22,7 @@ use function \sammo\getNationStaticInfo;
use \sammo\Constraint\Constraint; use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\GeneralQueryMode;
class che_종전수락 extends Command\NationCommand class che_종전수락 extends Command\NationCommand
{ {
@@ -86,7 +87,7 @@ class che_종전수락 extends Command\NationCommand
protected function initWithArg() protected function initWithArg()
{ {
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], [], 1); $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], null, GeneralQueryMode::Lite);
$this->setDestGeneral($destGeneral); $this->setDestGeneral($destGeneral);
$this->setDestNation($this->arg['destNationID']); $this->setDestNation($this->arg['destNationID']);
+6 -3
View File
@@ -15,6 +15,7 @@ use \sammo\Command;
use \sammo\Constraint\Constraint; use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\GeneralQueryMode;
class che_포상 extends Command\NationCommand class che_포상 extends Command\NationCommand
{ {
@@ -81,7 +82,7 @@ class che_포상 extends Command\NationCommand
protected function initWithArg() protected function initWithArg()
{ {
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['gold', 'rice', 'nation'], 1); $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], ['gold', 'rice', 'nation'], GeneralQueryMode::Lite);
$this->setDestGeneral($destGeneral); $this->setDestGeneral($destGeneral);
if($this->arg['destGeneralID'] == $this->getGeneral()->getID()){ if($this->arg['destGeneralID'] == $this->getGeneral()->getID()){
@@ -167,8 +168,10 @@ class che_포상 extends Command\NationCommand
$resKey => $db->sqleval('%b - %i', $resKey, $amount) $resKey => $db->sqleval('%b - %i', $resKey, $amount)
], 'nation=%i', $nationID); ], 'nation=%i', $nationID);
$destGeneral->getLogger()->pushGeneralActionLog("{$resName} <C>{$amountText}</>을 포상으로 받았습니다.", ActionLogger::PLAIN); $josaUl = JosaUtil::pick($amountText, '을');
$logger->pushGeneralActionLog("<Y>{$destGeneral->getName()}</>에게 {$resName} <C>$amountText</>을 수여했습니다. <1>$date</>");
$destGeneral->getLogger()->pushGeneralActionLog("{$resName} <C>{$amountText}</>{$josaUl} 포상으로 받았습니다.", ActionLogger::PLAIN);
$logger->pushGeneralActionLog("<Y>{$destGeneral->getName()}</>에게 {$resName} <C>$amountText</>{$josaUl} 수여했습니다. <1>$date</>");
$this->setResultTurn(new LastTurn(static::getName(), $this->arg)); $this->setResultTurn(new LastTurn(static::getName(), $this->arg));
$general->applyDB($db); $general->applyDB($db);
@@ -15,6 +15,7 @@ use \sammo\{
use \sammo\Constraint\Constraint; use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\GeneralQueryMode;
use sammo\Event\Action; use sammo\Event\Action;
class che_필사즉생 extends Command\NationCommand{ class che_필사즉생 extends Command\NationCommand{
@@ -94,7 +95,7 @@ class che_필사즉생 extends Command\NationCommand{
$broadcastMessage = "<Y>{$generalName}</>{$josaYi} <M>필사즉생</>을 발동하였습니다."; $broadcastMessage = "<Y>{$generalName}</>{$josaYi} <M>필사즉생</>을 발동하였습니다.";
$targetGeneralList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND no != %i', $nationID, $generalID); $targetGeneralList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND no != %i', $nationID, $generalID);
foreach(General::createGeneralObjListFromDB($targetGeneralList, ['train', 'atmos'], 1) as $targetGeneral){ foreach(General::createGeneralObjListFromDB($targetGeneralList, ['train', 'atmos'], GeneralQueryMode::Lite) as $targetGeneral){
$targetGeneral->getLogger()->pushGeneralActionLog($broadcastMessage, ActionLogger::PLAIN); $targetGeneral->getLogger()->pushGeneralActionLog($broadcastMessage, ActionLogger::PLAIN);
if($targetGeneral->getVar('train') < 100){ if($targetGeneral->getVar('train') < 100){
$targetGeneral->setVar('train', 100); $targetGeneral->setVar('train', 100);
@@ -39,7 +39,7 @@ class ReqGeneralCrewMargin extends Constraint{
//XXX: 왜 General -> obj -> General 변환을 하고 있나? //XXX: 왜 General -> obj -> General 변환을 하고 있나?
//FIXME: RankVar, city에 따라 통솔이 바뀐다면 이 부분에 문제가 발생. //FIXME: RankVar, city에 따라 통솔이 바뀐다면 이 부분에 문제가 발생.
$generalObj = new General($this->general, null, null, null, null, null, true); $generalObj = new General($this->general, null, null, null, null, null, null, true);
if($reqCrewType->id != $generalObj->getCrewTypeObj()->id){ if($reqCrewType->id != $generalObj->getCrewTypeObj()->id){
return true; return true;
+38
View File
@@ -0,0 +1,38 @@
<?php
namespace sammo\DTO;
use LDTO\Attr\Convert;
use LDTO\Attr\NullIsUndefined;
use LDTO\Attr\RawName;
use LDTO\Converter\DateTimeConverter;
class GeneralAccessLog extends \LDTO\DTO
{
public function __construct(
#[NullIsUndefined]
public ?int $id,
#[RawName('general_id')]
public int $generalID,
#[RawName('user_id')]
public ?int $userID,
#[RawName('last_refresh')]
#[Convert(DateTimeConverter::class)]
public \DateTimeImmutable $lastRefresh,
public int $refresh,
#[RawName('refresh_total')]
public int $refreshTotal,
#[RawName('refresh_score')]
public int $refreshScore,
#[RawName('refresh_score_total')]
public int $refreshScoreTotal,
) {
}
}
+4 -3
View File
@@ -1,6 +1,7 @@
<?php <?php
namespace sammo; namespace sammo;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\MessageType; use sammo\Enums\MessageType;
class DiplomaticMessage extends Message{ class DiplomaticMessage extends Message{
@@ -75,7 +76,7 @@ class DiplomaticMessage extends Message{
$gameStor = KVStorage::getStorage(DB::db(), 'game_env'); $gameStor = KVStorage::getStorage(DB::db(), 'game_env');
$destGeneralObj = General::createGeneralObjFromDB($this->dest->generalID, ['picture', 'imgsvr', 'aux'], 1); $destGeneralObj = General::createGeneralObjFromDB($this->dest->generalID, ['picture', 'imgsvr', 'aux'], GeneralQueryMode::Lite);
$commandObj = buildNationCommandClass('che_불가침수락', $destGeneralObj, $gameStor->getAll(true), new LastTurn(), [ $commandObj = buildNationCommandClass('che_불가침수락', $destGeneralObj, $gameStor->getAll(true), new LastTurn(), [
'destNationID'=>$this->src->nationID, 'destNationID'=>$this->src->nationID,
@@ -99,7 +100,7 @@ class DiplomaticMessage extends Message{
protected function cancelNA(){ protected function cancelNA(){
$gameStor = KVStorage::getStorage(DB::db(), 'game_env'); $gameStor = KVStorage::getStorage(DB::db(), 'game_env');
$destGeneralObj = General::createGeneralObjFromDB($this->dest->generalID, ['picture', 'imgsvr', 'aux'], 1); $destGeneralObj = General::createGeneralObjFromDB($this->dest->generalID, ['picture', 'imgsvr', 'aux'], GeneralQueryMode::Lite);
$commandObj = buildNationCommandClass('che_불가침파기수락', $destGeneralObj, $gameStor->getAll(true), new LastTurn(), [ $commandObj = buildNationCommandClass('che_불가침파기수락', $destGeneralObj, $gameStor->getAll(true), new LastTurn(), [
'destNationID'=>$this->src->nationID, 'destNationID'=>$this->src->nationID,
@@ -121,7 +122,7 @@ class DiplomaticMessage extends Message{
protected function stopWar(){ protected function stopWar(){
$gameStor = KVStorage::getStorage(DB::db(), 'game_env'); $gameStor = KVStorage::getStorage(DB::db(), 'game_env');
$destGeneralObj = General::createGeneralObjFromDB($this->dest->generalID, ['picture', 'imgsvr', 'aux'], 1); $destGeneralObj = General::createGeneralObjFromDB($this->dest->generalID, ['picture', 'imgsvr', 'aux'], GeneralQueryMode::Lite);
$commandObj = buildNationCommandClass('che_종전수락', $destGeneralObj, $gameStor->getAll(true), new LastTurn(), [ $commandObj = buildNationCommandClass('che_종전수락', $destGeneralObj, $gameStor->getAll(true), new LastTurn(), [
'destNationID'=>$this->src->nationID, 'destNationID'=>$this->src->nationID,
@@ -0,0 +1,14 @@
<?php
namespace sammo\Enums;
enum GeneralAccessLogColumn: string {
case id = 'id';
case generalID = 'general_id';
case userID = 'user_id';
case lastRefresh = 'last_refresh';
case refresh = 'refresh'; //순간 갱신 횟수(00:00에 초기화)
case refreshTotal = 'refresh_total'; //누적 갱신 횟수
case refreshScore = 'refresh_score'; //순간 벌점(턴 시간에 초기화)
case refreshScoreTotal = 'refresh_score_total'; //누적 벌점(지속적으로 감소, refreshScoreTotal <= refreshTotal)
}
-7
View File
@@ -15,11 +15,6 @@ enum GeneralColumn: string{
case bornyear = 'bornyear'; case bornyear = 'bornyear';
case deadyear = 'deadyear'; case deadyear = 'deadyear';
case newmsg = 'newmsg'; case newmsg = 'newmsg';
case con = 'con';
case connect = 'connect';
case refresh = 'refresh';
case logcnt = 'logcnt';
case refcnt = 'refcnt';
case picture = 'picture'; case picture = 'picture';
case imgsvr = 'imgsvr'; case imgsvr = 'imgsvr';
case name = 'name'; case name = 'name';
@@ -58,8 +53,6 @@ enum GeneralColumn: string{
case recent_war = 'recent_war'; case recent_war = 'recent_war';
case makelimit = 'makelimit'; case makelimit = 'makelimit';
case killturn = 'killturn'; case killturn = 'killturn';
case lastconnect = 'lastconnect';
case lastrefresh = 'lastrefresh';
case ip = 'ip'; case ip = 'ip';
case block = 'block'; case block = 'block';
case dedlevel = 'dedlevel'; case dedlevel = 'dedlevel';
+18
View File
@@ -0,0 +1,18 @@
<?php
namespace sammo\Enums;
// mergeQueryColumn, createGeneralObjListFromDB, createGeneralObjFromDB 호출시 column 특수 모드 지정
enum GeneralQueryMode: int
{
/** 장수 식별을 위한 최소한의 정보, logger 초기화 없음 */
case Core = 0;
/** 게임 내에서 필수 이벤트 처리를 위한 정보, iAction 제외 */
case Lite = 1;
/** 게임 내 모든 이벤트 처리를 위한 정보, iAction 제외 */
case FullWithoutIAction = 2;
/** 게임 내 모든 이벤트 처리를 위한 정보, iAction 포함 */
case Full = 3;
/** 접속 정보를 포함한 모든 정보 */
case FullWithAccessLog = 4;
}
+60
View File
@@ -0,0 +1,60 @@
<?php
namespace sammo\Enums;
enum TableName: string {
case general = 'general';
case generalTurn = 'general_turn';
case generalAccessLog = 'general_access_log';
case userRecord = 'user_record';
case nation = 'nation';
case nationTurn = 'nation_turn';
case nationEnv = 'nation_env';
case board = 'board';
case comment = 'comment';
case city = 'city';
case troop = 'troop';
case plock = 'plock';
case message = 'message';
case rankData = 'rank_data';
case hall = 'hall';
case oldNations = 'ng_old_nations';
case oldGenerals = 'ng_old_generals';
case emperior = 'emperior';
case diplomacy = 'diplomacy';
case diplomaticNotes = 'ng_diplomacy';
case tournament = 'tournament';
case betting = 'ng_betting';
case vote = 'vote';
case voteComment = 'vote_comment';
case auction = 'ng_auction';
case auctionBid = 'ng_auction_bid';
case statistic = 'statistic';
case history = 'ng_history';
case worldHistory = 'world_history';
case generalRecord = 'general_record';
case event = 'event';
case storage = 'storage';
case selectNPCToken = 'select_npc_token';
case selectPool = 'select_pool';
case games = 'ng_games';
case reservedOpen = 'reserved_open';
}
+1 -1
View File
@@ -63,7 +63,7 @@ class InvaderEnding extends \sammo\Event\Action{
$gameStor->setValue('isunited', 3); $gameStor->setValue('isunited', 3);
$logger->flush(); $logger->flush();
$gameStor->conlimit = $gameStor->conlimit * 100; $gameStor->refreshLimit = $gameStor->refreshLimit * 100;
$eventID = Util::array_get($env['currentEventID']); $eventID = Util::array_get($env['currentEventID']);
$db->delete('event', 'id = %i', $eventID); $db->delete('event', 'id = %i', $eventID);
@@ -18,7 +18,7 @@ class MergeInheritPointRank extends \sammo\Event\Action
{ {
$db = DB::db(); $db = DB::db();
$generals = General::createGeneralObjListFromDB(null, null, 2); $generals = General::createGeneralObjListFromDB(null, null);
$points = new Map(); $points = new Map();
$points->allocate(count($generals)); $points->allocate(count($generals));
+2 -2
View File
@@ -88,7 +88,7 @@ class ProcessIncome extends \sammo\Event\Action
// 각 장수들에게 지급 // 각 장수들에게 지급
foreach ($generalRawList as $rawGeneral) { foreach ($generalRawList as $rawGeneral) {
$generalObj = new General($rawGeneral, null, null, null, $year, $month, false); $generalObj = new General($rawGeneral, null, null, null, null, $year, $month, false);
$gold = Util::round(getBill($generalObj->getVar('dedication')) * $ratio); $gold = Util::round(getBill($generalObj->getVar('dedication')) * $ratio);
$generalObj->increaseVar('gold', $gold); $generalObj->increaseVar('gold', $gold);
@@ -169,7 +169,7 @@ class ProcessIncome extends \sammo\Event\Action
// 각 장수들에게 지급 // 각 장수들에게 지급
foreach ($generalRawList as $rawGeneral) { foreach ($generalRawList as $rawGeneral) {
$generalObj = new General($rawGeneral, null, null, null, $year, $month, false); $generalObj = new General($rawGeneral, null, null, null, null, $year, $month, false);
$rice = Util::round(getBill($generalObj->getVar('dedication')) * $ratio); $rice = Util::round(getBill($generalObj->getVar('dedication')) * $ratio);
$generalObj->increaseVar('rice', $rice); $generalObj->increaseVar('rice', $rice);
+1 -1
View File
@@ -131,7 +131,7 @@ class RaiseDisaster extends \sammo\Event\Action
$generalList = array_map( $generalList = array_map(
function ($rawGeneral) use ($city, $year, $month) { function ($rawGeneral) use ($city, $year, $month) {
return new General($rawGeneral, null, $city, null, $year, $month, false); return new General($rawGeneral, null, null, $city, null, $year, $month, false);
}, },
$generalListByCity[$city['city']] ?? [] $generalListByCity[$city['city']] ?? []
); );
+3 -2
View File
@@ -5,6 +5,7 @@ namespace sammo\Event\Action;
use sammo\ActionLogger; use sammo\ActionLogger;
use sammo\CityConst; use sammo\CityConst;
use sammo\DB; use sammo\DB;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\InheritanceKey; use sammo\Enums\InheritanceKey;
use sammo\GameConst; use sammo\GameConst;
use sammo\General; use sammo\General;
@@ -139,7 +140,7 @@ class UpdateNationLevel extends \sammo\Event\Action
$nation['nation'], $nation['nation'],
$targetKillTurn $targetKillTurn
); );
$nationGenList = General::createGeneralObjListFromDB($nationGenIDList, ['belong', 'npc', 'aux'], 2); $nationGenList = General::createGeneralObjListFromDB($nationGenIDList, ['belong', 'npc', 'aux']);
$chiefID = null; $chiefID = null;
$uniqueLotteryWeightList = []; $uniqueLotteryWeightList = [];
@@ -214,7 +215,7 @@ class UpdateNationLevel extends \sammo\Event\Action
} }
if ($chiefID) { if ($chiefID) {
$chiefObj = General::createGeneralObjFromDB($chiefID, ['belong', 'npc', 'aux'], 2); $chiefObj = General::createGeneralObjFromDB($chiefID, ['belong', 'npc', 'aux'], GeneralQueryMode::Lite);
$chiefObj->increaseInheritancePoint(InheritanceKey::unifier, 250 * $levelDiff); $chiefObj->increaseInheritancePoint(InheritanceKey::unifier, 250 * $levelDiff);
$chiefObj->applyDB($db); $chiefObj->applyDB($db);
} }
+132 -29
View File
@@ -4,6 +4,8 @@ namespace sammo;
use Ds\Map; use Ds\Map;
use sammo\Command\GeneralCommand; use sammo\Command\GeneralCommand;
use sammo\Enums\GeneralAccessLogColumn;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\InheritanceKey; use sammo\Enums\InheritanceKey;
use sammo\Enums\RankColumn; use sammo\Enums\RankColumn;
use sammo\WarUnitTrigger as WarUnitTrigger; use sammo\WarUnitTrigger as WarUnitTrigger;
@@ -23,6 +25,9 @@ class General implements iAction
/** @var Map<RankColumn,int|float> */ /** @var Map<RankColumn,int|float> */
protected Map $rankVarSet; protected Map $rankVarSet;
/** @var Map<GeneralAccessLogColumn,int|float> */
protected ?Map $accessLogRead;
/** @var \sammo\ActionLogger */ /** @var \sammo\ActionLogger */
protected $logger; protected $logger;
@@ -78,12 +83,13 @@ class General implements iAction
/** /**
* @param array $raw DB row값. * @param array $raw DB row값.
* @param null|Map<RankColumn,int|float> $rawRank * @param null|Map<RankColumn,int|float> $rawRank
* @param null|Map<GeneralAccessLogColumn,int> $rawAccessLog
* @param null|array $city DB city 테이블의 row값 * @param null|array $city DB city 테이블의 row값
* @param int|null $year 게임 연도 * @param int|null $year 게임 연도
* @param int|null $month 게임 월 * @param int|null $month 게임 월
* @param bool $fullConstruct iAction, 및 ActionLogger 초기화 여부, false인 경우 no, name, city, nation, officer_level 정도로 초기화 가능 * @param bool $fullConstruct iAction, 및 ActionLogger 초기화 여부, false인 경우 no, name, city, nation, officer_level 정도로 초기화 가능
*/ */
public function __construct(array $raw, ?Map $rawRank, ?array $city, ?array $nation, ?int $year, ?int $month, bool $fullConstruct = true) public function __construct(array $raw, ?Map $rawRank, ?Map $rawAccessLog, ?array $city, ?array $nation, ?int $year, ?int $month, bool $fullConstruct = true)
{ {
//TODO: 밖에서 가져오도록 하면 버그 확률이 높아짐. 필요한 raw 값을 직접 구해야함. //TODO: 밖에서 가져오도록 하면 버그 확률이 높아짐. 필요한 raw 값을 직접 구해야함.
@@ -109,6 +115,10 @@ class General implements iAction
} else { } else {
$this->rankVarRead = new Map(); $this->rankVarRead = new Map();
} }
$this->accessLogRead = $rawAccessLog;
$this->rankVarIncrease = new Map(); $this->rankVarIncrease = new Map();
$this->rankVarSet = new Map(); $this->rankVarSet = new Map();
@@ -329,7 +339,7 @@ class General implements iAction
function getCrewTypeObj(): GameUnitDetail function getCrewTypeObj(): GameUnitDetail
{ {
if($this->crewType === null) { if ($this->crewType === null) {
throw new \InvalidArgumentException('Invalid CrewType:' . $this->getVar('crewtype')); throw new \InvalidArgumentException('Invalid CrewType:' . $this->getVar('crewtype'));
} }
return $this->crewType; return $this->crewType;
@@ -677,6 +687,7 @@ class General implements iAction
$db->delete('general', 'no=%i', $generalID); $db->delete('general', 'no=%i', $generalID);
$db->delete('general_turn', 'general_id=%i', $generalID); $db->delete('general_turn', 'general_id=%i', $generalID);
$db->delete('rank_data', 'general_id=%i', $generalID); $db->delete('rank_data', 'general_id=%i', $generalID);
$db->delete('general_access_log', 'general_id=%i', $generalID);
$this->updatedVar = []; $this->updatedVar = [];
$db->update('nation', [ $db->update('nation', [
@@ -770,6 +781,19 @@ class General implements iAction
return $this->rankVarRead[$key]; return $this->rankVarRead[$key];
} }
function getAccessLogVar(GeneralAccessLogColumn $key, $defaultValue = null): int | string | null
{
if (!$this->accessLogRead) {
return $defaultValue;
}
if (!$this->accessLogRead->hasKey($key)) {
return $defaultValue;
}
return $this->accessLogRead[$key];
}
/** /**
* @param \MeekroDB $db * @param \MeekroDB $db
*/ */
@@ -844,7 +868,7 @@ class General implements iAction
$this->increaseVar($statName, -1); $this->increaseVar($statName, -1);
$result = true; $result = true;
} else if ($this->getVar($statExpName) >= $limit) { } else if ($this->getVar($statExpName) >= $limit) {
if($this->getVar($statName) < GameConst::$maxLevel) { if ($this->getVar($statName) < GameConst::$maxLevel) {
$logger->pushGeneralActionLog("<S>{$statNickName}</>이 <C>1</> 올랐습니다!", ActionLogger::PLAIN); $logger->pushGeneralActionLog("<S>{$statNickName}</>이 <C>1</> 올랐습니다!", ActionLogger::PLAIN);
$this->increaseVar($statName, 1); $this->increaseVar($statName, 1);
} }
@@ -856,7 +880,8 @@ class General implements iAction
return $result; return $result;
} }
protected function getActionList(): array{ protected function getActionList(): array
{
return array_merge([ return array_merge([
$this->nationType, $this->nationType,
$this->officerLevelObj, $this->officerLevelObj,
@@ -1007,7 +1032,7 @@ class General implements iAction
return $caller; return $caller;
} }
static public function mergeQueryColumn(?array $reqColumns = null, int $constructMode = 2): array static public function mergeQueryColumn(?array $reqColumns = null, GeneralQueryMode $queryMode = GeneralQueryMode::Full): array
{ {
$minimumColumn = ['no', 'name', 'npc', 'city', 'nation', 'officer_level', 'officer_city']; $minimumColumn = ['no', 'name', 'npc', 'city', 'nation', 'officer_level', 'officer_city'];
$defaultEventColumn = [ $defaultEventColumn = [
@@ -1023,52 +1048,84 @@ class General implements iAction
'personal', 'special', 'special2', 'defence_train', 'tnmt', 'npc', 'npc_org', 'deadyear', 'npcmsg', 'personal', 'special', 'special2', 'defence_train', 'tnmt', 'npc', 'npc_org', 'deadyear', 'npcmsg',
'dex1', 'dex2', 'dex3', 'dex4', 'dex5', 'betray', 'dex1', 'dex2', 'dex3', 'dex4', 'dex5', 'betray',
'recent_war', 'last_turn', 'myset', 'recent_war', 'last_turn', 'myset',
'specage', 'specage2', 'con', 'connect', 'aux', 'lastrefresh', 'permission', 'penalty', 'specage', 'specage2', 'aux', 'permission', 'penalty',
];
$fullAcessLogColumn = [
GeneralAccessLogColumn::refreshScore,
GeneralAccessLogColumn::refreshScoreTotal,
]; ];
if ($reqColumns === null) { if ($reqColumns === null) {
return [$fullColumn, RankColumn::cases()]; switch ($queryMode) {
case GeneralQueryMode::Core:
return [$minimumColumn, [], []];
case GeneralQueryMode::Lite:
return [$defaultEventColumn, [], []];
case GeneralQueryMode::FullWithoutIAction:
case GeneralQueryMode::Full:
return [$fullColumn, RankColumn::cases(), []];
case GeneralQueryMode::FullWithAccessLog:
return [$fullColumn, RankColumn::cases(), $fullAcessLogColumn];
}
} }
/** @var RankColumn[] */ /** @var RankColumn[] */
$rankColumn = []; $rankColumn = [];
$subColumn = []; $subColumn = [];
$accessLogColumn = [];
foreach ($reqColumns as $column) { foreach ($reqColumns as $column) {
if ($column instanceof RankColumn) { if ($column instanceof RankColumn) {
$rankColumn[] = $column; $rankColumn[] = $column;
continue; continue;
} }
if ($column instanceof GeneralAccessLogColumn) {
$rankKey = RankColumn::tryFrom($column); $accessLogColumn[] = $column;
if ($rankKey !== null) { continue;
$rankColumn[] = $rankKey;
} else {
$subColumn[] = $column;
} }
$enumKey = RankColumn::tryFrom($column);
if ($enumKey !== null) {
$rankColumn[] = $enumKey;
continue;
}
$enumKey = GeneralAccessLogColumn::tryFrom($column);
if ($enumKey !== null) {
$accessLogColumn[] = $enumKey;
continue;
}
$subColumn[] = $column;
} }
if ($constructMode > 1) { switch ($queryMode) {
return [array_unique(array_merge($defaultEventColumn, $subColumn)), $rankColumn]; case GeneralQueryMode::Core:
case GeneralQueryMode::Lite:
return [array_unique(array_merge($minimumColumn, $subColumn)), $rankColumn, $accessLogColumn];
case GeneralQueryMode::FullWithoutIAction:
case GeneralQueryMode::Full:
return [array_unique(array_merge($defaultEventColumn, $subColumn)), $rankColumn, $accessLogColumn];
case GeneralQueryMode::FullWithAccessLog:
return [array_unique(array_merge($fullColumn, $subColumn)), $rankColumn, array_unique(array_merge($fullAcessLogColumn, $accessLogColumn))];
default:
throw new \RuntimeException('invalid query mode');
} }
return [array_unique(array_merge($minimumColumn, $subColumn)), $rankColumn];
} }
/** /**
* @param ?int[] $generalIDList * @param ?int[] $generalIDList
* @param null|array<string|RankColumn> $column * @param null|array<string|RankColumn> $column
* @param int $constructMode * @param GeneralQueryMode $queryMode
* @return \sammo\General[] * @return \sammo\General[]
* @throws MustNotBeReachedException * @throws MustNotBeReachedException
*/ */
static public function createGeneralObjListFromDB(?array $generalIDList, ?array $column = null, int $constructMode = 2): array static public function createGeneralObjListFromDB(?array $generalIDList, ?array $column = null, GeneralQueryMode $queryMode = GeneralQueryMode::Full): array
{ {
if ($generalIDList === []) { if ($generalIDList === []) {
return []; return [];
} }
$db = DB::db(); $db = DB::db();
if ($constructMode > 0) { if ($queryMode->value > 0) {
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
[$year, $month] = $gameStor->getValuesAsArray(['year', 'month']); [$year, $month] = $gameStor->getValuesAsArray(['year', 'month']);
} else { } else {
@@ -1079,14 +1136,16 @@ class General implements iAction
/** /**
* @var string[] $column * @var string[] $column
* @var RankColumn[] $rankColumn * @var RankColumn[] $rankColumn
* @var GeneralAccessLogColumn[] $accessLogColumn
*/ */
[$column, $rankColumn] = static::mergeQueryColumn($column, $constructMode); [$column, $rankColumn, $accessLogColumn] = static::mergeQueryColumn($column, $queryMode);
if ($generalIDList === null) { if ($generalIDList === null) {
$rawGenerals = Util::convertArrayToDict( $rawGenerals = Util::convertArrayToDict(
$db->query('SELECT %l FROM general WHERE 1', Util::formatListOfBackticks($column)), $db->query('SELECT %l FROM general WHERE 1', Util::formatListOfBackticks($column)),
'no' 'no'
); );
$generalIDList = array_keys($rawGenerals); $generalIDList = array_keys($rawGenerals);
} else { } else {
$rawGenerals = Util::convertArrayToDict( $rawGenerals = Util::convertArrayToDict(
@@ -1114,25 +1173,42 @@ class General implements iAction
} }
} }
$rawAccessLogs = new Map();
if ($accessLogColumn) {
$rawValue = $db->query(
'SELECT `general_id`, %l FROM general_access_log WHERE general_id IN %li',
Util::formatListOfBackticks($accessLogColumn),
$generalIDList
);
foreach ($rawValue as $rawLog) {
$generalID = $rawLog['general_id'];
$logValue = new Map();
foreach ($rawLog as $key => $value) {
$logValue[GeneralAccessLogColumn::from($key)] = $value;
}
$rawAccessLogs[$generalID] = $logValue;
}
}
$result = []; $result = [];
foreach ($generalIDList as $generalID) { foreach ($generalIDList as $generalID) {
if (!key_exists($generalID, $rawGenerals)) { if (!key_exists($generalID, $rawGenerals)) {
$result[$generalID] = new DummyGeneral($constructMode > 0); $result[$generalID] = new DummyGeneral($queryMode->value > 0);
continue; continue;
} }
if ($rawRanks->hasKey($generalID) && $rawRanks[$generalID]->count() !== count($rankColumn)) { if ($rawRanks->hasKey($generalID) && $rawRanks[$generalID]->count() !== count($rankColumn)) {
throw new \RuntimeException('column의 수가 일치하지 않음 : ' . $generalID); throw new \RuntimeException('column의 수가 일치하지 않음 : ' . $generalID);
} }
$result[$generalID] = new static($rawGenerals[$generalID], $rawRanks[$generalID] ?? null, null, null, $year, $month, $constructMode > 1); $result[$generalID] = new static($rawGenerals[$generalID], $rawRanks[$generalID] ?? null, $rawAccessLogs[$generalID] ?? null, null, null, $year, $month, $queryMode->value >= GeneralQueryMode::Full->value);
} }
return $result; return $result;
} }
static public function createGeneralObjFromDB(int $generalID, ?array $column = null, int $constructMode = 2): self static public function createGeneralObjFromDB(int $generalID, ?array $column = null, GeneralQueryMode $queryMode = GeneralQueryMode::Full): self
{ {
$db = DB::db(); $db = DB::db();
if ($constructMode > 0) { if ($queryMode->value > 0) {
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
[$year, $month] = $gameStor->getValuesAsArray(['year', 'month']); [$year, $month] = $gameStor->getValuesAsArray(['year', 'month']);
} else { } else {
@@ -1143,12 +1219,39 @@ class General implements iAction
/** /**
* @var string[] $column * @var string[] $column
* @var RankColumn[] $rankColumn * @var RankColumn[] $rankColumn
* @var GeneralAccessLogCoumn[] $accessLogColumn
*/ */
[$column, $rankColumn] = static::mergeQueryColumn($column, $constructMode); [$column, $rankColumn, $accessLogColumn] = static::mergeQueryColumn($column, $queryMode);
/** @var Map<GeneralAccessLog,int>|null */
$rawAccessLog = null;
if (!$accessLogColumn) {
$rawGeneral = $db->queryFirstRow('SELECT %l FROM general WHERE no = %i', Util::formatListOfBackticks($column), $generalID);
} else {
$rawGeneral = $db->queryFirstRow(
'SELECT %l, %l FROM `general` LEFT JOIN general_access_log
ON general.no = general_access_log.general_id WHERE no = %i',
Util::formatListOfBackticks($column),
Util::formatListOfBackticks($accessLogColumn),
$generalID
);
$rawAccessLog = new Map();
foreach ($accessLogColumn as $accessLogKey) {
if (!key_exists($accessLogKey->value, $rawGeneral)) {
continue;
}
$rawAccessLog[$accessLogKey] = $rawGeneral[$accessLogKey->value];
unset($rawGeneral[$accessLogKey->value]);
}
if ($rawAccessLog->count() === 0) {
$rawAccessLog = null;
}
}
$rawGeneral = $db->queryFirstRow('SELECT %l FROM general WHERE no = %i', Util::formatListOfBackticks($column), $generalID);
if (!$rawGeneral) { if (!$rawGeneral) {
return new DummyGeneral($constructMode > 0); return new DummyGeneral($queryMode->value > 0);
} }
$rawRankValues = new Map(); $rawRankValues = new Map();
@@ -1165,7 +1268,7 @@ class General implements iAction
} }
$general = new static($rawGeneral, $rawRankValues, null, null, $year, $month, $constructMode > 1); $general = new static($rawGeneral, $rawRankValues, $rawAccessLog, null, null, $year, $month, $queryMode->value >= GeneralQueryMode::Full->value);
return $general; return $general;
} }
+1 -1
View File
@@ -3514,7 +3514,7 @@ class GeneralAI
$db = DB::db(); $db = DB::db();
$generalIDList = $db->queryFirstColumn('SELECT no FROM general WHERE nation = %i AND no != %i', $nationID, $this->general->getID()); $generalIDList = $db->queryFirstColumn('SELECT no FROM general WHERE nation = %i AND no != %i', $nationID, $this->general->getID());
$nationGenerals = General::createGeneralObjListFromDB($generalIDList, null, 2); $nationGenerals = General::createGeneralObjListFromDB($generalIDList);
$lastWar = \PHP_INT_MAX; $lastWar = \PHP_INT_MAX;
foreach ($nationGenerals as $nationGeneral) { foreach ($nationGenerals as $nationGeneral) {
+1 -1
View File
@@ -17,7 +17,7 @@ class InheritancePointManager
private function __construct() private function __construct()
{ {
$inheritanceKey = new Map(); $inheritanceKey = new Map();
$inheritanceKey->put(InheritanceKey::previous, new InheritancePointType(true, 1, '기존 포인트', 1)); $inheritanceKey->put(InheritanceKey::previous, new InheritancePointType(true, 1, '기존 보유', 1));
$inheritanceKey->put(InheritanceKey::lived_month, new InheritancePointType(true, 1, '생존', 1)); $inheritanceKey->put(InheritanceKey::lived_month, new InheritancePointType(true, 1, '생존', 1));
$inheritanceKey->put(InheritanceKey::max_belong, new InheritancePointType(false, 10, '최대 임관년 수', null)); $inheritanceKey->put(InheritanceKey::max_belong, new InheritancePointType(false, 10, '최대 임관년 수', null));
$inheritanceKey->put(InheritanceKey::max_domestic_critical, new InheritancePointType(true, 1, '최대 연속 내정 성공', null)); $inheritanceKey->put(InheritanceKey::max_domestic_critical, new InheritancePointType(true, 1, '최대 연속 내정 성공', null));
+1
View File
@@ -153,6 +153,7 @@ class Message
$db = DB::db(); $db = DB::db();
$now = new \DateTime(); $now = new \DateTime();
$row = $db->queryFirstRow('SELECT * FROM `message` WHERE `id` = %i AND valid_until', $messageID); $row = $db->queryFirstRow('SELECT * FROM `message` WHERE `id` = %i AND valid_until', $messageID);
//FIXME: $now가 들어가야 하는데 안 들어가있는데?
if (!$row) { if (!$row) {
return null; return null;
} }
+1 -1
View File
@@ -66,7 +66,7 @@ class RaiseInvaderMessage extends Message
} }
$gameStor = KVStorage::getStorage(DB::db(), 'game_env'); $gameStor = KVStorage::getStorage(DB::db(), 'game_env');
$general = \sammo\General::createGeneralObjFromDB($receiverID, null, 2); $general = \sammo\General::createGeneralObjFromDB($receiverID);
$logger = $general->getLogger(); $logger = $general->getLogger();
+1 -1
View File
@@ -280,7 +280,7 @@ class ResetHelper{
'msg'=>'공지사항',//TODO:공지사항 'msg'=>'공지사항',//TODO:공지사항
'maxgeneral'=>GameConst::$defaultMaxGeneral, 'maxgeneral'=>GameConst::$defaultMaxGeneral,
'maxnation'=>GameConst::$defaultMaxNation, 'maxnation'=>GameConst::$defaultMaxNation,
'conlimit'=>30000, 'refreshLimit'=>30000,
'develcost'=>$develcost, 'develcost'=>$develcost,
'turntime'=>$turntime, 'turntime'=>$turntime,
'starttime'=>$starttime, 'starttime'=>$starttime,
-1
View File
@@ -708,7 +708,6 @@ class GeneralBuilder{
'dex4'=>$this->dex4, 'dex4'=>$this->dex4,
'dex5'=>$this->dex5, 'dex5'=>$this->dex5,
'aux'=>\sammo\Json::encode($this->aux), 'aux'=>\sammo\Json::encode($this->aux),
'lastrefresh'=>TimeUtil::now(),
]); ]);
$this->generalID = $db->insertId(); $this->generalID = $db->insertId();
$turnRows = []; $turnRows = [];
+69 -37
View File
@@ -1,9 +1,11 @@
<?php <?php
namespace sammo; namespace sammo;
use sammo\Enums\MessageType; use sammo\Enums\MessageType;
class ScoutMessage extends Message{ class ScoutMessage extends Message
{
const ACCEPTED = 1; const ACCEPTED = 1;
const DECLINED = -1; const DECLINED = -1;
@@ -18,36 +20,36 @@ class ScoutMessage extends Message{
\DateTime $date, \DateTime $date,
\DateTime $validUntil, \DateTime $validUntil,
array $msgOption array $msgOption
) ) {
{ if ($msgType !== MessageType::private) {
if ($msgType !== MessageType::private){
throw new \InvalidArgumentException('DiplomaticMessage msgType'); throw new \InvalidArgumentException('DiplomaticMessage msgType');
} }
if(Util::array_get($msgOption['action']) !== 'scout'){ if (Util::array_get($msgOption['action']) !== 'scout') {
throw new \InvalidArgumentException('Action !== scout'); throw new \InvalidArgumentException('Action !== scout');
} }
parent::__construct(...func_get_args()); parent::__construct(...func_get_args());
if(Util::array_get($msgOption['used'])){ if (Util::array_get($msgOption['used'])) {
$this->validScout = false; $this->validScout = false;
} }
if($this->validUntil <= new \DateTime()){ if ($this->validUntil <= new \DateTime()) {
$this->validScout = false; $this->validScout = false;
} }
} }
protected function checkScoutMessageValidation(int $receiverID){ protected function checkScoutMessageValidation(int $receiverID)
if(!$this->validScout){ {
if (!$this->validScout) {
return [self::INVALID, '유효하지 않은 등용장입니다.']; return [self::INVALID, '유효하지 않은 등용장입니다.'];
} }
if($this->mailbox !== $this->dest->generalID){ if ($this->mailbox !== $this->dest->generalID) {
return [self::INVALID, '송신자가 등용장을 처리할 수 없습니다.']; return [self::INVALID, '송신자가 등용장을 처리할 수 없습니다.'];
} }
if($this->mailbox !== $receiverID){ if ($this->mailbox !== $receiverID) {
return [self::INVALID, '올바른 수신자가 아닙니다.']; return [self::INVALID, '올바른 수신자가 아닙니다.'];
} }
@@ -57,34 +59,35 @@ class ScoutMessage extends Message{
/** /**
* @return int 수행 결과 반환, ACCEPTED(등용장 소모), DECLINED(등용장 소모), INVALID 중 반환 * @return int 수행 결과 반환, ACCEPTED(등용장 소모), DECLINED(등용장 소모), INVALID 중 반환
*/ */
public function agreeMessage(int $receiverID, string &$reason):int{ public function agreeMessage(int $receiverID, string &$reason): int
{
//NOTE: 올바른 유저가 agreeMessage() 호출을 한건지는 외부에서 체크 필요(Session->userID 등) //NOTE: 올바른 유저가 agreeMessage() 호출을 한건지는 외부에서 체크 필요(Session->userID 등)
if(!$this->id){ if (!$this->id) {
throw new \RuntimeException('전송되지 않은 메시지에 수락 진행 중'); throw new \RuntimeException('전송되지 않은 메시지에 수락 진행 중');
} }
$gameStor = KVStorage::getStorage(DB::db(), 'game_env'); $gameStor = KVStorage::getStorage(DB::db(), 'game_env');
$general = \sammo\General::createGeneralObjFromDB($receiverID, null, 2); $general = \sammo\General::createGeneralObjFromDB($receiverID);
$logger = $general->getLogger(); $logger = $general->getLogger();
list($result, $reason) = $this->checkScoutMessageValidation($receiverID); list($result, $reason) = $this->checkScoutMessageValidation($receiverID);
if($result !== self::ACCEPTED){ if ($result !== self::ACCEPTED) {
$logger->pushGeneralActionLog("{$reason} 등용 수락 불가."); $logger->pushGeneralActionLog("{$reason} 등용 수락 불가.");
if($result === self::DECLINED){ if ($result === self::DECLINED) {
$this->_declineMessage(); $this->_declineMessage();
} }
return $result; return $result;
} }
$commandObj = buildGeneralCommandClass('che_등용수락', $general, $gameStor->getAll(true), [ $commandObj = buildGeneralCommandClass('che_등용수락', $general, $gameStor->getAll(true), [
'destNationID'=>$this->src->nationID, 'destNationID' => $this->src->nationID,
'destGeneralID'=>$this->src->generalID, 'destGeneralID' => $this->src->generalID,
]); ]);
if(!$commandObj->hasFullConditionMet()){ if (!$commandObj->hasFullConditionMet()) {
$logger->pushGeneralActionLog($commandObj->getFailString()); $logger->pushGeneralActionLog($commandObj->getFailString());
$reason = $commandObj->getFailString(); $reason = $commandObj->getFailString();
return self::DECLINED; return self::DECLINED;
@@ -96,6 +99,7 @@ class ScoutMessage extends Message{
//메시지 비 활성화 //메시지 비 활성화
$this->msgOption['used'] = true; $this->msgOption['used'] = true;
$this->invalidate(); $this->invalidate();
static::invalidateAll($this->src->generalID, $this->id);
$this->validScout = false; $this->validScout = false;
$josaRo = JosaUtil::pick($this->src->nationName, '로'); $josaRo = JosaUtil::pick($this->src->nationName, '로');
@@ -107,7 +111,7 @@ class ScoutMessage extends Message{
new \DateTime(), new \DateTime(),
new \DateTime('9999-12-31'), new \DateTime('9999-12-31'),
[ [
'delete'=>$this->id 'delete' => $this->id
] ]
); );
$newMsg->send(true); $newMsg->send(true);
@@ -115,7 +119,33 @@ class ScoutMessage extends Message{
return self::ACCEPTED; return self::ACCEPTED;
} }
protected function _declineMessage(){ public static function invalidateAll(int $generalID, ?int $exceptMsgID = null)
{
$db = DB::db();
$now = TimeUtil::now();
//XXX: 뭔가 기존 쿼리가 애매하다. invalid 관련해서 다른 옵션이 가능한가?
$rawMsgList = Util::convertArrayToDict($db->query(
'SELECT * FROM `message` WHERE
`mailbox` = %i AND `type` = "private" AND `dest` = `mailbox` AND `valid_until` > %s AND
JSON_VALUE(message, "$.option.action") = %s',
$generalID,
$now,
'scout',
), 'id');
if ($exceptMsgID && key_exists($exceptMsgID, $rawMsgList)) {
unset($rawMsgList[$exceptMsgID]);
}
if (!$rawMsgList) {
return;
}
foreach ($rawMsgList as $rawMsg) {
$msg = static::buildFromArray($rawMsg);
$msg->invalidate();
}
}
protected function _declineMessage()
{
$this->msgOption['used'] = true; $this->msgOption['used'] = true;
$this->invalidate(); $this->invalidate();
$this->validScout = false; $this->validScout = false;
@@ -129,7 +159,7 @@ class ScoutMessage extends Message{
new \DateTime(), new \DateTime(),
new \DateTime('9999-12-31'), new \DateTime('9999-12-31'),
[ [
'delete'=>$this->id 'delete' => $this->id
] ]
); );
$newMsg->send(true); $newMsg->send(true);
@@ -137,8 +167,9 @@ class ScoutMessage extends Message{
return self::DECLINED; return self::DECLINED;
} }
public function declineMessage(int $receiverID, string &$reason):int{ public function declineMessage(int $receiverID, string &$reason): int
if(!$this->id){ {
if (!$this->id) {
throw new \RuntimeException('전송되지 않은 메시지에 거절 진행 중'); throw new \RuntimeException('전송되지 않은 메시지에 거절 진행 중');
} }
@@ -148,7 +179,7 @@ class ScoutMessage extends Message{
list($result, $reason) = $this->checkScoutMessageValidation($receiverID); list($result, $reason) = $this->checkScoutMessageValidation($receiverID);
if($result === self::INVALID){ if ($result === self::INVALID) {
(new ActionLogger($receiverID, 0, $year, $month))->pushGeneralActionLog("{$reason} 등용 취소 불가.", ActionLogger::PLAIN); (new ActionLogger($receiverID, 0, $year, $month))->pushGeneralActionLog("{$reason} 등용 취소 불가.", ActionLogger::PLAIN);
return $result; return $result;
} }
@@ -162,9 +193,10 @@ class ScoutMessage extends Message{
return self::DECLINED; return self::DECLINED;
} }
public static function buildScoutMessage(int $srcGeneralID, int $destGeneralID, &$reason = null, \DateTime $date = null):?self{ public static function buildScoutMessage(int $srcGeneralID, int $destGeneralID, &$reason = null, \DateTime $date = null): ?self
if($srcGeneralID == $destGeneralID){ {
if($reason !== null){ if ($srcGeneralID == $destGeneralID) {
if ($reason !== null) {
$reason = '같은 장수에게 등용장을 보낼 수 없습니다'; $reason = '같은 장수에게 등용장을 보낼 수 없습니다';
} }
return null; return null;
@@ -173,26 +205,26 @@ class ScoutMessage extends Message{
$db = DB::db(); $db = DB::db();
$srcGeneral = $db->queryFirstRow('SELECT `name`, nation FROM general WHERE `no`=%i', $srcGeneralID); $srcGeneral = $db->queryFirstRow('SELECT `name`, nation FROM general WHERE `no`=%i', $srcGeneralID);
$destGeneral = $db->queryFirstRow('SELECT `name`, nation, `officer_level` FROM general WHERE `no`=%i', $destGeneralID); $destGeneral = $db->queryFirstRow('SELECT `name`, nation, `officer_level` FROM general WHERE `no`=%i', $destGeneralID);
if($date === null){ if ($date === null) {
$date = new \DateTime(); $date = new \DateTime();
} }
if($destGeneral['officer_level'] == 12){ if ($destGeneral['officer_level'] == 12) {
if($reason !== null){ if ($reason !== null) {
$reason = '군주에게 등용장을 보낼 수 없습니다'; $reason = '군주에게 등용장을 보낼 수 없습니다';
} }
return null; return null;
} }
if(!$srcGeneral['nation']){ if (!$srcGeneral['nation']) {
if($reason !== null){ if ($reason !== null) {
$reason = '재야 상태일 때에는 등용장을 보낼 수 없습니다'; $reason = '재야 상태일 때에는 등용장을 보낼 수 없습니다';
} }
return null; return null;
} }
if($srcGeneral['nation'] === $destGeneral['nation']){ if ($srcGeneral['nation'] === $destGeneral['nation']) {
if($reason !== null){ if ($reason !== null) {
$reason = '같은 소속의 장수에게 등용장을 보낼 수 없습니다'; $reason = '같은 소속의 장수에게 등용장을 보낼 수 없습니다';
} }
return null; return null;
@@ -222,9 +254,9 @@ class ScoutMessage extends Message{
$validUntil = new \DateTime("9999-12-31 12:59:59"); $validUntil = new \DateTime("9999-12-31 12:59:59");
$msgOption = [ $msgOption = [
'action'=>'scout' 'action' => 'scout'
]; ];
return new ScoutMessage(MessageType::private, $src, $dest, $msg, $date, $validUntil, $msgOption); return new ScoutMessage(MessageType::private, $src, $dest, $msg, $date, $validUntil, $msgOption);
} }
} }
+5 -1
View File
@@ -175,7 +175,9 @@ class TurnExecutionHelper
$general = $this->getGeneral(); $general = $this->getGeneral();
$generalID = $general->getID(); $generalID = $general->getID();
$logger = $general->getLogger(); $logger = $general->getLogger();
$general->setVar('con', 0); $db->update('general_access_log', [
'refresh_score' => 0,
], 'general_id=%i', $generalID);
$generalName = $general->getName(); $generalName = $general->getName();
@@ -194,6 +196,8 @@ class TurnExecutionHelper
$general->setVar('owner', 0); $general->setVar('owner', 0);
$general->setVar('defence_train', 80); $general->setVar('defence_train', 80);
$general->setVar('owner_name', null); $general->setVar('owner_name', null);
$db->delete('general_access_log', 'general_id=%i', $generalID);
} else { } else {
$general->applyDB($db); $general->applyDB($db);
$general->kill($db); $general->kill($db);
+5 -5
View File
@@ -3,7 +3,7 @@
$container-max-widths: ( $container-max-widths: (
md: 500px, md: 500px,
lg: 1020px, lg: 1000px,
xl: 1140px, xl: 1140px,
xxl: 1320px xxl: 1320px
); );
@@ -11,8 +11,8 @@ $container-max-widths: (
$grid-breakpoints: ( $grid-breakpoints: (
xs: 0, xs: 0,
sm: 520px, sm: 520px,
md: 900px, md: 760px,
lg: 992px, lg: 940px,
xl: 1200px, xl: 1200px,
xxl: 1400px xxl: 1400px
); );
@@ -24,7 +24,7 @@ $grid-breakpoints: (
} }
@mixin media-1000px{ @mixin media-1000px{
@media (min-width: map-get($grid-breakpoints, 'md')) { @media (min-width: map-get($grid-breakpoints, 'lg')) {
@content; @content;
} }
@@ -36,7 +36,7 @@ $grid-breakpoints: (
} }
@mixin media-500px{ @mixin media-500px{
@media (max-width: calc(map-get($grid-breakpoints, 'md') - .02px)) { @media (max-width: calc(map-get($grid-breakpoints, 'lg') - .02px)) {
@content; @content;
} }
} }
-5
View File
@@ -6,11 +6,6 @@
padding: 0; padding: 0;
} }
#app {
width: 100%;
}
@include media-1000px { @include media-1000px {
#container { #container {
width: 1000px; width: 1000px;
-5
View File
@@ -27,11 +27,6 @@
font-size: 1.4em; font-size: 1.4em;
} }
#app {
width: 100%;
overflow-x: hidden;
}
.tiptap-editor{ .tiptap-editor{
width: 100%; width: 100%;
overflow: hidden; overflow: hidden;
+1
View File
@@ -1,6 +1,7 @@
# #
DROP TABLE IF EXISTS general; DROP TABLE IF EXISTS general;
DROP TABLE IF EXISTS `general_turn`; DROP TABLE IF EXISTS `general_turn`;
DROP TABLE IF EXISTS `general_access_log`;
# #
DROP TABLE IF EXISTS nation; DROP TABLE IF EXISTS nation;
DROP TABLE IF EXISTS `nation_turn`; DROP TABLE IF EXISTS `nation_turn`;
+16 -17
View File
@@ -11,11 +11,6 @@ CREATE TABLE `general` (
`bornyear` INT(3) NULL DEFAULT '180', `bornyear` INT(3) NULL DEFAULT '180',
`deadyear` INT(3) NULL DEFAULT '300', `deadyear` INT(3) NULL DEFAULT '300',
`newmsg` INT(1) NULL DEFAULT '0', `newmsg` INT(1) NULL DEFAULT '0',
`con` INT(6) NOT NULL DEFAULT '0',
`connect` INT(6) NOT NULL DEFAULT '0',
`refresh` INT(6) NOT NULL DEFAULT '0',
`logcnt` INT(6) NULL DEFAULT '1',
`refcnt` INT(6) NULL DEFAULT '1',
`picture` VARCHAR(40) NOT NULL, `picture` VARCHAR(40) NOT NULL,
`imgsvr` INT(1) NOT NULL DEFAULT '0', `imgsvr` INT(1) NOT NULL DEFAULT '0',
`name` VARCHAR(32) NOT NULL COLLATE 'utf8mb4_bin', `name` VARCHAR(32) NOT NULL COLLATE 'utf8mb4_bin',
@@ -54,9 +49,6 @@ CREATE TABLE `general` (
`recent_war` DATETIME(6) NULL DEFAULT NULL, `recent_war` DATETIME(6) NULL DEFAULT NULL,
`makelimit` INT(2) NULL DEFAULT '0', `makelimit` INT(2) NULL DEFAULT '0',
`killturn` INT(3) NULL DEFAULT NULL, `killturn` INT(3) NULL DEFAULT NULL,
`lastconnect` DATETIME NULL DEFAULT NULL,
`lastrefresh` DATETIME NULL DEFAULT NULL,
`ip` VARCHAR(40) NULL DEFAULT '',
`block` INT(1) NULL DEFAULT '0', `block` INT(1) NULL DEFAULT '0',
`dedlevel` INT(2) NULL DEFAULT '0', `dedlevel` INT(2) NULL DEFAULT '0',
`explevel` INT(2) NULL DEFAULT '0', `explevel` INT(2) NULL DEFAULT '0',
@@ -87,7 +79,6 @@ CREATE TABLE `general` (
INDEX `officer_level` (`nation`, `officer_level`), INDEX `officer_level` (`nation`, `officer_level`),
INDEX `officer_city` (`officer_city`, `officer_level`), INDEX `officer_city` (`officer_city`, `officer_level`),
INDEX `name` (`name`), INDEX `name` (`name`),
INDEX `last_refresh` (`lastrefresh`),
CONSTRAINT `json1` CHECK (json_valid(`last_turn`)), CONSTRAINT `json1` CHECK (json_valid(`last_turn`)),
CONSTRAINT `json2` CHECK (json_valid(`aux`)), CONSTRAINT `json2` CHECK (json_valid(`aux`)),
CONSTRAINT `json3` CHECK (json_valid(`penalty`)) CONSTRAINT `json3` CHECK (json_valid(`penalty`))
@@ -100,9 +91,23 @@ CREATE TABLE `general_turn` (
`arg` TEXT NULL DEFAULT NULL COLLATE 'utf8mb4_bin', `arg` TEXT NULL DEFAULT NULL COLLATE 'utf8mb4_bin',
`brief` TEXT NULL DEFAULT NULL, `brief` TEXT NULL DEFAULT NULL,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
UNIQUE INDEX `general_id` (`general_id`, `turn_idx`), UNIQUE INDEX `general_id` (`general_id`, `turn_idx`)
INDEX `action` (`action`, `turn_idx`, `general_id`)
) COLLATE = 'utf8mb4_general_ci' ENGINE = Aria; ) COLLATE = 'utf8mb4_general_ci' ENGINE = Aria;
CREATE TABLE `general_access_log` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`general_id` INT(11) NOT NULL,
`user_id` INT(11) NULL DEFAULT NULL,
`last_refresh` DATETIME NULL DEFAULT NULL,
`refresh` INT(11) NOT NULL DEFAULT '0',
`refresh_total` INT(11) NOT NULL DEFAULT '0',
`refresh_score` INT(11) NOT NULL DEFAULT '0',
`refresh_score_total` INT(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE INDEX `general_id` (`general_id`)
)
COLLATE='utf8mb4_general_ci'
ENGINE=Aria;
############################## ##############################
## ##
############################## ##############################
@@ -144,12 +149,6 @@ CREATE TABLE `nation_turn` (
`brief` TEXT NULL DEFAULT NULL, `brief` TEXT NULL DEFAULT NULL,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
UNIQUE INDEX `nation` (`nation_id`, `officer_level`, `turn_idx`), UNIQUE INDEX `nation` (`nation_id`, `officer_level`, `turn_idx`),
INDEX `action` (
`action`,
`turn_idx`,
`nation_id`,
`officer_level`
),
CONSTRAINT `json` CHECK (json_valid(`arg`)) CONSTRAINT `json` CHECK (json_valid(`arg`))
) COLLATE = 'utf8mb4_general_ci' ENGINE = Aria; ) COLLATE = 'utf8mb4_general_ci' ENGINE = Aria;
############################## ##############################
+6 -3
View File
@@ -13,11 +13,14 @@ $gameStor = KVStorage::getStorage($db, 'game_env');
increaseRefresh("내무부", 1); increaseRefresh("내무부", 1);
$me = $db->queryFirstRow('SELECT no, nation, officer_level, permission, con, turntime, belong, penalty FROM general WHERE owner=%i', $userID); $me = $db->queryFirstRow(
'SELECT no, nation, officer_level, permission, refresh_score, turntime, belong, penalty FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$con = checkLimit($me['con']); $limitState = checkLimit($me['refresh_score']);
if ($con >= 2) { if ($limitState >= 2) {
printLimitMsg($me['turntime']); printLimitMsg($me['turntime']);
exit(); exit();
} }
+35 -35
View File
@@ -1,48 +1,48 @@
import chai, { assert } from "chai"; import chai, { assert } from "chai";
import _ from "lodash-es"; import _ from "lodash-es";
import { formatConnectScore } from "../ts/utilGame/formatConnectScore"; import { formatRefreshScore } from "../ts/utilGame/formatRefreshScore";
import { formatDexLevel } from "../ts/utilGame/formatDexLevel"; import { formatDexLevel } from "../ts/utilGame/formatDexLevel";
import { formatDefenceTrain } from "../ts/utilGame/formatDefenceTrain"; import { formatDefenceTrain } from "../ts/utilGame/formatDefenceTrain";
import { formatHonor } from "../ts/utilGame/formatHonor"; import { formatHonor } from "../ts/utilGame/formatHonor";
describe("formatConnectScore", () => { describe("formatRefreshScore", () => {
it("connectScoreEqual", () => { it("refreshScoreEqual", () => {
assert.equal(formatConnectScore(0), "안함"); assert.equal(formatRefreshScore(0), "안함");
assert.equal(formatConnectScore(50), "무관심"); assert.equal(formatRefreshScore(50), "무관심");
assert.equal(formatConnectScore(100), "보통"); assert.equal(formatRefreshScore(100), "보통");
assert.equal(formatConnectScore(200), "가끔"); assert.equal(formatRefreshScore(200), "가끔");
assert.equal(formatConnectScore(400), "자주"); assert.equal(formatRefreshScore(400), "자주");
assert.equal(formatConnectScore(800), "열심"); assert.equal(formatRefreshScore(800), "열심");
assert.equal(formatConnectScore(1600), "중독"); assert.equal(formatRefreshScore(1600), "중독");
assert.equal(formatConnectScore(3200), "폐인"); assert.equal(formatRefreshScore(3200), "폐인");
assert.equal(formatConnectScore(6400), "경고"); assert.equal(formatRefreshScore(6400), "경고");
assert.equal(formatConnectScore(12800), "헐..."); assert.equal(formatRefreshScore(12800), "헐...");
}); });
it("connectScore+1", () => { it("refreshScore+1", () => {
assert.equal(formatConnectScore(1), "안함"); assert.equal(formatRefreshScore(1), "안함");
assert.equal(formatConnectScore(51), "무관심"); assert.equal(formatRefreshScore(51), "무관심");
assert.equal(formatConnectScore(101), "보통"); assert.equal(formatRefreshScore(101), "보통");
assert.equal(formatConnectScore(201), "가끔"); assert.equal(formatRefreshScore(201), "가끔");
assert.equal(formatConnectScore(401), "자주"); assert.equal(formatRefreshScore(401), "자주");
assert.equal(formatConnectScore(801), "열심"); assert.equal(formatRefreshScore(801), "열심");
assert.equal(formatConnectScore(1601), "중독"); assert.equal(formatRefreshScore(1601), "중독");
assert.equal(formatConnectScore(3201), "폐인"); assert.equal(formatRefreshScore(3201), "폐인");
assert.equal(formatConnectScore(6401), "경고"); assert.equal(formatRefreshScore(6401), "경고");
assert.equal(formatConnectScore(12801), "헐..."); assert.equal(formatRefreshScore(12801), "헐...");
}); });
it("connectScoreF-1", () => { it("refreshScoreF-1", () => {
assert.equal(formatConnectScore(49), "안함"); assert.equal(formatRefreshScore(49), "안함");
assert.equal(formatConnectScore(99), "무관심"); assert.equal(formatRefreshScore(99), "무관심");
assert.equal(formatConnectScore(199), "보통"); assert.equal(formatRefreshScore(199), "보통");
assert.equal(formatConnectScore(399), "가끔"); assert.equal(formatRefreshScore(399), "가끔");
assert.equal(formatConnectScore(799), "자주"); assert.equal(formatRefreshScore(799), "자주");
assert.equal(formatConnectScore(1599), "열심"); assert.equal(formatRefreshScore(1599), "열심");
assert.equal(formatConnectScore(3199), "중독"); assert.equal(formatRefreshScore(3199), "중독");
assert.equal(formatConnectScore(6399), "폐인"); assert.equal(formatRefreshScore(6399), "폐인");
assert.equal(formatConnectScore(11799), "경고"); assert.equal(formatRefreshScore(11799), "경고");
assert.equal(formatConnectScore(20000), "헐..."); assert.equal(formatRefreshScore(20000), "헐...");
}); });
}); });
+9 -9
View File
@@ -3,10 +3,10 @@
<TopBackBar title="감찰부" :reloadable="true" type="close" @reload="reload" /> <TopBackBar title="감찰부" :reloadable="true" type="close" @reload="reload" />
<div class="row gx-0"> <div class="row gx-0">
<div class="col-2 col-md-1 d-grid"> <div class="col-2 col-lg-1 d-grid">
<BButton @click="changeTargetByOffset(-1)"> 이전</BButton> <BButton @click="changeTargetByOffset(-1)"> 이전</BButton>
</div> </div>
<div class="col-3 col-md-4"> <div class="col-3 col-lg-4">
<BFormSelect v-model="orderBy"> <BFormSelect v-model="orderBy">
<BFormSelectOption <BFormSelectOption
v-for="[orderKey, [orderName]] of Object.entries(textMap)" v-for="[orderKey, [orderName]] of Object.entries(textMap)"
@@ -17,7 +17,7 @@
</BFormSelectOption> </BFormSelectOption>
</BFormSelect> </BFormSelect>
</div> </div>
<div class="col-5 col-md-6"> <div class="col-5 col-lg-6">
<BFormSelect v-model="targetGeneralID"> <BFormSelect v-model="targetGeneralID">
<BFormSelectOption v-for="general of orderedGeneralList" :key="general.no" :value="general.no"> <BFormSelectOption v-for="general of orderedGeneralList" :key="general.no" :value="general.no">
<span <span
@@ -31,12 +31,12 @@
</BFormSelectOption> </BFormSelectOption>
</BFormSelect> </BFormSelect>
</div> </div>
<div class="col-2 col-md-1 d-grid"> <div class="col-2 col-lg-1 d-grid">
<BButton @click="changeTargetByOffset(1)">다음 </BButton> <BButton @click="changeTargetByOffset(1)">다음 </BButton>
</div> </div>
</div> </div>
<div v-if="targetGeneral && nationInfo && targetGeneralLogs" class="row gx-0 bg0"> <div v-if="targetGeneral && nationInfo && targetGeneralLogs" class="row gx-0 bg0">
<div class="col-12 col-md-6"> <div class="col-12 col-lg-6">
<div class="bg1 header-cell" style="color: skyblue">장수 정보</div> <div class="bg1 header-cell" style="color: skyblue">장수 정보</div>
<GeneralBasicCard <GeneralBasicCard
:general="targetGeneral" :general="targetGeneral"
@@ -46,22 +46,22 @@
/> />
<GeneralSupplementCard :general="targetGeneral" /> <GeneralSupplementCard :general="targetGeneral" />
</div> </div>
<div class="col-12 col-md-6"> <div class="col-12 col-lg-6">
<div class="bg1 header-cell">장수 열전</div> <div class="bg1 header-cell">장수 열전</div>
<!-- eslint-disable-next-line vue/no-v-html --> <!-- eslint-disable-next-line vue/no-v-html -->
<div v-for="[id, log] of targetGeneralLogs.generalHistory" :key="id" v-html="log" /> <div v-for="[id, log] of targetGeneralLogs.generalHistory" :key="id" v-html="log" />
</div> </div>
<div class="col-12 col-md-6"> <div class="col-12 col-lg-6">
<div class="bg1 header-cell">전투 기록</div> <div class="bg1 header-cell">전투 기록</div>
<!-- eslint-disable-next-line vue/no-v-html --> <!-- eslint-disable-next-line vue/no-v-html -->
<div v-for="[id, log] of targetGeneralLogs.battleDetail" :key="id" v-html="log" /> <div v-for="[id, log] of targetGeneralLogs.battleDetail" :key="id" v-html="log" />
</div> </div>
<div class="col-12 col-md-6"> <div class="col-12 col-lg-6">
<div class="bg1 header-cell">전투 결과</div> <div class="bg1 header-cell">전투 결과</div>
<!-- eslint-disable-next-line vue/no-v-html --> <!-- eslint-disable-next-line vue/no-v-html -->
<div v-for="[id, log] of targetGeneralLogs.battleResult" :key="id" v-html="log" /> <div v-for="[id, log] of targetGeneralLogs.battleResult" :key="id" v-html="log" />
</div> </div>
<div v-if="targetGeneralLogs.generalAction.size > 0" class="col-12 col-md-6"> <div v-if="targetGeneralLogs.generalAction.size > 0" class="col-12 col-lg-6">
<div class="bg1 header-cell">개인 기록</div> <div class="bg1 header-cell">개인 기록</div>
<!-- eslint-disable-next-line vue/no-v-html --> <!-- eslint-disable-next-line vue/no-v-html -->
<div v-for="[id, log] of targetGeneralLogs.generalAction" :key="id" v-html="log" /> <div v-for="[id, log] of targetGeneralLogs.generalAction" :key="id" v-html="log" />
+6 -6
View File
@@ -5,15 +5,15 @@
<div id="newArticle" class="bg0"> <div id="newArticle" class="bg0">
<div class="newArticleHeader bg2 center"> 게시물 작성</div> <div class="newArticleHeader bg2 center"> 게시물 작성</div>
<div class="row gx-0"> <div class="row gx-0">
<div class="col-2 col-md-1 articleTitle bg1 center">제목</div> <div class="col-2 col-lg-1 articleTitle bg1 center">제목</div>
<div class="col-10 col-md-11"> <div class="col-10 col-lg-11">
<!-- eslint-disable-next-line vue/max-attributes-per-line --> <!-- eslint-disable-next-line vue/max-attributes-per-line -->
<input v-model="newArticle.title" class="titleInput" type="text" maxlength="250" placeholder="제목" /> <input v-model="newArticle.title" class="titleInput" type="text" maxlength="250" placeholder="제목" />
</div> </div>
</div> </div>
<div class="row gx-0"> <div class="row gx-0">
<div class="col-2 col-md-1 bg1 center">내용</div> <div class="col-2 col-lg-1 bg1 center">내용</div>
<div class="col-10 col-md-11"> <div class="col-10 col-lg-11">
<textarea <textarea
ref="newArticleTextForm" ref="newArticleTextForm"
v-model="newArticle.text" v-model="newArticle.text"
@@ -24,8 +24,8 @@
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-8 col-md-10" /> <div class="col-8 col-lg-10" />
<div class="col-4 col-md-2 d-grid"> <div class="col-4 col-lg-2 d-grid">
<b-button id="submitArticle" @click="submitArticle"> 등록 </b-button> <b-button id="submitArticle" @click="submitArticle"> 등록 </b-button>
</div> </div>
</div> </div>

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