mpm_event 권장
+* PHP 7.0 이상
+ * php-fpm 권장
+ * php에서 curl을 실행가능해야 합니다.
+* MySQL 5.6 이상, 또는 MariaDB 10.0 이상
+* git
+* curl
+
+Linux는 Ubuntu 16.04, Windows는 Windows 10에서 XAMPP를 사용한 환경에서 테스트되었습니다.
+
+Docker를 이용한 설치는 계획중입니다.
+
+## 설치
+
+본 게임은 git을 이용한 업그레이드 시스템을 구현하였으므로, git이 필요합니다.
+또한 웹 서비스 데몬을 운영중인 사용자(일반적으로 www-data, apache)에게 디렉토리 권한이 주어져야합니다.
+
+### 다운로드
+
+웹 데몬 user가 www-data인 경우 다음과 같이 입력하여 최신 배포버전과 이미지 파일을 얻을 수 있습니다.
+
+```
+sudo -u www-data git clone ssh://git@storage.hided.net:2525/devsam/core.git
+git clone ssh://git@storage.hided.net:2525/devsam/image.git
+```
+
+> 이미지는 별도의 업데이트 기능을 제공하지 않습니다. 수동으로 git pull을 해야합니다.
+
+### 설치
+
+이후 해당 경로를 웹 브라우저를 통해 접근하여 설치를 진행할 수 있습니다.
+
+Database 수는 로그인 관리 서버 1개, 내부 서버 5개로, 총 6개의 Database가 필요합니다. 내부 설정을 고쳐서 서버 수를 늘리거나 줄일 경우 그에 맞는 Database 수가 필요합니다. 또한 Database마다 관리할 별도의 계정을 만드는 것을 추천합니다.
+
+설치 이후에는 서버관리 페이지에서 **업데이트** 명령을 통해 원 클릭 업데이트가 가능합니다.
+
+
+## 카카오로그인 연동
+
+현재 카카오로그인 API KEY를 입력하는 작업이 설치과정에 추가되어있지 않습니다.
+
+f_install/templates/KakaoKey.orig.php 를 d_setting/KakaoKey.php로 복사한 후 API 키를 입력하여야 합니다.
+
+
+## 라이선스
+
+본 게임을 수정하거나 재배포할 경우 다음 중 하나의 라이선스를 선택하여 적용할 수 있습니다.
+
+* MIT License
+* GPL 2.0 또는 이후
+
+만약 별도의 라이선스를 적용하고자 할 경우 Hide_D에게 문의하여 주십시오.
\ No newline at end of file
diff --git a/css/config.css b/css/config.css
index 10e622c5..e80690c4 100644
--- a/css/config.css
+++ b/css/config.css
@@ -1,7 +1,7 @@
@charset "utf-8";
* { margin: 0px; padding: 0px; }
-body { color:white; background-color:black; border-width:1; border-color:gray; }
+body { color:white; background-color:black; border-width:1px; border-color:gray; }
table {
border: solid 1px; border-spacing: 0px; border-collapse: separate; border-top-color: gray; border-left-color: gray; border-right-color: black; border-bottom-color: black;
padding: 0px;
diff --git a/f_install/j_install_status.php b/f_install/j_install_status.php
index 23e87164..15d7c65a 100644
--- a/f_install/j_install_status.php
+++ b/f_install/j_install_status.php
@@ -24,7 +24,7 @@ $rootDB->error_handler = function($params){
]);
};
-$memberCnt = $rootDB->queryFirstField('SELECT count(`NO`) from MEMBER');
+$memberCnt = $rootDB->queryFirstField('SELECT count(`NO`) from member');
if($memberCnt == 0){
Json::die([
'step'=>'admin',
diff --git a/f_install/templates/RootDB.orig.php b/f_install/templates/RootDB.orig.php
index c59ce260..f41fbd15 100644
--- a/f_install/templates/RootDB.orig.php
+++ b/f_install/templates/RootDB.orig.php
@@ -29,6 +29,8 @@ class RootDB
if (self::$uDB === null) {
self::$uDB = new \MeekroDB(self::$host, self::$user, self::$password, self::$dbName, self::$port, self::$encoding);
self::$uDB->connect_options[MYSQLI_OPT_INT_AND_FLOAT_NATIVE] = true;
+
+ self::$uDB->error_handler= function(){};
self::$uDB->throw_exception_on_error = true;
self::$uDB->throw_exception_on_nonsql_error = true;
}
diff --git a/f_install/templates/ServConfig.orig.php b/f_install/templates/ServConfig.orig.php
index c24d8501..adb6b8be 100644
--- a/f_install/templates/ServConfig.orig.php
+++ b/f_install/templates/ServConfig.orig.php
@@ -11,18 +11,24 @@ class ServConfig
public static $sharedIconPath = '_tK_sharedIconPath_';
public static $gameImagePath = "_tK_gameImagePath_";
- public static function getSharedIconPath() : string
+ public static function getSharedIconPath(string $filepath='') : string
{
+ if($filepath){
+ return static::$sharedIconPath."/{$filepath}";
+ }
return static::$sharedIconPath;
}
- public static function getUserIconPath() : string
+ public static function getUserIconPath(string $filepath='') : string
{
- return AppConf::getUserIconPathWeb();
+ return AppConf::getUserIconPathWeb($filepath);
}
- public static function getGameImagePath() : string
+ public static function getGameImagePath(string $filepath='') : string
{
+ if($filepath){
+ return static::$gameImagePath."/{$filepath}";
+ }
return static::$gameImagePath;
}
diff --git a/hwe/_119_b.php b/hwe/_119_b.php
index e6dfe110..34ba6505 100644
--- a/hwe/_119_b.php
+++ b/hwe/_119_b.php
@@ -24,6 +24,8 @@ $btn = Util::getReq('btn');
$minute = Util::getReq('minute', 'int');
$minute2 = Util::getReq('minute2', 'int');
+extractMissingPostToGlobals();
+
$db = DB::db();
$connect=$db->get();
diff --git a/hwe/_admin1_submit.php b/hwe/_admin1_submit.php
index 9a2c65de..88b4c4ac 100644
--- a/hwe/_admin1_submit.php
+++ b/hwe/_admin1_submit.php
@@ -22,6 +22,7 @@ if (!$v->validate()) {
Error($v->errorStr());
}
+$msg = Util::getReq('msg');
$btn = Util::getReq('btn');
$log = Util::getReq('log');
$starttime = Util::getReq('starttime', 'string', (new \DateTime())->format('Y-m-d H:i:s'));
@@ -29,6 +30,8 @@ $maxgeneral = Util::getReq('maxgeneral', 'int', GameConst::$defaultMaxGeneral);
$maxnation = Util::getReq('maxnation', 'int', GameConst::$defaultMaxNation);
$startyear = Util::getReq('startyear', 'int', GameConst::$defaultStartYear);
+extractMissingPostToGlobals();
+
$db = DB::db();
$connect=$db->get();
diff --git a/hwe/_admin2_submit.php b/hwe/_admin2_submit.php
index fc568cc1..c36380c2 100644
--- a/hwe/_admin2_submit.php
+++ b/hwe/_admin2_submit.php
@@ -7,6 +7,8 @@ include "func.php";
$btn = Util::getReq('btn');
$weap = Util::getReq('weap', 'int');
+extractMissingPostToGlobals();
+
//로그인 검사
$session = Session::requireLogin()->loginGame()->setReadOnly();
@@ -24,281 +26,326 @@ $connect=$db->get();
switch($btn) {
case "전체 접속허용":
- $query = "update general set con=0";
- MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
+ $db->update('general', [
+ 'con'=>0
+ ], true);
break;
case "전체 접속제한":
- $query = "update general set con=1000";
- MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
+ $db->update('general', [
+ 'con'=>1000
+ ], true);
break;
case "블럭 해제":
+ $db->update('general', [
+ 'block'=>0
+ ], '`no` IN %li', $genlist);
DB::db()->query('update general set block=0 where no IN %li', $genlist);
break;
case "1단계 블럭":
$date = date('Y-m-d H:i:s');
- $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 no IN %ls', $date, $uid);
+ $db->update('general', [
+ 'block'=>1,
+ 'killturn'=>24
+ ], '`no` IN %li', $genlist);
+ $uid = $db->queryFirstColumn('SELECT `owner` FROM general WHERE `no` IN %li', $genlist);
+ RootDB::db()->update('member',[
+ 'block_num'=>$db->sqleval('block_num+1'),
+ 'block_date'=>$date
+ ], 'id IN %li', $uid);
break;
case "2단계 블럭":
$date = date('Y-m-d H:i:s');
- $db = DB::db();
- $db->query('update general set gold=0,rice=0,block=2,killturn=24 where no IN %li',$genlist);
+ $db->update('general', [
+ 'gold'=>0,
+ 'rice'=>0,
+ 'block'=>2,
+ 'killturn'=>24
+ ], '`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);
+ RootDB::db()->update('member',[
+ 'block_num'=>$db->sqleval('block_num+1'),
+ 'block_date'=>$date
+ ], 'id IN %li', $uid);
break;
case "3단계 블럭":
$date = date('Y-m-d H:i:s');
- $db = DB::db();
- $db->query('update general set gold=0,rice=0,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);
+ $db->update('general', [
+ 'gold'=>0,
+ 'rice'=>0,
+ 'block'=>3,
+ 'killturn'=>24
+ ], '`no` IN %li', $genlist);
+ $uid = $db->queryFirstColumn('SELECT `owner` from general where no IN %li', $genlist);
+ RootDB::db()->update('member',[
+ 'block_num'=>$db->sqleval('block_num+1'),
+ 'block_date'=>$date
+ ], 'id IN %li', $uid);
break;
case "무한삭턴":
- DB::db()->query('update general set killturn=8000 where no IN %li',$genlist);
+ $db->update('general', [
+ 'killturn'=>8000
+ ], '`no` IN %li', $genlist);
break;
case "강제 사망":
$date = date('Y-m-d H:i:s');
- DB::db()->query('update general set turn0=0,killturn=0,turntime=%s where no IN %li',$date, $genlist);
+ $db->update('general', [
+ 'turn0'=>0,
+ 'killturn'=>0,
+ 'turntime'=>$date,
+ ], '`no` IN %li', $genlist);
break;
case "특기 부여":
- $admin = DB::db()->queryFirstRow('select `year`, `month` from `game` where `no`=1');
+ list($year, $month) = $db->queryFirstList('select `year`, `month` from `game` where `no`=1');
- for($i=0; $i < count($genlist); $i++) {
- $you = DB::db()->queryFirstRow('select `no`, `nation` from `general` where `no` = %i', $genlist[$i]);
- $msg = "특기 부여!";
- sendMessage('private', ['id'=>$generalID, 'nation_id'=>0], ['id'=>$you['no'], 'nation_id'=>$you['nation']], $msg);
- }
- for($i=0; $i < count($genlist); $i++) {
- $query = "select no,leader,power,intel from general where no='$genlist[$i]'";
- $result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
- $general = MYDB_fetch_array($result);
+ $src = MessageTarget::buildQuick($session->generalID);
+ $text = "특기 부여!";
- $special2 = getSpecial2($general['leader'], $general['power'], $general['intel']);
+ foreach($db->query("SELECT `no`,leader,power,intel,dex0,dex10,dex20,dex30,dex40 FROM general WHERE `no` IN %li", $genlist) as $general){
+ $msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($general['no']), $text, new DateTime(), new DateTime('9999-12-31'), []);
+ $msg->send(true);
- $query = "update general set specage2=age,special2='$special2' where no='{$general['no']}'";
- MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
-
- $log[0] = "| =getTrickLogRecent(20)?> |
| =getSabotageLogRecent(20)?> |
| "; } else { $imageTemp = GetImageURL($gen['imgsvr']); - echo " | "; } else { $imageTemp = GetImageURL($gen['imgsvr']??0); - echo " | "; } else { $imageTemp = GetImageURL($gen['imgsvr']??0); - echo " | 삭턴 | 벌점 | "; -for($j=0; $j < $gencount; $j++) { +for ($j=0; $j < $gencount; $j++) { $general = MYDB_fetch_array($genresult); $nation = $nationname[$general['nation']]; - if($general['level'] == 12) { + if ($general['level'] == 12) { $lbonus = $nationlevel[$general['nation']] * 2; - } elseif($general['level'] >= 5) { + } elseif ($general['level'] >= 5) { $lbonus = $nationlevel[$general['nation']]; } else { $lbonus = 0; } - if($lbonus > 0) { + if ($lbonus > 0) { $lbonus = "+{$lbonus}"; } else { $lbonus = ""; } - if($general['injury'] > 0) { + if ($general['injury'] > 0) { $leader = intdiv($general['leader'] * (100 - $general['injury']), 100); $power = intdiv($general['power'] * (100 - $general['injury']), 100); $intel = intdiv($general['intel'] * (100 - $general['injury']), 100); @@ -142,16 +151,20 @@ for($j=0; $j < $gencount; $j++) { $intel = "{$general['intel']}"; } - if($general['npc'] >= 2) { $name = "{$general['name']}"; } - elseif($general['npc'] == 1) { $name = "{$general['name']}"; } - else { $name = "{$general['name']}"; } + if ($general['npc'] >= 2) { + $name = "{$general['name']}"; + } elseif ($general['npc'] == 1) { + $name = "{$general['name']}"; + } else { + $name = "{$general['name']}"; + } $general['connect'] = Util::round($general['connect'] / 10) * 10; $imageTemp = GetImageURL($general['imgsvr']); echo "||||||||||||||||
| $name | {$general['age']}세 | ".getGenChar($general['personal'])." | @@ -160,12 +173,15 @@ for($j=0; $j < $gencount; $j++) {{$nation} | ".getHonor($general['experience'])." | ".getDed($general['dedication'])." | -"; echo getLevel($general['level']); echo " | +"; + echo getLevel($general['level']); + echo " | $leader | $power | $intel | {$general['killturn']} | -{$general['connect']}"; echo " 【".getConnect($general['connect'])."】 |
+ {$general['connect']}";
+ echo " 【".getConnect($general['connect'])."】 |
|||||||
| 명 예 의 전 당 =closeButton()?> |
| "; } else { $imageTemp = GetImageURL($gen['imgsvr']); - echo " |
| =closeButton()?> |
| =banner()?> |
| 접 속 량 | ||||
| 접 속 자 | ||||
| - | + | |||
| - | + | |||
| - | - | + | ||