Compare commits

..
81 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
Hide_D 96643567d4 game: 애니집결 시나리오의 대사 빈도를 낮춤 2023-06-24 16:53:21 +00:00
Hide_D 0a6db3d21f fix: 이민족 발동시 서버 시간 변경 문제 2023-06-23 11:27:59 +00:00
Hide_D 8a4cbbb976 game: 애니집결 10차 시나리오 2023-06-23 19:28:28 +09:00
Hide_D 696ba0b341 fix(game): 병가의 세율에 따른 인구 증감이 '정수'로 고정되는 문제
- onCalcNationalIncome에서 pop은 0~0.125 사이임
2023-06-18 13:23:01 +09:00
Hide_D 4efcbaed6a misc: d_setting에 관련 코드가 추가되어 TODO 제거 2023-06-11 21:57:45 +09:00
Hide_D eda5ecb124 feat: d_setting에 ServerEnv 추가 2023-06-11 21:56:26 +09:00
Hide_D 0ef69178a5 feat: 이민족 발동 시 장수수에 따라 턴시간 조절 2023-06-11 21:44:22 +09:00
Hide_D 5596eca326 feat: 서버 제어용 변수 공간 추가 2023-06-11 21:40:07 +09:00
Hide_D af2dec7e2c refac: 턴시간 변경에 락 무시하는 기능 추가 2023-06-11 21:27:14 +09:00
Hide_D 435dae801f refac: _admin1 턴시간 변경을 changeServerTerm으로 이전 2023-06-11 21:25:53 +09:00
Hide_D 320c8191dc feat: ServerTool::changeServerTerm
- 서버 턴 시간을 바꾸는 명령
- 기존 _admin1.php
2023-06-11 21:24:53 +09:00
Hide_D 803e18e3c3 fix: 이민족 이벤트 종료시 메시지 2023-06-11 21:02:57 +09:00
Hide_D fbac218c34 fix: 이민족 발동 시, 초기 이성이 없으면 동작하지 않도록 2023-06-10 22:41:19 +09:00
Hide_D 2e6ea3a00d fix: isunited warning 수정 2023-06-08 23:31:46 +09:00
Hide_D 1f8812c939 fix: MAX_RNG_SUPPORT_BIT warning 2023-06-08 23:23:05 +09:00
Hide_D 44c2323883 fix: 임시 땜빵 베팅 2023-06-07 00:23:36 +09:00
Hide_D 82fb532e4b fix: 조사 (으)로 미 반영부분 수정 2023-06-06 16:51:42 +09:00
Hide_D ae6ca5c1ec fix: 성벽 선제 시 분쟁 대상이 도시로 나타나지 않는 버그 수정 2023-06-06 16:41:13 +09:00
Hide_D 30ac7da4d7 misc: 이민족 생성 시, 전쟁 금지 및 임관 금지 해제 2023-06-04 20:22:45 +09:00
Hide_D 8c30634fd1 fix: 리셋 시 최근 읽은 메시지 번호를 초기화해야 함 2023-06-03 10:58:15 +09:00
Hide_D 59761743dc misc: 이민족 소환 권한을 2명에게 부여 2023-05-22 21:56:15 +09:00
Hide_D 5952dba533 fix: 천통시 이민족 소환에 npc 여부를 제대로 계산하지 않는 문제 2023-05-22 21:52:35 +09:00
Hide_D 2518ac021d fix: ProvideNPCTroopLeader 경고 우회 2023-05-22 02:48:41 +09:00
Hide_D e656c1e567 fix: 천통시 이민족 권한을 유저에게 부여
- 군주가 NPC인 경우 참모
- 참모도 NPC라면 각 수뇌까지
2023-05-22 02:43:54 +09:00
Hide_D b89c045f85 feat: 천하통일 시 군주에세 이민족이 침입 이벤트 권한 부여
- 세가지 종류 난이도
  - 천통국가 기준 [장수 수, 종합 스탯, 기술 수치, 숙련 수치]
  - 어려움:  2배, 1.2배, 최고등급, 1배
  - 보통: 2배, 1.2배, 동일 기술, 0.5배
  - 쉬움: 1배, 1배, 20% 낮은 기술, 숙련 없음
