dev 코드와 일치

This commit is contained in:
2020-03-22 23:30:11 +09:00
parent bdcc79ce34
commit 68e01c1e73
18 changed files with 307 additions and 30 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
The MIT License
Copyright (c) 2018 Hide_D, 62che
Copyright (c) 2020 Hide_D, 62che
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+15 -9
View File
@@ -7,20 +7,26 @@
* Apache2
* <code>mpm_event</code> 권장
* PHP 7.2 이상
* PHP 7.3 이상
* <code>php-fpm</code> 권장
* php에서 curl, pdo-sqlite을 실행가능해야 합니다. (기본값: 지원)
* mysqlnd가 지원되어야합니다. (기본값: 지원)
* mysqli
* gd
* MariaDB 10.2.1 이상
* MySQL 5.6 이상도 가능하도록 할 예정입니다.
* 현재 MySQL은 지원하지 않습니다.
* <code>git</code>
* <code>curl</code>
Linux는 Ubuntu 16.04, Windows는 Windows 10에서 XAMPP를 사용한 환경에서 테스트되었습니다.
Linux는 Ubuntu 16.04, 18.04, Windows는 Windows 10에서 XAMPP를 사용한 환경에서 테스트되었습니다.
Docker를 이용한 설치는 계획중입니다.
## 설치
## Docker를 이용한 설치
https://storage.hided.net/gogs/devsam/docker 를 참고해 주세요.
## 수동 설치
본 게임은 <code>git</code>을 이용한 업그레이드 시스템을 구현하였으므로, <code>git</code>이 필요합니다.
또한 웹 서비스 데몬을 운영중인 사용자(일반적으로 <code>www-data</code>, <code>apache</code>)에게 디렉토리 권한이 주어져야합니다.
@@ -30,11 +36,11 @@ Docker를 이용한 설치는 계획중입니다.
웹 데몬 user가 <code>www-data</code>인 경우 다음과 같이 입력하여 최신 배포버전과 이미지 파일을 얻을 수 있습니다.
```
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
sudo -u www-data git clone https://storage.hided.net/gogs/devsam/core.git
sudo -u www-data git clone https://storage.hided.net/gogs/devsam/image.git
```
> 이미지는 git hook을 이용한 업데이트 기능을 제공하지만 아직 범용성 있는 설계가 되어있진 않습니다.
> 이미지는 hook/git_hook.php을 통해 동기화되며, 서버 설치 과정에 이미지 갱신 키를 지정하는 것으로 '훼' 서버 업데이트 시 동기화됩니다. 이미지 서버가 게임 서버와 별개여도 동작하나, php와 git을 지원해야합니다.
### 설치
@@ -47,9 +53,9 @@ Database 수는 로그인 관리 서버 1개, 내부 서버 7개로, 총 8개의
## 카카오로그인 연동
현재 카카오로그인 API KEY를 입력하는 작업이 설치과정에 추가되어있지 않습니다.
서버 설치 시 카카오 로그인 연동을 위한 API KEY를 입력습니다.
설치 후 <code>d_setting/KakaoKey.php</code>에서 API키를 입력해야 합니다.
만약 설치 이후 API KEY를 변경하고자 하는 경우 <code>d_setting/KakaoKey.php</code>에서 API키를 변경해야 합니다.
## 라이선스
+11
View File
@@ -166,6 +166,17 @@ a.samButton.disabled {
content:'】'
}
.tooltip_copyable_info .tooltiptext{
display: inline;
color: rgba(0,0,0,0);
font-size: 0;
}
.tooltiptext {
display: none;
}
.hidden_but_copyable{
color: rgba(0,0,0,0);
font-size: 0;
}
File diff suppressed because one or more lines are too long
+32
View File
@@ -98,6 +98,38 @@ require(__dir__.'/../vendor/autoload.php');
</div>
</div>
<div class="form-group row">
<label for="image_request_key" class="col-sm-4 col-form-label">이미지 갱신 키</label>
<div class="input-group col-sm-8">
<input type="text" class="form-control" name="image_request_key" id="image_request_key"
placeholder="이미지 서버의 hook/HashKey.php의 값과 동일하게"
value="" />
<div class="input-group-append">
<button id="btn_random_generate_key" class="btn btn-secondary" type="button">랜덤 생성</button>
</div>
</div>
</div>
<hr style="width:100%; border-top: 1px solid lightgray;">
<div class="form-group row">
<label for="kakao_rest_key" class="col-sm-4 col-form-label">카카오 API Rest Key</label>
<div class="col-sm-8">
<input type="text" class="form-control" name="kakao_rest_key" id="kakao_rest_key"
placeholder="카카오톡 API의 Rest Key"
value="" />
</div>
</div>
<div class="form-group row">
<label for="kakao_admin_key" class="col-sm-4 col-form-label">카카오 API Admin Key</label>
<div class="col-sm-8">
<input type="text" class="form-control" name="kakao_admin_key" id="kakao_admin_key"
placeholder="카카오톡 API의 Admin Key"
value="" />
</div>
</div>
<div class="form-group row">
<div class="col-sm-4"></div>
<div class="col-sm-8">
+21 -2
View File
@@ -11,6 +11,11 @@ $dbName = Util::getReq('db_name');
$servHost = Util::getReq('serv_host');
$sharedIconPath = Util::getReq('shared_icon_path');
$gameImagePath = Util::getReq('game_image_path');
$imageRequestKey = Util::getReq('image_request_key');
$kakaoRESTKey = Util::getReq('kakao_rest_key', 'string', '');
$kakaoAdminKey = Util::getReq('kakao_admin_key', 'string', '');
if (!$host || !$port || !$username || !$password || !$dbName || !$servHost || !$sharedIconPath || !$gameImagePath) {
Json::die([
@@ -186,6 +191,8 @@ $globalSalt = bin2hex(random_bytes(16));
$sharedIconPath = WebUtil::resolveRelativePath($sharedIconPath, $servHost);
$gameImagePath = WebUtil::resolveRelativePath($gameImagePath, $servHost);
$imageRequestPath = WebUtil::resolveRelativePath($gameImagePath.'/../hook/git_pull.php', $servHost);
$imageKeyInstallPath = WebUtil::resolveRelativePath($gameImagePath.'/../hook/InstallKey.php', $servHost);
$result = Util::generateFileUsingSimpleTemplate(
__dir__.'/templates/ServConfig.orig.php',
@@ -193,11 +200,17 @@ $result = Util::generateFileUsingSimpleTemplate(
[
'serverBasePath'=>$servHost,
'sharedIconPath'=>$sharedIconPath,
'gameImagePath'=>$gameImagePath
'gameImagePath'=>$gameImagePath,
'imageRequestPath'=>$imageRequestPath,
'imageRequestKey'=>$imageRequestKey
],
true
);
if($imageRequestKey){
@file_get_contents($imageKeyInstallPath.'?key='.$imageRequestKey);
}
if ($result !== true) {
Json::die([
'result'=>false,
@@ -263,10 +276,15 @@ $result = Util::generateFileUsingSimpleTemplate(
]
);
$kakaoRedirectURI = WebUtil::resolveRelativePath('oauth_kakao/oauth.php', $servHost.'/');
Util::generateFileUsingSimpleTemplate(
__dir__.'/templates/KakaoKey.orig.php',
ROOT.'/d_setting/KakaoKey.php',
[
'REST_API_KEY'=>$kakaoRESTKey,
'ADMIN_KEY'=>$kakaoAdminKey,
'REDIRECT_URI'=>$kakaoRedirectURI
],
true
);
@@ -280,5 +298,6 @@ if ($result !== true) {
Json::die([
'result'=>true,
'reason'=>'success'
'reason'=>'success',
'globalSalt'=>$globalSalt
]);
+1 -1
View File
@@ -30,7 +30,7 @@ class RootDB
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= false;
self::$uDB->error_handler= function(){};
self::$uDB->throw_exception_on_error = true;
self::$uDB->throw_exception_on_nonsql_error = true;
}
+9
View File
@@ -10,6 +10,8 @@ class ServConfig
public static $serverWebPath = '_tK_serverBasePath_';
public static $sharedIconPath = '_tK_sharedIconPath_';
public static $gameImagePath = "_tK_gameImagePath_";
public static $imageRequestPath = "_tK_imageRequestPath_";
public static $imageRequestKey = '_tK_imageRequestKey_';
public static function getSharedIconPath(string $filepath='') : string
{
@@ -32,6 +34,13 @@ class ServConfig
return static::$gameImagePath;
}
public static function getImagePullURI() : string
{
$now = time();
$req_hash = Util::hashPassword(sprintf("%016x",$now), static::$imageRequestKey);
return static::$imageRequestPath."?req={$req_hash}&time={$now}";
}
/**
* 서버 주소 반환. 서버의 경로가 하부 디렉토리인 경우에 하부 디렉토리까지 포함
+61 -1
View File
@@ -88,6 +88,59 @@
background-size: 700px 500px;
}
/*미니체 지도*/
.map_theme_miniche_b.map_spring .map_bglayer1{
background: url('_tK_gameImagePath_/map/che/bg_spring.jpg') no-repeat;
background-size: 700px 500px;
}
.map_theme_miniche_b.map_summer .map_bglayer1{
background: url('_tK_gameImagePath_/map/che/bg_summer.jpg') no-repeat;
background-size: 700px 500px;
}
.map_theme_miniche_b.map_fall .map_bglayer1{
background: url('_tK_gameImagePath_/map/che/bg_fall.jpg') no-repeat;
background-size: 700px 500px;
}
.map_theme_miniche_b.map_winter .map_bglayer1{
background: url('_tK_gameImagePath_/map/che/bg_winter.jpg') no-repeat;
background-size: 700px 500px;
}
.map_theme_miniche_b .map_bgroad{
background: url('_tK_gameImagePath_/map/che/miniche_road.png') no-repeat;
background-size: 700px 500px;
}
/*미니체 지도*/
.map_theme_miniche_clean.map_spring .map_bglayer1{
background: url('_tK_gameImagePath_/map/che/bg_spring.jpg') no-repeat;
background-size: 700px 500px;
}
.map_theme_miniche_clean.map_summer .map_bglayer1{
background: url('_tK_gameImagePath_/map/che/bg_summer.jpg') no-repeat;
background-size: 700px 500px;
}
.map_theme_miniche_clean.map_fall .map_bglayer1{
background: url('_tK_gameImagePath_/map/che/bg_fall.jpg') no-repeat;
background-size: 700px 500px;
}
.map_theme_miniche_clean.map_winter .map_bglayer1{
background: url('_tK_gameImagePath_/map/che/bg_winter.jpg') no-repeat;
background-size: 700px 500px;
}
.map_theme_miniche_clean .map_bgroad{
background: url('_tK_gameImagePath_/map/che/miniche_road.png') no-repeat;
background-size: 700px 500px;
}
/*루드라사움 지도*/
.map_theme_ludo_rathowm .map_bglayer1{
background: url('_tK_gameImagePath_/map/ludo_rathowm/back.jpg') no-repeat;
@@ -109,4 +162,11 @@
.map_theme_chess .map_bglayer1{
background: url('_tK_gameImagePath_/map/chess/chessboard.png') no-repeat;
background-size: 700px 500px;
}
}
/*포켓몬 v1 지도*/
.map_theme_pokemon_v1 .map_bglayer1{
background: url('_tK_gameImagePath_/map/pokemon_v1/back_pal8.png') no-repeat;
background-size: 700px 500px;
}
+1
View File
@@ -32,6 +32,7 @@ $acl = $session->acl;
<!-- 액션 -->
<?=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
<?=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
<?=WebUtil::printJS('../e_lib/moment.min.js')?>
<?=WebUtil::printJS('../js/common.js')?>
<?=WebUtil::printJS('../js/func.js')?>
<?=WebUtil::printJS('../js/entrance.js')?>
+1 -1
View File
@@ -196,7 +196,7 @@ function postOAuthResult(result){
</div>
</div>
<div id="bottom_box">
<div class="container"><a href="terms.2.html">개인정보처리방침</a> &amp; <a href="terms.1.html">이용약관</a><br>© 2018 • HideD
<div class="container"><a href="terms.2.html">개인정보처리방침</a> &amp; <a href="terms.1.html">이용약관</a><br>© 2020 • HideD
<br>크롬과 파이어폭스에 최적화되어있습니다.</div></div>
</div>
+58 -6
View File
@@ -58,12 +58,13 @@ if(!$allowUpdate){
]);
}
$src_target = $storage->$server;
if($src_target){
$src_target = $src_target[0];
}
if(!$allowFullUpdate || !$target){
$target = $storage->$server;
if($target){
$target = $target[0];
}
$target = $src_target;
}
else{
$target = $request['target'];
@@ -114,6 +115,26 @@ if(!file_exists($server)){
if($server == $baseServerName){
exec("git fetch -q 2>&1", $output);
if($output){
Json::die([
'result'=>false,
'reason'=>'git pull 작업 : '.join(', ', $output)
]);
}
if($target != $src_target){
$command = sprintf('git checkout %s -q 2>&1', $target);
exec($command, $output);
if($output){
Json::die([
'result'=>false,
'reason'=>join(', ', $output)
]);
}
}
exec("git pull -q 2>&1", $output);
if($output && $output[0] != 'Already up-to-date.'){
Json::die([
@@ -129,13 +150,44 @@ if($server == $baseServerName){
'verionGit'=>$version
], true
);
if(ServConfig::$imageRequestKey){
try {
$imagePullPath = ServConfig::getImagePullURI();
$pullResult = @file_get_contents($imagePullPath);
if($pullResult === false){
throw new \ErrorException('Invalid URI');
}
$pullResult = Json::decode($pullResult);
if($pullResult['result']){
$imgResult = true;
$imgDetail = $pullResult['version'];
}
else{
$imgResult = false;
$imgDetail = $pullResult['reason'];
}
}
catch(\Exception $e){
$imgResult = false;
$imgDetail = $e->getMessage();
}
}
else{
$imgResult = true;
$imgDetail = 'No key';
}
$storage->$server = [null, $version];
$storage->$server = [$target, $version];
Json::die([
'server'=>$server,
'result'=>true,
'version'=>$version
'version'=>$version,
'imgResult'=>$imgResult,
'imgDetail'=>$imgDetail,
]);
}
+1
View File
@@ -205,6 +205,7 @@ def extractGeneralList(generalSheet, nationList={}, nationChiefInfo={}):
if '환경 변수' in wb.sheet_names():
config = parseConfig(wb.sheet_by_name('환경 변수'))
config['startYear'] -= 3
else:
config = {
'title':'타이틀'
+7 -3
View File
@@ -5,9 +5,11 @@ import time
import glob
import urllib.request
import concurrent.futures
from datetime import datetime
def run(webPath):
print(webPath)
now = datetime.now()
print(now.strftime("%Y-%m-%d %H:%M:%S"), webPath)
obj = urllib.request.urlopen(webPath)
obj.read()
@@ -44,15 +46,17 @@ def main():
servList.append(webPath)
with concurrent.futures.ThreadPoolExecutor(max_workers=len(servList)) as executor:
with concurrent.futures.ThreadPoolExecutor(max_workers=max(1,len(servList))) as executor:
waiters=[]
for resetPath in autoResetList:
future = executor.submit(run, resetPath)
waiters.append(future)
for _ in range(4):
for idx in range(4):
for webPath in servList:
future = executor.submit(run, webPath)
waiters.append(future)
if idx == 3:
break
time.sleep(15)
for future in waiters:
future.done()
+1 -1
View File
@@ -10,7 +10,7 @@ class KVStorage{
static private $storageList = [];
static public function getStorage(\MeekroDB $db, string $storNamespace, string $tableName='storage'):self{
$obj_id = spl_object_id($db);
$obj_id = spl_object_hash($db);
$fullKey = $obj_id.','.$storNamespace.','.$tableName;
if(key_exists($fullKey, static::$storageList)){
return static::$storageList[$fullKey];
+12 -4
View File
@@ -312,9 +312,13 @@ class Session
* 로그인 유저의 전역 grade를 받아옴
* @return int|null
*/
public static function getUserGrade($actionOnError = '..')
public static function getUserGrade(bool $requireLogin = false, string $exitPath = '..')
{
$obj = self::requireLogin($actionOnError);
if ($requireLogin) {
$obj = self::requireLogin($exitPath);
} else {
$obj = self::getInstance();
}
return $obj->userGrade;
}
@@ -324,9 +328,13 @@ class Session
*
* @return int|null
*/
public static function getUserID($actionOnError = '..')
public static function getUserID(bool $requireLogin = false, string $exitPath = '..')
{
$obj = self::requireLogin($actionOnError);
if ($requireLogin) {
$obj = self::requireLogin($exitPath);
} else {
$obj = self::getInstance();
}
return $obj->userID;
}
+73
View File
@@ -3,6 +3,79 @@ namespace sammo;
class TimeUtil
{
/** @deprecated */
public static function DateToday()
{
return date('Y-m-d');
}
/** @deprecated */
public static function DatetimeNow()
{
return date('Y-m-d H:i:s');
}
/** @deprecated */
public static function DatetimeFromNowDay($day)
{
return date('Y-m-d H:i:s', strtotime("{$day} days"));
}
/** @deprecated */
public static function DatetimeFromNowHour($hour)
{
return date('Y-m-d H:i:s', strtotime("{$hour} hours"));
}
/** @deprecated */
public static function DatetimeFromNowMinute($minute)
{
return date('Y-m-d H:i:s', strtotime("{$minute} minutes"));
}
/** @deprecated */
public static function DatetimeFromNowSecond($second)
{
return date('Y-m-d H:i:s', strtotime("{$second} seconds"));
}
/** @deprecated */
public static function DatetimeFromMinute($date, $minute)
{
return date('Y-m-d H:i:s', strtotime($date) + $minute*60);
}
/** @deprecated */
public static function DatetimeFromSecond($date, $second)
{
return date('Y-m-d H:i:s', strtotime($date) + $second);
}
/** @deprecated */
public static function CutSecond($date)
{
$date[17] = '0';
$date[18] = '0';
return $date;
}
/** @deprecated */
public static function CutMinute($date)
{
$date[14] = '0';
$date[15] = '0';
$date[17] = '0';
$date[18] = '0';
return $date;
}
/** @deprecated */
public static function HourMinuteSecond($second)
{
return date('H:i:s', strtotime('00:00:00') + $second);
}
public static function today()
{
$obj = new \DateTime();
+1 -1
View File
@@ -156,7 +156,7 @@ class WebUtil
$config = \HTMLPurifier_HTML5Config::createDefault();
$config->set('Filter.Custom', array (new \HTMLPurifier_Filter_YouTube()));
$config->set('HTML.SafeIframe', true);
$config->set('URI.SafeIframeRegexp', '%^(https?:)?//(www\.youtube(?:-nocookie)?\.com/embed/|player\.vimeo\.com/video/)%'); //allow YouTube and Vime
$config->set('URI.SafeIframeRegexp', '%^(https?:)?//(www\.youtube(?:-nocookie)?\.com/embed/|player\.vimeo\.com/video/)%'); //allow YouTube and Vimeo
$def = $config->getHTMLDefinition();
$def->info_global_attr['data-flip'] = new \HTMLPurifier_AttrDef_Text;
$purifier = new \HTMLPurifier($config);