diff --git a/.phan/config.php b/.phan/config.php index 513c421a..b6a5feea 100644 --- a/.phan/config.php +++ b/.phan/config.php @@ -101,13 +101,11 @@ return [ 'hwe/j_export_simulator_object.php', 'hwe/j_general_log_old.php', 'hwe/j_general_set_permission.php', - 'hwe/j_general_turn.php', 'hwe/j_get_basic_general_list.php', 'hwe/j_getChiefTurn.php', 'hwe/j_get_city_list.php', 'hwe/j_get_general_list.php', 'hwe/j_get_nation_general_list.php', - 'hwe/j_get_reserved_command.php', 'hwe/j_get_select_npc_token.php', 'hwe/j_get_select_pool.php', 'hwe/j_image_upload.php', diff --git a/hwe/css/common.css b/hwe/css/common.css index 664b4c21..0dfca57d 100644 --- a/hwe/css/common.css +++ b/hwe/css/common.css @@ -1,7 +1,3 @@ -@charset "UTF-8"; - -/* font-boostring Block */ - html * { max-height: 1000000px; } diff --git a/hwe/css/main.css b/hwe/css/main.css deleted file mode 100644 index 600aea20..00000000 --- a/hwe/css/main.css +++ /dev/null @@ -1,100 +0,0 @@ -@charset "UTF-8"; - -body { -color:white; - background-color:black; - border-width:1px; - border-color:gray; background-position:center; background-repeat:repeat-y; -} - -#container { - width:1000px; - margin: 0 auto; -} - -.buttonPlate{ - width:1000px; - height:60px; -} - -.toolbarButton { - float:left; - background-color:#225500; - color:white; - width:125px; - height:30px; - font-weight:bold; - font-size:13px; - margin:0; - display:block; -} - -.commandButton { - float:left; - width:100px; - height:30px; - font-weight:bold; - font-size:13px; - margin:0; - display:block; -} - -.commandButton:disabled::before{ - content:'【' -} - -.commandButton:disabled::after{ - content:'】' -} - -.commandButton:disabled{ - background-color:transparent !important; - color:gray !important; - border-color:transparent !important; -} - -.toolbarButton2 { - float:left; - background-color:#225500; - color:magenta; - width:125px; - height:30px; - font-weight:bold; - font-size:13px; - margin:0; - display:block; -} - -.nation_info td{ - height:18px; -} - -#generalTurnSelector{ - width:50px; - color:white; - background-color:black; - font-size:13px; -} - -#sidebar{ - position:fixed; - right:0; - top: 50%; - transform: translateY(-50%); -} - -#sidebar button{ - /*width:100px;*/ -} - -.turn_pad{ - white-space:nowrap; - font-weight:lighter; - max-width: 162px; - width: 162px; - -} - -.turn_pad .turn_text{ - display:inline-block; -} \ No newline at end of file diff --git a/hwe/css/map.css b/hwe/css/map.css index 44ff4fb9..9e3f0e73 100644 --- a/hwe/css/map.css +++ b/hwe/css/map.css @@ -5,6 +5,7 @@ background:black; font-size:13px; color:white; + position: relative; } .map_title{ @@ -33,6 +34,7 @@ width:700px; height:500px; position:relative; + overflow: hidden; } .map_body .map_bglayer1{ @@ -88,7 +90,7 @@ .world_map .city_tooltip{ position: absolute; - z-index:6; + z-index:16; display:none; min-width:120px; border: 0.02em gray solid; @@ -99,7 +101,7 @@ z-index: 6; line-height:15px; height:15px; - + } .world_map .nation_name{ background-color: rgb(30, 164, 255); @@ -491,4 +493,9 @@ .map_basic .city_base .city_state.city_state_good{ background-color:blue; +} + +.btn.btn-minimum{ + padding-top: 1px; + padding-bottom: 1px; } \ No newline at end of file diff --git a/hwe/css/msg.css b/hwe/css/msg.css deleted file mode 100644 index dc21a268..00000000 --- a/hwe/css/msg.css +++ /dev/null @@ -1,202 +0,0 @@ -@charset "UTF-8"; - -/*임시용 */ - -#container{ - width:1000px; - margin:auto; - font-size:13px; -} -/*임시용 끝*/ - -#message_board{ - height:1370px; - position:relative; -} - -#message_board section{ - overflow-y:auto; - overflow-x:hidden; -} - -.msg_plate{ - width:100%; - outline-style:solid; - outline-width:1px; - outline-color: gray; - min-height:64px; - font-size:12px; - word-break:break-all; - color:white; -} - -.msg_plate_private{ - background-color:#5d1e1a; -} - -.msg_plate_private.msg_plate_dest{ - background-color:#5d461a; -} - -.msg_plate_public{ - background-color:#141c65; - -} - -.msg_plate_national, .msg_plate_diplomacy{ - background-color:#00582c; -} - -.msg_plate_national.msg_plate_dest, .msg_plate_diplomacy.msg_plate_dest { - background-color:#704615; -} - -.msg_plate_national.msg_plate_src, .msg_plate_diplomacy.msg_plate_src { - background-color:#70153b; -} - -.public_message{ - height:667px; -} - -.diplomacy_message{ - flex: 1; -} - -.national_message{ - height:667px; -} - -.private_message{ - flex: 1; -} - -.msg_icon{ - float:left; - width:64px; - height:64px; - border-right:solid 1px gray; -} - -.msg_time{ - font-size:0.75em; - font-weight:normal; -} - -.msg_header{ - font-weight: bold; - margin-bottom:3px; - color:white; - position: relative; -} - -.message_input_form{ - position:relative; -} - -#msg_input{ - color:white; - background-color:black; - font-size:12px; - width:715px; - margin:0 2px; - height:20px; - border:solid 1px gray; -} - -#msg_submit{ - position:absolute; - right:0; - margin-right:2px; -} - -#mailbox_list{ - float:left; - color:white; - background-color:black; - font-size:12px; - width:160px; - height:20px; -} - -.board_header{ - color:white; - outline-style:solid; - outline-width:1px; - outline-color: gray; -} - -.board_side{ - position:absolute; - height:1370px; - width:50%; - overflow-y: hidden; - outline-style:solid; - outline-width:1px; - outline-color: gray; - display: flex; - flex-wrap: wrap; - flex-direction: column; -} -.board_side > div{ - height: 1.2em; -} - -.msg_invalid{ - color:rgba(255,255,255,0.5); -} - -.msg_body{ - padding-left:64px; -} - -.msg_target{ - margin:2px 2px 0 2px; - padding:2px 3px; - display:inline-block; - box-shadow: 2px 2px black; - border-radius: 3px; -} - -.btn-delete-msg{ - position: absolute; - right: 0; - top: 0; - margin:2px 2px 0 2px; - font-size:8px; -} - -/* -.public_message .msg_target{ - box-shadow: 2px 2px darkslategrey; -} -*/ - -.msg_target.msg_bright{ - color:black; -} - -.msg_target.msg_dark{ - color:white; -} - -.msg_from_to{ - display:inline-block; -} - -.msg_content{ - margin-left:10px; - margin-right:5px; - overflow:hidden; -} - -.msg_prompt{ - text-align:right; - margin-top:5px; - margin-right:5px; -} - -#mailbox_list option{ - color:white; - background-color:black; -} \ No newline at end of file diff --git a/hwe/d_setting/templates/allButton.php.orig b/hwe/d_setting/templates/allButton.php.orig index af1a4562..e21f008b 100644 --- a/hwe/d_setting/templates/allButton.php.orig +++ b/hwe/d_setting/templates/allButton.php.orig @@ -1,5 +1,4 @@ -
-
+ -
@@ -18,5 +15,4 @@ -
diff --git a/hwe/func.php b/hwe/func.php index e1ab09ce..c734626e 100644 --- a/hwe/func.php +++ b/hwe/func.php @@ -461,6 +461,37 @@ function commandGroup($typename, $type = 0) } } +function getCommandTable(General $general){ + $db = DB::db(); + $gameStor = KVStorage::getStorage($db, 'game_env'); + $gameStor->turnOnCache(); + $env = $gameStor->getAll(); + + $result = []; + foreach (GameConst::$availableGeneralCommand as $commandCategory => $commandList) { + $subList = []; + foreach ($commandList as $commandClassName) { + $commandObj = buildGeneralCommandClass($commandClassName, $general, $env); + if (!$commandObj->canDisplay()) { + continue; + } + $subList[Util::getClassNameFromObj($commandObj)] = [ + 'compansation'=>$commandObj->getCompensationStyle(), + 'possible'=>$commandObj->hasMinConditionMet(), + 'title'=>$commandObj->getCommandDetailTitle(), + 'reqArg'=>$commandObj::$reqArg, + ]; + } + + $result[] = [ + 'category'=>$commandCategory, + 'values'=>$subList + ]; + } + + return $result; +} + function printCommandTable(General $generalObj) { $db = DB::db(); diff --git a/hwe/func_command.php b/hwe/func_command.php index a42e78f3..22936254 100644 --- a/hwe/func_command.php +++ b/hwe/func_command.php @@ -63,7 +63,7 @@ function pullGeneralCommand(int $generalID, int $turnCnt=1){ if($turnCnt >= GameConst::$maxTurn){ return; } - + $db = DB::db(); $db->update('general_turn', [ @@ -96,7 +96,7 @@ function repeatGeneralCommand(int $generalId, int $turnCnt){ foreach($turnList as $turnItem){ $turnIdx = $turnItem['turn_idx']; $turnTarget = iterator_to_array(Util::range($turnIdx+$turnCnt, GameConst::$maxTurn, $turnCnt)); - + $db->update('general_turn', [ 'action'=>$turnItem['action'], 'arg'=>$turnItem['arg'], @@ -116,7 +116,7 @@ function pushNationCommand(int $nationID, int $officerLevel, int $turnCnt=1){ return; } if($turnCnt < 0){ - pullNationCommand($nationID, $officerLevel, -$turnCnt); + pullNationCommand($nationID, $officerLevel, -$turnCnt); return; } if($turnCnt >= GameConst::$maxChiefTurn){ @@ -153,7 +153,7 @@ function pullNationCommand(int $nationID, int $officerLevel, int $turnCnt=1){ if($turnCnt >= GameConst::$maxChiefTurn){ return; } - + $db = DB::db(); $db->update('nation_turn', [ @@ -269,7 +269,7 @@ function checkCommandArg(?array $arg):?string{ } function setGeneralCommand(int $generalID, array $rawTurnList, string $command, ?array $arg = null):array{ - + $turnList = []; foreach($rawTurnList as $turnIdx){ if(!is_int($turnIdx) || $turnIdx < -3 || $turnIdx >= GameConst::$maxTurn){ diff --git a/hwe/func_template.php b/hwe/func_template.php index 61fe96d2..b1fc4397 100644 --- a/hwe/func_template.php +++ b/hwe/func_template.php @@ -5,7 +5,7 @@ namespace sammo; /** * 템플릿 생성과 관련된 함수들을 모아두는 파일 - * + * * NOTE: 아직 converter와 명확한 구분이 되어있지 않음. * TODO: legacy template들을 전부 template 폴더로 모아둘 필요 있음 * TODO: side effect를 제거 @@ -13,7 +13,7 @@ namespace sammo; /** * 관리자 권한이 필요함을 출력. - * @return void + * @return void */ function requireAdminPermissionHTML() { @@ -41,28 +41,6 @@ function requireAdminPermissionHTML() return ob_get_clean(); } -function turnTable() -{ - - $turnList = []; - $turnList[] = ""; - foreach (Util::range(1, GameConst::$maxTurn) as $turnIdx) { - $turnText = $turnIdx + 1; - $turnList[] = ""; - } - - $turnText = join("\n", $turnList); - - return " - -"; -} - function chiefTurnTable() { $turnList = []; @@ -272,3 +250,38 @@ function getInvitationList(array $nationList) 'nationList' => $nationList ]); } + + +function getAutorunInfo($autorunOption){ + $templates = new \League\Plates\Engine(__DIR__.'/templates'); + $auto_info = []; + foreach($autorunOption['options'] as $auto_option => $value){ + assert($value); + switch($auto_option){ + case 'develop': $auto_info['내정'] = '내정'; break; + case 'warp': $auto_info['순간이동'] = '순간이동'; break; + case 'recruit': $auto_info['징병'] = $auto_info['징병']??'징병'; break; + case 'recruit_high': $auto_info['징병'] = '모병'; break; + case 'train': $auto_info['훈사'] = '훈련/사기진작'; break; + case 'battle': $auto_info['출병'] = '출병'; break; + case 'chief': $auto_info['사령턴'] = '사령턴'; break; + } + } + $limit = Util::toInt($autorunOption['limit_minutes']); + if($limit >= 43200){ + $auto_info['제한'] = '항상 유효'; + } + else if($limit % 60 == 0){ + $auto_info['제한'] = ($limit/60).'시간 유효'; + } + else{ + $auto_info['제한'] = ($limit).'분 유효'; + } + $auto_info = join(', ', array_values($auto_info)); + return $templates->render('tooltip', [ + 'text'=>'자율행동', + 'info'=>$auto_info, + 'style'=>'text-decoration:underline', + 'copyable_info'=>true + ]); +} \ No newline at end of file diff --git a/hwe/func_tournament.php b/hwe/func_tournament.php index 51345b8d..0c1c1f8f 100644 --- a/hwe/func_tournament.php +++ b/hwe/func_tournament.php @@ -156,17 +156,17 @@ function getTournamentTime() { function getTournament(int $tnmt) { return [ - "경기 없음", - "참가 모집중", - "예선 진행중", - "본선 추첨중", - "본선 진행중", - "16강 배정중", - "베팅 진행중", - "16강 진행중", - "8강 진행중", - "4강 진행중", - "결승 진행중", + "경기 없음", + "참가 모집중", + "예선 진행중", + "본선 추첨중", + "본선 진행중", + "16강 배정중", + "베팅 진행중", + "16강 진행중", + "8강 진행중", + "4강 진행중", + "결승 진행중", ][$tnmt]??"TOURNAMENT_TYPE_ERR_{$tnmt}"; } diff --git a/hwe/index.php b/hwe/index.php index f50bf567..e2a99fc8 100644 --- a/hwe/index.php +++ b/hwe/index.php @@ -1,4 +1,5 @@ isGameLoggedIn()){ +if (!$session->isGameLoggedIn()) { header('Location:..'); die(); } @@ -41,8 +42,8 @@ $gameStor->cacheAll(true); if ($me['newmsg'] == 1 || $me['newvote'] == 1) { $db->update('general', [ - 'newmsg'=>0, - 'newvote'=>0 + 'newmsg' => 0, + 'newvote' => 0 ], 'owner=%i', $userID); } @@ -59,29 +60,25 @@ $generalObj->setRawCity($db->queryFirstRow('SELECT * FROM city WHERE city = %i', $scenario = $gameStor->scenario_text; $nationID = $generalObj->getNationID(); -if($nationID){ +if ($nationID) { $nationStor = KVStorage::getStorage($db, $nationID, 'nation_env'); $nationStor->cacheAll(); } -$valid = 0; if ($gameStor->extended_general == 0) { $extend = "표준"; } else { $extend = "확장"; - $valid = 1; } if ($gameStor->fiction == 0) { $fiction = "사실"; } else { $fiction = "가상"; - $valid = 1; } if ($gameStor->npcmode == 0) { $npcmode = "불가능"; -} else if($gameStor->npcmode == 1){ +} else if ($gameStor->npcmode == 1) { $npcmode = "가능"; - $valid = 1; } else { $npcmode = "선택 생성"; } @@ -89,285 +86,281 @@ $color = "cyan"; $mapTheme = $gameStor->map_theme; $serverName = UniqueConst::$serverName; $serverCnt = $gameStor->server_cnt; + +$auctionCount = $db->queryFirstField('SELECT count(`no`) FROM auction'); + +$myNationStatic = getNationStaticInfo($generalObj->getNationID()); +$nationColorType = substr($myNationStatic['color'] ?? '#000000', 1); + +$autorunUser = ($gameStor->autorun_user) ?? []; +$otherTextInfo = []; + +if ($gameStor->join_mode == 'onlyRandom') { + $otherTextInfo[] = '랜덤 임관 전용'; +} +if ($autorunUser['limit_minutes'] ?? false) { + $otherTextInfo[] = getAutorunInfo($autorunUser); +} + +if (!$otherTextInfo) { + $otherTextInfo = '표준'; +} else { + $otherTextInfo = join(', ', $otherTextInfo); +} ?> - -<?=$serverName?>: 메인 - - - - - - - - - - - - - - - - + + <?= $serverName ?>: 메인 + + + + + + + + + + + + + + + + GameConst::$maxTurn, + 'maxPushTurn' => 12, + 'commandList' => getCommandTable($generalObj), + 'serverNow' => TimeUtil::now(false), + 'baseColor2' => GameConst::$basecolor2, + ]) ?> + + - -
-
npcmode==1)?>
- - - - - - - - - - - - - - - - - - - - - - - - - "; -?> - - - - -userGrade >= 5) { -?> - -userGrade == 4){ - ?> - - - -
삼국지 모의전투 HiDCHe 기 ()
>>NPC수 : >NPC상성 : >NPC선택 :
전체 접속자 수 : online_user_cnt?> 명턴당 갱신횟수 : conlimit?>회
-동작 시각: ".substr($gameStor->turntime, 5, 14).""; -} else { - echo "동작 시각: ".substr($gameStor->turntime, 5, 14).""; -} - -echo " - -"; - -if ($gameStor->tournament == 0) { - echo "현재 토너먼트 경기 없음"; -} else { - switch ($gameStor->tnmt_type) { - case 0: $str = "전력전"; break; - case 1: $str = "통솔전"; break; - case 2: $str = "일기토"; break; - case 3: $str = "설전"; break; - } - $str2 = getTournament($gameStor->tournament); - $str3 = getTournamentTime(); - echo "{$str} {$str2} {$str3}↑"; -} - -echo " - -"; - -$auctionCount = $db->queryFirstField('SELECT count(`no`) FROM auction'); -if ($auctionCount > 0) { - echo "{$auctionCount}건 거래 진행중"; -} else { - echo "진행중 거래 없음"; -} - -echo " - -"; - -$vote = $gameStor->vote?:['']; -$vote_title = Tag2Code($gameStor->vote_title??'-'); -if ($vote[0] == "") { - echo "진행중 설문 없음"; -} else { - echo "설문 진행중 : $vote_title"; -} - - -echo " -
접속중인 국가: online_nation?>
운영자 메세지 : msg?>
【 국가방침 】
【 접속자 】
- - - - - - - -
- -
- - - - - - - - - - - - - - - -
- - -
- - - - - - - - - -
- 명령 목록 -
+ +
+
npcmode == 1) ?>
+
+
+

삼국지 모의전투 HiDCHe ()

-
- Ctrl, Shift, 드래그로 복수선택 가능  반복&수정 -

- - ;color:white;width:160px;font-size:13px; - > -
- - - - - - -
- - - - - - - - - - - -
장수 동향개인 기록
중원 정세
-
- +
+
+ +
+
+ NPC수 : +
+
+ NPC상성 : +
+
+ NPC선택 : +
+
+ 기타 설정: +
+ +
+
전체 접속자 수 : online_user_cnt ?> 명
+
턴당 갱신횟수 : conlimit ?>회
+
+
tournament == 0) : ?> + 현재 토너먼트 경기 없음 + + ↑tnmt_type] ?? '' ?> tournament) ?> ↑ + + + +
+
+
동작 시각: " . substr($gameStor->turntime, 5, 14) . "") : ("동작 시각: " . substr($gameStor->turntime, 5, 14) . "") ?>
+
+
+ 0) : ?> + 거래 진행중 + + 진행중 거래 없음 + +
+
+ vote ?: ['']; + $vote_title = Tag2Code($gameStor->vote_title ?? '-'); + ?> + + 진행중 설문 없음 + + 설문 진행중 : + +
+
+
+
접속중인 국가: online_nation ?>
+
+
+
운영자 메세지 : msg ?>
+
+
+
+
【 국가방침 】
+
+
+
+
+
+
+
+ 【 접속자 】 +
+
+ userGrade >= 5) : ?> + + userGrade == 4) : ?> +
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+ +
+
+
+
장수 동향
+
+
+
+
개인 기록
+
+
+
+
중원 정세
+
+
+
+
npcmode == 1) ?>
+
+
+ +
+
+ +
+
+
+
+
+
전체 메시지(최고99자)
+
+
+
+
+
+
국가 메시지(최고99자)
+
+
+
+
- - -
- 내용 없이 '서신전달&갱신'을 누르면 메세지창이 갱신됩니다. -
-
npcmode==1)?>
-
-
전체 메시지(최고99자)
-
- -
-
개인 메시지(최고99자)
-
- -
-
-
국가 메시지(최고99자)
-
- -
-
외교 메시지(최고99자)
-
- -
-
-
npcmode==1)?>
-
-develcost*5; - MessageBox("설문조사에 참여하시면 금{$develcost}과 유니크템을 드립니다! (우측 상단 설문조사 메뉴)"); -} -?> + +
+
개인 메시지(최고99자)
+
+
+
+
+ +
+
외교 메시지(최고99자)
+
+
+
+
+
+
+
npcmode == 1) ?>
+ + develcost * 5; + MessageBox("설문조사에 참여하시면 금{$develcost}과 유니크템을 드립니다! (우측 상단 설문조사 메뉴)"); + } + ?> +
+
+ 방침 + 지도 + 명령 + 도시 + 국가 + 장수 +
+
+ 동향 + 개인 + 정세 +
+
+ 전체 + 국가 + 개인 + 외교 +
+
+ + +
+
- + + \ No newline at end of file diff --git a/hwe/j_general_turn.php b/hwe/j_general_turn.php deleted file mode 100644 index 358e00b9..00000000 --- a/hwe/j_general_turn.php +++ /dev/null @@ -1,42 +0,0 @@ -setReadOnly(); - -$generalID = $session->generalID; - -$turnAmount = Util::getPost('amount', 'int'); -$isRepeat = Util::getPost('is_repeat', 'bool', false); - -if($turnAmount == null){ - Json::die([ - 'result'=>false, - 'reason'=>'턴이 입력되지 않았습니다.', - ]); -} - -if(abs($turnAmount) >= GameConst::$maxTurn){ - Json::die([ - 'result'=>false, - 'reason'=>'턴 숫자가 올바르지 않습니다.', - ]); -} - -if($isRepeat){ - repeatGeneralCommand($generalID, $turnAmount); -} -else{ - pushGeneralCommand($generalID, $turnAmount); -} - -Json::die([ - 'result'=>true, - 'reason'=>'success', -]); \ No newline at end of file diff --git a/hwe/j_get_reserved_command.php b/hwe/j_get_reserved_command.php deleted file mode 100644 index 593508c9..00000000 --- a/hwe/j_get_reserved_command.php +++ /dev/null @@ -1,49 +0,0 @@ -setReadOnly(); - -$db = DB::db(); - -$commandList = []; -$gameStor = KVStorage::getStorage($db, 'game_env'); -$generalID = $session->generalID; - -$rawTurn = $db->queryAllLists('SELECT turn_idx, action, arg, brief FROM general_turn WHERE general_id = %i ORDER BY turn_idx ASC', $generalID); -foreach($rawTurn as [$turn_idx, $action, $arg, $brief]){ - $commandList[$turn_idx] = [ - 'action'=>$action, - 'brief'=>$brief, - 'arg'=>Json::decode($arg) - ]; -} - - -[$turnTerm, $year, $month, $lastExecute] = $gameStor->getValuesAsArray(['turnterm', 'year', 'month', 'turntime']); - -[$turnTime, $rawGeneralAux] = $db->queryFirstList('SELECT turntime, aux FROM general WHERE no=%i', $generalID); -$generalAux = Json::decode($rawGeneralAux??'{}'); - -if(cutTurn($turnTime, $turnTerm) > cutTurn($lastExecute, $turnTerm)){ - //이미 이번달에 실행된 턴이다. - $month++; - if($month >= 13){ - $month -= 12; - $year += 1; - } -} - - -Json::die([ - 'result'=>true, - 'turnTime'=>$turnTime, - 'turnTerm'=>$turnTerm, - 'year'=>$year, - 'month'=>$month, - 'date'=>TimeUtil::now(true), - 'turn'=>$commandList, - 'autorun_limit'=> $generalAux['autorun_limit']??null, -]); \ No newline at end of file diff --git a/hwe/j_msg_get_old.php b/hwe/j_msg_get_old.php index 858a4c8f..ec332914 100644 --- a/hwe/j_msg_get_old.php +++ b/hwe/j_msg_get_old.php @@ -40,7 +40,7 @@ if(count($lastMsgGet) >= 10){ } catch(\Exception $e){ $lastMsgGet = []; - } + } } $lastMsgGet[] = $now; $session->lastMsgGet = Json::encode($lastMsgGet); @@ -83,7 +83,7 @@ if($reqType == 'private'){ $nextSequence = $msg->id; } return $msg->toArray(); - }, Message::getMessagesFromMailBoxOld($generalID, Message::MSGTYPE_PRIVATE, $reqTo, 20)); + }, Message::getMessagesFromMailBoxOld($generalID, Message::MSGTYPE_PRIVATE, $reqTo, 15)); } else if($reqType == 'public'){ $result['public'] = array_map(function(Message $msg)use (&$nextSequence){ @@ -91,7 +91,7 @@ else if($reqType == 'public'){ $nextSequence = $msg->id; } return $msg->toArray(); - }, Message::getMessagesFromMailBoxOld(Message::MAILBOX_PUBLIC, Message::MSGTYPE_PUBLIC, $reqTo, 20)); + }, Message::getMessagesFromMailBoxOld(Message::MAILBOX_PUBLIC, Message::MSGTYPE_PUBLIC, $reqTo, 15)); } else if($reqType == 'national'){ $result['national'] = array_map(function(Message $msg)use (&$nextSequence){ @@ -99,7 +99,7 @@ else if($reqType == 'national'){ $nextSequence = $msg->id; } return $msg->toArray(); - }, Message::getMessagesFromMailBoxOld(Message::MAILBOX_NATIONAL + $nationID, Message::MSGTYPE_NATIONAL, $reqTo, 20)); + }, Message::getMessagesFromMailBoxOld(Message::MAILBOX_NATIONAL + $nationID, Message::MSGTYPE_NATIONAL, $reqTo, 15)); } else{ $result['diplomacy'] = array_map(function(Message $msg)use (&$nextSequence, $permission){ @@ -112,7 +112,7 @@ else{ $values['option']['invalid'] = true; } return $values; - }, Message::getMessagesFromMailBoxOld(Message::MAILBOX_NATIONAL + $nationID, Message::MSGTYPE_DIPLOMACY, $reqTo, 20)); + }, Message::getMessagesFromMailBoxOld(Message::MAILBOX_NATIONAL + $nationID, Message::MSGTYPE_DIPLOMACY, $reqTo, 15)); } Json::die($result); \ No newline at end of file diff --git a/hwe/j_msg_get_recent.php b/hwe/j_msg_get_recent.php index e71e9b65..addfcc1e 100644 --- a/hwe/j_msg_get_recent.php +++ b/hwe/j_msg_get_recent.php @@ -26,7 +26,7 @@ if(count($lastMsgGet) >= 10){ } catch(\Exception $e){ $lastMsgGet = []; - } + } } $lastMsgGet[] = TimeUtil::now(); $session->lastMsgGet = Json::encode($lastMsgGet); @@ -66,7 +66,7 @@ $result['private'] = array_map(function(Message $msg) use (&$nextSequence, &$min $lastType = 'private'; } return $msg->toArray(); -}, Message::getMessagesFromMailBox($generalID, Message::MSGTYPE_PRIVATE, 20, $reqSequence)); +}, Message::getMessagesFromMailBox($generalID, Message::MSGTYPE_PRIVATE, 15, $reqSequence)); $result['public'] = array_map(function(Message $msg)use (&$nextSequence, &$minSequence, &$lastType){ if($msg->id > $nextSequence){ @@ -77,7 +77,7 @@ $result['public'] = array_map(function(Message $msg)use (&$nextSequence, &$minSe $lastType = 'public'; } return $msg->toArray(); -}, Message::getMessagesFromMailBox(Message::MAILBOX_PUBLIC, Message::MSGTYPE_PUBLIC, 20, $reqSequence)); +}, Message::getMessagesFromMailBox(Message::MAILBOX_PUBLIC, Message::MSGTYPE_PUBLIC, 15, $reqSequence)); $result['national'] = array_map(function(Message $msg)use (&$nextSequence, &$minSequence, &$lastType){ if($msg->id > $nextSequence){ @@ -88,7 +88,7 @@ $result['national'] = array_map(function(Message $msg)use (&$nextSequence, &$min $lastType = 'national'; } return $msg->toArray(); -}, Message::getMessagesFromMailBox(Message::MAILBOX_NATIONAL + $nationID, Message::MSGTYPE_NATIONAL, 20, $reqSequence)); +}, Message::getMessagesFromMailBox(Message::MAILBOX_NATIONAL + $nationID, Message::MSGTYPE_NATIONAL, 15, $reqSequence)); $result['diplomacy']= array_map(function(Message $msg)use (&$nextSequence, &$minSequence, &$lastType, $permission){ if($msg->id > $nextSequence){ @@ -104,7 +104,7 @@ $result['diplomacy']= array_map(function(Message $msg)use (&$nextSequence, &$min $values['option']['invalid'] = true; } return $values; -}, Message::getMessagesFromMailBox(Message::MAILBOX_NATIONAL + $nationID, Message::MSGTYPE_DIPLOMACY, 20, $reqSequence)); +}, Message::getMessagesFromMailBox(Message::MAILBOX_NATIONAL + $nationID, Message::MSGTYPE_DIPLOMACY, 15, $reqSequence)); if($lastType !== null){ array_pop($result[$lastType]); diff --git a/hwe/j_server_basic_info.php b/hwe/j_server_basic_info.php index 334d8f67..db088fdf 100644 --- a/hwe/j_server_basic_info.php +++ b/hwe/j_server_basic_info.php @@ -2,42 +2,7 @@ namespace sammo; include "lib.php"; - -$templates = new \League\Plates\Engine(__DIR__.'/templates'); - -function getAutorunInfo($autorunOption){ - global $templates; - $auto_info = []; - foreach($autorunOption['options'] as $auto_option => $value){ - assert($value); - switch($auto_option){ - case 'develop': $auto_info['내정'] = '내정'; break; - case 'warp': $auto_info['순간이동'] = '순간이동'; break; - case 'recruit': $auto_info['징병'] = $auto_info['징병']??'징병'; break; - case 'recruit_high': $auto_info['징병'] = '모병'; break; - case 'train': $auto_info['훈사'] = '훈련/사기진작'; break; - case 'battle': $auto_info['출병'] = '출병'; break; - case 'chief': $auto_info['사령턴'] = '사령턴'; break; - } - } - $limit = Util::toInt($autorunOption['limit_minutes']); - if($limit >= 43200){ - $auto_info['제한'] = '항상 유효'; - } - else if($limit % 60 == 0){ - $auto_info['제한'] = ($limit/60).'시간 유효'; - } - else{ - $auto_info['제한'] = ($limit).'분 유효'; - } - $auto_info = join(', ', array_values($auto_info)); - return $templates->render('tooltip', [ - 'text'=>'자율행동', - 'info'=>$auto_info, - 'style'=>'text-decoration:underline', - 'copyable_info'=>true - ]); -} +include "func_template.php"; $session = Session::requireLogin([ 'game'=>null, diff --git a/hwe/sammo/API/Command/GetReservedCommand.php b/hwe/sammo/API/Command/GetReservedCommand.php new file mode 100644 index 00000000..5ed77069 --- /dev/null +++ b/hwe/sammo/API/Command/GetReservedCommand.php @@ -0,0 +1,69 @@ +generalID; + + $rawTurn = $db->queryAllLists('SELECT turn_idx, action, arg, brief FROM general_turn WHERE general_id = %i ORDER BY turn_idx ASC', $generalID); + foreach ($rawTurn as [$turn_idx, $action, $arg, $brief]) { + $commandList[$turn_idx] = [ + 'action' => $action, + 'brief' => $brief, + 'arg' => Json::decode($arg) + ]; + } + + + [$turnTerm, $year, $month, $lastExecute] = $gameStor->getValuesAsArray(['turnterm', 'year', 'month', 'turntime']); + + [$turnTime, $rawGeneralAux] = $db->queryFirstList('SELECT turntime, aux FROM general WHERE no=%i', $generalID); + $generalAux = Json::decode($rawGeneralAux ?? '{}'); + + if (cutTurn($turnTime, $turnTerm) > cutTurn($lastExecute, $turnTerm)) { + //이미 이번달에 실행된 턴이다. + $month++; + if ($month >= 13) { + $month -= 12; + $year += 1; + } + } + + return [ + 'result' => true, + 'turnTime' => $turnTime, + 'turnTerm' => $turnTerm, + 'year' => $year, + 'month' => $month, + 'date' => TimeUtil::now(true), + 'turn' => $commandList, + 'autorun_limit' => $generalAux['autorun_limit'] ?? null, + ]; + } +} diff --git a/hwe/sammo/API/Command/PushCommand.php b/hwe/sammo/API/Command/PushCommand.php new file mode 100644 index 00000000..dd3f8bf1 --- /dev/null +++ b/hwe/sammo/API/Command/PushCommand.php @@ -0,0 +1,47 @@ +args); + $v->rule('required', [ + 'amount', + ]) + ->rule('integer', 'amount') + ->rule('min', 'amount', -12) + ->rule('max', 'amount', 12); + + if (!$v->validate()) { + return $v->errorStr(); + } + return null; + } + + public function getRequiredSessionMode(): int + { + return static::REQ_GAME_LOGIN | static::REQ_READ_ONLY; + } + + public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag) + { + $amount = $this->args['amount']; + if($amount == 0){ + return '0은 불가능합니다'; + } + pushGeneralCommand($session->generalID, $amount); + + return [ + 'result'=>true + ]; + } +} diff --git a/hwe/sammo/API/Command/RepeatCommand.php b/hwe/sammo/API/Command/RepeatCommand.php new file mode 100644 index 00000000..b48e571c --- /dev/null +++ b/hwe/sammo/API/Command/RepeatCommand.php @@ -0,0 +1,45 @@ +args); + $v->rule('required', [ + 'amount', + ]) + ->rule('integer', 'amount') + ->rule('min', 'amount', 1) + ->rule('max', 'amount', 12); + + if (!$v->validate()) { + return $v->errorStr(); + } + return null; + } + + public function getRequiredSessionMode(): int + { + return static::REQ_GAME_LOGIN | static::REQ_READ_ONLY; + } + + public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag) + { + + $amount = $this->args['amount']; + repeatGeneralCommand($session->generalID, $amount); + + return [ + 'result'=>true + ]; + } +} diff --git a/hwe/sammo/API/Command/ReserveCommand.php b/hwe/sammo/API/Command/ReserveCommand.php new file mode 100644 index 00000000..802c5dbd --- /dev/null +++ b/hwe/sammo/API/Command/ReserveCommand.php @@ -0,0 +1,56 @@ +args); + $v->rule('required', [ + 'action', + 'turnList' + ]) + ->rule('lengthMin', 'action', 1) + ->rule('integerArray', 'turnList'); + + if (!$v->validate()) { + return $v->errorStr(); + } + return null; + } + + public function getRequiredSessionMode(): int + { + return static::REQ_GAME_LOGIN | static::REQ_READ_ONLY; + } + + public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag) + { + $action = $this->args['action']; + $turnList = $this->args['turnList']; + $arg = $this->args['arg']??[]; + + if(!$turnList){ + return '턴이 입력되지 않았습니다'; + } + + if(!in_array($action, Util::array_flatten(GameConst::$availableGeneralCommand))){ + return '사용할 수 없는 커맨드입니다.'; + } + + if(!is_array($arg)){ + '올바른 arg 형태가 아닙니다.'; + } + + return setGeneralCommand($session->generalID, $turnList, $action, $arg); + } +} diff --git a/hwe/scss/bootstrap5.scss b/hwe/scss/bootstrap5.scss index dcae837e..eaf644ee 100644 --- a/hwe/scss/bootstrap5.scss +++ b/hwe/scss/bootstrap5.scss @@ -7,6 +7,8 @@ $input-color: #303030; @import url("https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.css"); -@import "../../node_modules/bootswatch/dist/darkly/_variables.scss"; +@import "./variables.scss"; +@import "./bootswatch_custom_variables.scss"; @import "../../node_modules/bootstrap5/scss/bootstrap.scss"; -@import "../../node_modules/bootswatch/dist/darkly/_bootswatch.scss"; \ No newline at end of file +@import "./bootswatch_custom.scss"; +@import "./bootstrap_sammo.scss"; \ No newline at end of file diff --git a/hwe/scss/bootstrap_sammo.scss b/hwe/scss/bootstrap_sammo.scss new file mode 100644 index 00000000..2a7bcb18 --- /dev/null +++ b/hwe/scss/bootstrap_sammo.scss @@ -0,0 +1,67 @@ + + +@function frontColor($color) { + @return color-contrast($color); +} + +@each $colorType, $color in $nationColors { + .sam-color-#{$colorType} { + .sam-nation-own-bgcolor{ + background-color: $color; + color: frontColor($color); + } + + .btn-sammo-nation{ + @include button-variant($color, $color); + + &:hover, + &:active, + &:focus { + background-color: $color; + } + + &, + &:not(.disabled):hover, + &:not(.disabled):active, + &:focus { + border-color: shade-color($color, 10%); + } + } + } + + .btn-sammo-nation-#{$colorType}{ + @include button-variant($color, $color); + + &:hover, + &:active, + &:focus { + background-color: $color; + } + + &, + &:not(.disabled):hover, + &:not(.disabled):active, + &:focus { + border-color: shade-color($color, 10%); + } + } +} + +@each $colorType, $color in $sammoColors { + .btn-sammo-#{$colorType}{ + @include button-variant($color, $color); + + &:hover, + &:active, + &:focus { + background-color: $color; + } + + &, + &:not(.disabled):hover, + &:not(.disabled):active, + &:focus { + border-color: shade-color($color, 10%); + } + } +} \ No newline at end of file diff --git a/hwe/scss/bootswatch_custom.scss b/hwe/scss/bootswatch_custom.scss new file mode 100644 index 00000000..029220c2 --- /dev/null +++ b/hwe/scss/bootswatch_custom.scss @@ -0,0 +1,329 @@ +// Lumen 5.1.3 +// Bootswatch + + +// Variables + +$web-font-path: "https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400&display=swap" !default; +@if $web-font-path { + @import url($web-font-path); +} + +// Mixins + +@mixin shadow($width: 4px){ + border-style: solid; + border-width: 0 1px $width 1px; +} + +// Navbar + +.navbar { + @include shadow(); + + @each $color, $value in $theme-colors { + &.bg-#{$color} { + border-color: shade-color($value, 10%); + } + } +} + +// Buttons + +.btn { + @include shadow(); + text-transform: uppercase; + + &:not(.disabled):hover { + margin-top: 1px; + border-bottom-width: 3px; + } + + &:not(.disabled):active { + margin-top: 2px; + border-bottom-width: 2px; + @include box-shadow(none); + } + + @each $color, $value in $theme-colors { + &-#{$color} { + &:hover, + &:active, + &:focus { + background-color: $value; + } + + &, + &:not(.disabled):hover, + &:not(.disabled):active, + &:focus { + border-color: shade-color($value, 10%); + } + } + } +} + +[class*="btn-outline"] { + border-top-width: 1px; +} + +.btn-group-vertical { + .btn + .btn { + &:hover { + margin-top: -1px; + border-top-width: 1px; + } + + &:active { + margin-top: -1px; + border-top-width: 2px; + } + } +} + +// Typography + +.text-secondary { + color: $gray-700 !important; +} + +.blockquote-footer { + color: $gray-600; +} + +// Forms + + +.form-control { + box-shadow: inset 0 2px 0 rgba(0, 0, 0, .075); +} + +// Navs + +.nav { + .open > a, + .open > a:hover, + .open > a:focus { + border-color: transparent; + } +} + +.nav-tabs { + .nav-link { + color: $body-color; + + &, + &.disabled, + &.disabled:hover, + &.disabled:focus { + margin-top: 6px; + border-color: $nav-tabs-border-color; + transition: padding-bottom .2s ease-in-out, margin-top .2s ease-in-out, border-bottom .2s ease-in-out; + } + + &:not(.disabled):hover, + &:not(.disabled):focus, + &.active { + padding-bottom: add(.5rem, 6px); + border-bottom-color: transparent; + margin-top: 0; + } + } + + &.nav-justified > li { + vertical-align: bottom; + } +} + +.dropdown-menu { + margin-top: 0; + @include shadow(); + border-top-width: 1px; + @include box-shadow(none); +} + +.breadcrumb { + border-color: shade-color($breadcrumb-bg, 10%); + @include shadow(); +} + +.pagination { + a:hover { + text-decoration: none; + } +} + + +.pagination { + > li > a, + > li > span { + position: relative; + top: 0; + @include shadow(); + color: $pagination-color; + font-weight: 700; + text-transform: uppercase; + + &:hover, + &:focus { + top: 1px; + border-bottom-width: 3px; + text-decoration: none; + } + + &:active { + top: 2px; + border-bottom-width: 2px; + } + } + + > .disabled > a, + > .disabled > span { + &:hover { + top: 0; + @include shadow(); + } + + &:active { + top: 0; + @include shadow(); + } + } +} + +.pager { + > li > a, + > li > span, + > .disabled > a, + > .disabled > span { + &, + &:hover, + &:active { + border-left-width: 2px; + border-right-width: 2px; + } + } +} + +// Indicators + +.btn-close { + text-decoration: none; + opacity: .4; + + &:hover, + &:focus { + opacity: 1; + } +} + +.alert { + color: $white; + @include shadow(); + + &-primary { + background-color: $primary; + border-color: shade-color($primary, 10%); + } + + &-secondary { + background-color: $secondary; + border-color: shade-color($secondary, 10%); + } + + &-success { + background-color: $success; + border-color: shade-color($success, 10%); + } + + &-info { + background-color: $info; + border-color: shade-color($info, 10%); + } + + &-danger { + background-color: $danger; + border-color: shade-color($danger, 10%); + } + + &-warning { + background-color: $warning; + border-color: shade-color($warning, 10%); + } + + &-dark { + background-color: $dark; + border-color: shade-color($dark, 10%); + } + + &-light { + background-color: $light; + border-color: shade-color($light, 10%); + } + + .alert-link { + font-weight: 400; + color: $white; + text-decoration: underline; + } + + &-secondary, + &-light { + &, + a, + .alert-link { + color: $body-color; + } + } +} + +.badge { + &.bg-secondary, + &.bg-light { + color: $dark; + } +} + +// Containers + +a.list-group-item { + &-success { + &.active { + background-color: $success; + } + + &.active:hover, + &.active:focus { + background-color: shade-color($success, 10%); + } + } + + &-warning { + &.active { + background-color: $warning; + } + + &.active:hover, + &.active:focus { + background-color: shade-color($warning, 10%); + } + } + + &-danger { + &.active { + background-color: $danger; + } + + &.active:hover, + &.active:focus { + background-color: shade-color($danger, 10%); + } + } +} + +.modal, +.toast { + .btn-close { + background-image: url("data:image/svg+xml,"); + } +} diff --git a/hwe/scss/bootswatch_custom_variables.scss b/hwe/scss/bootswatch_custom_variables.scss new file mode 100644 index 00000000..652500df --- /dev/null +++ b/hwe/scss/bootswatch_custom_variables.scss @@ -0,0 +1,177 @@ +// Darkly 5.1.3 +// Bootswatch + +$theme: "darkly" !default; + +// +// Color system +// + +$white: #fff !default; +$gray-100: #f8f9fa !default; +$gray-200: #ebebeb !default; +$gray-300: #dee2e6 !default; +$gray-400: #ced4da !default; +$gray-500: #adb5bd !default; +$gray-600: #888 !default; +$gray-700: #444 !default; +$gray-800: #303030 !default; +$gray-900: #222 !default; +$black: #000 !default; + +$blue: #375a7f !default; +$indigo: #6610f2 !default; +$purple: #6f42c1 !default; +$pink: #e83e8c !default; +$red: #e74c3c !default; +$orange: #fd7e14 !default; +$yellow: #f39c12 !default; +$green: #00bc8c !default; +$teal: #20c997 !default; +$cyan: #3498db !default; + +$primary: $blue !default; +$secondary: $gray-700 !default; +$success: $green !default; +$info: $cyan !default; +$warning: $yellow !default; +$danger: $red !default; +$light: $gray-500 !default; +$dark: $gray-800 !default; + +$min-contrast-ratio: 1.9 !default; + +// Body + +$body-bg: $gray-900 !default; +$body-color: $white !default; + +// Links + +$link-color: $success !default; + +// Fonts + +// stylelint-disable-next-line value-keyword-case +$font-family-sans-serif: Lato, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" !default; +$h1-font-size: 3rem !default; +$h2-font-size: 2.5rem !default; +$h3-font-size: 2rem !default; +$text-muted: $gray-600 !default; + +// Tables + +$table-border-color: $gray-700 !default; + +$table-bg-scale: 0 !default; + +// Buttons + +$btn-font-weight: 700 !default; + +// Forms + +$input-bg: $white !default; +$input-color: $gray-800 !default; +$input-border-color: $body-bg !default; +$input-group-addon-color: $gray-500 !default; +$input-group-addon-bg: $gray-700 !default; + +$form-check-input-bg: $white !default; +$form-check-input-border: none !default; + +$form-file-button-color: $white !default; + +// Dropdowns + +$dropdown-bg: $gray-900 !default; +$dropdown-border-color: $gray-700 !default; +$dropdown-divider-bg: $gray-700 !default; +$dropdown-link-color: $white !default; +$dropdown-link-hover-color: $white !default; +$dropdown-link-hover-bg: $primary !default; + +// Navs + +$nav-link-padding-x: 2rem !default; +$nav-link-disabled-color: $gray-500 !default; +$nav-tabs-border-color: $gray-700 !default; +$nav-tabs-link-hover-border-color: $nav-tabs-border-color $nav-tabs-border-color transparent !default; +$nav-tabs-link-active-color: $white !default; +$nav-tabs-link-active-border-color: $nav-tabs-border-color $nav-tabs-border-color transparent !default; + +// Navbar + +$navbar-padding-y: 1rem !default; +$navbar-dark-color: rgba($white, .6) !default; +$navbar-dark-hover-color: $white !default; +$navbar-light-color: rgba($gray-900, .7) !default; +$navbar-light-hover-color: $gray-900 !default; +$navbar-light-active-color: $gray-900 !default; +$navbar-light-toggler-border-color: rgba($gray-900, .1) !default; + +// Pagination + +$pagination-color: $white !default; +$pagination-bg: $success !default; +$pagination-border-width: 0 !default; +$pagination-border-color: transparent !default; +$pagination-hover-color: $white !default; +$pagination-hover-bg: lighten($success, 10%) !default; +$pagination-hover-border-color: transparent !default; +$pagination-active-bg: $pagination-hover-bg !default; +$pagination-active-border-color: transparent !default; +$pagination-disabled-color: $white !default; +$pagination-disabled-bg: darken($success, 15%) !default; +$pagination-disabled-border-color: transparent !default; + +// Cards + +$card-cap-bg: $gray-700 !default; +$card-bg: $gray-800 !default; + +// Popovers + +$popover-bg: $gray-800 !default; +$popover-header-bg: $gray-700 !default; + +// Toasts + +$toast-background-color: $gray-700 !default; +$toast-header-background-color: $gray-800 !default; + +// Modals + +$modal-content-bg: $gray-800 !default; +$modal-content-border-color: $gray-700 !default; +$modal-header-border-color: $gray-700 !default; + +// Progress bars + +$progress-bg: $gray-700 !default; + +// List group + +$list-group-color: $body-color !default; +$list-group-bg: $gray-800 !default; +$list-group-border-color: $gray-700 !default; +$list-group-hover-bg: $gray-700 !default; +$list-group-action-hover-color: $list-group-color !default; +$list-group-action-active-bg: $gray-900 !default; + +// Breadcrumbs + +$breadcrumb-padding-y: .375rem !default; +$breadcrumb-padding-x: .75rem !default; +$breadcrumb-bg: $gray-700 !default; +$breadcrumb-border-radius: .25rem !default; + +// Close + +$btn-close-color: $white !default; +$btn-close-opacity: .4 !default; +$btn-close-hover-opacity: 1 !default; + +// Code + +$pre-color: inherit !default; diff --git a/hwe/scss/break_500px.scss b/hwe/scss/break_500px.scss new file mode 100644 index 00000000..abcbe6e7 --- /dev/null +++ b/hwe/scss/break_500px.scss @@ -0,0 +1,16 @@ +$container-max-widths: ( + sm: 500px, + md: 500px, + lg: 1020px, + xl: 1140px, + xxl: 1320px + ) !default; + +$grid-breakpoints: ( + xs: 0, + sm: 520px, + md: 900px, + lg: 992px, + xl: 1200px, + xxl: 1400px +); \ No newline at end of file diff --git a/hwe/scss/common_legacy.scss b/hwe/scss/common_legacy.scss new file mode 100644 index 00000000..9520d2af --- /dev/null +++ b/hwe/scss/common_legacy.scss @@ -0,0 +1,286 @@ +@import "./bootstrap5.scss"; + +html * { + max-height: 1000000px; +} + +html, +body { + background-color: black; + color: white; + line-height: 1.3; + font-family: '맑은 고딕'; + font-size: 13px; +} + +table { + font-family: '맑은 고딕'; +} + +font { + font-family: '맑은 고딕'; +} + +input { + font-family: '맑은 고딕'; + font-size: 13px; +} + +select { + font-family: '굴림'; + line-height: 100%; +} + +.center { + text-align: center; +} + +table.mimic_flex { + border-collapse: collapse; + border: none; + padding: 0; +} + +.mimic_flex td, +.mimic_flex th { + border: none !important; + padding: 0px; + word-break: break-all; +} + +table.tb_layout { + border-collapse: collapse; + padding: 0px; + font-size: 13px; + word-break: break-all; + font-family: '맑은 고딕'; +} + +.tb_layout td, +.tb_layout th { + border: solid 1px gray; + padding: 0px; + word-break: break-all; + font-family: '맑은 고딕'; + ; +} + +div.bar_out { + position: relative; + border-top: solid 1px #888888; + border-bottom: solid 1px #333333; + padding: 0; + margin: 0; + width: 100%; + overflow: hidden; +} + +div.bar_out div { + position: absolute; + left: 0; + top: 0; + height: 100%; +} + +div.bar_out div.bar_in { + width: 100%; +} + + +/* */ + +.ev_warning { + color: orangered; +} + +.ev_notice { + color: orangered; +} + +.ev_succes { + color: lightgreen; +} + +.ev_sell { + color: orange; +} + +.ev_failed { + color: orangered; +} + +.ev_highlight { + color: orangered; +} + + +/* TODO: 색상값이 아니라 의미에 따라 클래스 지정 */ + +.o_bullet::before { + color: cyan; + content: "●"; +} + +.o_diamond::before { + color: orangered; + content: "◆"; +} + +.small_war_log { + display: inline-block; +} + +.small_war_log .war_type_attack { + color: cyan; +} + +.small_war_log .war_type_defense { + color: magenta; +} + +.small_war_log .war_type_siege { + color: white; +} + +.small_war_log .name_plate { + font-size: 0.75em; +} + +.small_war_log .name_plate_cover { + color: yellow; +} + +.small_war_log .crew_plate { + color: orangered; + font-size: 90%; +} + +.t_date { + font-size: 0.75em; +} + +.t_red { + color: red; +} + +.t_blue { + color: blue; +} + +.t_green { + color: green; +} + +.t_magenta { + color: magenta; +} + +.t_cyan { + color: cyan; +} + +.t_limegreen { + color: limegreen; +} + +.t_skyblue { + color: skyblue; +} + +.t_orangered { + color: orangered; +} + +.t_yellow { + color: yellow; +} + +.t_white { + color: white; +} + +.float_left { + float: left; +} + +.tooltip { + font-size: 12px; + font-family: '맑은 고딕'; +} + +.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; +} + +.btn-group-xs>.btn, +.btn-xs { + padding: .25rem .4rem; + font-size: .875rem; + line-height: .5; + border-radius: .2rem; +} + +.edit_form.viewer { + max-height: 200px; + overflow-y: auto; +} + +.trumbowyg-box { + margin: 0; + border-left: none; + border-right: none; +} + +.edit_form.trumbowyg-editor { + margin: 0; + padding: 0; +} + +.commandBasic { + background-color: black; + color: white; +} + +.compensatePositive { + color: skyblue; +} + +.compensateNegative { + color: orange; +} + +.compensateNeutral { + color: white; +} + +.commandBasic.commandImpossible { + background-color: red; + color: white; +} + +.select2-selection--single.simple-select2-align-center .select2-selection__rendered { + text-align: center; +} + +.select2-dropdown.simple-select2-align-center li.select2-results__option { + text-align: center; +} + +.select2-container--bootstrap4 .select2-selection--single.text-secondary .select2-selection__rendered { + color: white; +} + +.select2-container--bootstrap4 .text-secondary .select2-results__option[aria-selected=false] { + color: white; +} \ No newline at end of file diff --git a/hwe/scss/game_bg.scss b/hwe/scss/game_bg.scss index 716bcecd..5bde826d 100644 --- a/hwe/scss/game_bg.scss +++ b/hwe/scss/game_bg.scss @@ -1,5 +1,3 @@ -@charset "UTF-8"; - @import url('https://fonts.googleapis.com/css2?family=Nanum+Gothic:wght@400;700&display=swap'); @import '../../d_shared/common.css'; diff --git a/hwe/scss/main.scss b/hwe/scss/main.scss new file mode 100644 index 00000000..06db29f4 --- /dev/null +++ b/hwe/scss/main.scss @@ -0,0 +1,545 @@ +@import "./break_500px.scss"; +@import "./bootstrap5.scss"; + +body { + color: white; + background-color: black; + border-width: 1px; + border-color: gray; + background-position: center; + background-repeat: repeat-y; +} + +@include media-breakpoint-up(md) { + #container { + width: 1000px; + margin: 0 auto; + } +} + +@include media-breakpoint-down(md) { + body { + overflow-x: hidden; + } + + #container { + width: 500px; + margin: 0 auto; + } +} + +.avoid-wrap { + display: inline-block; +} + + +#map_view { + display: grid; +} + +.mainCityInfo { + display: grid; + border-right: solid 1px gray; + border-bottom: solid 1px gray; + + .gPanel { + display: grid; + grid-template-columns: 1fr 2fr; + border-top: solid 1px gray; + border-left: solid 1px gray; + + .gHead { + display: flex; + justify-content: center; + align-items: center; + } + } + + .cityNamePanel, + .nationNamePanel { + font-weight: bold; + text-align: center; + border-top: solid 1px gray; + border-left: solid 1px gray; + } + + .popPanel { + grid-column: 1 / 3; + grid-template-columns: 1fr 5fr; + } +} + +.vote-cell { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +@include media-breakpoint-up(md) { + #map_view { + grid-template-columns: 700px 300px; + grid-template-rows: 520px 130px auto; + } + + #mapZone { + height: 520px; + grid-column: 1 / 2; + grid-row: 1 / 2; + } + + #cityInfo { + grid-column: 1 / 2; + grid-row: 2 / 3; + } + + + #routeButtons { + grid-column: 1 / 3; + grid-row: 3 / 4; + } + + #reservedCommandList { + width: 300px; + grid-column: 2 / 3; + grid-row: 1 / 3; + position: relative; + } + + .commandPad { + position: absolute; + z-index: 7; + } + + + .buttonPlate { + display: grid; + grid-template-columns: repeat(10, 1fr); + padding: 0; + } + + .toolbars>.buttonPlate { + grid-template-columns: repeat(8, 1fr); + } + + .buttonPlate>a { + display: block; + text-decoration: none; + } + + .commandButton { + width: 100%; + font-weight: bold; + font-size: 13px; + display: block; + } + + + .mainCityInfo { + grid-template-columns: 1fr 1fr 1fr 1fr; + + .cityNamePanel, + .nationNamePanel { + grid-column: 1 / 5; + } + + .officer4Panel { + grid-column: 4 / 5; + grid-row: 3 / 4; + } + + .officer3Panel { + grid-column: 4 / 5; + grid-row: 4 / 5; + } + + .officer2Panel { + grid-column: 4 / 5; + grid-row: 5 / 6; + } + } +} + +#nation-msg-box { + position: relative; + overflow: hidden; +} + +@include media-breakpoint-down(md) { + .buttonPlate { + display: grid; + grid-template-columns: repeat(5, 1fr); + padding: 0; + } + + .toolbars>.buttonPlate { + grid-template-columns: repeat(4, 1fr); + } + + .buttonPlate>a { + display: block; + text-decoration: none; + } + + .commandButton { + width: 100%; + font-weight: bold; + font-size: 13px; + display: block; + } + + #nation-msg { + transform-origin: 0px 0px; + width: 1000px; + transform: scale(0.5); + } + + #mapZone { + grid-column: 1 / 2; + grid-row: 1 / 2; + + + .world_map { + width: 500px; + height: calc((500px + 20px) * 500 / 700); + } + + .map_title { + transform-origin: 0px 0px; + transform: scale(calc(500 / 700)); + margin-bottom: calc(-20px * 200 / 700); + } + + .map_body { + transform-origin: 0px 0px; + transform: scale(calc(500 / 700)); + } + } + + + #reservedCommandList { + grid-column: 1 / 2; + grid-row: 2 / 3; + } + + #routeButtons { + grid-column: 1 / 2; + grid-row: 3 / 4; + } + + + #cityInfo { + grid-column: 1 / 2; + grid-row: 4 / 5; + } + + .mainCityInfo { + display: grid; + grid-template-columns: 1fr 1fr 1fr; + + .cityNamePanel, + .nationNamePanel { + grid-column: 1 / 4; + } + } +} + +.toolbarButton { + @extend .btn; + @extend .btn-sammo-base2; + width: 100%; + font-weight: bold; + font-size: 13px; +} + +.toolbarButton2 { + @extend .btn; + @extend .btn-sammo-base2; + color: magenta; + width: 100%; + font-weight: bold; + font-size: 13px; + + &:hover, + &:focus, + &:active { + color: magenta; + } +} + +.nation_info td { + height: 18px; +} + +#sidebar { + position: fixed; + right: 0; + top: 50%; + transform: translateY(-50%); +} + +/*임시용 */ + +#container { + /*width:1000px;*/ + margin: auto; + font-size: 13px; +} + +/*임시용 끝*/ + +#message_board { + position: relative; +} + +/* +#message_board section{ + overflow-y:auto; + overflow-x:hidden; +} +*/ +.msg_plate { + width: 100%; + outline-style: solid; + outline-width: 1px; + outline-color: gray; + min-height: 64px; + font-size: 12px; + word-break: break-all; + color: white; +} + +.msg_plate_private { + background-color: #5d1e1a; +} + +.msg_plate_private.msg_plate_dest { + background-color: #5d461a; +} + +.msg_plate_public { + background-color: #141c65; + +} + +@include media-breakpoint-up(md) { + #message_board section { + overflow-y: auto; + overflow-x: hidden; + height: 650px; + } + + + .public_message, + .diplomacy_message, + .national_message, + .private_message { + min-height: 300px; + } +} + +@include media-breakpoint-down(md) { + + .public_message, + .diplomacy_message, + .national_message, + .private_message { + min-height: 150px; + } +} + +.msg_plate_national, +.msg_plate_diplomacy { + background-color: #00582c; +} + +.msg_plate_national.msg_plate_dest, +.msg_plate_diplomacy.msg_plate_dest { + background-color: #704615; +} + +.msg_plate_national.msg_plate_src, +.msg_plate_diplomacy.msg_plate_src { + background-color: #70153b; +} + +.msg_icon { + float: left; + width: 64px; + height: 64px; + border-right: solid 1px gray; +} + +.msg_time { + font-size: 0.75em; + font-weight: normal; +} + +.msg_header { + font-weight: bold; + margin-bottom: 3px; + color: white; + position: relative; +} + +.message_input_form { + position: relative; +} + +#mailbox_list { + font-weight: bold; +} + +.board_header { + color: white; + outline-style: solid; + outline-width: 1px; + outline-color: gray; +} + +/* +.board_side{ + position:absolute; + height:1370px; + width:50%; + overflow-y: hidden; + outline-style:solid; + outline-width:1px; + outline-color: gray; + display: flex; + flex-wrap: wrap; + flex-direction: column; +} +.board_side > div{ + height: 1.2em; +} +*/ +.msg_invalid { + color: rgba(255, 255, 255, 0.5); +} + +.msg_body { + padding-left: 64px; +} + +.msg_target { + margin: 2px 2px 0 2px; + padding: 2px 3px; + display: inline-block; + box-shadow: 2px 2px black; + border-radius: 3px; +} + +.btn-delete-msg { + position: absolute; + right: 0; + top: 0; + margin: 2px 2px 0 2px; + font-size: 8px; +} + + +@include media-breakpoint-down(md) { + #mailbox_list-col { + order: 1; + } + + #msg_submit-col { + order: 2; + } + + #msg_input-col { + order: 3; + } +} + + +/* +.public_message .msg_target{ + box-shadow: 2px 2px darkslategrey; +} +*/ + +.msg_target.msg_bright { + color: black; +} + +.msg_target.msg_dark { + color: white; +} + +.msg_from_to { + display: inline-block; +} + +.msg_content { + margin-left: 10px; + margin-right: 5px; + overflow: hidden; +} + +.msg_prompt { + text-align: right; + margin-top: 5px; + margin-right: 5px; +} + +#mailbox_list option { + color: white; + background-color: black; +} + + +@include media-breakpoint-up(md) { + #float-tabs { + display: none; + } +} + +@include media-breakpoint-down(md) { + #float-tabs { + position: fixed; + right: -1rem; + top: 10%; + width: 3rem; + + .btn-group-vertical { + margin-bottom: 0.5em; + } + + .btn { + padding-left: 0.5em; + padding-right: 1.5rem; + line-height: 1em; + } + } +} + +@media (max-width: 560px) { + #float-tabs { + .btn { + opacity: 0.7; + } + + .btn.active { + opacity: 1.0; + } + + .btn:active { + opacity: 0.7; + } + } +} + + +.s-border-t { + border-top: gray solid 1px; +} + +.s-border-b { + border-bottom: gray solid 1px; +} + +.s-border-tb { + border-top: gray solid 1px; + border-bottom: gray solid 1px; +} \ No newline at end of file diff --git a/hwe/scss/troop.scss b/hwe/scss/troop.scss index d86a7477..060d2d1c 100644 --- a/hwe/scss/troop.scss +++ b/hwe/scss/troop.scss @@ -1,5 +1,3 @@ -@charset "UTF-8"; - #troop_list .cityText{ display:none; } diff --git a/hwe/scss/variables.scss b/hwe/scss/variables.scss new file mode 100644 index 00000000..cb85a787 --- /dev/null +++ b/hwe/scss/variables.scss @@ -0,0 +1,49 @@ +$base1color: #141c65; +$base2color: #00582c; +$base3color: #704615; +$base4color: #70153b; + +$sammoColors: ( + 'base1': $base1color, + 'base2': $base2color, + 'base3': $base3color, + 'base4': $base4color, +); + +$nationColors: ( + "000000": #000000, + "FF0000": #FF0000, + "800000": #800000, + "A0522D": #A0522D, + "FF6347": #FF6347, + "FFA500": #FFA500, + "FFDAB9": #FFDAB9, + "FFD700": #FFD700, + "FFFF00": #FFFF00, + "7CFC00": #7CFC00, + "00FF00": #00FF00, + "808000": #808000, + "008000": #008000, + "2E8B57": #2E8B57, + "008080": #008080, + "20B2AA": #20B2AA, + "6495ED": #6495ED, + "7FFFD4": #7FFFD4, + "AFEEEE": #AFEEEE, + "87CEEB": #87CEEB, + "00FFFF": #00FFFF, + "00BFFF": #00BFFF, + "0000FF": #0000FF, + "000080": #000080, + "483D8B": #483D8B, + "7B68EE": #7B68EE, + "BA55D3": #BA55D3, + "800080": #800080, + "FF00FF": #FF00FF, + "FFC0CB": #FFC0CB, + "F5F5DC": #F5F5DC, + "E0FFFF": #E0FFFF, + "FFFFFF": #FFFFFF, + "A9A9A9": #A9A9A9, + "330000": #330000, +); diff --git a/hwe/templates/allButton.php b/hwe/templates/allButton.php index af1a4562..52663965 100644 --- a/hwe/templates/allButton.php +++ b/hwe/templates/allButton.php @@ -1,22 +1,18 @@ -
-
- - - - - - - - -
-
- - - - - - - - -
-
+
+ + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/hwe/templates/commandButton.php b/hwe/templates/commandButton.php index a2770617..478e79e5 100644 --- a/hwe/templates/commandButton.php +++ b/hwe/templates/commandButton.php @@ -1,25 +1,22 @@
-
- - - - - - - - - - - - - - - - - - - - - -
+ =1?'':'disabled'?>>회 의 실 + 기 밀 실 + '>부대 편성 + '>외 교 부 + '>인 사 부 + '>내 무 부 + '>사 령 부 + '>NPC 정책 + '>암 행 부 + 토 너 먼 트 + '>세력 정보 + '>세력 도시 + '>세력 장수 + 중원 정보 + 현재 도시 + '>감 찰 부 + 유산 관리 + 내 정보&설정 + 거 래 장 + 베 팅 장
\ No newline at end of file diff --git a/hwe/templates/mainCityInfo.php b/hwe/templates/mainCityInfo.php index 6a21122b..dd86ced2 100644 --- a/hwe/templates/mainCityInfo.php +++ b/hwe/templates/mainCityInfo.php @@ -1,47 +1,48 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
주민bar($pop/$pop_max*100)?>민심bar($trust)?>태수
/
농업bar($agri/$agri_max*100)?>상업bar($comm/$comm_max*100)?>치안bar($secu/$secu_max*100)?>군사
///
수비bar($def/$def_max*100)?>성벽bar($wall/$wall_max*100)?>시세bar(($trade-95)*10)?>종사
//
\ No newline at end of file +
+
|
+
+
+
주민
+
bar($pop / $pop_max * 100) ?>/
+
+
+
민심
+
bar($trust) ?>
+
+
+
농업
+
bar($agri / $agri_max * 100) ?>/
+
+
+
상업
+
bar($comm / $comm_max * 100) ?>/
+
+
+
치안
+
bar($secu / $secu_max * 100) ?>/
+
+
+
수비
+
bar($def / $def_max * 100) ?>/
+
+
+
성벽
+
bar($wall / $wall_max * 100) ?>/
+
+
+
시세
+
bar(($trade - 95) * 10) ?>
+
+
+
태수
+
+
+
+
군사
+
+
+
+
종사
+
+
+
\ No newline at end of file diff --git a/hwe/templates/map.php b/hwe/templates/map.php index bc50e3b0..b446f6ee 100644 --- a/hwe/templates/map.php +++ b/hwe/templates/map.php @@ -1,4 +1,4 @@ -
+
@@ -9,20 +9,20 @@
-
- +
+
-
-
+
+
+
-
-
+
+
-
\ No newline at end of file diff --git a/hwe/ts/ReservedCommand.vue b/hwe/ts/ReservedCommand.vue new file mode 100644 index 00000000..81593a8e --- /dev/null +++ b/hwe/ts/ReservedCommand.vue @@ -0,0 +1,516 @@ + + + + \ No newline at end of file diff --git a/hwe/ts/build_exports.json b/hwe/ts/build_exports.json index 4f185db8..d64ecacf 100644 --- a/hwe/ts/build_exports.json +++ b/hwe/ts/build_exports.json @@ -13,7 +13,6 @@ "bossInfo": "bossInfo.ts", "myPage": "myPage.ts", "extExpandCity": "extExpandCity.ts", - "main": "main.ts", "dipcenter": "dipcenter.ts", "diplomacy": "diplomacy.ts", "currentCity": "currentCity.ts", @@ -21,12 +20,14 @@ "history": "history.ts", "select_general_from_pool": "select_general_from_pool.ts", "extKingdoms": "extKingdoms.ts", - "common": "common_deprecated.ts" + "common": "common_deprecated.ts", + "main": "main.ts" }, "ingame_vue": { "v_inheritPoint": "v_inheritPoint.ts", "v_board": "v_board.ts", "v_NPCControl": "v_NPCControl.ts", - "v_join": "v_join.ts" + "v_join": "v_join.ts", + "v_main": "v_main.ts" } } \ No newline at end of file diff --git a/hwe/ts/chiefCenter.ts b/hwe/ts/chiefCenter.ts index 808ee5de..6fd6468b 100644 --- a/hwe/ts/chiefCenter.ts +++ b/hwe/ts/chiefCenter.ts @@ -10,6 +10,9 @@ import { unwrap_any } from "./util/unwrap_any"; import { parseTime } from './util/parseTime'; import { formatTime } from './util/formatTime'; import { stringifyUrl } from 'query-string'; +import { setAxiosXMLHttpRequest } from './util/setAxiosXMLHttpRequest'; + +setAxiosXMLHttpRequest(); declare const maxChiefTurn: number; diff --git a/hwe/ts/common_deprecated.ts b/hwe/ts/common_deprecated.ts index bd161546..35852e94 100644 --- a/hwe/ts/common_deprecated.ts +++ b/hwe/ts/common_deprecated.ts @@ -11,6 +11,8 @@ import Popper from 'popper.js'; exportWindow(Popper, 'Popper');//XXX: 왜 popper를 이렇게 불러야 하는가? import 'bootstrap'; +import "../scss/common_legacy.scss"; + exportWindow(jQuery, '$'); exportWindow(jQuery, 'jQuery'); diff --git a/hwe/ts/common_legacy.ts b/hwe/ts/common_legacy.ts index 5a686eda..35a2d316 100644 --- a/hwe/ts/common_legacy.ts +++ b/hwe/ts/common_legacy.ts @@ -1,7 +1,6 @@ import $ from "jquery"; import axios from "axios"; -axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; /** * object의 array를 id를 key로 삼는 object로 재 변환 */ diff --git a/hwe/ts/main.ts b/hwe/ts/main.ts index 28b390df..69b290a7 100644 --- a/hwe/ts/main.ts +++ b/hwe/ts/main.ts @@ -2,213 +2,30 @@ import $ from 'jquery'; import Popper from 'popper.js'; exportWindow(Popper, 'Popper');//XXX: 왜 popper를 이렇게 불러야 하는가? import 'bootstrap'; -import { parseTime } from './util/parseTime'; -import { addMilliseconds, addMinutes, differenceInMilliseconds } from 'date-fns'; -import { formatTime } from './util/formatTime'; -import { unwrap_any } from './util/unwrap_any'; -import { activateFlip, errUnknown, initTooltip } from './common_legacy'; -import { unwrap } from './util/unwrap'; -import { setAxiosXMLHttpRequest } from './util/setAxiosXMLHttpRequest'; +import { activateFlip, initTooltip } from './common_legacy'; import './msg.ts'; import './map.ts'; import { exportWindow } from './util/exportWindow'; -import {stringifyUrl} from 'query-string'; -import { joinYearMonth } from './util/joinYearMonth'; -import { parseYearMonth } from './util/parseYearMonth'; + + exportWindow($, '$'); -type TurnArg = { - //TODO: 채울것 -} - -type TurnItem = { - action: string, - brief: string, - arg: TurnArg, -} - -type ReservedTurnResponse = { - result: true, - turnTime: string, - turnTerm: number, - year: number, - month: number, - date: string, - turn: TurnItem[], - autorun_limit: number|null, -} +import '../scss/main.scss'; +import { unwrap } from './util/unwrap'; +import { number } from 'vue-types'; $(function ($) { - setAxiosXMLHttpRequest(); - - $('#refreshPage').click(function () { + $('.refreshPage').click(function () { document.location.reload(); return false; }); - - function reloadCommandList() { - void $.get({ - url: 'j_get_reserved_command.php', - dataType: 'json', - cache: false, - }).then(function (data: ReservedTurnResponse) { - if (!data) { - return; - } - if (!data.result) { - return; - } - const game_clock = parseTime(data.date); - const now_clock = new Date(); - const $clock = $('#clock'); - $clock.data('time-diff', differenceInMilliseconds(game_clock, now_clock)); - $clock.val(formatTime(game_clock)); - - const turnTime = parseTime(data.turnTime); - let nextTurnTime = new Date(turnTime); - - let nowYearMonth = joinYearMonth(data.year, data.month); - const autorunLimitYearMonth = data.autorun_limit ?? nowYearMonth - 1; - const [autorunLimitYear, autorunLimitMonth] = parseYearMonth(autorunLimitYearMonth); - - for (const [turnIdx, turnInfo] of Object.entries(data.turn)) { - const [year, month] = parseYearMonth(nowYearMonth); - const $tr = $(`#command_${turnIdx}`); - - $tr.find('.time_pad').text(formatTime(nextTurnTime, 'HH:mm')); - $tr.find('.month_pad').text(`${year}年 ${month}月`); - const $turn_pad = $tr.find('.turn_pad'); - const $turn_text = $turn_pad.find('.turn_text'); - $turn_text.text(turnInfo.brief).css('font-size', '13px'); - if(nowYearMonth <= autorunLimitYearMonth){ - const brief = turnInfo.brief != '휴식'? turnInfo.brief :'휴식(자율 행동)'; - const autorunTooltip = `${brief}자율 행동 기간: ${autorunLimitYear}년 ${autorunLimitMonth}월까지`; - $turn_text.html(autorunTooltip); - initTooltip($turn_text); - } - - - const oWidth = unwrap($turn_pad.innerWidth()); - const iWidth = unwrap($turn_text.outerWidth()); - if (iWidth > oWidth * 0.95) { - const newFontSize = 13 * oWidth / iWidth * 0.9; - $turn_text.css('font-size', `${newFontSize}px`); - } - - nextTurnTime = addMinutes(nextTurnTime, data.turnTerm); - nowYearMonth += 1; - } - console.log(data); - - - }); - } - - function myclock() { - - const $clock = $('#clock'); - const now_clock = new Date(); - - const rawTimeDiff = $clock.data('time-diff'); - if (rawTimeDiff === null || rawTimeDiff === undefined) { - return; - } - const timeDiff = unwrap_any(rawTimeDiff); - - const gameClock = addMilliseconds(now_clock, timeDiff); - - $('#clock').val(formatTime(gameClock)); - } - - function pushTurn(pushAmount: number) { - $.post({ - url: 'j_general_turn.php', - dataType: 'json', - data: { - amount: pushAmount - } - }).then(function (data) { - if (!data.result) { - alert(data.reason); - } - reloadCommandList(); - }, errUnknown); - } - - function repeatTurn(repeatAmount: number) { - $.post({ - url: 'j_general_turn.php', - dataType: 'json', - data: { - amount: repeatAmount, - is_repeat: true - } - }).then(function (data) { - if (!data.result) { - alert(data.reason); - } - reloadCommandList(); - }, errUnknown); - } - - $('#pullTurn').click(function () { - pushTurn(-parseInt(unwrap_any($('#repeatAmount').val()))); - }); - - $('#pushTurn').click(function () { - pushTurn(parseInt(unwrap_any($('#repeatAmount').val()))); - }); - - $('#repeatTurn').click(function () { - repeatTurn(parseInt(unwrap_any($('#repeatAmount').val()))); - }); - - - function reserveTurn(turnList: number[], command: string) { - console.log(turnList, command); - $.post({ - url: 'j_set_general_command.php', - dataType: 'json', - data: { - action: command, - turnList: turnList - } - }).then(function (data) { - if (!data.result) { - alert(data.reason); - } - reloadCommandList(); - }, errUnknown); - } - - $('#reserveTurn').click(function () { - const turnList = unwrap_any($('#generalTurnSelector').val()).map(v => parseInt(v)); - const $command = $('#generalCommandList option:selected'); - if ($command.data('reqarg')) { - document.location.href = stringifyUrl({ - url: 'b_processing.php', - query: { - command: unwrap_any($command.val()), - turnList: turnList.join('_') - } - }); - } - else { - reserveTurn(turnList, unwrap_any($command.val())); - } - return false; - }) - - $('.open-window').on('click', function(e){ + $('.open-window').on('click', function (e) { e.preventDefault(); let target = $(e.target as HTMLAnchorElement); - while(target.attr('href') === undefined){ + while (target.attr('href') === undefined) { target = target.parent('a'); - if(target.length == 0){ + if (target.length == 0) { return; } } @@ -216,8 +33,136 @@ $(function ($) { window.open(href); }); - setInterval(myclock, 500); - reloadCommandList(); activateFlip(); initTooltip(); -}); \ No newline at end of file +}); + +function ready(fn: () => unknown) { + if (document.readyState != 'loading') { + fn(); + } else { + document.addEventListener('DOMContentLoaded', fn); + } +} + +(() => { + + let finInit = false; + const objects: { + target: HTMLElement, + button: HTMLAnchorElement, + }[] = []; + + let nationMsgBox!: HTMLElement; + let nationMsg!: HTMLElement; + let nationMsgHeight : number|undefined = undefined; + + let commandSelector!: HTMLElement; + let deviceWidth = -1; + let viewportMeta! : HTMLMetaElement; + + function init() { + const buttons = document.querySelectorAll('#float-tabs a.btn'); + if (!buttons) { + return false; + } + finInit = true; + + for (const button of buttons) { + const targetQuery = button.href.split('#'); + if (!targetQuery || targetQuery.length < 2) { + continue; + } + const target = document.getElementById(targetQuery[1]); + if (!target) { + continue; + } + objects.push({ target, button }); + } + + nationMsgBox = unwrap(document.getElementById('nation-msg-box')); + nationMsg = unwrap(document.getElementById('nation-msg')); + + commandSelector = unwrap(document.getElementById('reservedCommandList')); + viewportMeta = unwrap(document.querySelector("meta[name=viewport]")); + } + + function adjustViewportWidth() { + if(deviceWidth == window.screen.availWidth){ + return; + } + deviceWidth = window.screen.availWidth; + const innerHeight = window.innerHeight; + const selectorHeight = commandSelector.offsetHeight*1.1; + + if(deviceWidth < 500){ + viewportMeta.content = 'width=500, initial-scale=1'; + console.log(`2`); + return; + } + + if(innerHeight < selectorHeight){ + const maybeNextWidth = deviceWidth / innerHeight * selectorHeight; + if(maybeNextWidth >= 750){ + viewportMeta.content = 'width=1000, initial-scale=1'; + } + else{ + viewportMeta.content = `height=${Math.ceil(selectorHeight)}, initial-scale=1`; + } + return; + } + } + function onScroll() { + if (!finInit && !init()) return; + + for (const { button } of objects) { + button.classList.remove('active'); + } + + const screenHeight = window.innerHeight + for (const { target, button } of objects) { + const { top, bottom, height } = target.getBoundingClientRect(); + + if (top >= 0 && bottom <= screenHeight) { + //valid + } + else if (top <= 0 && bottom >= screenHeight) { + //valid + } + else if (top < 0) { + if (bottom / height < 0.8) { + continue; + } + } + else if (bottom > screenHeight) { + if ((screenHeight - top) / height < 0.8) { + continue; + } + } + + button.classList.add('active'); + } + + if(nationMsgBox.offsetWidth < nationMsg.offsetWidth){ + if(nationMsgHeight === undefined){ + nationMsgHeight = nationMsgBox.offsetHeight; + nationMsgBox.style.height = `${nationMsgHeight / 2}px`; + } + } + else{ + if(nationMsgBox.style.height){ + nationMsgHeight = undefined; + nationMsgBox.style.height = ''; + } + } + + adjustViewportWidth(); + } + + ready(() => { + init(); + onScroll(); + window.addEventListener('scroll', onScroll, true); + window.addEventListener('orientationchange', onScroll, true); + }); +})(); \ No newline at end of file diff --git a/hwe/ts/map.ts b/hwe/ts/map.ts index 61cd1ff2..4ce3f2eb 100644 --- a/hwe/ts/map.ts +++ b/hwe/ts/map.ts @@ -18,7 +18,7 @@ declare global { interface Window { sam_toggleSingleTap?: boolean, getCityPosition: () => CityPositionMap; - formatCityInfo: (city: MapCityParsedRaw)=>MapCityParsedRegionLevelText + formatCityInfo: (city: MapCityParsedRaw) => MapCityParsedRegionLevelText } } @@ -323,7 +323,7 @@ export async function reloadWorldMap(option: loadMapOption, drawTarget = '.world }; } - function mergeNationInfo(city: MapCityParsedName):MapCityParsedNation{ + function mergeNationInfo(city: MapCityParsedName): MapCityParsedNation { //nationID 값으로 isCapital, color, nation을 통합 const nationID = city.nationID; @@ -343,7 +343,7 @@ export async function reloadWorldMap(option: loadMapOption, drawTarget = '.world }; } - function mergeClickable(city:MapCityParsedNation): MapCityParsedClickable { + function mergeClickable(city: MapCityParsedNation): MapCityParsedClickable { //clickable = (defaultCity << 4 ) | (remainSpy << 3) | (ourCity << 2) | (shownByGeneral << 1) | clickableAll const id = city.id; const nationID = city.nationID; @@ -436,7 +436,7 @@ export async function reloadWorldMap(option: loadMapOption, drawTarget = '.world }); - if(myCity){ + if (myCity) { $world_map.find(`.city_base_${myCity} .city_filler`).addClass('my_city'); } @@ -444,7 +444,7 @@ export async function reloadWorldMap(option: loadMapOption, drawTarget = '.world return obj; } - function drawBasicWorldMap(obj:MapCityDrawable) { + function drawBasicWorldMap(obj: MapCityDrawable) { const $map_body = $(`${drawTarget} .map_body`); @@ -496,7 +496,7 @@ export async function reloadWorldMap(option: loadMapOption, drawTarget = '.world $map_body.append($cityObj); }); - if(myCity){ + if (myCity) { $world_map.find(`.city_base_${myCity} .city_filler`).addClass('my_city'); } @@ -504,7 +504,7 @@ export async function reloadWorldMap(option: loadMapOption, drawTarget = '.world return obj; } - function setMouseWork(obj:MapCityDrawable) { + function setMouseWork(obj: MapCityDrawable) { const $tooltip = $(drawTarget + ' .city_tooltip'); const $tooltip_city = $tooltip.find('.city_name'); const $tooltip_nation = $tooltip.find('.nation_name'); @@ -552,16 +552,17 @@ export async function reloadWorldMap(option: loadMapOption, drawTarget = '.world $tooltip_nation.html('').hide(); } - let left = position.left; - let top = position.top; + const left = position.left; + const top = position.top; - const scale = $map_body.data('scale'); - if (scale) { - left /= scale; - top /= scale; + const tooltipWidth = unwrap($tooltip.width()); + + if (left + tooltipWidth + 35 > window.innerWidth) { + $tooltip.css({ 'top': top + 45, 'left': left - tooltipWidth - 10 }).show(); + } + else { + $tooltip.css({ 'top': top + 45, 'left': left + 35 }).show(); } - - $tooltip.css({ 'top': top + 25, 'left': left + 35 }).show(); const touchMode = $this.data('touchMode') as number; if (touchMode <= 1) { @@ -590,16 +591,19 @@ export async function reloadWorldMap(option: loadMapOption, drawTarget = '.world } const rect = this.getBoundingClientRect(); - let left = (e.clientX - rect.left - this.clientLeft + this.scrollLeft); - let top = (e.clientY - rect.top - this.clientTop + this.scrollTop); + const left = (e.clientX - rect.left - this.clientLeft + this.scrollLeft); + const top = (e.clientY - rect.top - this.clientTop + this.scrollTop); - const scale = $map_body.data('scale'); - if (scale) { - left /= scale; - top /= scale; + const tooltipWidth = unwrap($tooltip.width()); + + if (e.clientX + rect.left + tooltipWidth + 10 > window.innerWidth) { + $tooltip.css({ 'top': top + 30, 'left': left - tooltipWidth - 10 }); + } + else { + $tooltip.css({ 'top': top + 30, 'left': left + 10 }); } - $tooltip.css({ 'top': top + 10, 'left': left + 10 }); + }); $objs.on('mouseenter', function () { @@ -627,7 +631,7 @@ export async function reloadWorldMap(option: loadMapOption, drawTarget = '.world $objs.on('click', function () { //xxx: touchend 다음 click 이벤트가 갈 수도 있고, 안 갈 수도 있다. - const touchMode = $(this).data('touchMode') as number|undefined; + const touchMode = $(this).data('touchMode') as number | undefined; if (touchMode === undefined) { return; } @@ -641,7 +645,7 @@ export async function reloadWorldMap(option: loadMapOption, drawTarget = '.world return obj; } - function setCityClickable(obj:MapCityDrawable) { + function setCityClickable(obj: MapCityDrawable) { obj.cityList.forEach(function (city) { const $cityLink = $world_map.find(`.city_base_${city.id} .city_link`); @@ -746,7 +750,7 @@ export async function reloadWorldMap(option: loadMapOption, drawTarget = '.world if ($world_map.hasClass('draw_required')) { if (useCachedMap) { //일단 불러옴 - await (async ()=>{ + await (async () => { const rawStoredMap = localStorage.getItem(storedOldMapKey); if (!rawStoredMap) { return; @@ -757,14 +761,14 @@ export async function reloadWorldMap(option: loadMapOption, drawTarget = '.world } await setMapBackground(storedMap) - .then(convertCityObjs) - .then(isDetailMap?drawDetailWorldMap:drawBasicWorldMap) - .then(setMouseWork) - .then(setCityClickable) - .then(saveCityInfo); + .then(convertCityObjs) + .then(isDetailMap ? drawDetailWorldMap : drawBasicWorldMap) + .then(setMouseWork) + .then(setCityClickable) + .then(saveCityInfo); })(); } else if (option.year && option.month) { - const rawStartYear = localStorage.getItem(storedStartYear) as string|undefined; + const rawStartYear = localStorage.getItem(storedStartYear) as string | undefined; let startYear: number; if (rawStartYear) { startYear = JSON.parse(rawStartYear); diff --git a/hwe/ts/util/sammoAPI.ts b/hwe/ts/util/sammoAPI.ts new file mode 100644 index 00000000..2897242e --- /dev/null +++ b/hwe/ts/util/sammoAPI.ts @@ -0,0 +1,28 @@ +import axios from "axios"; +import { isArray } from "lodash"; +import { InvalidResponse } from "../defs"; + +type ValidResponse = { + result: true +} + +export async function sammoAPI(path: string | string[], args?: Record): Promise { + if (isArray(path)) { + path = path.join('/'); + } + + const response = await axios({ + url: "api.php", + method: "post", + responseType: "json", + data: { + path, + args, + }, + }); + const result: InvalidResponse | ResultType = response.data; + if (!result.result) { + throw result.reason; + } + return result; +} \ No newline at end of file diff --git a/hwe/ts/v_main.ts b/hwe/ts/v_main.ts new file mode 100644 index 00000000..7141ad33 --- /dev/null +++ b/hwe/ts/v_main.ts @@ -0,0 +1,9 @@ +import { createApp } from 'vue' +import ReservedCommand from './ReservedCommand.vue'; +import BootstrapVue3 from 'bootstrap-vue-3' +import { setAxiosXMLHttpRequest } from './util/setAxiosXMLHttpRequest'; + + +setAxiosXMLHttpRequest(); + +createApp(ReservedCommand).use(BootstrapVue3).mount('#reservedCommandList') \ No newline at end of file diff --git a/package.json b/package.json index 47cab1be..79aecc61 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "async-validator": "^4.0.3", "axios": "^0.21.4", "bootstrap": "^4.6.0", - "bootstrap5": "npm:bootstrap@^5.1.1", + "bootstrap5": "npm:bootstrap@^5.1.3", "core-js": "^3.17.3", "date-fns": "^2.24.0", "downloadjs": "^1.4.7", @@ -58,8 +58,8 @@ "@vue/eslint-config-typescript": "^7.0.0", "babel-plugin-lodash": "^3.3.4", "babel-preset-modern-browsers": "^15.0.2", - "bootstrap-vue-3": "^0.0.3", - "bootswatch": "^5.1.1", + "bootstrap-vue-3": "^0.0.5", + "bootswatch": "^5.1.3", "clean-terminal-webpack-plugin": "^3.0.0", "css-loader": "^6.2.0", "esbuild-loader": "^2.15.1",