- 이민족 멸망시 타 이민족으로 임관
2023-05-22 02:41:17 +09:00
Hide_D d347054ad0 feat: 이민족 침입 메시지 타입 추가 2023-05-22 02:38:35 +09:00
Hide_D 3ebc44ea5a fix: RaiseInvader의 중첩 호줄 대비
- isunited 변수를 빠르게 1로 설정
- 만약 RaiseInavder를 빠르게 두번 호출하더라도 isunited 변수를 검사하게 하여 대응 가능
2023-05-22 02:19:47 +09:00
Hide_D 57c8c3f6a4 feat: MessageType 간이 생성 함수 추가
- General 객체에서 생성
- 왜 여태까지 이 함수가 없었을까?
2023-05-22 02:15:45 +09:00
Hide_D fee769714d feat: System MessageTarget를 빠르게 생성하는 함수 2023-05-22 01:55:09 +09:00
Hide_D 9fcb24533a feat: sendPrivateMsgAsNotice 인자로 MessageTarget 추가 2023-05-22 01:44:25 +09:00
Hide_D 1061632290 feat: 단순한 공지용 개인 메시지 전송 기능 2023-05-22 01:41:35 +09:00
Hide_D 7dc297a266 fix: 성벽 선제 후 전투 종료시 점유율 관련 문제 2023-05-20 13:04:37 +09:00
Hide_D f019a642a2 fix: 구형 관리자 도구 warning 수정 2023-05-20 12:56:57 +09:00
Hide_D 5554ac3003 fix: 성벽 전투 반영 2023-05-20 03:37:09 +09:00
Hide_D 7f9ad8b7d5 fix: 정란/벽력의 성벽선제가 정상적으로 반영되지 않는 문제
- 수비/성벽
- 점유율
2023-05-20 01:03:19 +09:00
Hide_D 82af3a2e2d fix: 수비자에 수비 도시 정보가 입력되지 않는 버그 수정 2023-05-19 19:16:39 +09:00
Hide_D 7a4fcb30dc fix: 거울세계에서 국가 규모 승급이 일어나지 않던 버그 수정 2023-05-12 01:21:12 +09:00
180 changed files with 2178 additions and 1526 deletions
+2
View File
@@ -69,3 +69,5 @@ gateway/js/*
gateway/css/*
*.db-journal
d_log/cachegrind.*
+1 -1
View File
@@ -29,5 +29,5 @@
"josa",
"sammo"
],
"editor.tabSize": 2
"editor.tabSize": 4
}
+3 -3
View File
@@ -30,10 +30,10 @@ require(__DIR__ . '/../vendor/autoload.php');
<body>
<div class="container">
<h1 class="row justify-content-md-center">삼국지 모의전투 HiDCHe 설치</h1>
<div class="row justify-content-md-center">
<h1 class="row justify-content-lg-center">삼국지 모의전투 HiDCHe 설치</h1>
<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">
<h3 class="card-header">
설치(DB 설정)
+1 -22
View File
@@ -74,28 +74,7 @@ switch ($btn) {
case "120분턴": $turnterm = 120; break;
default: throw new \Exception("알 수 없는 턴 기간");
}
$oldunit = $admin['turnterm'] * 60;
$unit = $turnterm * 60;
$unitDiff = $unit / $oldunit;
$servTurnTime = new \DateTimeImmutable($admin['turntime']);
foreach ($db->query('SELECT no,turntime FROM general') as $gen) {
$genTurnTime = new \DateTimeImmutable($gen['turntime']);
$timeDiff = TimeUtil::DateIntervalToSeconds($genTurnTime->diff($servTurnTime));
$timeDiff *= $unitDiff;
$newGenTurnTime = $servTurnTime->add(TimeUtil::secondsToDateInterval($timeDiff));
$db->update('general', [
'turntime'=>$newGenTurnTime->format('Y-m-d H:i:s.u')
], 'no=%i', $gen['no']);
}
$turn = ($admin['year'] - $admin['startyear']) * 12 + $admin['month'] - 1;
$starttime = $servTurnTime->sub(TimeUtil::secondsToDateInterval($turn * $unit))->format('Y-m-d H:i:s');
$starttime = cutTurn($starttime, $turnterm, false);
$gameStor->turnterm = $turnterm;
$gameStor->starttime = $starttime;
pushGlobalHistoryLog(["<R>★</>턴시간이 <C>$btn</>으로 변경됩니다."]);
ServerTool::changeServerTerm($turnterm);
break;
}
+10 -10
View File
@@ -38,13 +38,13 @@ if ($genlist) {
}
switch ($btn) {
case "전체 접속허용":
$db->update('general', [
'con' => 0
$db->update('general_access_log', [
'refresh_score' => 0
], true);
break;
case "전체 접속제한":
$db->update('general', [
'con' => 1000
$db->update('general_access_log', [
'refresh_score' => 1000
], true);
break;
case "블럭 해제":
@@ -186,14 +186,14 @@ switch ($btn) {
], '`no` IN %li', $genlist);
break;
case "접속 허용":
$db->update('general', [
'con' => 0
], '`no` IN %li', $genlist);
$db->update('general_access_log', [
'refresh_score' => 0
], '`general_id` IN %li', $genlist);
break;
case "접속 제한":
$db->update('general', [
'con' => 1000
], '`no` IN %li', $genlist);
$db->update('general_access_log', [
'refresh_score' => 1000
], '`general_id` IN %li', $genlist);
break;
case "메세지 전달":
$text = $msg ?? '';
-133
View File
@@ -1,133 +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'
);
function colorBlockedName($general)
{
if (!$general['blocked']) {
return $general['name'];
}
return "<span style='color:magenta;'>{$general['name']}</span>";
}
?>
<!DOCTYPE html>
<html>
<head>
<title>멀티관리</title>
<meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" />
<?= WebUtil::printCSS('../d_shared/common.css') ?>
<?= WebUtil::printDist('ts', 'common', true) ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
</head>
<body>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td>멀 티 관 리<br><?= backButton() ?></td>
</tr>
</table>
<form name=form1 method=post action=_admin4_submit.php>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td width=80 align=center rowspan=3>회원선택<br><br>
<font color=cyan>NPC</font><br>
<font color=skyblue>NPC유저</font><br>
<font color=red>접속제한</font><br><b style=background-color:red;>블럭회원</b>
</td>
<td width=105 rowspan=3>
<?php
echo "
<select name=genlist[] size=20 multiple style='color:white;background-color:black;font-size:14px'>";
foreach ($db->query('SELECT no,name,npc,block,con from general where ip!=\'\' order by npc,ip') as $general) {
$style = "style=;";
if ($general['block'] > 0) {
$style .= "background-color:red;";
}
$npcColor = getNPCColor($general['npc']);
if($npcColor !== null){
$style .= "color:{$npcColor};";
}
echo "
<option value={$general['no']} $style>{$general['name']}</option>";
}
echo "
</select>";
?>
</td>
<td width=100 align=center>블럭</td>
<td width=504>
<input type=submit name=btn value='블럭 해제'><input type=submit name=btn value='1단계 블럭'><input type=submit name=btn value='2단계 블럭'><input type=submit name=btn value='3단계 블럭'><input type=submit name=btn value='무한삭턴'><br>
1단계:발언권, 2단계:턴블럭
</td>
</tr>
<tr>
<td align=center>강제 사망</td>
<td><input type=submit name=btn value='강제 사망'></td>
</tr>
<tr>
<td align=center>메세지 전달</td>
<td><input type=textarea size=60 maxlength=255 name=msg style=background-color:black;color:white;><input type=submit name=btn value='메세지 전달'></td>
</tr>
</table>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td align=center width=100>장수명</td>
<td align=center width=180>최근로그인</td>
<td align=center width=129>IP</td>
<td align=center width=100>ID</td>
</tr>
<?php foreach ($ipGroupList as $ipGroupC => $users) : ?>
<tr>
<td><?= join('<br>', array_map('\sammo\colorBlockedName', $users)) ?></td>
<td><?= join('<br>', array_column($users, 'lastconnect')) ?></td>
<td><?= join('<br>', array_column($users, 'ip')) ?></td>
<td><?= join('<br>', array_column($users, 'owner')) ?></td>
</tr>
<?php endforeach; ?>
</table>
<?php
//NOTE: password의 md5 해시가 같은지 확인하는 방식으로는 앞으로 잡아낼 수 없다. 폐기
?>
</form>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td><?= backButton() ?></td>
</tr>
<tr>
<td><?= banner() ?> </td>
</tr>
</table>
</body>
</html>
-86
View File
@@ -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[9] ?? '' ?> value=9>평지</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[14] ?? '' ?> value=14>궁숙</option>
<option <?= $sel[15] ?? '' ?> value=15>기숙</option>
@@ -105,8 +103,6 @@ $sel2[$type2] = "selected";
<table align=center width=1600 class="tb_layout bg0">
<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>
@@ -147,8 +143,6 @@ SELECT
A.gold,
A.rice,
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.dex2)) AS dex2,
ROUND(AVG(B.dex3)) AS dex3,
@@ -193,12 +187,6 @@ GROUP BY B.nation
case 10:
$query .= " order by avg(B.explevel) desc";
break;
case 11:
$query .= " order by avg(B.connect) desc";
break;
case 12:
$query .= " order by avg(B.con) desc";
break;
case 13:
$query .= " order by avg(B.dex1) desc";
break;
@@ -240,8 +228,6 @@ from city where nation=%i', $nation['nation']);
echo "
<tr>
<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;{$gen['cnt']}&nbsp;</td>
<td align=center>&nbsp;{$city['cnt']}&nbsp;</td>
+3 -1
View File
@@ -2,6 +2,8 @@
namespace sammo;
use sammo\Enums\GeneralQueryMode;
include "lib.php";
include "func.php";
@@ -74,7 +76,7 @@ if (!$gen) {
$gen = $generalBasicList[0]['no'];
}
$generalObj = General::createGeneralObjFromDB($gen);
$generalObj = General::createGeneralObjFromDB($gen, null, GeneralQueryMode::FullWithAccessLog);
?>
<!DOCTYPE html>
+16 -8
View File
@@ -16,10 +16,13 @@ $gameStor = KVStorage::getStorage($db, 'game_env');
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']);
if ($con >= 2) {
$limitState = checkLimit($me['refresh_score']);
if ($limitState >= 2) {
printLimitMsg($me['turntime']);
exit();
}
@@ -102,7 +105,7 @@ if ($gameStor->isunited) {
6 => ['dedication', true],
7 => ['officer_level', true],
8 => ['killturn', false],
9 => ['connect', true],
9 => ['refresh_score_total', true],
10 => ['experience', true],
11 => ['personal', true],
12 => ['special', true],
@@ -111,7 +114,12 @@ if ($gameStor->isunited) {
15 => ['npc', true],
][$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 "
<table align=center width=1000 class='tb_layout bg0'>
@@ -163,7 +171,7 @@ if ($gameStor->isunited) {
$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']);
echo "
@@ -192,8 +200,8 @@ if ($gameStor->isunited) {
<td align=center>$strength</td>
<td align=center>$intel</td>
<td align=center>{$general['killturn']}</td>
<td align=center>{$general['connect']}";
echo "<br>【" . getConnect($general['connect']) . "】</td>
<td align=center>" . $general['refresh_score_total'] ?? 0;
echo "<br>【" . getRefreshScoreText($general['refresh_score_total'] ?? 0) . "】</td>
</tr>";
}
echo "
+6 -3
View File
@@ -13,10 +13,13 @@ $gameStor = KVStorage::getStorage($db, 'game_env');
$gameStor->cacheValues(['killturn', 'autorun_user', 'turnterm']);
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']);
if ($con >= 2) {
$limitState = checkLimit($me['refresh_score']);
if ($limitState >= 2) {
printLimitMsg($me['turntime']);
exit();
}
+15 -8
View File
@@ -2,6 +2,8 @@
namespace sammo;
use sammo\Enums\GeneralAccessLogColumn;
include "lib.php";
include "func.php";
@@ -23,10 +25,10 @@ $online = [];
$curonline = getOnlineNum();
foreach ($log as $i => $value) {
$parse = Json::decode($value);
if(is_array($parse) === false){
if (is_array($parse) === false) {
continue;
}
if(count($parse) < 5){
if (count($parse) < 5) {
continue;
}
$date[$i] = $parse[0];
@@ -193,19 +195,24 @@ if ($admin['maxonline'] < $curonline) {
</td>
</tr>
<?php
$max_refresh = $db->queryFirstRow('SELECT sum(refresh) as refresh, sum(`connect`) as `connect` from general');
$max_refresh['name'] = '접속자 총합';
$totalRefresh = [
...$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) {
$w = round($user['refresh'] / max(1, $max_refresh['refresh']) * 100, 1);
foreach (array_merge([$totalRefresh], $top5Refresh) as $i => $user) {
$w = round($user['refresh'] / max(1, $totalRefresh['refresh']) * 100, 1);
$w2 = round(100 - $w, 1);
$color = getTrafficColor($w);
?>
<tr>
<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>
<?php if ($w == 0) : ?>
<?php elseif ($w < 10) : ?>
+9 -5
View File
@@ -2,6 +2,7 @@
namespace sammo;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\RankColumn;
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']);
$turnTerm = $admin['turnterm'];
$con = checkLimit($me['con']);
if ($con >= 2) {
$limitState = checkLimit($me['refresh_score']);
if ($limitState >= 2) {
printLimitMsg($me['turntime']);
exit();
}
@@ -107,7 +111,7 @@ if ($str3) {
?>
<!DOCTYPE html>
<html>
<?php if ($con == 1) {
<?php if ($limitState == 1) {
MessageBox("접속제한이 얼마 남지 않았습니다!");
} ?>
@@ -563,7 +567,7 @@ if ($str3) {
$tournamentRankerList = General::createGeneralObjListFromDB(
$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'],
0
GeneralQueryMode::Core
);
usort($tournamentRankerList, function (General $lhs, General $rhs) use ($gameColumn, $winColumn, $drawColumn, $loseColumn) {
$result = - ($lhs->getRankVar($gameColumn) <=> $rhs->getRankVar($gameColumn));
+2 -2
View File
@@ -211,7 +211,7 @@ $templates = new \League\Plates\Engine('templates');
$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) {
$generals = $db->query(
'SELECT %l from general where city=%i order by turntime',
@@ -327,7 +327,7 @@ $templates = new \League\Plates\Engine('templates');
if ($ourGeneral && !$isNPC) {
$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) {
$turnIdx = $turnRawIdx + 1;
$turnText[] = "{$turnIdx} : $turn";
+7 -4
View File
@@ -19,12 +19,15 @@ $gameStor = KVStorage::getStorage($db, 'game_env');
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']);
$con = checkLimit($me['con']);
if ($con >= 2) {
$limitState = checkLimit($me['refresh_score']);
if ($limitState >= 2) {
printLimitMsg($me['turntime']);
exit();
}
@@ -45,7 +48,7 @@ $templates = new \League\Plates\Engine('templates');
?>
<!DOCTYPE html>
<html>
<?php if ($con == 1) {
<?php if ($limitState == 1) {
MessageBox("접속제한이 얼마 남지 않았습니다!");
} ?>
+6 -4
View File
@@ -97,7 +97,7 @@ if ($gameStor->isunited) {
7 => ['gold', true],
8 => ['rice', true],
9 => ['crew', true],
10 => ['connect', true],
10 => ['refresh_score_total', true],
11 => ['personal', true],
12 => ['special', true],
13 => ['special2', true],
@@ -105,7 +105,9 @@ if ($gameStor->isunited) {
15 => ['npc', true],
][$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 "
<table align=center class='tb_layout bg0'>
@@ -173,8 +175,8 @@ if ($gameStor->isunited) {
<td align=center>" . displayCharInfo($general['personal']) . "</td>
<td align=center>" . displaySpecialDomesticInfo($general['special']) . " / " . displaySpecialWarInfo($general['special2']) . "</td>
<td align=center>{$general['belong']}</td>
<td align=center>{$general['connect']}";
echo "<br>(" . getConnect($general['connect']) . ")</td>
<td align=center>". $general['refresh_score_total'] ?? 0;
echo "<br>(" . getRefreshScoreText($general['refresh_score_total'] ?? 0) . ")</td>
</tr>";
}
echo "
+19 -8
View File
@@ -2,6 +2,10 @@
namespace sammo;
use sammo\Enums\GeneralAccessLogColumn;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\TableName;
include "lib.php";
include "func.php";
@@ -20,7 +24,7 @@ $gameStor->cacheValues(['turntime', 'opentime', 'autorun_user', 'npcmode']);
increaseRefresh("내정보", 1);
$me = General::createGeneralObjFromDB($generalID);
$me = General::createGeneralObjFromDB($generalID, null, GeneralQueryMode::FullWithAccessLog);
$myset = $me->getVar('myset');
if ($myset > 0) {
@@ -29,7 +33,14 @@ if ($myset > 0) {
$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 ($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>
<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="col"><?php generalInfo($me); ?><?php generalInfo2($me); ?></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="col" style='padding-left:2ch;'>
토너먼트 【
@@ -178,7 +189,7 @@ $use_auto_nation_turn = $me->getAuxVar('use_auto_nation_turn') ?? 1;
</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="col bg1 text-center">
<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>
</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="col bg1 text-center">
<h4 style='color:orange'>전투 기록</h4>
@@ -205,7 +216,7 @@ $use_auto_nation_turn = $me->getAuxVar('use_auto_nation_turn') ?? 1;
</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="col bg1 text-center">
<h4 style='color:skyblue'>장수 열전</h4>
@@ -215,7 +226,7 @@ $use_auto_nation_turn = $me->getAuxVar('use_auto_nation_turn') ?? 1;
<?= formatHistoryToHTML(getGeneralHistoryLogAll($generalID)) ?>
</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="col bg1 text-center">
<h4 style='color:orange'>전투 결과</h4>
+7 -5
View File
@@ -14,14 +14,16 @@ $gameStor = KVStorage::getStorage($db, 'game_env');
increaseRefresh("토너먼트", 1);
TurnExecutionHelper::executeAllCommand();
$me = $db->queryFirstRow('select no,tournament,con,turntime from general where owner=%i', $userID);
$generalID = $session->generalID;
$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', 'turnterm', 'tnmt_msg', 'tnmt_type', 'develcost', 'tnmt_trig']);
$turnTerm = $admin['turnterm'];
$con = checkLimit($me['con']);
if ($con >= 2) {
$limitState = checkLimit($me['refresh_score']);
if ($limitState >= 2) {
printLimitMsg($me['turntime']);
exit();
}
@@ -100,7 +102,7 @@ $globalBetTotal = array_sum($globalBet);
?>
<!DOCTYPE html>
<html>
<?php if ($con == 1) {
<?php if ($limitState == 1) {
MessageBox("접속제한이 얼마 남지 않았습니다! 제한량이 모자라다면 참여를 해보세요^^");
} ?>
+6
View File
@@ -0,0 +1,6 @@
<?php
namespace sammo;
class ServerEnv extends ServerDefaultEnv {
//ServerEnv 기본값을 변경하고 싶다면 orig를 제거한 복사본을 만들고 수정
}
+75 -65
View File
@@ -5,6 +5,9 @@ namespace sammo;
use DateTime;
use Ds\Set;
use sammo\Enums\AuctionType;
use sammo\Enums\GeneralAccessLogColumn;
use sammo\Enums\GeneralColumn;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\InheritanceKey;
use sammo\Enums\RankColumn;
@@ -103,10 +106,9 @@ function GetImageURL($imgsvr, $filepath = '')
}
/**
* @param null|int $con 장수의 벌점
* @param null|int $conlimit 최대 벌점
* @param null|int $refreshScore 장수의 벌점
*/
function checkLimit($con = null)
function checkLimit($refreshScore = null)
{
$session = Session::getInstance();
if ($session->userGrade >= 4) {
@@ -116,15 +118,15 @@ function checkLimit($con = null)
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
if ($con === null) {
$con = $db->queryFirstField('SELECT con FROM general WHERE `owner`=%i', Session::getUserID());
if ($refreshScore === null) {
$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;
//접속제한 90%이면 경고문구
} elseif ($con > $conlimit * 0.9) {
} elseif ($refreshScore > $refreshLimit * 0.9) {
return 1;
} else {
return 0;
@@ -642,7 +644,7 @@ function generalInfo(General $generalObj)
$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
? "{$generalObj->getVar('specage')}세"
: "<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;' colspan=3>{$troopInfo}</td>
<td style='text-align:center;' class='bg1'><b>벌점</b></td>
<td style='text-align:center;' colspan=5>" . getConnect($connectCnt) . " {$connectCnt}({$generalObj->getVar('con')})</td>
<td style='text-align:center;' colspan=5>" . getRefreshScoreText($refreshScoreTotal) . " {$refreshScoreTotal}({$generalObj->getAccessLogVar(GeneralAccessLogColumn::refreshScore)})</td>
</tr>
</table>";
}
@@ -998,52 +1000,69 @@ function increaseRefresh($type = "", $cnt = 1)
$generalID = $session->generalID;
$userGrade = $session->userGrade;
$date = TimeUtil::now();
$dateObj = new \DateTimeImmutable();
$date = TimeUtil::format($dateObj, false);
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$isunited = $gameStor->isunited;
$opentime = $gameStor->opentime;
if($userGrade == 6){
if ($userGrade == 6) {
return;
}
if($isunited == 2){
if ($isunited == 2) {
return;
}
if(!$generalID){
if (!$generalID) {
return;
}
if($opentime > $date){
if ($opentime > $date) {
return;
}
$gameStor->refresh = $gameStor->refresh + $cnt; //TODO: +로 증가하는 값은 별도로 분리
$db->update('general', [
'lastrefresh' => $date,
'con' => $db->sqleval('con + %i', $cnt),
'connect' => $db->sqleval('connect + %i', $cnt),
'refcnt' => $db->sqleval('refcnt + %i', $cnt),
'refresh' => $db->sqleval('refresh + %i', $cnt)
], 'owner=%i', $userID);
$db->insertUpdate('general_access_log', [
GeneralAccessLogColumn::generalID->value => $generalID,
GeneralAccessLogColumn::userID->value => $userID,
GeneralAccessLogColumn::lastRefresh->value => $date,
GeneralAccessLogColumn::refreshTotal->value => $cnt,
GeneralAccessLogColumn::refresh->value => $cnt,
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');
$date2 = substr($date, 0, 10);
$online = getOnlineNum();
file_put_contents(
__DIR__ . "/logs/" . UniqueConst::$serverID . "/_{$date2}_refresh.txt",
sprintf(
"%s, %s, %s, %s, %s, %d\n",
$date,
$session->userName,
$session->generalName,
$session->ip,
$type,
$online
),
FILE_APPEND
);
$serverPath = __DIR__;
$serverID = UniqueConst::$serverID;
$logPath = "{$serverPath}/logs/{$serverID}/api_log.db";
$logDB = FileDB::db($logPath, $serverPath . '/../f_install/sql/api_log.sql');
$ip = $_SERVER['REMOTE_ADDR'] ?? 'local';
$date = date('Y-m-d H:i:s');
$logDB->insert('api_log', [
'user_id' => $session->userID,
'ip' => $ip,
'date' => $date,
'path' => "refresh",
'arg' => JSON::encode([
'type' => $type,
]),
'aux' => JSON::encode([
'generalID' => $generalID,
'generalName' => $session->generalName,
'userName' => $session->userName,
]),
]);
}
function updateTraffic()
@@ -1054,9 +1073,6 @@ function updateTraffic()
$admin = $gameStor->getValues(['year', 'month', 'refresh', 'maxonline', 'maxrefresh']);
/** @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']) {
$admin['maxrefresh'] = $admin['refresh'];
}
@@ -1067,22 +1083,7 @@ function updateTraffic()
$gameStor->maxrefresh = $admin['maxrefresh'];
$gameStor->maxonline = $admin['maxonline'];
$db->update('general', ['refresh' => 0], true);
$date = TimeUtil::now();
//일시|년|월|총갱신|접속자|최다갱신자
file_put_contents(
__DIR__ . "/logs/" . UniqueConst::$serverID . "/_traffic.txt",
Json::encode([
$date,
$admin['year'],
$admin['month'],
$admin['refresh'],
$online,
$user['name'] . "(" . $user['refresh'] . ")"
]) . "\n",
FILE_APPEND
);
$db->update('general_access_log', ['refresh' => 0], true);
}
function CheckOverhead()
@@ -1090,13 +1091,13 @@ function CheckOverhead()
//서버정보
$db = DB::db();
$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) {
$gameStor->conlimit = $con;
if ($nextRefreshLimit != $refreshLimit) {
$gameStor->refreshLimit = $nextRefreshLimit;
}
}
@@ -1200,7 +1201,16 @@ function updateOnline()
//동접수
$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);
$onlineNationUsers = Util::arrayGroupBy($onlineUser, 'nation');
@@ -1314,7 +1324,7 @@ function CheckHall($no)
["betrate", 'calc'],
];
$generalObj = General::createGeneralObjFromDB($no, null, 2);
$generalObj = General::createGeneralObjFromDB($no);
$ttw = $generalObj->getRankVar(RankColumn::ttw);
$ttd = $generalObj->getRankVar(RankColumn::ttd);
@@ -1711,7 +1721,7 @@ function deleteNation(General $lord, bool $applyDB): array
$lordID
),
['npc', 'owner', 'gold', 'rice', 'experience', 'explevel', 'dedication', 'dedlevel', 'belong', 'aux'],
1
GeneralQueryMode::Lite,
);
$nationGeneralList[$lordID] = $lord;
@@ -1728,7 +1738,7 @@ function deleteNation(General $lord, bool $applyDB): array
// 전 장수 재야로
foreach ($nationGeneralList as $general) {
if($general->getNPCType() < 2){
if ($general->getNPCType() < 2) {
$general->setAuxVar(
InheritanceKey::max_belong->value,
max(
+12 -12
View File
@@ -133,19 +133,19 @@ function getNationType(?string $type) {
}
function getConnect($con) {
if($con < 50) $conname = '안함';
elseif($con < 100) $conname = '무관심';
elseif($con < 200) $conname = '가끔';
elseif($con < 400) $conname = '보통';
elseif($con < 800) $conname = '자주';
elseif($con < 1600) $conname = '열심';
elseif($con < 3200) $conname = '중독';
elseif($con < 6400) $conname = '폐인';
elseif($con < 12800) $conname = '경고';
else $conname = '헐...';
function getRefreshScoreText($score) {
if($score < 50) $scoreName = '안함';
elseif($score < 100) $scoreName = '무관심';
elseif($score < 200) $scoreName = '가끔';
elseif($score < 400) $scoreName = '보통';
elseif($score < 800) $scoreName = '자주';
elseif($score < 1600) $scoreName = '열심';
elseif($score < 3200) $scoreName = '중독';
elseif($score < 6400) $scoreName = '폐인';
elseif($score < 12800) $scoreName = '경고';
else $scoreName = '헐...';
return $conname;
return $scoreName;
}
function getNationType2(?string $type) {
+34 -5
View File
@@ -202,8 +202,10 @@ function preUpdateMonthly()
$admin = $gameStor->getValues(['startyear', 'year', 'month']);
//접률감소, 건국제한-1
$db->update('general_access_log', [
'refresh_score_total' => $db->sqleval('floor(refresh_score_total*0.99)'),
], true);
$db->update('general', [
'connect' => $db->sqleval('floor(connect*0.99)'),
'makelimit' => $db->sqleval('greatest(0, makelimit - 1)'),
], true);
//전략제한-1, 외교제한-1, 세율동기화
@@ -301,7 +303,6 @@ function postUpdateMonthly(RandUtil $rng)
WHERE g.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(avg(connect)) from general where nation=A.nation)
)/10)
as power,
(select sum(crew) from general where nation=A.nation) as totalCrew
@@ -697,7 +698,7 @@ function checkEmperior()
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$admin = $gameStor->getValues(['year', 'month', 'isunited', 'conlimit']);
$admin = $gameStor->getValues(['year', 'month', 'isunited', 'refreshLimit']);
if ($admin['isunited'] != 0) {
return;
}
@@ -759,7 +760,7 @@ function checkEmperior()
}
$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) {
CheckHall($hallGeneralNo);
@@ -771,7 +772,7 @@ function checkEmperior()
$chiefs = Util::convertArrayToDict(
$db->query(
'SELECT no,name,picture,belong,officer_level FROM general WHERE nation=%i AND officer_level >= 5',
'SELECT no,npc,name,picture,belong,officer_level FROM general WHERE nation=%i AND officer_level >= 5',
$nationID
),
'officer_level'
@@ -908,6 +909,34 @@ function checkEmperior()
//연감 월결산
LogHistory();
$availableInvaderGame = false;
foreach(CityConst::all() as $city){
if($city->level == 4){
$availableInvaderGame = true;
break;
}
}
if($availableInvaderGame){
$invaderMsgCnt = 2;
foreach(range(12, 5, -1) as $chiefLevel){
if(!key_exists($chiefLevel, $chiefs)){
continue;
}
$targetChief = $chiefs[$chiefLevel];
if($targetChief['npc'] >= 2){
continue;
}
$invaderMsgs = RaiseInvaderMessage::buildRaiseInvaderMessage($targetChief['no']);
foreach($invaderMsgs as $invaderMsg){
$invaderMsg->send();
}
$invaderMsgCnt--;
if($invaderMsgCnt <= 0){
break;
}
}
}
}
function updateMaxDomesticCritical(General $general, $score)
+1 -1
View File
@@ -383,7 +383,7 @@ function disaster(RandUtil $rng) {
$generalList = array_map(
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']]??[]
);
+2 -2
View File
@@ -39,8 +39,8 @@ if ($session->userGrade < 5 && !$allowReset) {
<body>
<div class="container">
<h1 class="row justify-content-md-center">삼국지 모의전투 HiDCHe 리셋</h1>
<div class="row justify-content-md-center">
<h1 class="row justify-content-lg-center">삼국지 모의전투 HiDCHe 리셋</h1>
<div class="row justify-content-lg-center">
<div class="col col-lg-8">
<div class="card" id="game_form_card">
+2 -2
View File
@@ -32,8 +32,8 @@ if ($session->userGrade == 5) {
<body>
<div class="container" style="min-width:720px;">
<h1 class="row justify-content-md-center">삼국지 모의전투 HiDCHe 리셋</h1>
<div class="row justify-content-md-center">
<h1 class="row justify-content-lg-center">삼국지 모의전투 HiDCHe 리셋</h1>
<div class="row justify-content-lg-center">
<div class="col col-lg-8">
<div class="card" id="db_form_card">
+7 -4
View File
@@ -17,10 +17,13 @@ $text = Util::getPost('text');
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']);
if ($con >= 2) {
$limitState = checkLimit($me['refresh_score']);
if ($limitState >= 2) {
Json::die([
'result'=>false,
'reason'=>'접속 제한입니다.'
@@ -50,7 +53,7 @@ if($permission < 0){
'result'=>false,
'reason'=>'국가에 소속되어있지 않습니다.'
]);
}
else if ($isSecretBoard && $permission < 2) {
Json::die([
+7 -4
View File
@@ -16,10 +16,13 @@ $text = Util::getPost('text');
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']);
if ($con >= 2) {
$limitState = checkLimit($me['refresh_score']);
if ($limitState >= 2) {
Json::die([
'result'=>false,
'reason'=>'접속 제한입니다.'
@@ -58,7 +61,7 @@ if($permission < 0){
'result'=>false,
'reason'=>'국가에 소속되어있지 않습니다.'
]);
}
else if ($isSecretBoard && $permission < 2) {
Json::die([
+7 -5
View File
@@ -16,11 +16,14 @@ $isSecretBoard = Util::getPost('isSecret', 'bool', false);
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']);
if ($con >= 2) {
$limitState = checkLimit($me['refresh_score']);
if ($limitState >= 2) {
Json::die([
'result'=>false,
'reason'=>'접속 제한입니다.'
@@ -33,7 +36,7 @@ if($permission < 0){
'result'=>false,
'reason'=>'국가에 소속되어있지 않습니다.'
]);
}
else if ($isSecretBoard && $permission < 2) {
Json::die([
@@ -72,4 +75,3 @@ Json::die([
'articles'=>$articles,
'reason'=>'success'
]);
+6 -3
View File
@@ -17,10 +17,13 @@ $letterNo = Util::getPost('letterNo', 'int');
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']);
if ($con >= 2) {
$limitState = checkLimit($me['refresh_score']);
if ($limitState >= 2) {
Json::die([
'result'=>false,
'reason'=>'접속 제한입니다.'
+7 -5
View File
@@ -16,11 +16,14 @@ $isSecretBoard = Util::getPost('isSecret', 'bool', false);
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']);
if ($con >= 2) {
$limitState = checkLimit($me['refresh_score']);
if ($limitState >= 2) {
Json::die([
'result'=>false,
'reason'=>'접속 제한입니다.'
@@ -33,7 +36,7 @@ if($permission < 0){
'result'=>false,
'reason'=>'국가에 소속되어있지 않습니다.'
]);
}
$letters = [];
@@ -83,4 +86,3 @@ Json::die([
'myNationID'=>$me['nation'],
'reason'=>'success'
]);
+6 -3
View File
@@ -22,10 +22,13 @@ $reason = Util::getPost('reason', 'string', '');
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']);
if ($con >= 2) {
$limitState = checkLimit($me['refresh_score']);
if ($limitState >= 2) {
Json::die([
'result'=>false,
'reason'=>'접속 제한입니다.'
+6 -3
View File
@@ -17,10 +17,13 @@ $letterNo = Util::getPost('letterNo', 'int');
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']);
if ($con >= 2) {
$limitState = checkLimit($me['refresh_score']);
if ($limitState >= 2) {
Json::die([
'result'=>false,
'reason'=>'접속 제한입니다.'
+6 -3
View File
@@ -24,10 +24,13 @@ if($prevNo < 1){
$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']);
if ($con >= 2) {
$limitState = checkLimit($me['refresh_score']);
if ($limitState >= 2) {
Json::die([
'result'=>false,
'reason'=>'접속 제한입니다.'
+7 -4
View File
@@ -33,12 +33,15 @@ if($generalID <= 0 || $reqTo <= 0){
$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'];
$con = checkLimit($me['con']);
if ($con >= 2) {
$limitState = checkLimit($me['refresh_score']);
if ($limitState >= 2) {
Json::die([
'result'=>false,
'reason'=>'접속 제한입니다.'
@@ -61,7 +64,7 @@ if($generalID !== $targetID){
'reason'=>'권한이 부족합니다. 수뇌부가 아니거나 사관년도가 부족합니다.'
]);
}
if($testGeneralNationID !== $nationID){
Json::die([
'result'=>false,
+2 -1
View File
@@ -1,6 +1,7 @@
<?php
namespace sammo;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\MessageType;
include "lib.php";
@@ -50,7 +51,7 @@ else{
'troop','officer_level','npc','picture','imgsvr',
'permission','penalty','belong', 'crewtype',
'experience', 'dedication', 'betray', 'dedlevel', 'explevel', 'makelimit', 'aux',
], 1);
], GeneralQueryMode::Lite);
if($general instanceof DummyGeneral){
Json::die([
+7
View File
@@ -1,6 +1,8 @@
<?php
namespace sammo;
use sammo\Enums\GeneralAccessLogColumn;
include "lib.php";
include "func.php";
@@ -86,6 +88,11 @@ $db->update('general', [
'owner'=>$userID,
'aux'=>Json::encode($genAux)
], '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()){
Json::die([
+4 -1
View File
@@ -39,7 +39,10 @@ if (!$data || !is_array($data)) {
$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'];
+4 -4
View File
@@ -270,7 +270,7 @@ if (key_exists('inheritBuff', $rawAttacker)) {
}
$rawAttacker['aux'] = Json::encode($rawAttacker['aux']);
$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(
$tmpRNG,
$attackerGeneral,
@@ -308,7 +308,7 @@ foreach ($rawDefenderList as $idx => $rawDefenderGeneral) {
$rawDefenderGeneral['aux'] = Json::encode($rawDefenderGeneral['aux']);
$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(
$tmpRNG,
@@ -382,7 +382,7 @@ function simulateBattle(
$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(
$warRng,
$attackerGeneral,
@@ -395,7 +395,7 @@ function simulateBattle(
$defenderList = [];
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(
$warRng,
+30 -28
View File
@@ -3,6 +3,7 @@
namespace sammo;
use sammo\DTO\VoteInfo;
use sammo\Enums\GeneralQueryMode;
include "lib.php";
include "func.php";
@@ -29,7 +30,8 @@ if (!$session->isGameLoggedIn()) {
}
$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
);
@@ -51,13 +53,13 @@ if ($me['newmsg'] == 1 || $me['newvote'] == 1) {
$plock = boolval($db->queryFirstField('SELECT plock FROM plock WHERE `type`="GAME" LIMIT 1'));
$con = checkLimit($me['con']);
if ($con >= 2) {
$limitState = checkLimit($me['refresh_score']);
if ($limitState >= 2) {
printLimitMsg($me['turntime']);
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()));
$scenario = $gameStor->scenario_text;
@@ -180,44 +182,44 @@ if ($lastVoteID) {
</div>
<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 ?>
</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 ?>
</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 ?>
</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) ?>
</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 ?>
</div>
<div class="s-border-t col py-2 col-8 col-md-4"><?= info(2) ?></div>
<div class="s-border-t col py-2 col-4 col-md-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-8 col-md-4"><?= info(3) ?></div>
<div class="s-border-t py-2 col col-6 col-md-4">
<div class="s-border-t col py-2 col-8 col-lg-4"><?= info(2) ?></div>
<div class="s-border-t col py-2 col-4 col-lg-2">전체 접속자 수 : <?= $gameStor->online_user_cnt ?> 명</div>
<div class="s-border-t col py-2 col-4 col-lg-2">턴당 갱신횟수 : <?= $gameStor->refreshLimit ?>회</div>
<div class="s-border-t col py-2 col-8 col-lg-4"><?= info(3) ?></div>
<div class="s-border-t py-2 col col-6 col-lg-4">
<?php if ($isTournamentActive) : ?>
↑<span style='color:cyan'><?= (['전력전', '통솔전', '일기토', '설전',])[$gameStor->tnmt_type] ?? '' ?> <?= getTournament($gameStor->tournament) ?> <?= getTournamentTime() ?></span>↑
<?php else : ?>
<span style='color:magenta'>현재 토너먼트 경기 없음</span>
<?php endif; ?>
</div>
<div class="s-border-t py-2 col col-6 col-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>
<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) : ?>
<span style='color:cyan'><?= $auctionCount ?>건</span> 거래 진행중
<?php else : ?>
<span style='color:magenta'>진행중 거래 없음</span>
<?php endif; ?>
</div>
<div class="s-border-t py-2 col col-6 col-md-4 vote-cell">
<div class="s-border-t py-2 col col-6 col-lg-4 vote-cell">
<?php
?>
<?php if ($lastVote === null) : ?>
@@ -310,11 +312,11 @@ if ($lastVoteID) {
</div>
</div>
<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 id="general_public_record" style="text-align:left;"><?= formatHistoryToHTML(getGlobalActionLogRecent(15)) ?></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 id="general_log" style="text-align:left;"><?= formatHistoryToHTML(getGeneralActionLogRecent($me['no'], 15)) ?></div>
</div>
@@ -328,34 +330,34 @@ if ($lastVoteID) {
<div id="message_board" class="row gx-0">
<div class="message_input_form bg0 gx-0 row">
<div id="mailbox_list-col" class="col-6 col-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>
</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">
</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 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>
<section class="public_message">
<div class="d-grid"><button type="button" class="load_old_message btn btn-secondary" data-msg_type="public">이전 메시지 불러오기</button></div>
</section>
</div>
<div class="col-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>
<section class="national_message">
<div class="d-grid"><button type="button" class="load_old_message btn btn-secondary" data-msg_type="national">이전 메시지 불러오기</button></div>
</section>
</div>
<div class="col-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>
<section class="private_message">
<div class="d-grid"><button type="button" class="load_old_message btn btn-secondary" data-msg_type="private">이전 메시지 불러오기</button></div>
</section>
</div>
<div class="col-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>
<section class="diplomacy_message">
<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>
<?php
if ($con == 1) {
if ($limitState == 1) {
MessageBox("접속제한이 얼마 남지 않았습니다!");
}
if ($me['newmsg'] == 1) {
@@ -379,7 +381,7 @@ if ($lastVoteID) {
}
?>
</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="collapse navbar-collapse">
<ul class="navbar-nav me-auto mx-auto">
+16 -13
View File
@@ -3,6 +3,7 @@
namespace sammo;
use sammo\Enums\EventTarget;
use sammo\Enums\GeneralQueryMode;
function processWar(string $warSeed, General $attackerGeneral, array $rawAttackerNation, array $rawDefenderCity)
{
@@ -37,12 +38,12 @@ function processWar(string $warSeed, General $attackerGeneral, array $rawAttacke
$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'));
$defenderGeneralList = General::createGeneralObjListFromDB($defenderIDList, null, 2);
$defenderGeneralList = General::createGeneralObjListFromDB($defenderIDList, null);
/** @var WarUnit[] */
$defenderList = [];
foreach($defenderGeneralList as $defenderGeneral){
$defenderGeneral->setRawCity($rawDefenderCity);
$defenderCandidate = new WarUnitGeneral($rng, $defenderGeneral, $rawDefenderNation, false);
if(extractBattleOrder($defenderCandidate, $attacker) <= 0){
continue;
@@ -480,17 +481,18 @@ function processWar_NG(
$attacker->finishBattle();
$defender->finishBattle();
if($city->getDead()){
$city->setSiege();
$city->finishBattle();
}
if($city->getDead() || $defender instanceof WarUnitCity){
if($city !== $defender){
$city->setOppose($attacker);
$city->setSiege();
$city->finishBattle();
}
if ($defender instanceof WarUnitCity) {
$newConflict = $defender->addConflict();
$newConflict = $city->addConflict();
if ($newConflict) {
$nationName = $attacker->getNationVar('name');
$josaYi = JosaUtil::pick($nationName, '이');
$logger->pushGlobalHistoryLog("<M><b>【분쟁】</b></><D><b>{$nationName}</b></>{$josaYi} <G><b>{$defender->getName()}</b></> 공략에 가담하여 분쟁이 발생하고 있습니다.");
$logger->pushGlobalHistoryLog("<M><b>【분쟁】</b></><D><b>{$nationName}</b></>{$josaYi} <G><b>{$city->getName()}</b></> 공략에 가담하여 분쟁이 발생하고 있습니다.");
}
}
@@ -594,10 +596,10 @@ function ConquerCity(array $admin, General $general, array $city)
$lord = new General($db->queryFirstRow(
'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,
12
), null, $city, $loseNation, $year, $month, false);
), null, null, $city, $loseNation, $year, $month, false);
$josaUl = JosaUtil::pick($defenderNationName, '을');
$attackerLogger->pushNationalHistoryLog("<D><b>{$defenderNationName}</b></>{$josaUl} 정복");
@@ -694,11 +696,12 @@ function ConquerCity(array $admin, General $general, array $city)
$minCity = findNextCapital($cityID, $defenderNationID);
$minCityName = CityConst::byID($minCity)->name;
$josaRo = JosaUtil::pick($minCityName, '로');
$josaYi = JosaUtil::pick($defenderNationName, '이');
$attackerLogger->pushGlobalHistoryLog("<M><b>【긴급천도】</b></><D><b>{$defenderNationName}</b></>{$josaYi} 수도가 함락되어 <G><b>$minCityName</b></>으로 긴급천도하였습니다.");
$attackerLogger->pushGlobalHistoryLog("<M><b>【긴급천도】</b></><D><b>{$defenderNationName}</b></>{$josaYi} 수도가 함락되어 <G><b>$minCityName</b></>{$josaRo} 긴급천도하였습니다.");
$moveLog = "수도가 함락되어 <G><b>$minCityName</b></>으로 <M>긴급천도</>합니다.";
$moveLog = "수도가 함락되어 <G><b>$minCityName</b></>{$josaRo} <M>긴급천도</>합니다.";
//아국 수뇌부에게 로그 전달
foreach ($db->queryFirstColumn(
'SELECT no FROM general WHERE nation=%i AND officer_level>=5',
@@ -10,6 +10,7 @@ use sammo\DTO\AuctionBidItem;
use sammo\DTO\AuctionInfo;
use sammo\Enums\APIRecoveryType;
use sammo\Enums\AuctionType;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\InheritanceKey;
use sammo\InheritancePointManager;
use sammo\TimeUtil;
@@ -76,7 +77,7 @@ class GetUniqueItemAuctionDetail extends \sammo\BaseAPI
$inheritMgr = InheritancePointManager::getInstance();
//preveious라서 column을 최대한 비울 수 있다.
$remainPoint = $inheritMgr->getInheritancePoint(
General::createGeneralObjFromDB($generalID, ['owner'], 0),
General::createGeneralObjFromDB($generalID, ['owner'], GeneralQueryMode::Core),
InheritanceKey::previous
);
+6 -3
View File
@@ -42,9 +42,12 @@ class GetBettingList extends \sammo\BaseAPI
$bettingStor = KVStorage::getStorage($db, 'betting');
$userID = $session->userID;
$me = $db->queryFirstRow('SELECT no,nation,officer_level,con,turntime,belong,penalty,permission FROM general WHERE owner=%i', $userID);
$con = checkLimit($me['con']);
if ($con >= 2) {
$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
);
$limitState = checkLimit($me['refresh_score']);
if ($limitState >= 2) {
return "접속 제한중입니다.";
}
@@ -39,7 +39,7 @@ class BuildNationCandidate extends \sammo\BaseAPI
$gameStor = KVStorage::getStorage($db, 'game_env');
$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) {
return '장수가 없습니다';
+9 -2
View File
@@ -5,6 +5,7 @@ namespace sammo\API\General;
use sammo\DB;
use sammo\DummyGeneral;
use sammo\Enums\APIRecoveryType;
use sammo\Enums\GeneralAccessLogColumn;
use sammo\GameConst;
use sammo\Session;
use sammo\General;
@@ -37,7 +38,13 @@ class DieOnPrestart extends \sammo\BaseAPI
$gameStor = KVStorage::getStorage($db, 'game_env');
$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) {
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()) {
$targetTimeShort = substr($targetTime, 0, 19);
return "아직 삭제할 수 없습니다. {$targetTimeShort} 부터 가능합니다.";
+9 -6
View File
@@ -9,7 +9,9 @@ use sammo\DB;
use sammo\DTO\VoteInfo;
use sammo\Enums\APIRecoveryType;
use sammo\Enums\CityColumn;
use sammo\Enums\GeneralAccessLogColumn;
use sammo\Enums\GeneralColumn;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\RankColumn;
use sammo\GameConst;
use sammo\General;
@@ -173,7 +175,7 @@ class GetFrontInfo extends \sammo\BaseAPI
'online_nation', 'online_user_cnt',
'year', 'month', 'startyear',
'maxgeneral',
'conlimit',
'refreshLimit',
'server_cnt',
]);
@@ -383,7 +385,8 @@ class GetFrontInfo extends \sammo\BaseAPI
'specialWar' => $general->getVar(GeneralColumn::special2), // GameObjClassKey;
'personal' => $general->getVar(GeneralColumn::personal), // GameObjClassKey;
'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;
'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;
//P0 End
'con' => $general->getVar(GeneralColumn::con), // number;
'refreshScore' => $general->getAccessLogVar(GeneralAccessLogColumn::refreshScore, 0), // number;
'specage' => $general->getVar(GeneralColumn::specage), // number;
'specage2' => $general->getVar(GeneralColumn::specage2), // number;
'leadership_exp' => $general->getVar(GeneralColumn::leadership_exp), // number;
@@ -531,12 +534,12 @@ class GetFrontInfo extends \sammo\BaseAPI
{
$generalID = $session->generalID;
//NOTE: 이 경우 staticNation 정보를 조회한다.
$general = General::createGeneralObjFromDB($generalID);
$general = General::createGeneralObjFromDB($generalID, null, GeneralQueryMode::FullWithAccessLog);
$nationID = $general->getNationID();
$cityID = $general->getCityID();
$con = checkLimit($general->getVar('con'));
if ($con >= 2) {
$limitState = checkLimit($general->getAccessLogVar(GeneralAccessLogColumn::refreshScore, 0));
if ($limitState >= 2) {
return [
'result' => false,
'reason' => '접속 제한중입니다.',
+6 -2
View File
@@ -8,6 +8,7 @@ use sammo\Auction;
use sammo\CityConst;
use sammo\DB;
use sammo\Enums\APIRecoveryType;
use sammo\Enums\GeneralAccessLogColumn;
use sammo\Enums\RankColumn;
use sammo\GameConst;
use sammo\GameUnitConst;
@@ -414,8 +415,6 @@ class Join extends \sammo\BaseAPI
'officer_level' => 0,
'turntime' => $turntime,
'killturn' => 6,
'lastconnect' => $now,
'lastrefresh' => $now,
'crewtype' => GameUnitConst::DEFAULT_CREWTYPE,
'makelimit' => 0,
'betray' => $betray,
@@ -428,6 +427,11 @@ class Join extends \sammo\BaseAPI
'special2' => $special2
]);
$generalID = $db->insertId();
$db->insert('general_access_log', [
GeneralAccessLogColumn::generalID->value => $generalID,
GeneralAccessLogColumn::userID->value => $userID,
GeneralAccessLogColumn::lastRefresh->value => $now,
]);
if($blockCustomGeneralName){
//XXX: 클래스가 이게 맞나?
+12 -6
View File
@@ -42,9 +42,12 @@ class GeneralList extends \sammo\BaseAPI
$userID = $session->userID;
if ($session->isGameLoggedIn()) {
increaseRefresh("장수일람", 2);
$me = $db->queryFirstRow('SELECT con, turntime FROM general WHERE owner=%i', $userID);
$con = checkLimit($me['con']);
if ($con >= 2) {
$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
);
$limitState = checkLimit($me['refresh_score']);
if ($limitState >= 2) {
return '접속 제한중입니다. 1턴 이내에 너무 많은 갱신을 하셨습니다.';
}
} else {
@@ -62,7 +65,8 @@ class GeneralList extends \sammo\BaseAPI
$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 = [];
if ($gameStor->isunited) {
@@ -73,7 +77,7 @@ class GeneralList extends \sammo\BaseAPI
$generalList = [];
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)) {
$ownerName = $ownerNameList[$owner];
@@ -104,7 +108,7 @@ class GeneralList extends \sammo\BaseAPI
getDed($dedication),
getOfficerLevelText($officerLevel, $nationArr['level']),
$killturn,
$connectCnt
$refreshScoreTotal ?: 0,
];
}
@@ -129,6 +133,8 @@ class GeneralList extends \sammo\BaseAPI
'honorText',
'dedLevelText',
'officerLevelText',
'killturn',
'refreshScoreTotal',
];
$result = [
+6 -3
View File
@@ -148,13 +148,16 @@ class GetHistory extends \sammo\BaseAPI
}
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) {
return '장수가 사망했습니다.';
}
$con = checkLimit($me['con']);
if ($con >= 2) {
$limitState = checkLimit($me['refresh_score']);
if ($limitState >= 2) {
return templateLimitMsg($me['turntime']);
}
}
+1 -1
View File
@@ -75,7 +75,7 @@ class GetOldMessage extends \sammo\BaseAPI
$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) {
return '장수가 사망했습니다.';
+1 -1
View File
@@ -73,7 +73,7 @@ class GetRecentMessage extends \sammo\BaseAPI
$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) {
return '장수가 사망했습니다.';
+7 -4
View File
@@ -108,7 +108,7 @@ class SendMessage extends \sammo\BaseAPI
$unlimited = new \DateTime('9999-12-31');
$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) {
return '존재하지 않는 유저입니다.';
@@ -160,15 +160,18 @@ class SendMessage extends \sammo\BaseAPI
}
$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) {
$session->logoutGame();
return '장수가 없습니다.';
}
$con = checkLimit($me['con']);
if ($con >= 2) {
$limitState = checkLimit($me['refresh_score']);
if ($limitState >= 2) {
return '접속 제한입니다.';
}
+31 -13
View File
@@ -5,6 +5,7 @@ namespace sammo\API\Nation;
use ArrayObject;
use sammo\DB;
use sammo\Enums\APIRecoveryType;
use sammo\Enums\GeneralQueryMode;
use sammo\General;
use sammo\Session;
use sammo\Util;
@@ -44,12 +45,10 @@ class GeneralList extends \sammo\BaseAPI
'special2' => 0,
'personal' => 0,
'belong' => 0,
'connect' => 0,
'troop' => 0,
'city' => 0,
'con' => 1,
'specage' => 0,
'specage2' => 0,
'leadership_exp' => 1,
@@ -83,6 +82,11 @@ class GeneralList extends \sammo\BaseAPI
'owner_name' => 9, //안씀.
//accessLog
'refresh_score_total' => 0,
'refresh_score' => 1,
//RANK
'warnum' => 1,
'killnum' => 1,
@@ -95,6 +99,8 @@ class GeneralList extends \sammo\BaseAPI
static $columnRemap = [
'special' => 'specialDomestic',
'special2' => 'specialWar',
'refresh_score_total' => 'refreshScoreTotal',
'refresh_score' => 'refreshScore',
'aux' => null,
];
@@ -143,9 +149,12 @@ class GeneralList extends \sammo\BaseAPI
$gameStor = \sammo\KVStorage::getStorage($db, 'game_env');
$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());
$con = checkLimit($me['con']);
if ($con >= 2) {
$me = $db->queryFirstRow(
'SELECT refresh_score, turntime, belong, nation, officer_level, permission, penalty FROM `general`
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턴 이내에 너무 많은 갱신을 하셨습니다.';
}
@@ -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[] */
$troops = [];
@@ -179,19 +197,19 @@ class GeneralList extends \sammo\BaseAPI
if ($this->permission >= 1 || count($troops)) {
$reservedCommandTargetGeneralIDList = [];
if($this->permission >= 1){
if ($this->permission >= 1) {
foreach ($rawGeneralList as $rawGeneral) {
if ($rawGeneral['npc'] < 2) {
$reservedCommandTargetGeneralIDList[$rawGeneral['no']] = $rawGeneral['no'];
}
}
}
foreach($troops as $troop){
foreach ($troops as $troop) {
$reservedCommandTargetGeneralIDList[$troop['id']] = $troop['id'];
}
if($reservedCommandTargetGeneralIDList){
if ($reservedCommandTargetGeneralIDList) {
$rawTurnList = $db->query(
'SELECT general_id, turn_idx, action, arg, brief FROM general_turn WHERE general_id IN %li AND turn_idx < 5 ORDER BY general_id asc, turn_idx asc',
array_values($reservedCommandTargetGeneralIDList)
@@ -278,11 +296,11 @@ class GeneralList extends \sammo\BaseAPI
$resultColumns[$column] = $column;
}
foreach ($troops as $troop){
foreach ($troops as $troop) {
$troopLeaderID = $troop['id'];
$troop['reservedCommand'] = array_map(function($turnObj){
$troop['reservedCommand'] = array_map(function ($turnObj) {
$brief = $turnObj['brief'];
if($brief == '집합'){
if ($brief == '집합') {
return $brief;
}
return '-';
+5 -3
View File
@@ -109,10 +109,12 @@ class GetGeneralLog extends \sammo\BaseAPI
$reqTo = $this->args['reqTo'] ?? null;
$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']);
if ($con >= 2) {
$limitState = checkLimit($me['refresh_score']);
if ($limitState >= 2) {
return '접속 제한입니다.';
}
+2 -1
View File
@@ -4,6 +4,7 @@ namespace sammo\API\Nation;
use sammo\DB;
use sammo\Enums\APIRecoveryType;
use sammo\Enums\GeneralQueryMode;
use sammo\GameConst;
use sammo\General;
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');
$gameEnv = $gameStor->getValues(['year', 'month', 'startyear']);
@@ -6,6 +6,7 @@ use sammo\Session;
use DateTimeInterface;
use sammo\DB;
use sammo\Enums\APIRecoveryType;
use sammo\Enums\GeneralQueryMode;
use sammo\GameConst;
use sammo\General;
use sammo\Json;
@@ -39,12 +40,15 @@ class GetReservedCommand extends \sammo\BaseAPI
$gameStor = KVStorage::getStorage($db, 'game_env');
$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']);
$nationID = $me['nation'];
$con = checkLimit($me['con']);
if ($con >= 2) {
$limitState = checkLimit($me['refresh_score']);
if ($limitState >= 2) {
return "접속 제한중입니다. 1턴 이내에 너무 많은 갱신을 하셨습니다. (다음 갱신 가능 시각 : {$me['turntime']})";
}
@@ -59,7 +63,7 @@ class GetReservedCommand extends \sammo\BaseAPI
$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) {
$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 = [];
@@ -109,7 +113,7 @@ class GetReservedCommand extends \sammo\BaseAPI
];
}
$generalObj = General::createGeneralObjFromDB($session->generalID);
$generalObj = General::createGeneralObjFromDB($session->generalID, null, GeneralQueryMode::FullWithoutIAction);
return [
+2 -1
View File
@@ -6,6 +6,7 @@ use DateTimeInterface;
use sammo\DB;
use sammo\DTO\VoteComment;
use sammo\Enums\APIRecoveryType;
use sammo\Enums\GeneralQueryMode;
use sammo\General;
use sammo\Session;
use sammo\TimeUtil;
@@ -40,7 +41,7 @@ class AddComment extends \sammo\BaseAPI
$text = mb_substr($this->args['text'], 0, 200);
$generalID = $session->generalID;
$general = General::createGeneralObjFromDB($generalID, [], 0);
$general = General::createGeneralObjFromDB($generalID, null, GeneralQueryMode::Core);
$generalName = $general->getName();
$nationID = $general->getNationID();
$nationName = $general->getStaticNation()['name'];
+2 -1
View File
@@ -6,6 +6,7 @@ use DateTimeInterface;
use sammo\DB;
use sammo\DTO\VoteInfo;
use sammo\Enums\APIRecoveryType;
use sammo\Enums\GeneralQueryMode;
use sammo\General;
use sammo\Json;
use sammo\KVStorage;
@@ -105,7 +106,7 @@ class Vote extends \sammo\BaseAPI
$gameStor = KVStorage::getStorage($db, 'game_env');
$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);
$uniqueRng = new RandUtil(new LiteHashDRBG(Util::simpleSerialize(
UniqueConst::$hiddenSeed,
+3 -3
View File
@@ -25,15 +25,15 @@ class che_병가 extends \sammo\BaseNation{
if($varType == 'score') return $value * 0.9;
if($varType == 'cost') return $value * 1.2;
}
return $value;
}
public function onCalcNationalIncome(string $type, $amount):int{
if($type == 'pop' && $amount > 0){
return Util::toInt($amount * 0.8);
return $amount * 0.8;
}
return $amount;
}
}
+2 -1
View File
@@ -5,6 +5,7 @@ namespace sammo;
use Ds\Map;
use sammo\DTO\BettingInfo;
use sammo\DTO\BettingItem;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\RankColumn;
class Betting
@@ -401,7 +402,7 @@ class Betting
$userLogger->flush();
}
} 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) {
$gambler = $generalList[$rewardItem['generalID']];
$reward = Util::round($rewardItem['amount']);
+2 -2
View File
@@ -21,7 +21,7 @@ use function \sammo\getNationStaticInfo;
use function sammo\tryUniqueItemLottery;
use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\GeneralQueryMode;
class che_등용 extends Command\GeneralCommand
{
@@ -77,7 +77,7 @@ class che_등용 extends Command\GeneralCommand
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);
[$reqGold, $reqRice] = $this->getCost();
@@ -68,7 +68,7 @@ class che_등용수락 extends Command\GeneralCommand{
protected function initWithArg()
{
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], null, 2);
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], null);
$this->setDestGeneral($destGeneral);
$this->setDestNation($this->arg['destNationID'], ['gennum', 'scout']);
@@ -77,6 +77,7 @@ class che_등용수락 extends Command\GeneralCommand{
$this->fullConditionConstraints=[
ConstraintHelper::ReqEnvValue('join_mode', '!=', 'onlyRandom', '랜덤 임관만 가능합니다'),
ConstraintHelper::ExistsDestNation(),
ConstraintHelper::BeNeutral(),
ConstraintHelper::AllowJoinDestNation($relYear),
ConstraintHelper::ReqDestNationValue('level', '국가규모', '>', 0, '방랑군에는 임관할 수 없습니다.'),
ConstraintHelper::DifferentDestNation(),
+2 -1
View File
@@ -19,6 +19,7 @@ use function\sammo\tryUniqueItemLottery;
use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\InheritanceKey;
class che_선양 extends Command\GeneralCommand
@@ -65,7 +66,7 @@ class che_선양 extends Command\GeneralCommand
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->fullConditionConstraints = [
@@ -17,6 +17,7 @@ use function \sammo\tryUniqueItemLottery;
use function \sammo\getNationStaticInfo;
use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\InheritanceKey;
class che_장수대상임관 extends Command\GeneralCommand{
@@ -83,7 +84,7 @@ class che_장수대상임관 extends Command\GeneralCommand{
protected function initWithArg()
{
$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->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\ConstraintHelper;
use sammo\Enums\GeneralQueryMode;
use function sammo\tryUniqueItemLottery;
@@ -86,7 +87,7 @@ class che_증여 extends Command\GeneralCommand
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->fullConditionConstraints = [
+2 -1
View File
@@ -15,6 +15,7 @@ use function \sammo\searchDistance;
use \sammo\Constraint\ConstraintHelper;
use sammo\CityConst;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\RankColumn;
use sammo\RandUtil;
@@ -268,7 +269,7 @@ class che_화계 extends Command\GeneralCommand
$destCityGeneralList = [];
$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) {
$destCityGeneral->setRawCity($this->destCity);
unset($destCityGeneral);
+7 -4
View File
@@ -19,6 +19,7 @@ use function \sammo\GetImageURL;
use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\MessageType;
class che_몰수 extends Command\NationCommand
@@ -91,7 +92,7 @@ class che_몰수 extends Command\NationCommand
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);
$env = $this->env;
@@ -173,7 +174,7 @@ class che_몰수 extends Command\NationCommand
$npcTexts = [
'몰수를 하다니... 이것이 윗사람이 할 짓이란 말입니까...',
'사유재산까지 몰수해가면서 이 나라가 잘 될거라 믿습니까? 정말 이해할 수가 없군요...',
'내 돈 내놔라! 내 돈! 몰수가 말이냐!',
'내 돈 내놔라! 내 돈! 몰수가 말이냐!',
'몰수해간 내 자금... 언젠가 몰래 다시 빼내올 것이다...',
'몰수로 인한 사기 저하는 몰수로 얻은 물자보다 더 손해란걸 모른단 말인가!'
];
@@ -205,8 +206,10 @@ class che_몰수 extends Command\NationCommand
$resKey => $db->sqleval('%b + %i', $resKey, $amount)
], 'nation=%i', $nationID);
$destGeneral->getLogger()->pushGeneralActionLog("{$resName} {$amountText}을 몰수 당했습니다.", ActionLogger::PLAIN);
$logger->pushGeneralActionLog("<Y>{$destGeneral->getName()}</>에게서 {$resName} <C>$amountText</>을 몰수했습니다. <1>$date</>");
$josaUl = JosaUtil::pick($amountText, '을');
$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));
$general->applyDB($db);
@@ -215,14 +215,16 @@ class che_물자원조 extends Command\NationCommand
$chiefLogger->flush();
}
$logger->pushGeneralHistoryLog("<D><b>{$destNationName}</b></>{$josaRo} 금<C>{$goldAmountText}</> 쌀<C>{$riceAmountText}</>을 지원");
$logger->pushNationalHistoryLog("<D><b>{$destNationName}</b></>{$josaRo} 금<C>{$goldAmountText}</> 쌀<C>{$riceAmountText}</>을 지원");
$josaUlRiceAmount = JosaUtil::pick($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->pushGeneralActionLog($broadcastMessage);
$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);
foreach ($destChiefList as $destChiefID) {
$destChiefLogger = new ActionLogger($destChiefID, $nationID, $year, $month);
@@ -232,7 +234,7 @@ class che_물자원조 extends Command\NationCommand
$josaRoSrc = JosaUtil::pick($nationName, '로');
$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');
$destRecvAssist = $destNationStor->getValue('recv_assist') ?? [];
+2 -1
View File
@@ -21,6 +21,7 @@ use function \sammo\cutTurn;
use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\GeneralQueryMode;
class che_발령 extends Command\NationCommand
{
@@ -71,7 +72,7 @@ class che_발령 extends Command\NationCommand
{
$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);
if ($this->arg['destGeneralID'] == $this->getGeneral()->getID()) {
@@ -20,6 +20,7 @@ use function \sammo\getNationStaticInfo;
use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\GeneralQueryMode;
use sammo\Json;
use sammo\KVStorage;
use sammo\RandUtil;
@@ -103,7 +104,7 @@ class che_불가침수락 extends Command\NationCommand
$env = $this->env;
$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->setDestNation($this->arg['destNationID']);
@@ -165,6 +165,7 @@ class che_불가침제의 extends Command\NationCommand
$nation = $this->nation;
$nationID = $nation['nation'];
$nationName = $nation['name'];
$josaRo = JosaUtil::pick($nationName, '로');
$destNation = $this->destNation;
$destNationID = $destNation['nation'];
@@ -176,7 +177,7 @@ class che_불가침제의 extends Command\NationCommand
$logger = $general->getLogger();
$destLogger = new ActionLogger(0, $destNationID, $env['year'], $env['month']);
$logger->pushGeneralActionLog("<D><b>{$destNationName}</b></>으로 불가침 제의 서신을 보냈습니다.<1>$date</>");
$logger->pushGeneralActionLog("<D><b>{$destNationName}</b></>{$josaRo} 불가침 제의 서신을 보냈습니다.<1>$date</>");
// 상대에게 발송
$src = new MessageTarget(
@@ -20,6 +20,7 @@ use function \sammo\getNationStaticInfo;
use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\GeneralQueryMode;
use sammo\RandUtil;
class che_불가침파기수락 extends Command\NationCommand
@@ -77,7 +78,7 @@ class che_불가침파기수락 extends Command\NationCommand
protected function initWithArg()
{
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], [], 1);
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], null, GeneralQueryMode::Lite);
$this->setDestGeneral($destGeneral);
$this->setDestNation($this->arg['destNationID']);
@@ -122,11 +122,12 @@ class che_불가침파기제의 extends Command\NationCommand{
$destNation = $this->destNation;
$destNationID = $destNation['nation'];
$destNationName = $destNation['name'];
$josaRo = JosaUtil::pick($destNationName, '로');
$logger = $general->getLogger();
$destLogger = new ActionLogger(0, $destNationID, $env['year'], $env['month']);
$logger->pushGeneralActionLog("<D><b>{$destNationName}</b></>으로 불가침 파기 제의 서신을 보냈습니다.<1>$date</>");
$logger->pushGeneralActionLog("<D><b>{$destNationName}</b></>{$josaRo} 불가침 파기 제의 서신을 보냈습니다.<1>$date</>");
// 상대에게 발송
$src = new MessageTarget(
@@ -22,6 +22,7 @@ use function \sammo\getNationStaticInfo;
use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\GeneralQueryMode;
class che_종전수락 extends Command\NationCommand
{
@@ -86,7 +87,7 @@ class che_종전수락 extends Command\NationCommand
protected function initWithArg()
{
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], [], 1);
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], null, GeneralQueryMode::Lite);
$this->setDestGeneral($destGeneral);
$this->setDestNation($this->arg['destNationID']);
@@ -120,11 +120,12 @@ class che_종전제의 extends Command\NationCommand{
$destNation = $this->destNation;
$destNationID = $destNation['nation'];
$destNationName = $destNation['name'];
$josaRo = JosaUtil::pick($destNationName, '로');
$logger = $general->getLogger();
$destLogger = new ActionLogger(0, $destNationID, $env['year'], $env['month']);
$logger->pushGeneralActionLog("<D><b>{$destNationName}</b></>으로 종전 제의 서신을 보냈습니다.<1>$date</>");
$logger->pushGeneralActionLog("<D><b>{$destNationName}</b></>{$josaRo} 종전 제의 서신을 보냈습니다.<1>$date</>");
// 상대에게 발송
$src = new MessageTarget(
+6 -3
View File
@@ -15,6 +15,7 @@ use \sammo\Command;
use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\GeneralQueryMode;
class che_포상 extends Command\NationCommand
{
@@ -81,7 +82,7 @@ class che_포상 extends Command\NationCommand
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);
if($this->arg['destGeneralID'] == $this->getGeneral()->getID()){
@@ -167,8 +168,10 @@ class che_포상 extends Command\NationCommand
$resKey => $db->sqleval('%b - %i', $resKey, $amount)
], 'nation=%i', $nationID);
$destGeneral->getLogger()->pushGeneralActionLog("{$resName} <C>{$amountText}</>을 포상으로 받았습니다.", ActionLogger::PLAIN);
$logger->pushGeneralActionLog("<Y>{$destGeneral->getName()}</>에게 {$resName} <C>$amountText</>을 수여했습니다. <1>$date</>");
$josaUl = JosaUtil::pick($amountText, '을');
$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));
$general->applyDB($db);
@@ -15,6 +15,7 @@ use \sammo\{
use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\GeneralQueryMode;
use sammo\Event\Action;
class che_필사즉생 extends Command\NationCommand{
@@ -94,7 +95,7 @@ class che_필사즉생 extends Command\NationCommand{
$broadcastMessage = "<Y>{$generalName}</>{$josaYi} <M>필사즉생</>을 발동하였습니다.";
$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);
if($targetGeneral->getVar('train') < 100){
$targetGeneral->setVar('train', 100);
@@ -39,7 +39,7 @@ class ReqGeneralCrewMargin extends Constraint{
//XXX: 왜 General -> obj -> General 변환을 하고 있나?
//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){
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
namespace sammo;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\MessageType;
class DiplomaticMessage extends Message{
@@ -75,7 +76,7 @@ class DiplomaticMessage extends Message{
$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(), [
'destNationID'=>$this->src->nationID,
@@ -99,7 +100,7 @@ class DiplomaticMessage extends Message{
protected function cancelNA(){
$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(), [
'destNationID'=>$this->src->nationID,
@@ -121,7 +122,7 @@ class DiplomaticMessage extends Message{
protected function stopWar(){
$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(), [
'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 deadyear = 'deadyear';
case newmsg = 'newmsg';
case con = 'con';
case connect = 'connect';
case refresh = 'refresh';
case logcnt = 'logcnt';
case refcnt = 'refcnt';
case picture = 'picture';
case imgsvr = 'imgsvr';
case name = 'name';
@@ -58,8 +53,6 @@ enum GeneralColumn: string{
case recent_war = 'recent_war';
case makelimit = 'makelimit';
case killturn = 'killturn';
case lastconnect = 'lastconnect';
case lastrefresh = 'lastrefresh';
case ip = 'ip';
case block = 'block';
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';
}
+21 -6
View File
@@ -31,29 +31,44 @@ class InvaderEnding extends \sammo\Event\Action{
$logger = new ActionLogger(0, 0, $env['year'], $env['month']);
$needStop = false;
$userWin = false;
$cityCnt = $db->queryFirstField('SELECT count(*) FROM city WHERE nation = 0');
if($cityCnt == 0){
$needStop = true;
$nationName = $db->queryFirstField('SELECT name FROM nation LIMIT 1');
if(!\str_starts_with($nationName, 'ⓞ')){
$userWin = true;
}
}
else if($cityCnt == count(CityConst::all())){
$needStop = true;
$userWin = false;
}
if(!$needStop){
return [__CLASS__, "On Event"];
}
if($userWin){
//천통 엔딩
$logger->pushGlobalHistoryLog("<L><b>【이벤트】</b></>이민족을 모두 소탕했습니다!");
$logger->pushGlobalHistoryLog("<L><b>【이벤트】</b></>중원은 당분간 태평성대를 누릴 것입니다.");
}
else if($cityCnt == count(CityConst::all())){
else {
//이민족 엔딩
$logger->pushGlobalHistoryLog("<L><b>【이벤트】</b></>중원은 이민족에 의해 혼란에 빠졌습니다.");
$logger->pushGlobalHistoryLog("<L><b>【이벤트】</b></>백성은 언젠가 영웅이 나타나길 기다립니다.");
}
else{
return [__CLASS__, "On Event"];
}
$gameStor->setValue('isunited', 3);
$logger->flush();
$gameStor->conlimit = $gameStor->conlimit * 100;
$gameStor->refreshLimit = $gameStor->refreshLimit * 100;
$eventID = Util::array_get($env['currentEventID']);
$db->delete('event', 'id = %i', $eventID);
return [__CLASS__, 'Deleted'];
return [__CLASS__, 'Deleted'];
}
}
@@ -18,7 +18,7 @@ class MergeInheritPointRank extends \sammo\Event\Action
{
$db = DB::db();
$generals = General::createGeneralObjListFromDB(null, null, 2);
$generals = General::createGeneralObjListFromDB(null, null);
$points = new Map();
$points->allocate(count($generals));
+2 -2
View File
@@ -88,7 +88,7 @@ class ProcessIncome extends \sammo\Event\Action
// 각 장수들에게 지급
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);
$generalObj->increaseVar('gold', $gold);
@@ -169,7 +169,7 @@ class ProcessIncome extends \sammo\Event\Action
// 각 장수들에게 지급
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);
$generalObj->increaseVar('rice', $rice);
@@ -41,7 +41,7 @@ class ProvideNPCTroopLeader extends \sammo\Event\Action
foreach ($db->query('SELECT nation,name,level,tech,aux FROM nation') as $nation) {
$nationID = $nation['nation'];
$maxNPCTroopLeaderCnt = self::MaxNPCTroopLeaderCnt[$nation['level']];
$maxNPCTroopLeaderCnt = self::MaxNPCTroopLeaderCnt[$nation['level']] ?? 0;
$NPCTroopLeaderCnt = $NPCTroopLeaderCntByNation[$nationID] ?? 0;
if ($NPCTroopLeaderCnt >= $maxNPCTroopLeaderCnt) {
+1 -1
View File
@@ -131,7 +131,7 @@ class RaiseDisaster extends \sammo\Event\Action
$generalList = array_map(
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']] ?? []
);
+31 -2
View File
@@ -12,6 +12,8 @@ use sammo\LiteHashDRBG;
use sammo\RandUtil;
use sammo\Scenario\GeneralBuilder;
use sammo\Scenario\Nation;
use sammo\ServerEnv;
use sammo\ServerTool;
use sammo\UniqueConst;
use sammo\Util;
@@ -93,6 +95,7 @@ class RaiseInvader extends \sammo\Event\Action
public function run(array $env)
{
$db = DB::db();
$npcEachCount = $this->npcEachCount;
/** @var \sammo\CityInitDetail[] */
@@ -104,6 +107,16 @@ class RaiseInvader extends \sammo\Event\Action
$cities[] = $cityObj;
}
if(!$cities){
return [__CLASS__, 0];
}
$gameStor = KVStorage::getStorage($db, 'game_env');
$gameStor->setValue('isunited', 1);
$turnterm = $gameStor->turnterm;
$generalCnt = $db->queryFirstField('SELECT count(*) FROM general');
if ($npcEachCount < 0) {
$npcEachCount =
$db->queryFirstField('SELECT count(no) from general where npc < 4') / count($cities);
@@ -111,6 +124,19 @@ class RaiseInvader extends \sammo\Event\Action
}
$npcEachCount = max(10, Util::toInt($npcEachCount));
$totalGenerals = $npcEachCount * count($cities) + $generalCnt;
if ($totalGenerals > ServerEnv::$maxGeneralsPerMinute * $turnterm) {
foreach ([1, 2, 5, 10, 20, 30, 60, 120] as $nextTurnterm) {
if ($totalGenerals > ServerEnv::$maxGeneralsPerMinute * $nextTurnterm) {
continue;
}
ServerTool::changeServerTerm($nextTurnterm, true);
break;
}
}
$specAvg = $this->specAvg;
if ($specAvg < 0) {
$specAvg = $db->queryFirstField('SELECT avg((`leadership` + `strength` + `intel`)) from general where npc < 4');
@@ -140,6 +166,11 @@ class RaiseInvader extends \sammo\Event\Action
$month,
)));
$db->update('nation', [
'war' => 0,
'scout' => 0,
], '1');
$disabledInvaderCity = $this->moveCapital($rng);
$serverID = UniqueConst::$serverID;
$existNations = $db->queryFirstColumn("SELECT nation FROM `nation`");
@@ -260,8 +291,6 @@ class RaiseInvader extends \sammo\Event\Action
'secu' => $db->sqleval('secu_max'),
], true);
$gameStor = KVStorage::getStorage($db, 'game_env');
$gameStor->setValue('isunited', 1);
refreshNationStaticInfo();
$logger = new ActionLogger(0, 0, $year, $env['month']);
+3 -2
View File
@@ -5,6 +5,7 @@ namespace sammo\Event\Action;
use sammo\ActionLogger;
use sammo\CityConst;
use sammo\DB;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\InheritanceKey;
use sammo\GameConst;
use sammo\General;
@@ -139,7 +140,7 @@ class UpdateNationLevel extends \sammo\Event\Action
$nation['nation'],
$targetKillTurn
);
$nationGenList = General::createGeneralObjListFromDB($nationGenIDList, ['belong', 'npc', 'aux'], 2);
$nationGenList = General::createGeneralObjListFromDB($nationGenIDList, ['belong', 'npc', 'aux']);
$chiefID = null;
$uniqueLotteryWeightList = [];
@@ -214,7 +215,7 @@ class UpdateNationLevel extends \sammo\Event\Action
}
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->applyDB($db);
}
+132 -29
View File
@@ -4,6 +4,8 @@ namespace sammo;
use Ds\Map;
use sammo\Command\GeneralCommand;
use sammo\Enums\GeneralAccessLogColumn;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\InheritanceKey;
use sammo\Enums\RankColumn;
use sammo\WarUnitTrigger as WarUnitTrigger;
@@ -23,6 +25,9 @@ class General implements iAction
/** @var Map<RankColumn,int|float> */
protected Map $rankVarSet;
/** @var Map<GeneralAccessLogColumn,int|float> */
protected ?Map $accessLogRead;
/** @var \sammo\ActionLogger */
protected $logger;
@@ -78,12 +83,13 @@ class General implements iAction
/**
* @param array $raw DB row값.
* @param null|Map<RankColumn,int|float> $rawRank
* @param null|Map<GeneralAccessLogColumn,int> $rawAccessLog
* @param null|array $city DB city 테이블의 row값
* @param int|null $year 게임 연도
* @param int|null $month 게임 월
* @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 값을 직접 구해야함.
@@ -109,6 +115,10 @@ class General implements iAction
} else {
$this->rankVarRead = new Map();
}
$this->accessLogRead = $rawAccessLog;
$this->rankVarIncrease = new Map();
$this->rankVarSet = new Map();
@@ -329,7 +339,7 @@ class General implements iAction
function getCrewTypeObj(): GameUnitDetail
{
if($this->crewType === null) {
if ($this->crewType === null) {
throw new \InvalidArgumentException('Invalid CrewType:' . $this->getVar('crewtype'));
}
return $this->crewType;
@@ -677,6 +687,7 @@ class General implements iAction
$db->delete('general', 'no=%i', $generalID);
$db->delete('general_turn', 'general_id=%i', $generalID);
$db->delete('rank_data', 'general_id=%i', $generalID);
$db->delete('general_access_log', 'general_id=%i', $generalID);
$this->updatedVar = [];
$db->update('nation', [
@@ -770,6 +781,19 @@ class General implements iAction
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
*/
@@ -844,7 +868,7 @@ class General implements iAction
$this->increaseVar($statName, -1);
$result = true;
} 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);
$this->increaseVar($statName, 1);
}
@@ -856,7 +880,8 @@ class General implements iAction
return $result;
}
protected function getActionList(): array{
protected function getActionList(): array
{
return array_merge([
$this->nationType,
$this->officerLevelObj,
@@ -1007,7 +1032,7 @@ class General implements iAction
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'];
$defaultEventColumn = [
@@ -1023,52 +1048,84 @@ class General implements iAction
'personal', 'special', 'special2', 'defence_train', 'tnmt', 'npc', 'npc_org', 'deadyear', 'npcmsg',
'dex1', 'dex2', 'dex3', 'dex4', 'dex5', 'betray',
'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) {
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[] */
$rankColumn = [];
$subColumn = [];
$accessLogColumn = [];
foreach ($reqColumns as $column) {
if ($column instanceof RankColumn) {
$rankColumn[] = $column;
continue;
}
$rankKey = RankColumn::tryFrom($column);
if ($rankKey !== null) {
$rankColumn[] = $rankKey;
} else {
$subColumn[] = $column;
if ($column instanceof GeneralAccessLogColumn) {
$accessLogColumn[] = $column;
continue;
}
$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) {
return [array_unique(array_merge($defaultEventColumn, $subColumn)), $rankColumn];
switch ($queryMode) {
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 null|array<string|RankColumn> $column
* @param int $constructMode
* @param GeneralQueryMode $queryMode
* @return \sammo\General[]
* @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 === []) {
return [];
}
$db = DB::db();
if ($constructMode > 0) {
if ($queryMode->value > 0) {
$gameStor = KVStorage::getStorage($db, 'game_env');
[$year, $month] = $gameStor->getValuesAsArray(['year', 'month']);
} else {
@@ -1079,14 +1136,16 @@ class General implements iAction
/**
* @var string[] $column
* @var RankColumn[] $rankColumn
* @var GeneralAccessLogColumn[] $accessLogColumn
*/
[$column, $rankColumn] = static::mergeQueryColumn($column, $constructMode);
[$column, $rankColumn, $accessLogColumn] = static::mergeQueryColumn($column, $queryMode);
if ($generalIDList === null) {
$rawGenerals = Util::convertArrayToDict(
$db->query('SELECT %l FROM general WHERE 1', Util::formatListOfBackticks($column)),
'no'
);
$generalIDList = array_keys($rawGenerals);
} else {
$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 = [];
foreach ($generalIDList as $generalID) {
if (!key_exists($generalID, $rawGenerals)) {
$result[$generalID] = new DummyGeneral($constructMode > 0);
$result[$generalID] = new DummyGeneral($queryMode->value > 0);
continue;
}
if ($rawRanks->hasKey($generalID) && $rawRanks[$generalID]->count() !== count($rankColumn)) {
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;
}
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();
if ($constructMode > 0) {
if ($queryMode->value > 0) {
$gameStor = KVStorage::getStorage($db, 'game_env');
[$year, $month] = $gameStor->getValuesAsArray(['year', 'month']);
} else {
@@ -1143,12 +1219,39 @@ class General implements iAction
/**
* @var string[] $column
* @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) {
return new DummyGeneral($constructMode > 0);
return new DummyGeneral($queryMode->value > 0);
}
$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;
}
+1 -1
View File
@@ -3514,7 +3514,7 @@ class GeneralAI
$db = DB::db();
$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;
foreach ($nationGenerals as $nationGeneral) {
+3 -2
View File
@@ -17,7 +17,7 @@ class InheritancePointManager
private function __construct()
{
$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::max_belong, new InheritancePointType(false, 10, '최대 임관년 수', null));
$inheritanceKey->put(InheritanceKey::max_domestic_critical, new InheritancePointType(true, 1, '최대 연속 내정 성공', null));
@@ -165,7 +165,8 @@ class InheritancePointManager
case InheritanceKey::betting:
$extractFn = function () use ($general, $multiplier) {
$betWin = $general->getRankVar(RankColumn::betwin);
$betWinRate = $general->getRankVar(RankColumn::betwingold) / max(1, $general->getRankVar(RankColumn::betgold));
//FIXME: 올바른 위치에서 은퇴 전후 베팅 기록을 처리해야함.
$betWinRate = $general->getRankVar(RankColumn::betwingold) / max(1000, $general->getRankVar(RankColumn::betgold));
return [$betWin * $multiplier * pow($betWinRate, 2), null];
};
+62
View File
@@ -126,6 +126,8 @@ class Message
$objMessage = new DiplomaticMessage(...$args);
} elseif ($action === 'scout') {
$objMessage = new ScoutMessage(...$args);
} elseif ($action === 'raiseInvader') {
$objMessage = new RaiseInvaderMessage(...$args);
} else {
$objMessage = new Message(...$args);
}
@@ -151,6 +153,7 @@ class Message
$db = DB::db();
$now = new \DateTime();
$row = $db->queryFirstRow('SELECT * FROM `message` WHERE `id` = %i AND valid_until', $messageID);
//FIXME: $now가 들어가야 하는데 안 들어가있는데?
if (!$row) {
return null;
}
@@ -376,6 +379,65 @@ class Message
throw new \RuntimeException('이곳에 올 수 없습니다.');
}
/**
* @param int[]|MessageTarget[]|int|MessageTarget $targets
* @param string $msg
*/
public static function sendPrivateMsgAsNotice(array|int|MessageTarget $targets, string $msg): void{
$src = MessageTarget::buildSystemTarget();
if(is_int($targets)){
$targets = [$targets];
}
else if($targets instanceof MessageTarget){
$targets = [$targets];
}
$reqTargetGeneralIDList = [];
$objTargets = [];
foreach($targets as $target){
if($target instanceof MessageTarget){
$objTargets[] = $target;
continue;
}
if(!is_int($target)){
throw new \InvalidArgumentException('올바르지 않은 타입');
}
$reqTargetGeneralIDList[] = $target;
}
if($reqTargetGeneralIDList){
$db = DB::db();
$rawGenerals = $db->query('SELECT no, name, nation, imgsvr, picture FROM general WHERE no in %li', $reqTargetGeneralIDList);
foreach($rawGenerals as $rawGeneral){
$staticNation = getNationStaticInfo($rawGeneral['nation']);
$objTarget = new MessageTarget(
$rawGeneral['no'],
$rawGeneral['name'],
$rawGeneral['nation'],
$staticNation['name'],
$staticNation['color'],
GetImageURL($rawGeneral['imgsvr'], $rawGeneral['picture'])
);
$objTargets[] = $objTarget;
}
}
foreach($objTargets as $dest){
$msg = new Message(
MessageType::private,
$src,
$dest,
$msg,
new \DateTime(),
new \DateTime('9999-12-31'),
[]
);
$msg->send(true);
}
}
public function send(bool $sendDestOnly=false):int{
[$receiverMailbox, $receiveID] = $this->sendToReceiver();
if(!$receiveID && !$sendDestOnly){
+29 -13
View File
@@ -10,7 +10,7 @@ class MessageTarget extends Target {
public $color;
/** @var string */
public $icon;
public function __construct(
int $generalID,
string $generalName,
@@ -19,13 +19,13 @@ class MessageTarget extends Target {
string $color,
string $icon=''
){
parent::__construct($generalID, $nationID);
if(!$icon){
$icon = ServConfig::getSharedIconPath().'/default.jpg';
}
$this->generalName = $generalName;
$this->nationName = $nationName;
$this->color = $color;
@@ -47,28 +47,28 @@ class MessageTarget extends Target {
}
return new MessageTarget(
$arr['id'],
$arr['name'],
$arr['nation_id'],
$arr['nation'],
$arr['color'],
$arr['id'],
$arr['name'],
$arr['nation_id'],
$arr['nation'],
$arr['color'],
$arr['icon']??''
);
}
/**
* DB 부하 감수하고 일일히 찾아줌.
* DB 부하 감수하고 일일히 찾아줌.
* 게임 로직과 크게 연관이 없는 곳에서 메시지를 생성해야 할 경우에만 사용할 것을 권함.
* @return MessageTarget
*/
public static function buildQuick(int $generalID){
$db = DB::db();
list(
$generalName,
$nationID,
$imgsvr,
$generalName,
$nationID,
$imgsvr,
$picture
) = $db->queryFirstList('SELECT `name`, nation, imgsvr, picture FROM general WHERE `no`=%i', $generalID);
) = $db->queryFirstList('SELECT `name`, nation, imgsvr, picture FROM general WHERE `no`=%i', $generalID);
if($generalName === null){
throw new \RuntimeException('장수가 없음:'.$generalID);
@@ -79,6 +79,22 @@ class MessageTarget extends Target {
return new MessageTarget($generalID, $generalName, $nationID, $nation['name'], $nation['color'], $icon);
}
public static function buildFromGeneralObj(General $general): MessageTarget{
$nation = getNationStaticInfo($general->getNationID());
return new MessageTarget(
$general->getID(),
$general->getName(),
$general->getNationID(),
$nation['name'],
$nation['color'],
GetImageURL($general->getVar('imgsvr'), $general->getVar('picture')),
);
}
public static function buildSystemTarget(): MessageTarget{
return new MessageTarget(0, '', 0, 'System', '#000000');
}
public function toArray() : array{
return [
'id'=>$this->generalID,
+178
View File
@@ -0,0 +1,178 @@
<?php
namespace sammo;
use DateTime;
use sammo\Enums\MessageType;
use sammo\Event\Action\RaiseInvader;
class RaiseInvaderMessage extends Message
{
const ACCEPTED = 1;
const DECLINED = -1;
const INVALID = 0;
protected $valid = true;
public function __construct(
MessageType $msgType,
MessageTarget $src,
MessageTarget $dest,
string $msg,
\DateTime $date,
\DateTime $validUntil,
array $msgOption
) {
if ($msgType !== MessageType::private) {
throw new \InvalidArgumentException('private msgType');
}
if (Util::array_get($msgOption['action']) !== 'raiseInvader') {
throw new \InvalidArgumentException('Action !== raiseInvader');
}
parent::__construct(...func_get_args());
if (Util::array_get($msgOption['used'])) {
$this->valid = false;
}
}
protected function checkMessageValidation(int $receiverID)
{
if (!$this->valid) {
return [self::INVALID, '이미 사용하였습니다.'];
}
if ($this->mailbox !== $this->dest->generalID) {
return [self::INVALID, '송신자가 메시지를 처리할 수 없습니다.'];
}
if ($this->mailbox !== $receiverID) {
return [self::INVALID, '올바른 수신자가 아닙니다.'];
}
return [self::ACCEPTED, '성공'];
}
/**
* @return int 수행 결과 반환, ACCEPTED(등용장 소모), DECLINED(등용장 소모), INVALID 중 반환
*/
public function agreeMessage(int $receiverID, string &$reason): int
{
//NOTE: 올바른 유저가 agreeMessage() 호출을 한건지는 외부에서 체크 필요(Session->userID 등)
if (!$this->id) {
throw new \RuntimeException('전송되지 않은 메시지에 수락 진행 중');
}
$gameStor = KVStorage::getStorage(DB::db(), 'game_env');
$general = \sammo\General::createGeneralObjFromDB($receiverID);
$logger = $general->getLogger();
[$result, $reason] = $this->checkMessageValidation($receiverID);
if($result === self::ACCEPTED && $gameStor->isunited != 2){
$result = self::INVALID;
$reason = '천하통일이 되지 않았습니다.';
}
if ($result !== self::ACCEPTED) {
if ($result === self::DECLINED) {
$this->_declineMessage();
}
else{
Message::sendPrivateMsgAsNotice($this->dest, "{$reason} 이민족 등장 불가.");
}
return $result;
}
[$npcEachCount, $specAvg, $tech, $dex] = $this->msgOption['args'];
$invaderAction = new RaiseInvader(
$npcEachCount,
$specAvg,
$tech,
$dex
);
$invaderAction->run($gameStor->getAll());
return self::ACCEPTED;
}
protected function _declineMessage()
{
$this->msgOption['used'] = true;
$this->invalidate();
$this->valid = false;
return self::DECLINED;
}
public function declineMessage(int $receiverID, string &$reason): int
{
if (!$this->id) {
throw new \RuntimeException('전송되지 않은 메시지에 거절 진행 중');
}
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
[$result, $reason] = $this->checkMessageValidation($receiverID);
if ($result === self::INVALID) {
Message::sendPrivateMsgAsNotice($this->dest, "{$reason} 취소 불가.");
return $result;
}
$this->_declineMessage();
return self::DECLINED;
}
/**
*
* @param int $destGeneralID
* @param DateTime|null $date
* @return RaiseInvaderMessage[]
*/
public static function buildRaiseInvaderMessage(int $destGeneralID, \DateTime $date = null): array
{
$srcTarget = MessageTarget::buildSystemTarget();
$destTarget = MessageTarget::buildQuick($destGeneralID);
if ($date === null) {
$date = new \DateTime();
}
/**
* @var [[float,float,float,float],string][] $argsList
*/
$argsList = [
[[-2, -1.2, 15000, -1], '어려움'],
[[-2, -1.2, -1, -0.5], '보통'],
[[-1, -1, -0.8, 0], '쉬움'],
];
//XXX: 난이도 설정을 어디서 해야하는가?
$msgList = [];
foreach($argsList as [$args, $difficulty]){
$msg = new self(
MessageType::private,
$srcTarget,
$destTarget,
"이벤트 게임으로 이민족[{$difficulty}]을 소환",
$date,
new \DateTime('9999-12-31'),
[
'action' => 'raiseInvader',
'args' => $args,
'used' => false
]
);
$msgList[] = $msg;
}
return $msgList;
}
}
+5 -1
View File
@@ -143,6 +143,9 @@ class ResetHelper{
$voteStor = KVStorage::getStorage($db, 'vote');
$voteStor->resetValues();
//삭제하는 타입은 enum GeneralStorKey 참고
$db->delete('storage', 'namespace LIKE "general_%"');
$lastExecuteStor = KVStorage::getStorage($db, 'next_execute');
$lastExecuteStor->resetValues();
@@ -269,6 +272,7 @@ class ResetHelper{
'startyear'=>$startyear,
'year'=> $year,
'month'=> $month,
'isunited' => 0,
'init_year'=> $year,
'init_month'=>$month,
'map_theme' => $scenarioObj->getMapTheme(), //@deprecated
@@ -276,7 +280,7 @@ class ResetHelper{
'msg'=>'공지사항',//TODO:공지사항
'maxgeneral'=>GameConst::$defaultMaxGeneral,
'maxnation'=>GameConst::$defaultMaxNation,
'conlimit'=>30000,
'refreshLimit'=>30000,
'develcost'=>$develcost,
'turntime'=>$turntime,
'starttime'=>$starttime,
-1
View File
@@ -708,7 +708,6 @@ class GeneralBuilder{
'dex4'=>$this->dex4,
'dex5'=>$this->dex5,
'aux'=>\sammo\Json::encode($this->aux),
'lastrefresh'=>TimeUtil::now(),
]);
$this->generalID = $db->insertId();
$turnRows = [];
+69 -37
View File
@@ -1,9 +1,11 @@
<?php
namespace sammo;
use sammo\Enums\MessageType;
class ScoutMessage extends Message{
class ScoutMessage extends Message
{
const ACCEPTED = 1;
const DECLINED = -1;
@@ -18,36 +20,36 @@ class ScoutMessage extends Message{
\DateTime $date,
\DateTime $validUntil,
array $msgOption
)
{
if ($msgType !== MessageType::private){
) {
if ($msgType !== MessageType::private) {
throw new \InvalidArgumentException('DiplomaticMessage msgType');
}
if(Util::array_get($msgOption['action']) !== 'scout'){
if (Util::array_get($msgOption['action']) !== 'scout') {
throw new \InvalidArgumentException('Action !== scout');
}
parent::__construct(...func_get_args());
if(Util::array_get($msgOption['used'])){
if (Util::array_get($msgOption['used'])) {
$this->validScout = false;
}
if($this->validUntil <= new \DateTime()){
if ($this->validUntil <= new \DateTime()) {
$this->validScout = false;
}
}
protected function checkScoutMessageValidation(int $receiverID){
if(!$this->validScout){
protected function checkScoutMessageValidation(int $receiverID)
{
if (!$this->validScout) {
return [self::INVALID, '유효하지 않은 등용장입니다.'];
}
if($this->mailbox !== $this->dest->generalID){
if ($this->mailbox !== $this->dest->generalID) {
return [self::INVALID, '송신자가 등용장을 처리할 수 없습니다.'];
}
if($this->mailbox !== $receiverID){
if ($this->mailbox !== $receiverID) {
return [self::INVALID, '올바른 수신자가 아닙니다.'];
}
@@ -57,34 +59,35 @@ class ScoutMessage extends Message{
/**
* @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 등)
if(!$this->id){
if (!$this->id) {
throw new \RuntimeException('전송되지 않은 메시지에 수락 진행 중');
}
$gameStor = KVStorage::getStorage(DB::db(), 'game_env');
$general = \sammo\General::createGeneralObjFromDB($receiverID, null, 2);
$general = \sammo\General::createGeneralObjFromDB($receiverID);
$logger = $general->getLogger();
list($result, $reason) = $this->checkScoutMessageValidation($receiverID);
if($result !== self::ACCEPTED){
if ($result !== self::ACCEPTED) {
$logger->pushGeneralActionLog("{$reason} 등용 수락 불가.");
if($result === self::DECLINED){
if ($result === self::DECLINED) {
$this->_declineMessage();
}
return $result;
}
$commandObj = buildGeneralCommandClass('che_등용수락', $general, $gameStor->getAll(true), [
'destNationID'=>$this->src->nationID,
'destGeneralID'=>$this->src->generalID,
'destNationID' => $this->src->nationID,
'destGeneralID' => $this->src->generalID,
]);
if(!$commandObj->hasFullConditionMet()){
if (!$commandObj->hasFullConditionMet()) {
$logger->pushGeneralActionLog($commandObj->getFailString());
$reason = $commandObj->getFailString();
return self::DECLINED;
@@ -96,6 +99,7 @@ class ScoutMessage extends Message{
//메시지 비 활성화
$this->msgOption['used'] = true;
$this->invalidate();
static::invalidateAll($this->src->generalID, $this->id);
$this->validScout = false;
$josaRo = JosaUtil::pick($this->src->nationName, '로');
@@ -107,7 +111,7 @@ class ScoutMessage extends Message{
new \DateTime(),
new \DateTime('9999-12-31'),
[
'delete'=>$this->id
'delete' => $this->id
]
);
$newMsg->send(true);
@@ -115,7 +119,33 @@ class ScoutMessage extends Message{
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->invalidate();
$this->validScout = false;
@@ -129,7 +159,7 @@ class ScoutMessage extends Message{
new \DateTime(),
new \DateTime('9999-12-31'),
[
'delete'=>$this->id
'delete' => $this->id
]
);
$newMsg->send(true);
@@ -137,8 +167,9 @@ class ScoutMessage extends Message{
return self::DECLINED;
}
public function declineMessage(int $receiverID, string &$reason):int{
if(!$this->id){
public function declineMessage(int $receiverID, string &$reason): int
{
if (!$this->id) {
throw new \RuntimeException('전송되지 않은 메시지에 거절 진행 중');
}
@@ -148,7 +179,7 @@ class ScoutMessage extends Message{
list($result, $reason) = $this->checkScoutMessageValidation($receiverID);
if($result === self::INVALID){
if ($result === self::INVALID) {
(new ActionLogger($receiverID, 0, $year, $month))->pushGeneralActionLog("{$reason} 등용 취소 불가.", ActionLogger::PLAIN);
return $result;
}
@@ -162,9 +193,10 @@ class ScoutMessage extends Message{
return self::DECLINED;
}
public static function buildScoutMessage(int $srcGeneralID, int $destGeneralID, &$reason = null, \DateTime $date = null):?self{
if($srcGeneralID == $destGeneralID){
if($reason !== null){
public static function buildScoutMessage(int $srcGeneralID, int $destGeneralID, &$reason = null, \DateTime $date = null): ?self
{
if ($srcGeneralID == $destGeneralID) {
if ($reason !== null) {
$reason = '같은 장수에게 등용장을 보낼 수 없습니다';
}
return null;
@@ -173,26 +205,26 @@ class ScoutMessage extends Message{
$db = DB::db();
$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);
if($date === null){
if ($date === null) {
$date = new \DateTime();
}
if($destGeneral['officer_level'] == 12){
if($reason !== null){
if ($destGeneral['officer_level'] == 12) {
if ($reason !== null) {
$reason = '군주에게 등용장을 보낼 수 없습니다';
}
return null;
}
if(!$srcGeneral['nation']){
if($reason !== null){
if (!$srcGeneral['nation']) {
if ($reason !== null) {
$reason = '재야 상태일 때에는 등용장을 보낼 수 없습니다';
}
return null;
}
if($srcGeneral['nation'] === $destGeneral['nation']){
if($reason !== null){
if ($srcGeneral['nation'] === $destGeneral['nation']) {
if ($reason !== null) {
$reason = '같은 소속의 장수에게 등용장을 보낼 수 없습니다';
}
return null;
@@ -222,9 +254,9 @@ class ScoutMessage extends Message{
$validUntil = new \DateTime("9999-12-31 12:59:59");
$msgOption = [
'action'=>'scout'
'action' => 'scout'
];
return new ScoutMessage(MessageType::private, $src, $dest, $msg, $date, $validUntil, $msgOption);
}
}
}
+13
View File
@@ -0,0 +1,13 @@
<?php
namespace sammo;
/** 서버 내 변수 모음 */
class ServerDefaultEnv
{
private function __construct()
{
}
static int $maxGeneralsPerMinute = 1000;
}

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