로그인 form draw 예시

This commit is contained in:
2020-06-26 23:31:45 +09:00
parent f74a7b31c3
commit cfc897055b
5 changed files with 1219 additions and 1108 deletions
+131 -130
View File
@@ -1,131 +1,132 @@
body, html{ body,
height: 100%; html {
background-repeat: no-repeat; height: 100%;
} background-repeat: no-repeat;
}
.main{
margin-top: 70px; .main {
} margin-top: 70px;
}
h1.title {
font-size: 50px; h1.title {
font-family: 'Passion One', cursive; font-size: 50px;
font-weight: 400; font-family: 'Passion One', cursive;
} font-weight: 400;
}
hr{
width: 10%; hr {
/*color: #fff;*/ width: 10%;
} /*color: #fff;*/
}
.form-group{
margin-bottom: 15px; .form-group {
} margin-bottom: 15px;
}
label{
margin-bottom: 15px; label {
} margin-bottom: 15px;
}
input,
input::-webkit-input-placeholder { input,
font-size: 11px; input::-webkit-input-placeholder {
padding-top: 3px; font-size: 11px;
} padding-top: 3px;
}
.main-login{
/*background-color: #fff;*/ .main-login {
/* shadows and rounded borders */ /*background-color: #fff;*/
-moz-border-radius: 2px; /* shadows and rounded borders */
-webkit-border-radius: 2px; -moz-border-radius: 2px;
border-radius: 2px; -webkit-border-radius: 2px;
-moz-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3); border-radius: 2px;
-webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3); -moz-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3); -webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
} }
.main-center{ .main-center {
margin-top: 30px; margin-top: 30px;
margin: 0 auto; margin: 0 auto;
max-width: 330px; max-width: 330px;
padding: 40px 40px; padding: 40px 40px;
}
}
.login_btn_group {
.login_btn_group{ margin-top: 5px;
margin-top: 5px; }
}
.login-register {
.login-register{ font-size: 11px;
font-size: 11px; text-align: center;
text-align: center; }
}
.col-form-label {
text-align: center;
.col-form-label{ }
text-align:center;
} .terms {
max-height: 200px;
.terms{ overflow-y: auto;
max-height: 200px; overflow-y: auto; }
}
.terms pre {
.terms pre{ width: 100%;
width:100%; white-space: pre-wrap;
white-space: pre-wrap; /* Since CSS 2.1 */ /* Since CSS 2.1 */
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ white-space: -moz-pre-wrap;
white-space: -pre-wrap; /* Opera 4-6 */ /* Mozilla, since 1999 */
white-space: -o-pre-wrap; /* Opera 7 */ white-space: -pre-wrap;
word-wrap: break-word; /* Internet Explorer 5.5+ */ /* Opera 4-6 */
} white-space: -o-pre-wrap;
/* Opera 7 */
.vertical-center { word-wrap: break-word;
min-height: 100%; /* Fallback for browsers do NOT support vh unit */ /* Internet Explorer 5.5+ */
min-height: 100vh; /* These two lines are counted as one :-) */ }
display: flex; .vertical-center {
align-items: center; min-height: 100%;
} /* Fallback for browsers do NOT support vh unit */
min-height: 100vh;
.full-content { /* These two lines are counted as one :-) */
position:fixed; display: flex;
left:0; align-items: center;
top:0; }
width:100%;
height:100%; #login_card {
margin:0; z-index: 801;
padding:0; }
z-index:800;
} #btn_kakao_login {
cursor: pointer;
#login_card{ height: 46px;
z-index:801; width: 116px;
} background-color: transparent;
color: transparent;
#btn_kakao_login{ border: 0;
cursor: pointer; background-size: 100%;
height:46px; /* To fill the dimensions of container (button), or */
width:116px; background-repeat: no-repeat;
background-color: transparent; background-position: bottom center;
color:transparent; margin-top: 5px;
border:0; background-image: url('../oauth_kakao/kakao_login_join.png');
background-size: 100%; /* To fill the dimensions of container (button), or */ }
background-repeat: no-repeat;
background-position: bottom center; #btn_kakao_login:hover {
margin-top:5px; background-image: url('../oauth_kakao/kakao_login_join_ov.png');
background-image:url('../oauth_kakao/kakao_login_join.png'); }
}
#bottom_box .container {
#btn_kakao_login:hover { text-align: center;
background-image:url('../oauth_kakao/kakao_login_join_ov.png'); }
}
.btn-group-xs>.btn,
#bottom_box{ .btn-xs {
position:fixed; padding: .25rem .4rem;
bottom:0; font-size: .875rem;
width:100%; line-height: .5;
left:0; border-radius: .2rem;
} }
#bottom_box .container{
text-align:center; #running_map {
margin-top: 20px;
} }
+6 -1
View File
@@ -54,7 +54,7 @@ $defaultPost = [
'showMe' => false, 'showMe' => false,
]; ];
$history = getGlobalHistoryLogRecent(15); $history = formatHistoryToHTML(getGlobalHistoryLogRecent(10));
$rawMap = getWorldMap([ $rawMap = getWorldMap([
'year' => null, 'year' => null,
'month' => null, 'month' => null,
@@ -63,7 +63,12 @@ $rawMap = getWorldMap([
'showMe' => false, 'showMe' => false,
]); ]);
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$mapTheme = $gameStor->map_theme ?? 'che';
$rawMap['history'] = $history; $rawMap['history'] = $history;
$rawMap['theme'] = $mapTheme;
$etag = hash('sha256', $serverID.$now); $etag = hash('sha256', $serverID.$now);
$map = [ $map = [
+685 -653
View File
@@ -1,654 +1,686 @@
function is_touch_device() {
function is_touch_device() { var prefixes = ' -webkit- -moz- -o- -ms- '.split(' ');
var prefixes = ' -webkit- -moz- -o- -ms- '.split(' '); var mq = function(query) {
var mq = function(query) { return window.matchMedia(query).matches;
return window.matchMedia(query).matches; }
}
if (('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch) {
if (('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch) { return true;
return true; }
}
// include the 'heartz' as a way to have a non matching MQ to help terminate the join
// include the 'heartz' as a way to have a non matching MQ to help terminate the join // https://git.io/vznFH
// https://git.io/vznFH var query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join('');
var query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join(''); return mq(query);
return mq(query); }
}
function reloadWorldMap(option, drawTarget) {
function reloadWorldMap(option){ if (drawTarget === undefined || drawTarget === null) {
var $world_map = $('.world_map'); drawTarget = '.world_map'
}
if($world_map.length == 0){ var $world_map = $(drawTarget);
return;
} if ($world_map.length == 0) {
return;
var defaultOption = { }
isDetailMap:true, //복잡 지도, 단순 지도
clickableAll:false, //어떤 경우든 클릭을 가능하게 함. 해당 동작의 동작 가능성 여부와는 별도. var defaultOption = {
selectCallback:null, //callback을 지정시 clickable과 관계 없이 해당 함수를 실행. isDetailMap: true, //복잡 지도, 단순 지도
hrefTemplate:'#', //도시가 클릭가능할 경우 지정할 href값. {0}은 도시 id로 변환됨 clickableAll: false, //어떤 경우든 클릭을 가능하게 함. 해당 동작의 동작 가능성 여부와는 별도.
useCachedMap:false, //맵 캐시를 사용 selectCallback: null, //callback을 지정시 clickable과 관계 없이 해당 함수를 실행.
hrefTemplate: '#', //도시가 클릭가능할 경우 지정할 href값. {0}은 도시 id로 변환됨
//아래부터는 post query에 들어갈 녀석 useCachedMap: false, //맵 캐시를 사용
year:null, //year값, 연감등에 사용
month:null, //month값, 연감등에 사용 //아래부터는 post query에 들어갈 녀석
aux:null, //기타 넣고 싶은 값을 입력 year: null, //year값, 연감등에 사용
neutralView:false, //clickable, 소속 국가, 첩보 여부 등을 반환여부를 설정 month: null, //month값, 연감등에 사용
showMe:true, //반환 값에 본인이 위치한 도시 값을 반환하도록 설정. neutralView와 별개 aux: null, //기타 넣고 싶은 값을 입력
targetJson:'j_map.php', neutralView: false, //clickable, 소속 국가, 첩보 여부 등을 반환여부를 설정
showMe: true, //반환 값에 본인이 위치한 도시 값을 반환하도록 설정. neutralView와 별개
//기타 보조 값
startYear:null, targetJson: 'j_map.php',
}; reqType: 'post',
dynamicMapTheme: false,
option = $.extend(defaultOption, option); callback: null,
var useCachedMap = option.useCachedMap; //기타 보조 값
var isDetailMap = option.isDetailMap; startYear: null,
var clickableAll = option.clickableAll; };
var selectCallback = option.selectCallback;
var hrefTemplate = option.hrefTemplate; option = $.extend(defaultOption, option);
var cityPosition = getCityPosition(); var useCachedMap = option.useCachedMap;
var isDetailMap = option.isDetailMap;
var storedOldMapKey = 'sam.{0}.map'.format(serverNick); var clickableAll = option.clickableAll;
var storedStartYear = 'sam.{0}.startYear'.format(serverNick); var selectCallback = option.selectCallback;
//OBJ : startYear, year, month, cityList, nationList, spyList, shownByGeneralList, myCity var hrefTemplate = option.hrefTemplate;
function checkReturnObject(obj){ var cityPosition = getCityPosition();
if(!obj.result){
var obj = $.Deferred(); var storedOldMapKey = 'sam.{0}.map'.format(serverNick);
obj.reject('fail'); var storedStartYear = 'sam.{0}.startYear'.format(serverNick);
return obj.promise(); //OBJ : startYear, year, month, cityList, nationList, spyList, shownByGeneralList, myCity
}
function checkReturnObject(obj) {
if(!$.isNumeric(obj.startYear) if (!obj.result) {
||!$.isNumeric(obj.year) var obj = $.Deferred();
||!$.isNumeric(obj.month) obj.reject('fail');
){ return obj.promise();
var obj = $.Deferred(); }
obj.reject('fail');
return obj.promise(); if (!$.isNumeric(obj.startYear) ||
} !$.isNumeric(obj.year) ||
!$.isNumeric(obj.month)
if(useCachedMap){ ) {
localStorage.setItem(storedOldMapKey, JSON.stringify([serverID, obj])); var obj = $.Deferred();
localStorage.setItem(storedStartYear, JSON.stringify(obj.startYear)); obj.reject('fail');
} return obj.promise();
}
$world_map.removeClass('draw_required');
if (useCachedMap) {
return obj; localStorage.setItem(storedOldMapKey, JSON.stringify([serverID, obj]));
} localStorage.setItem(storedStartYear, JSON.stringify(obj.startYear));
}
function setMapBackground(obj){
var startYear = obj.startYear; $world_map.removeClass('draw_required');
var year = obj.year;
var month = obj.month; return obj;
}
if(isDetailMap){
$world_map.addClass('map_detail').removeClass('map_basic');
}
else{ function setMapBackground(obj) {
$world_map.addClass('map_basic').removeClass('map_detail'); function setTheme() {
} var oldTheme = $world_map.data('currentTheme');
var newTheme = obj.theme;
var $map_title = $('.map_title_text'); if (oldTheme === newTheme) {
if(year < startYear + 1){ return;
$map_title.css('color', 'magenta'); }
} if (oldTheme) {
else if(year < startYear + 2){ $world_map.removeClass('map_theme_' + oldTheme);
$map_title.css('color', 'orange'); }
} $world_map.addClass('map_theme_' + newTheme);
else if(year < startYear + 3){ $world_map.data('currentTheme', newTheme);
$map_title.css('color', 'yellow'); }
} if (option.dynamicMapTheme) {
setTheme();
$map_title_tooltip = $('.map_title .tooltiptext'); }
$map_title_tooltip.empty(); var startYear = obj.startYear;
var year = obj.year;
var tooltipTexts = []; var month = obj.month;
if(year < startYear + 3){
var startYearText = []; if (isDetailMap) {
var remainYear = startYear + 3 - year; $world_map.addClass('map_detail').removeClass('map_basic');
var remainMonth = 12 - month + 1; } else {
if(remainMonth > 0){ $world_map.addClass('map_basic').removeClass('map_detail');
remainYear -= 1; }
}
if(remainYear){ var $map_title = $('.map_title_text');
startYearText.push('{0}년'.format(remainYear)); if (year < startYear + 1) {
} $map_title.css('color', 'magenta');
if(remainMonth){ } else if (year < startYear + 2) {
startYearText.push('{0}개월'.format(remainMonth)); $map_title.css('color', 'orange');
} } else if (year < startYear + 3) {
$map_title.css('color', 'yellow');
tooltipTexts.push('초반제한 기간 : {0} ({1}년)'.format(startYearText.join(' '), startYear + 3)); }
}
$map_title_tooltip = $('.map_title .tooltiptext');
var currentTechLimit = Math.floor(Math.max(0, year - startYear) / 5) + 1; $map_title_tooltip.empty();
var nextTechLimitYear = currentTechLimit * 5 + startYear;
var tooltipTexts = [];
tooltipTexts.push('기술등급 제한 : {0}등급 ({1}년 해제)'.format(currentTechLimit, nextTechLimitYear, currentTechLimit+1)); if (year < startYear + 3) {
$map_title_tooltip.html(tooltipTexts.join('<br>')); var startYearText = [];
var remainYear = startYear + 3 - year;
$world_map.removeClass('map_string map_summer map_fall map_winter'); var remainMonth = 12 - month + 1;
if(month <= 3){ if (remainMonth > 0) {
$world_map.addClass('map_spring'); remainYear -= 1;
} }
else if(month <= 6){ if (remainYear) {
$world_map.addClass('map_summer'); startYearText.push('{0}년'.format(remainYear));
} }
else if(month <= 9){ if (remainMonth) {
$world_map.addClass('map_fall'); startYearText.push('{0}개월'.format(remainMonth));
} }
else{
$world_map.addClass('map_winter'); tooltipTexts.push('초반제한 기간 : {0} ({1}년)'.format(startYearText.join(' '), startYear + 3));
} }
$map_title.html('{0}年 {1}月'.format(year, month)); var currentTechLimit = Math.floor(Math.max(0, year - startYear) / 5) + 1;
var nextTechLimitYear = currentTechLimit * 5 + startYear;
return obj;
} tooltipTexts.push('기술등급 제한 : {0}등급 ({1}년 해제)'.format(currentTechLimit, nextTechLimitYear, currentTechLimit + 1));
$map_title_tooltip.html(tooltipTexts.join('<br>'));
function convertCityObjs(obj){
//원본 Obj는 굉장히 간소하게 온다, Object 형태로 변환해서 사용한다. $world_map.removeClass('map_string map_summer map_fall map_winter');
if (month <= 3) {
function toCityObj(arr){ $world_map.addClass('map_spring');
return { } else if (month <= 6) {
id:arr[0], $world_map.addClass('map_summer');
level:arr[1], } else if (month <= 9) {
state:arr[2], $world_map.addClass('map_fall');
nationId:(arr[3]>0)?arr[3]:null, } else {
region:arr[4], $world_map.addClass('map_winter');
supply:(arr[5]!=0) }
};
} $map_title.html('{0}年 {1}月'.format(year, month));
function toNationObj(arr){ return obj;
return { }
id:arr[0],
name:arr[1], function convertCityObjs(obj) {
color:arr[2], //원본 Obj는 굉장히 간소하게 온다, Object 형태로 변환해서 사용한다.
capital:arr[3]
}; function toCityObj(arr) {
} return {
id: arr[0],
var cityList = obj.cityList.map(toCityObj); level: arr[1],
var nationList = obj.nationList.map(toNationObj); state: arr[2],
nationList = convertDictById(nationList); //array of object -> dict nationId: (arr[3] > 0) ? arr[3] : null,
region: arr[4],
var spyList = obj.spyList; supply: (arr[5] != 0)
var shownByGeneralList = convertSet(obj.shownByGeneralList);//Array -> Set };
}
var myCity = obj.myCity;
var myNation = obj.myNation; function toNationObj(arr) {
return {
id: arr[0],
function mergePositionInfo(city){ name: arr[1],
var id = city.id; color: arr[2],
if(!(id in cityPosition)){ capital: arr[3]
return city; };
} }
var xy_val = cityPosition[id];
city.name = xy_val[0]; var cityList = obj.cityList.map(toCityObj);
city.x = xy_val[1]; var nationList = obj.nationList.map(toNationObj);
city.y = xy_val[2]; nationList = convertDictById(nationList); //array of object -> dict
return city;
} var spyList = obj.spyList;
var shownByGeneralList = convertSet(obj.shownByGeneralList); //Array -> Set
function mergeNationInfo(city){
//nationId 값으로 isCapital, color, nation을 통합 var myCity = obj.myCity;
var myNation = obj.myNation;
var nationId = city.nationId;
if(nationId === null || !(nationId in nationList)){
city.nationId = null; function mergePositionInfo(city) {
city.nation = null; var id = city.id;
city.color = null; if (!(id in cityPosition)) {
city.isCapital = false; return city;
return city; }
} var xy_val = cityPosition[id];
city.name = xy_val[0];
var nationObj = nationList[nationId]; city.x = xy_val[1];
city.nation = nationObj.name; city.y = xy_val[2];
city.color = nationObj.color; return city;
city.isCapital = (nationObj.capital == city.id); }
return city; function mergeNationInfo(city) {
} //nationId 값으로 isCapital, color, nation을 통합
function mergeClickable(city){ var nationId = city.nationId;
//clickable = (remainSpy << 3) | (ourCity << 2) | (shownByGeneral << 1) | clickableAll if (nationId === null || !(nationId in nationList)) {
var id = city.id; city.nationId = null;
var nationId = city.nationId; city.nation = null;
var clickable = 0; city.color = null;
if(id in spyList){ city.isCapital = false;
clickable |= spyList[id] << 3; return city;
} }
if(myNation !== null && nationId == myNation){
clickable |= 4; var nationObj = nationList[nationId];
} city.nation = nationObj.name;
if(shownByGeneralList.hasOwnProperty(id)){ city.color = nationObj.color;
clickable |= 2; city.isCapital = (nationObj.capital == city.id);
}
if(myCity !== null && id == myCity){ return city;
clickable |= 2; }
}
if(clickableAll){ function mergeClickable(city) {
clickable |= 1; //clickable = (remainSpy << 3) | (ourCity << 2) | (shownByGeneral << 1) | clickableAll
} var id = city.id;
var nationId = city.nationId;
var clickable = 0;
city.clickable = clickable; if (id in spyList) {
return city; clickable |= spyList[id] << 3;
} }
if (myNation !== null && nationId == myNation) {
cityList = cityList clickable |= 4;
.map(mergePositionInfo) }
.map(mergeNationInfo) if (shownByGeneralList.hasOwnProperty(id)) {
.map(mergeClickable) clickable |= 2;
.map(formatCityInfo); }
if (myCity !== null && id == myCity) {
return { clickable |= 2;
'cityList' : cityList, }
'myCity' : myCity if (clickableAll) {
}; clickable |= 1;
} }
function drawDetailWorldMap(obj){
city.clickable = clickable;
var $map_body = $('.world_map .map_body'); return city;
}
var cityList = obj.cityList;
var myCity = obj.myCity; cityList = cityList
.map(mergePositionInfo)
cityList.forEach(function(city){ .map(mergeNationInfo)
var id = city.id; .map(mergeClickable)
$('.city_base_{0}'.format(id)).detach(); .map(formatCityInfo);
//이전 도시는 지운다.
return {
var $cityObj = $('<div class="city_base city_base_{0}"></div>'.format(id)); 'cityList': cityList,
$cityObj.addClass('city_level_{0}'.format(city.level)); 'myCity': myCity
$cityObj.data('obj', city).css({'left':city.x-20,'top':city.y-15}); };
}
if('color' in city && city.color !== null){
var $bgObj = $('<div class="city_bg"></div>'); function drawDetailWorldMap(obj) {
$cityObj.append($bgObj);
$bgObj.css({'background-image':'url({0}/b{1}.png)'.format(pathConfig.gameImage, convColorValue(city.color))}); var $map_body = $(drawTarget + ' .map_body');
}
var cityList = obj.cityList;
var $linkObj = $('<a class="city_link"></a>'); var myCity = obj.myCity;
$linkObj.data({'text':city.text,'nation':city.nation,'id':city.id});
$cityObj.append($linkObj); cityList.forEach(function(city) {
var id = city.id;
var $imgObj = $('<div class="city_img"><img src="{0}/cast_{1}.gif"><div class="city_filler"></div></div>'.format(pathConfig.gameImage, city.level)); $('.city_base_{0}'.format(id)).detach();
$linkObj.append($imgObj); //이전 도시는 지운다.
var $cityObj = $('<div class="city_base city_base_{0}"></div>'.format(id));
$cityObj.addClass('city_level_{0}'.format(city.level));
if(city.state > 0){ $cityObj.data('obj', city).css({ 'left': city.x - 20, 'top': city.y - 15 });
var $stateObj = $('<div class="city_state"><img src="{0}/event{1}.gif"></div>'.format(pathConfig.gameImage, city.state));
$linkObj.append($stateObj); if ('color' in city && city.color !== null) {
} var $bgObj = $('<div class="city_bg"></div>');
$cityObj.append($bgObj);
if(city.nationId && city.nationId > 0){ $bgObj.css({ 'background-image': 'url({0}/b{1}.png)'.format(pathConfig.gameImage, convColorValue(city.color)) });
var flagType = city.supply?'f':'d'; }
var $flagObj = $('<div class="city_flag"><img src="{0}/{1}{2}.gif"></div>'.format(pathConfig.gameImage, flagType, convColorValue(city.color)));
if(city.isCapital){ var $linkObj = $('<a class="city_link"></a>');
var $capitalObj = $('<div class="city_capital"><img src="{0}/event51.gif"></div>'.format(pathConfig.gameImage)); $linkObj.data({ 'text': city.text, 'nation': city.nation, 'id': city.id });
$flagObj.append($capitalObj); $cityObj.append($linkObj);
}
$imgObj.append($flagObj); var $imgObj = $('<div class="city_img"><img src="{0}/cast_{1}.gif"><div class="city_filler"></div></div>'.format(pathConfig.gameImage, city.level));
} $linkObj.append($imgObj);
var $nameObj = $('<span class="city_detail_name">{0}</span>'.format(city.name));
$imgObj.append($nameObj);
if (city.state > 0) {
var $stateObj = $('<div class="city_state"><img src="{0}/event{1}.gif"></div>'.format(pathConfig.gameImage, city.state));
$map_body.append($cityObj); $linkObj.append($stateObj);
}
}); if (city.nationId && city.nationId > 0) {
var flagType = city.supply ? 'f' : 'd';
$world_map.find('.city_base_{0} .city_filler'.format(myCity)).addClass('my_city'); var $flagObj = $('<div class="city_flag"><img src="{0}/{1}{2}.gif"></div>'.format(pathConfig.gameImage, flagType, convColorValue(city.color)));
if (city.isCapital) {
return obj; var $capitalObj = $('<div class="city_capital"><img src="{0}/event51.gif"></div>'.format(pathConfig.gameImage));
} $flagObj.append($capitalObj);
}
function drawBasicWorldMap(obj){ $imgObj.append($flagObj);
}
var $map_body = $('.world_map .map_body');
var $nameObj = $('<span class="city_detail_name">{0}</span>'.format(city.name));
var cityList = obj.cityList; $imgObj.append($nameObj);
var myCity = obj.myCity;
cityList.forEach(function(city){ $map_body.append($cityObj);
var id = city.id;
$('.city_base_{0}'.format(id)).detach();
//이전 도시는 지운다. });
var $cityObj = $('<div class="city_base city_base_{0}"></div>'.format(id)); $world_map.find('.city_base_{0} .city_filler'.format(myCity)).addClass('my_city');
$cityObj.addClass('city_level_{0}'.format(city.level));
$cityObj.data('obj', city).css({'left':city.x-20,'top':city.y-15}); return obj;
}
var $linkObj = $('<a class="city_link"></a>');
$linkObj.data({'text':city.text,'nation':city.nation,'id':city.id}); function drawBasicWorldMap(obj) {
$cityObj.append($linkObj);
var $map_body = $(drawTarget + ' .map_body');
var $imgObj = $('<div class="city_img"><div class="city_filler"></div></div>');
if('color' in city && city.color !== null){ var cityList = obj.cityList;
$imgObj.css({'background-color':city.color}); var myCity = obj.myCity;
}
$linkObj.append($imgObj); cityList.forEach(function(city) {
var id = city.id;
if(city.state > 0){ $('.city_base_{0}'.format(id)).detach();
var state_text = 'wrong'; //이전 도시는 지운다.
if(city.state < 10){
state_text = 'good'; var $cityObj = $('<div class="city_base city_base_{0}"></div>'.format(id));
} $cityObj.addClass('city_level_{0}'.format(city.level));
else if(city.state < 40){ $cityObj.data('obj', city).css({ 'left': city.x - 20, 'top': city.y - 15 });
state_text = 'bad';
} var $linkObj = $('<a class="city_link"></a>');
else if(city.state < 50){ $linkObj.data({ 'text': city.text, 'nation': city.nation, 'id': city.id });
state_text = 'war'; $cityObj.append($linkObj);
}
var $imgObj = $('<div class="city_img"><div class="city_filler"></div></div>');
var $stateObj = $('<div class="city_state city_state_{0}"></div>'.format(state_text)); if ('color' in city && city.color !== null) {
$imgObj.append($stateObj); $imgObj.css({ 'background-color': city.color });
} }
$linkObj.append($imgObj);
//단순 표기에서는 깃발 여부가 없음
if(city.isCapital){ if (city.state > 0) {
var $capitalObj = $('<div class="city_capital"></div>'); var state_text = 'wrong';
$imgObj.append($capitalObj); if (city.state < 10) {
} state_text = 'good';
} else if (city.state < 40) {
var $nameObj = $('<span class="city_detail_name">{0}</span>'.format(city.name)); state_text = 'bad';
$imgObj.append($nameObj); } else if (city.state < 50) {
state_text = 'war';
$map_body.append($cityObj); }
});
var $stateObj = $('<div class="city_state city_state_{0}"></div>'.format(state_text));
$world_map.find('.city_base_{0} .city_filler'.format(myCity)).addClass('my_city'); $imgObj.append($stateObj);
}
return obj;
} //단순 표기에서는 깃발 여부가 없음
if (city.isCapital) {
function setMouseWork(obj){ var $capitalObj = $('<div class="city_capital"></div>');
var $tooltip = $('.world_map .city_tooltip'); $imgObj.append($capitalObj);
var $tooltip_city = $tooltip.find('.city_name'); }
var $tooltip_nation = $tooltip.find('.nation_name');
var $nameObj = $('<span class="city_detail_name">{0}</span>'.format(city.name));
var $objs = $('.world_map .city_link'); $imgObj.append($nameObj);
var $map_body = $('.world_map .map_body'); $map_body.append($cityObj);
});
//터치스크린 탭
$world_map.find('.city_base_{0} .city_filler'.format(myCity)).addClass('my_city');
if(!option.neutralView && is_touch_device()){
$objs.on('touchstart', function(e){ return obj;
if(window.sam_toggleSingleTap){ }
return true;
} function setMouseWork(obj) {
var $this = $(this); var $tooltip = $(drawTarget + ' .city_tooltip');
var $tooltip_city = $tooltip.find('.city_name');
var touchMode = $this.data('touchMode'); var $tooltip_nation = $tooltip.find('.nation_name');
if($tooltip_city.data('target') != $this.data('id')){
$this.data('touchMode', 1); var $objs = $(drawTarget + ' .city_link');
}
else if(touchMode === undefined){ var $map_body = $(drawTarget + ' .map_body');
$this.data('touchMode', 1);
} //터치스크린 탭
else{
$this.data('touchMode', touchMode + 1); if (!option.neutralView && is_touch_device()) {
} $objs.on('touchstart', function(e) {
$map_body.data('touchMode', 1); if (window.sam_toggleSingleTap) {
return true;
$tooltip_city.data('target', $this.data('id')); }
var $this = $(this);
}); var touchMode = $this.data('touchMode');
if ($tooltip_city.data('target') != $this.data('id')) {
$objs.on('touchend', function(e){ $this.data('touchMode', 1);
if(window.sam_toggleSingleTap){ } else if (touchMode === undefined) {
return true; $this.data('touchMode', 1);
} } else {
var $this = $(this); $this.data('touchMode', touchMode + 1);
var position = $this.parent().position(); }
$tooltip_city.html($this.data('text')); $map_body.data('touchMode', 1);
var nation_text = $this.data('nation'); $tooltip_city.data('target', $this.data('id'));
if(nation_text){
$tooltip_nation.html(nation_text).show();
} });
else{
$tooltip_nation.html('').hide(); $objs.on('touchend', function(e) {
} if (window.sam_toggleSingleTap) {
return true;
$tooltip.css({'top': position.top + 25, 'left': position.left + 35}).show(); }
var $this = $(this);
var touchMode = $this.data('touchMode'); var position = $this.parent().position();
if(touchMode <= 1){ $tooltip_city.html($this.data('text'));
return false;
} var nation_text = $this.data('nation');
if (nation_text) {
//xxx: touchend 다음 click 이벤트가 갈 수도 있고, 안 갈 수도 있다. $tooltip_nation.html(nation_text).show();
$this.data('touchMode', 0); } else {
}); $tooltip_nation.html('').hide();
}
$map_body.on('touchend',function(e){
if(window.sam_toggleSingleTap){ var left = position.left;
return true; var top = position.top;
}
//위의 touchend bind에 해당하지 않는 경우 -> 빈 지도 터치 var scale = $map_body.data('scale');
$tooltip.hide(); if (scale) {
}); left /= scale;
top /= scale;
} }
//Mouse over 모드 작동 $tooltip.css({ 'top': top + 25, 'left': left + 35 }).show();
$map_body.on('mousemove', function(e){ var touchMode = $this.data('touchMode');
if($(this).data('touchMode')){ if (touchMode <= 1) {
return true; return false;
} }
var parentOffset = $map_body.offset(); //xxx: touchend 다음 click 이벤트가 갈 수도 있고, 안 갈 수도 있다.
var relX = e.pageX - parentOffset.left; $this.data('touchMode', 0);
var relY = e.pageY - parentOffset.top; });
$tooltip.css({'top': relY + 10, 'left': relX + 10}); $map_body.on('touchend', function(e) {
}); if (window.sam_toggleSingleTap) {
return true;
$objs.on('mouseenter', function(e){ }
if($map_body.data('touchMode')){ //위의 touchend bind에 해당하지 않는 경우 -> 빈 지도 터치
return true; $tooltip.hide();
} });
var $this = $(this); }
$tooltip_city.data('target', $this.data('id')); //Mouse over 모드 작동
$tooltip_city.html($this.data('text'));
var nation_text = $this.data('nation'); $map_body.on('mousemove', function(e) {
if(nation_text){ if ($(this).data('touchMode')) {
$tooltip_nation.html(nation_text).show(); return true;
} }
else{
$tooltip_nation.html('').hide(); var rect = this.getBoundingClientRect();
} var left = (e.clientX - rect.left - this.clientLeft + this.scrollLeft);
var top = (e.clientY - rect.top - this.clientTop + this.scrollTop);
$tooltip.show();
}); var scale = $map_body.data('scale');
if (scale) {
$objs.on('mouseleave', function(event){ left /= scale;
$tooltip.hide(); top /= scale;
}); }
$objs.on('click', function(e){ $tooltip.css({ 'top': top + 10, 'left': left + 10 });
//xxx: touchend 다음 click 이벤트가 갈 수도 있고, 안 갈 수도 있다. });
var touchMode = $(this).data('touchMode');
if(touchMode === undefined){ $objs.on('mouseenter', function(e) {
return; if ($map_body.data('touchMode')) {
} return true;
}
if(touchMode === 1){
return false; var $this = $(this);
}
}); $tooltip_city.data('target', $this.data('id'));
$tooltip_city.html($this.data('text'));
var nation_text = $this.data('nation');
return obj; if (nation_text) {
} $tooltip_nation.html(nation_text).show();
} else {
function setCityClickable(obj){ $tooltip_nation.html('').hide();
}
obj.cityList.forEach(function(city){
var $cityLink = $world_map.find('.city_base_{0} .city_link'.format(city.id)); $tooltip.show();
});
if('clickable' in city && city.clickable > 0){
$cityLink.attr('href',hrefTemplate.format(city.id)); $objs.on('mouseleave', function(event) {
} $tooltip.hide();
});
if(selectCallback){
$cityLink.click(function(){ $objs.on('click', function(e) {
return selectCallback(city); //xxx: touchend 다음 click 이벤트가 갈 수도 있고, 안 갈 수도 있다.
}); var touchMode = $(this).data('touchMode');
} if (touchMode === undefined) {
}); return;
}
return obj;
} if (touchMode === 1) {
return false;
function saveCityInfo(obj){ }
$world_map.data('cityInfo', obj); });
return obj;
}
return obj;
var $hideCityNameBtn = $world_map.find('.map_toggle_cityname'); }
if(localStorage.getItem('sam.hideMapCityName') == 'yes'){
$world_map.addClass('hide_cityname'); function setCityClickable(obj) {
$hideCityNameBtn.addClass('active').attr('aria-pressed', 'true');
} obj.cityList.forEach(function(city) {
var $cityLink = $world_map.find('.city_base_{0} .city_link'.format(city.id));
$hideCityNameBtn.click(function(){
//이전 상태 확인 if ('clickable' in city && city.clickable > 0) {
var state = !$hideCityNameBtn.hasClass('active'); $cityLink.attr('href', hrefTemplate.format(city.id));
if(state){ }
$world_map.addClass('hide_cityname');
localStorage.setItem('sam.hideMapCityName', 'yes'); if (selectCallback) {
} $cityLink.click(function() {
else{ return selectCallback(city);
$world_map.removeClass('hide_cityname'); });
localStorage.setItem('sam.hideMapCityName', 'no'); }
} });
});
return obj;
var $toggleSingleTapBtn = $world_map.find('.map_toggle_single_tap'); }
if(localStorage.getItem('sam.toggleSingleTap') == 'yes'){
window.sam_toggleSingleTap = true; function saveCityInfo(obj) {
$toggleSingleTapBtn.addClass('active').attr('aria-pressed', 'true'); $world_map.data('cityInfo', obj);
} return obj;
else{ }
window.sam_toggleSingleTap = false;
} var $hideCityNameBtn = $world_map.find('.map_toggle_cityname');
if (localStorage.getItem('sam.hideMapCityName') == 'yes') {
var $map_body = $('.world_map .map_body'); $world_map.addClass('hide_cityname');
$hideCityNameBtn.addClass('active').attr('aria-pressed', 'true');
$toggleSingleTapBtn.click(function(){ }
//이전 상태 확인
var state = !$toggleSingleTapBtn.hasClass('active'); $hideCityNameBtn.click(function() {
if(state){ //이전 상태 확인
$map_body.removeData('touchMode'); var state = !$hideCityNameBtn.hasClass('active');
localStorage.setItem('sam.toggleSingleTap', 'yes'); if (state) {
window.sam_toggleSingleTap = true; $world_map.addClass('hide_cityname');
} localStorage.setItem('sam.hideMapCityName', 'yes');
else{ } else {
localStorage.setItem('sam.toggleSingleTap', 'no'); $world_map.removeClass('hide_cityname');
window.sam_toggleSingleTap = false; localStorage.setItem('sam.hideMapCityName', 'no');
} }
}); });
if(isDetailMap){ var $toggleSingleTapBtn = $world_map.find('.map_toggle_single_tap');
$world_map.addClass('map_detail'); if (localStorage.getItem('sam.toggleSingleTap') == 'yes') {
} window.sam_toggleSingleTap = true;
else{ $toggleSingleTapBtn.addClass('active').attr('aria-pressed', 'true');
$world_map.removeClass('map_datail'); } else {
} window.sam_toggleSingleTap = false;
}
//deferred mode of jQuery. != promise-then.
var deferred = $.ajax({ var $map_body = $(drawTarget + ' .map_body');
url: option.targetJson,
type: 'post', $toggleSingleTapBtn.click(function() {
dataType:'json', //이전 상태 확인
data: { var state = !$toggleSingleTapBtn.hasClass('active');
data: JSON.stringify({ if (state) {
neutralView:option.neutralView, $map_body.removeData('touchMode');
year:option.year, localStorage.setItem('sam.toggleSingleTap', 'yes');
month:option.month, window.sam_toggleSingleTap = true;
showMe:option.showMe, } else {
aux:option.aux localStorage.setItem('sam.toggleSingleTap', 'no');
}) window.sam_toggleSingleTap = false;
} }
}); });
deferred if (isDetailMap) {
.then(checkReturnObject) $world_map.addClass('map_detail');
.then(setMapBackground) } else {
.then(convertCityObjs) $world_map.removeClass('map_datail');
.then(isDetailMap?drawDetailWorldMap:drawBasicWorldMap) }
.then(setMouseWork)
.then(setCityClickable) //deferred mode of jQuery. != promise-then.
.then(saveCityInfo); var deferred = $.ajax({
url: option.targetJson,
if($world_map.hasClass('draw_required')){ type: option.reqType,
if(useCachedMap){ dataType: 'json',
//일단 불러옴 ifModified: true,
do{ data: {
var storedMap = localStorage.getItem(storedOldMapKey); data: JSON.stringify({
if(!storedMap){ neutralView: option.neutralView,
break; year: option.year,
} month: option.month,
storedMap = JSON.parse(storedMap); showMe: option.showMe,
var storedServerID = storedMap[0]; aux: option.aux
if(storedServerID != serverID){ })
break; }
} });
storedMap = storedMap[1]; var rawObject = null;
storedMap = setMapBackground(storedMap);
storedMap = convertCityObjs(storedMap); deferred
if(isDetailMap){ .then(function(data) {
storedMap = drawDetailWorldMap(storedMap); rawObject = data;
} return data;
else{ })
storedMap = drawBasicWorldMap(storedMap); .then(checkReturnObject)
} .then(setMapBackground)
storedMap = setMouseWork(storedMap); .then(convertCityObjs)
storedMap = setCityClickable(storedMap); .then(isDetailMap ? drawDetailWorldMap : drawBasicWorldMap)
storedMap = saveCityInfo(storedMap); .then(setMouseWork)
}while(false); .then(setCityClickable)
} .then(saveCityInfo)
else if(option.year && option.month){ .then(function(data) {
var startYear = localStorage.getItem(storedStartYear); if (option.callback) {
if(startYear){ option.callback(data, rawObject);
startYear = JSON.parse(startYear); }
}
else{ });
startYear = option.year;
} if ($world_map.hasClass('draw_required')) {
var tmp = { if (useCachedMap) {
year : option.year, //일단 불러옴
month : option.month, do {
startYear : startYear var storedMap = localStorage.getItem(storedOldMapKey);
}; if (!storedMap) {
setMapBackground(tmp); break;
} }
storedMap = JSON.parse(storedMap);
var storedServerID = storedMap[0];
} if (storedServerID != serverID) {
} break;
$(function(){ }
if(is_touch_device()){
$('.map_body .map_toggle_single_tap').show(); storedMap = storedMap[1];
} storedMap = setMapBackground(storedMap);
storedMap = convertCityObjs(storedMap);
if (isDetailMap) {
storedMap = drawDetailWorldMap(storedMap);
} else {
storedMap = drawBasicWorldMap(storedMap);
}
storedMap = setMouseWork(storedMap);
storedMap = setCityClickable(storedMap);
storedMap = saveCityInfo(storedMap);
} while (false);
} else if (option.year && option.month) {
var startYear = localStorage.getItem(storedStartYear);
if (startYear) {
startYear = JSON.parse(startYear);
} else {
startYear = option.year;
}
var tmp = {
year: option.year,
month: option.month,
startYear: startYear
};
setMapBackground(tmp);
}
}
}
$(function() {
if (is_touch_device()) {
$('.map_body .map_toggle_single_tap').show();
}
}) })
+280 -231
View File
@@ -1,232 +1,281 @@
<?php <?php
namespace sammo; namespace sammo;
require(__DIR__ . '/vendor/autoload.php'); require(__DIR__ . '/vendor/autoload.php');
if (!class_exists('\\sammo\\RootDB')) { if (!class_exists('\\sammo\\RootDB')) {
header('Location:install.php'); header('Location:install.php');
die(); die();
} }
$session = Session::getInstance(); $session = Session::getInstance();
use \kakao\KakaoKey as KakaoKey; use \kakao\KakaoKey as KakaoKey;
if ($session->isLoggedIn()) { if ($session->isLoggedIn()) {
header('Location:i_entrance/entrance.php'); header('Location:i_entrance/entrance.php');
die(); die();
} }
?> $runningServer = null;
<!DOCTYPE html>
<html lang="ko"> foreach(ServConfig::getServerList() as $setting){
if(!$setting->isExists()){
<head> continue;
<meta charset="UTF-8"> }
<meta http-equiv="X-UA-Compatible" content="IE=edge"> if(!$setting->isRunning()){
<meta name="viewport" content="width=device-width, initial-scale=1" /> continue;
<title>삼국지 모의전투 HiDCHe</title> }
<?= WebUtil::printJS('e_lib/jquery-3.3.1.min.js') ?> $runningServer = [
<?= WebUtil::printJS('e_lib/bootstrap.bundle.min.js') ?> 'color'=>$setting->getColor(),
<?= WebUtil::printJS('e_lib/jquery.validate.min.js') ?> 'korName'=>$setting->getKorName(),
<?= WebUtil::printJS('e_lib/sha512.min.js') ?> 'name'=>$setting->getShortName(),
<?= WebUtil::printJS('js/common.js') ?> 'exists'=>$setting->isExists(),
<?= WebUtil::printJS('js/login.js') ?> 'enable'=>$setting->isRunning()
<?= WebUtil::printCSS('e_lib/bootstrap.min.css') ?> ];
<?= WebUtil::printCSS('css/login.css') ?> }
<meta name="description" content="실시간으로 진행되는 삼국지 웹게임(삼모전)입니다">
<meta name="keywords" content="삼국지,삼모전,웹게임,힏체,힏체섭,히데체,히데체섭,HiDCHe,체섭"> if($runningServer){
<meta property="og:type" content="website"> $subTemplates = new \League\Plates\Engine(__DIR__.'/'.$runningServer['name'].'/templates');
<meta property="og:title" content="삼국지 모의전투 HiDCHe"> }
<meta property="og:description" content="실시간으로 진행되는 삼국지 웹게임(삼모전)입니다">
<meta property="og:url" content="https://sam.hided.net"> ?>
<script> <!DOCTYPE html>
var oauthMode = null; <html lang="ko">
function getOAuthToken(mode, scope_list) { <head>
if (mode === undefined) { <meta charset="UTF-8">
mode = 'login'; <meta http-equiv="X-UA-Compatible" content="IE=edge">
} <meta name="viewport" content="width=device-width, initial-scale=1" />
if (scope_list === undefined) { <title>삼국지 모의전투 HiDCHe</title>
scope_list = null; <script>
} var runningServer = <?=Json::encode($runningServer)?>;
oauthMode = mode; </script>
var url = 'https://kauth.kakao.com/oauth/authorize?' + <?= WebUtil::printJS('e_lib/jquery-3.3.1.min.js') ?>
'client_id=<?= KakaoKey::REST_KEY ?>&' + <?= WebUtil::printJS('e_lib/bootstrap.bundle.min.js') ?>
'redirect_uri=<?= KakaoKey::REDIRECT_URI ?>&' + <?= WebUtil::printJS('e_lib/jquery.validate.min.js') ?>
'response_type=code'; <?= WebUtil::printJS('e_lib/sha512.min.js') ?>
if (Array.isArray(scope_list)) { <?= WebUtil::printJS('js/common.js') ?>
url += '&scope=' + scope_list.join(','); <?= WebUtil::printJS('js/login.js') ?>
} else if (typeof scope_list === 'string' || scope_list instanceof String) { <?= WebUtil::printJS('d_shared/common_path.js') ?>
url += '&scope=' + scope_list; <?= WebUtil::printCSS('d_shared/common.css') ?>
} <?= WebUtil::printCSS('e_lib/bootstrap.min.css') ?>
<?= WebUtil::printCSS('css/login.css') ?>
window.open(url, "KakaoAccountLogin", "width=600,height=450,resizable=yes,scrollbars=yes"); <?php if($runningServer): ?>
} <script>
var serverNick = '<?=$runningServer['korName']?>';
function sendTempPasswordToKakaoTalk() { </script>
$.post({ <?= WebUtil::printJS($runningServer['name'].'/d_shared/base_map.js') ?>
url: 'oauth_kakao/j_login_oauth.php', <?= WebUtil::printJS($runningServer['name'].'/js/map.js') ?>
dataType: 'json' <?= WebUtil::printCSS($runningServer['name'].'/css/map.css') ?>
}).then(function(obj) { <?php endif; ?>
var t = $.Deferred(); <meta name="description" content="실시간으로 진행되는 삼국지 웹게임(삼모전)입니다">
if (!obj.result) { <meta name="keywords" content="삼국지,삼모전,웹게임,힏체,힏체섭,히데체,히데체섭,HiDCHe,체섭">
t.reject(); <meta property="og:type" content="website">
} <meta property="og:title" content="삼국지 모의전투 HiDCHe">
return $.post({ <meta property="og:description" content="실시간으로 진행되는 삼국지 웹게임(삼모전)입니다">
url: 'oauth_kakao/j_change_pw.php', <meta property="og:url" content="https://sam.hided.net">
dataType: 'json' <script>
}); var oauthMode = null;
}).then(function(obj) {
if (!obj.result) { function getOAuthToken(mode, scope_list) {
alert(obj.reason); if (mode === undefined) {
} else { mode = 'login';
alert('임시 비밀번호가 카카오톡으로 전송되었습니다.'); }
} if (scope_list === undefined) {
}); scope_list = null;
} }
oauthMode = mode;
function doLoginUsingOAuth() { var url = 'https://kauth.kakao.com/oauth/authorize?' +
$.post({ 'client_id=<?= KakaoKey::REST_KEY ?>&' +
url: 'oauth_kakao/j_login_oauth.php', 'redirect_uri=<?= KakaoKey::REDIRECT_URI ?>&' +
dataType: 'json' 'response_type=code';
}).then(function(obj) { if (Array.isArray(scope_list)) {
if (obj.result) { url += '&scope=' + scope_list.join(',');
window.location.href = "./"; } else if (typeof scope_list === 'string' || scope_list instanceof String) {
return; url += '&scope=' + scope_list;
} }
if (!obj.reqOTP) {
alert(obj.reason); window.open(url, "KakaoAccountLogin", "width=600,height=450,resizable=yes,scrollbars=yes");
return; }
}
$('#modalOTP').modal().on('shown.bs.modal', function() { function sendTempPasswordToKakaoTalk() {
$('#otp_code').focus(); $.post({
}); url: 'oauth_kakao/j_login_oauth.php',
dataType: 'json'
}); }).then(function(obj) {
} var t = $.Deferred();
if (!obj.result) {
function postOAuthResult(result) { t.reject();
if (result == 'join') { }
window.location.href = 'oauth_kakao/join.php'; return $.post({
} else if (result == 'req_email') { url: 'oauth_kakao/j_change_pw.php',
alert('이메일 정보 공유를 허가해 주셔야 합니다.'); dataType: 'json'
} else if (result == 'login') { });
console.log('로그인모드'); }).then(function(obj) {
if (oauthMode == 'change_pw') { if (!obj.result) {
sendTempPasswordToKakaoTalk(); alert(obj.reason);
} else { } else {
doLoginUsingOAuth(); alert('임시 비밀번호가 카카오톡으로 전송되었습니다.');
} }
} else { });
alert('예외 발생!'); }
}
} function doLoginUsingOAuth() {
</script> $.post({
</head> url: 'oauth_kakao/j_login_oauth.php',
dataType: 'json'
<body> }).then(function(obj) {
<nav class="navbar navbar-expand-lg fixed-top navbar-dark bg-dark"> if (obj.result) {
<a class="navbar-brand" href=".">삼국지 모의전투 HiDCHe</a> window.location.href = "./";
<button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"> return;
<span class="navbar-toggler-icon"></span> }
</button> if (!obj.reqOTP) {
<div class="collapse navbar-collapse" id="navbarNav"> alert(obj.reason);
<ul class="navbar-nav"> return;
<?= WebUtil::drawMenu(ROOT . '/d_shared/menu.json') ?> }
</ul> $('#modalOTP').modal().on('shown.bs.modal', function() {
</div> $('#otp_code').focus();
</nav> });
<div class="full-content">
<div class="vertical-center"> });
<div class="container"> }
<h1 class="row justify-content-md-center">삼국지 모의전투 HiDCHe</h1>
<div class="row justify-content-md-center"> function postOAuthResult(result) {
<div class="col" style="max-width:450px;"> if (result == 'join') {
<div class="card" id="login_card"> window.location.href = 'oauth_kakao/join.php';
<h3 class="card-header"> } else if (result == 'req_email') {
로그인 alert('이메일 정보 공유를 허가해 주셔야 합니다.');
</h3> } else if (result == 'login') {
<div class="card-body"> console.log('로그인모드');
if (oauthMode == 'change_pw') {
<form id="main_form" method="post" action="#"> sendTempPasswordToKakaoTalk();
<div class="form-group row"> } else {
<label for="username" class="col-5 col-md-4 col-form-label">계정명</label> doLoginUsingOAuth();
<div class="col-7 col-md-8"> }
<input autocomplete="username" type="text" class="form-control" name="username" id="username" autofocus="autofocus" placeholder="계정명" /> } else {
</div> alert('예외 발생!');
</div> }
}
</script>
<div class="form-group row"> </head>
<label for="password" class="col-5 col-md-4 col-form-label">비밀번호</label>
<div class="col-7 col-md-8"> <body>
<input autocomplete="current-password" type="password" class="form-control" name="password" id="password" placeholder="비밀번호" /> <nav class="navbar navbar-expand-lg fixed-top navbar-dark bg-dark">
</div> <a class="navbar-brand" href=".">삼국지 모의전투 HiDCHe</a>
</div> <button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
<input type="hidden" id="global_salt" name="global_salt" value="<?= RootDB::getGlobalSalt() ?>"> </button>
<div class="form-group row"> <div class="collapse navbar-collapse" id="navbarNav">
<div class="col-5 col-md-4 " style="position:relative;"><button type="button" onclick="getOAuthToken('login', ['account_email','talk_message']);" id="btn_kakao_login" title="카카오톡으로 가입&amp;로그인"></button></div> <ul class="navbar-nav">
<div class="col-7 col-md-8"> <?= WebUtil::drawMenu(ROOT . '/d_shared/menu.json') ?>
<div class="btn-group btn-group-lg d-flex login_btn_group" role="group"> </ul>
<button type="submit" class="btn btn-primary login-button w-100">로그인</button> </div>
<div class="btn-group" role="group"> </nav>
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> </button> <div class="container" style="margin-top:120px;">
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="btnGroupDrop1"> <h1 class="row justify-content-md-center">삼국지 모의전투 HiDCHe</h1>
<a class="dropdown-item" href="javascript:getOAuthToken('change_pw', 'talk_message');">비밀번호 초기화</a> <div class="row justify-content-md-center">
</div> <div class="col" style="max-width:450px;">
</div> <div class="card" id="login_card">
</div> <h3 class="card-header">
</div> 로그인
</div> </h3>
</form> <div class="card-body">
</div>
</div> <form id="main_form" method="post" action="#">
</div> <div class="form-group row">
</div> <label for="username" class="col-5 col-md-4 col-form-label">계정명</label>
</div> <div class="col-7 col-md-8">
</div> <input autocomplete="username" type="text" class="form-control" name="username" id="username" autofocus="autofocus" placeholder="계정명" />
<div id="bottom_box"> </div>
<div class="container"><a href="terms.2.html">개인정보처리방침</a> &amp; <a href="terms.1.html">이용약관</a><br>© 2020 • HideD </div>
<br>크롬과 파이어폭스에 최적화되어있습니다.</div>
</div>
</div> <div class="form-group row">
<label for="password" class="col-5 col-md-4 col-form-label">비밀번호</label>
<div class="modal fade" id="modalOTP" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true"> <div class="col-7 col-md-8">
<div class="modal-dialog" role="document"> <input autocomplete="current-password" type="password" class="form-control" name="password" id="password" placeholder="비밀번호" />
<div class="modal-content"> </div>
<form id="otp_form" method="post" action="#"> </div>
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">인증 코드 필요</h5> <input type="hidden" id="global_salt" name="global_salt" value="<?= RootDB::getGlobalSalt() ?>">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"> <div class="form-group row">
<span aria-hidden="true">&times;</span> <div class="col-5 col-md-4 " style="position:relative;"><button type="button" onclick="getOAuthToken('login', ['account_email','talk_message']);" id="btn_kakao_login" title="카카오톡으로 가입&amp;로그인"></button></div>
</button> <div class="col-7 col-md-8">
</div> <div class="btn-group btn-group-lg d-flex login_btn_group" role="group">
<div class="modal-body"> <button type="submit" class="btn btn-primary login-button w-100">로그인</button>
<div> <div class="btn-group" role="group">
인증 코드가 필요합니다.<br><br> <button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> </button>
카카오톡의 '나와의 채팅'란을 확인해 주세요.<br> <div class="dropdown-menu dropdown-menu-right" aria-labelledby="btnGroupDrop1">
(별도의 알림[소리, 진동, 숫자]이 발생하지 않습니다.) <a class="dropdown-item" href="javascript:getOAuthToken('change_pw', 'talk_message');">비밀번호 초기화</a>
</div> </div>
<div class="input-group mt-4" role="group"> </div>
<div class="input-group-prepend"> </div>
<span class="input-group-text">인증 코드</span> </div>
</div> </div>
<input type="number" class="form-control" name='otp' id="otp_code" placeholder="인증 코드"> </form>
</div> </div>
</div> </div>
<div class="modal-footer"> </div>
<button type="button" class="btn btn-secondary" data-dismiss="modal">취소</button> </div>
<button type="submit" class="btn btn-primary">제출</button> <?php if($runningServer): ?>
</div> <div class="row justify-content-md-center" id="running_map">
</form> <div class="col" style="max-width:700px;">
</div> <div class="card" style="width:700px;">
</div> <h3 class="card-header">
</div> <?=$runningServer['korName']?> 현황
</h3>
</body> <div class='map-container' style='position:relative;'>
<?=$subTemplates->render('map', [
'mapTheme' => ''
])?>
</div>
<div class="card-body">
</div>
</div>
</div>
</div>
<?php endif; ?>
</div>
<div id="bottom_box">
<div class="container"><a href="terms.2.html">개인정보처리방침</a> &amp; <a href="terms.1.html">이용약관</a><br>© 2020 • HideD
<br>크롬과 파이어폭스에 최적화되어있습니다.</div>
</div>
<div class="modal fade" id="modalOTP" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<form id="otp_form" method="post" action="#">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">인증 코드 필요</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div>
인증 코드가 필요합니다.<br><br>
카카오톡의 '나와의 채팅'란을 확인해 주세요.<br>
(별도의 알림[소리, 진동, 숫자]이 발생하지 않습니다.)
</div>
<div class="input-group mt-4" role="group">
<div class="input-group-prepend">
<span class="input-group-text">인증 코드</span>
</div>
<input type="number" class="form-control" name='otp' id="otp_code" placeholder="인증 코드">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">취소</button>
<button type="submit" class="btn btn-primary">제출</button>
</div>
</form>
</div>
</div>
</div>
</body>
</html> </html>
+117 -93
View File
@@ -1,93 +1,117 @@
$(document).ready( function () { $(document).ready(function() {
$( "#main_form" ).validate( { $("#main_form").validate({
rules: { rules: {
username: { username: {
required: true required: true
}, },
password: { password: {
required: true, required: true,
} }
}, },
messages: { messages: {
username: { username: {
required: "유저명을 입력해주세요" required: "유저명을 입력해주세요"
}, },
password: { password: {
required: "비밀번호를 입력해주세요" required: "비밀번호를 입력해주세요"
} }
}, },
errorElement: "div", errorElement: "div",
errorPlacement: function ( error, element ) { errorPlacement: function(error, element) {
// Add the `help-block` class to the error element // Add the `help-block` class to the error element
error.addClass( "invalid-feedback" ); error.addClass("invalid-feedback");
if ( element.prop( "type" ) === "checkbox" ) { if (element.prop("type") === "checkbox") {
error.insertAfter( element.parent( "label" ) ); error.insertAfter(element.parent("label"));
} else { } else {
error.insertAfter( element ); error.insertAfter(element);
} }
}, },
highlight: function ( element, errorClass, validClass ) { highlight: function(element, errorClass, validClass) {
$( element ).addClass( "is-invalid" ).removeClass( "is-valid" ); $(element).addClass("is-invalid").removeClass("is-valid");
}, },
unhighlight: function (element, errorClass, validClass) { unhighlight: function(element, errorClass, validClass) {
$( element ).addClass( "is-valid" ).removeClass( "is-invalid" ); $(element).addClass("is-valid").removeClass("is-invalid");
} }
} ); });
$( "#main_form" ).submit(function(){ $("#main_form").submit(function() {
var raw_password = $('#password').val(); var raw_password = $('#password').val();
var salt = $('#global_salt').val(); var salt = $('#global_salt').val();
var hash_pw = sha512(salt + raw_password + salt); var hash_pw = sha512(salt + raw_password + salt);
$.post({ $.post({
url:'j_login.php', url: 'j_login.php',
dataType:'json', dataType: 'json',
data:{ data: {
'username':$('#username').val(), 'username': $('#username').val(),
'password':hash_pw 'password': hash_pw
} }
}).then(function(obj){ }).then(function(obj) {
if(obj.result){ if (obj.result) {
window.location.href = "./"; window.location.href = "./";
return; return;
} }
if(!obj.reqOTP){ if (!obj.reqOTP) {
alert(obj.reason); alert(obj.reason);
return; return;
} }
var $modal = $('#modalOTP').modal(); var $modal = $('#modalOTP').modal();
$modal.on('shown.bs.modal', function(){ $modal.on('shown.bs.modal', function() {
$('#otp_code').focus(); $('#otp_code').focus();
}); });
}); });
return false; return false;
}); });
$('#otp_form').submit(function(){ $('#otp_form').submit(function() {
$.post({ $.post({
url:'oauth_kakao/j_check_OTP.php', url: 'oauth_kakao/j_check_OTP.php',
dataType:'json', dataType: 'json',
data:{ data: {
'otp':$('#otp_code').val(), 'otp': $('#otp_code').val(),
} }
}).then(function(obj){ }).then(function(obj) {
if(obj.result){ if (obj.result) {
alert(obj.reason); alert(obj.reason);
window.location.href = "./"; window.location.href = "./";
return; return;
} }
alert(obj.reason); alert(obj.reason);
if(obj.reset){ if (obj.reset) {
$('#modalOTP').modal('hide') $('#modalOTP').modal('hide')
return; return;
} }
}); });
return false; return false;
}) });
} );
if (document.body.clientWidth < 700) {
var targetWidth = document.body.clientWidth * 0.9;
var scale = targetWidth / 700;
var $map = $('#running_map');
$map.find('.col').css('max-width', targetWidth);
$map.find('.card').css('width', targetWidth);
$map.find('.map-container').css({
'transform-origin': 'top left',
'transform': 'scale({0}, {0})'.format(scale),
'height': 500 * scale,
});
$map.find('.map_body').data('scale', scale);
}
reloadWorldMap({
targetJson: "{0}/j_map_recent.php".format(runningServer.name),
reqType: 'get',
dynamicMapTheme: true,
callback: function(data, rawObject) {
$('#running_map .card-body').html(rawObject.history);
}
});
});