├── .github └── workflows │ └── update.yml ├── .gitignore ├── edge ├── get.js ├── package.json └── vercel.json ├── gadget_html5 ├── js │ ├── kcs_cda.js │ ├── kcs_const.js │ ├── kcs_content.js │ ├── kcs_global.js │ ├── kcs_inspection.js │ ├── kcs_login.js │ ├── kcs_options.js │ └── kcs_payment.js └── script │ ├── cookie.js │ ├── jquery.min.js │ ├── jss.js │ └── rollover.js ├── html ├── ban.png ├── deny.png ├── maintenance.html └── maintenance.png ├── kcscontents ├── css │ ├── common.css │ ├── default.css │ ├── import.css │ └── style.css ├── image │ ├── nav_item01.png │ ├── nav_item01_on.png │ ├── nav_item02.png │ ├── nav_item02_on.png │ ├── nav_item03.png │ ├── nav_item03_on.png │ ├── nav_item04.png │ ├── nav_item04_on.png │ ├── nav_item05.png │ └── nav_item05_on.png ├── news │ ├── index.html │ ├── post.html │ └── style.css └── script │ └── timing.min.js ├── last-modified.json ├── package.json ├── push.sh ├── readme.md ├── redirector.json ├── update.js └── yarn.lock /.github/workflows/update.yml: -------------------------------------------------------------------------------- 1 | name: Update 2 | on: 3 | workflow_dispatch: 4 | schedule: 5 | - cron: '*/30 * * * *' 6 | jobs: 7 | report: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v4 11 | - uses: actions/setup-node@v4 12 | with: 13 | node-version: '20' 14 | cache: 'yarn' 15 | - run: yarn --frozen-lockfile 16 | - run: node update.js - 17 | env: 18 | # EDGE: ${{ secrets.EDGE }} 19 | GITHUB: true 20 | - run: | 21 | git config --global user.name "Botkaze" 22 | git config --global user.email "gkpyon+1@gmail.com" 23 | TZ=Asia/Tokyo git commit -a -m "$(date +%Y-%m-%d)" 24 | git push 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /edge/get.js: -------------------------------------------------------------------------------- 1 | // seems more stable 2 | const fetch = require('node-fetch') 3 | 4 | export default async (req, res) => { 5 | try { 6 | const url = `http://w00g.kancolle-server.com/${decodeURIComponent(req.url.split('?url=')[1])}` 7 | const subReq = await fetch(url, { headers: { 'if-modified-since': req.headers['if-modified-since'] } }) 8 | res.writeHead(subReq.status, { 'last-modified': subReq.headers.get('last-modified') }) 9 | if (subReq.ok) { 10 | for await (const chunk of subReq.body) { 11 | res.write(chunk) 12 | } 13 | } 14 | res.end() 15 | } catch (err) { 16 | console.error(err.toString()) 17 | res.writeHead(500) 18 | res.end() 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /edge/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "node-fetch": "^2.7.0" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /edge/vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "regions": ["kix1"] 3 | } 4 | -------------------------------------------------------------------------------- /gadget_html5/js/kcs_cda.js: -------------------------------------------------------------------------------- 1 | window.addEventListener('message', function (event) { 2 | 3 | // サーバ選択前 4 | if (event.data == "w") { 5 | if (ConstServerInfo.Gadget == event.origin + "/") { 6 | Viewer_SendMessage(); 7 | return; 8 | } else { 9 | return; 10 | } 11 | } 12 | 13 | // サーバ選択後 14 | if (event.data == "r") { 15 | if (ConstServerInfo.Gadget == event.origin + "/") { 16 | kcsLogin_StartLogin(); 17 | return; 18 | } else { 19 | return; 20 | } 21 | } 22 | 23 | // ゲームサーバー以外の呼び出しや空のデータに対しては何もしない 24 | if ((ConstServerInfo.NETGAME != event.origin && userWorldInfo.worldServerAddr != event.origin) || event.data == "") { 25 | return; 26 | } 27 | // データの種別により処理を分岐 28 | var data = event.data.split("\t"); 29 | if (data[0] == "0") { 30 | // 0: アイテム購入 31 | kcsPayment_StartPayment(data[1], data[2], data[3], data[4], data[5], data[6]); 32 | return; 33 | } else if(data[0] == "1") { 34 | // 1: コメント変更 35 | kcsInspection_CreateInspectionComment(data[1]); 36 | return; 37 | } else if(data[0] == "2") { 38 | // 2: 艦隊名変更 39 | kcsInspection_CreateInspectionDeckName(data[1]); 40 | return; 41 | } else if(data[0] == "3") { 42 | // 3: 提督名変更 43 | kcsInspection_CreateInspectionNickName(data[1]); 44 | return; 45 | } else if(data[0] == "5") { 46 | // 5: 設定情報を cookie に保存する 47 | var options = data[1]; 48 | kcsOptions_Save(options); 49 | return; 50 | } else if(data[0] == "6") { 51 | // 6: 設定情報を cookie から取得してゲーム側へ送信する 52 | Options_SendMessage(kcsOptions_Load()); 53 | return; 54 | } 55 | }, false); 56 | 57 | function PaymentResult_SendMessage(paymentResult) { 58 | 59 | var gameElement = document.getElementById("htmlWrap").contentWindow; 60 | 61 | if (gameElement) { 62 | gameElement.postMessage(paymentResult, userWorldInfo.worldServerAddr); 63 | } 64 | } 65 | 66 | function Inspection_SendMessage(CommentId) { 67 | 68 | var gameElement = document.getElementById("htmlWrap").contentWindow; 69 | 70 | if (gameElement) { 71 | gameElement.postMessage(CommentId, userWorldInfo.worldServerAddr); 72 | } 73 | } 74 | 75 | function Viewer_SendMessage() { 76 | 77 | var gameElement = document.getElementById("htmlWrap").contentWindow; 78 | 79 | if (gameElement) { 80 | gameElement.postMessage(viewerInfo.id, ConstServerInfo.Gadget); 81 | } 82 | } 83 | 84 | function Options_SendMessage(options) { 85 | 86 | var gameElement = document.getElementById("htmlWrap").contentWindow; 87 | 88 | if (gameElement) { 89 | gameElement.postMessage(options, userWorldInfo.worldServerAddr); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /gadget_html5/js/kcs_const.js: -------------------------------------------------------------------------------- 1 | // ガジェット情報 2 | var ConstGadgetInfo = {}; 3 | ConstGadgetInfo.height = 860; //1160; 4 | 5 | // SNS 情報 6 | var ConstSNSInfo = {}; 7 | ConstSNSInfo.id = "DMM"; 8 | 9 | // サーバー情報 10 | var ConstServerInfo = {}; 11 | ConstServerInfo.Gadget = "http://w00g.kancolle-server.com/"; 12 | ConstServerInfo.World_1 = "http://w01y.kancolle-server.com/"; 13 | ConstServerInfo.World_2 = "http://w02k.kancolle-server.com/"; 14 | ConstServerInfo.World_3 = "http://w03s.kancolle-server.com/"; 15 | ConstServerInfo.World_4 = "http://w04m.kancolle-server.com/"; 16 | ConstServerInfo.World_5 = "http://w05o.kancolle-server.com/"; 17 | ConstServerInfo.World_6 = "http://w06t.kancolle-server.com/"; 18 | ConstServerInfo.World_7 = "http://w07l.kancolle-server.com/"; 19 | ConstServerInfo.World_8 = "http://w08r.kancolle-server.com/"; 20 | ConstServerInfo.World_9 = "http://w09s.kancolle-server.com/"; 21 | ConstServerInfo.World_10 = "http://w10b.kancolle-server.com/"; 22 | ConstServerInfo.World_11 = "http://w11t.kancolle-server.com/"; 23 | ConstServerInfo.World_12 = "http://w12p.kancolle-server.com/"; 24 | ConstServerInfo.World_13 = "http://w13b.kancolle-server.com/"; 25 | ConstServerInfo.World_14 = "http://w14h.kancolle-server.com/"; 26 | ConstServerInfo.World_15 = "http://w15p.kancolle-server.com/"; 27 | ConstServerInfo.World_16 = "http://w16s.kancolle-server.com/"; 28 | ConstServerInfo.World_17 = "http://w17k.kancolle-server.com/"; 29 | ConstServerInfo.World_18 = "http://w18i.kancolle-server.com/"; 30 | ConstServerInfo.World_19 = "http://w19s.kancolle-server.com/"; 31 | ConstServerInfo.World_20 = "http://w20h.kancolle-server.com/"; 32 | ConstServerInfo.OSAPI = "osapi.dmm.com"; 33 | ConstServerInfo.NETGAME = "http://www.dmm.com"; 34 | 35 | // URL 情報 36 | var ConstURLInfo = {}; 37 | ConstURLInfo.GetUserWorldURL = ConstServerInfo.Gadget + "kcsapi/api_world/get_id/"; 38 | ConstURLInfo.ConnectionCheckURL = ConstServerInfo.Gadget + "index.html"; 39 | ConstURLInfo.LoginURL = "kcsapi/api_auth_member/dmmlogin/"; 40 | 41 | // Parameter 情報 42 | var ConstParameterInfo = {}; 43 | ConstParameterInfo.PaymentResult_Paid = 0; 44 | ConstParameterInfo.PaymentResult_Cancel = -1; 45 | ConstParameterInfo.GetUserWorld_IsNew = 0; 46 | ConstParameterInfo.APIResult_OK = 1; 47 | ConstParameterInfo.APIResult_NG_Reload = -2; 48 | 49 | // Connection 情報 50 | var ConnectionInfo = {}; 51 | ConnectionInfo.Interval_Min = 10; 52 | 53 | // Maintenance 情報 54 | var MaintenanceInfo = {}; 55 | MaintenanceInfo.IsDoing = 0; 56 | MaintenanceInfo.IsEmergency = 0; 57 | MaintenanceInfo.StartDateTime = Date.parse("2025/05/30 00:00:00"); 58 | MaintenanceInfo.EndDateTime = Date.parse("2025/05/30 00:59:59"); 59 | 60 | // Version 情報 61 | var VersionInfo = {}; 62 | VersionInfo.scriptVesion = "6.1.2.0"; 63 | 64 | // Entrance 情報 65 | var EntranceInfo = {}; 66 | EntranceInfo.Groups = 10; 67 | EntranceInfo.Interval_Min = 1; 68 | EntranceInfo.UidIndex = 0; 69 | 70 | // Entrance 情報(ワールド別) 71 | EntranceInfo.NewUser = 2; 72 | EntranceInfo.World_1_User = 2; 73 | EntranceInfo.World_2_User = 2; 74 | EntranceInfo.World_3_User = 2; 75 | EntranceInfo.World_4_User = 2; 76 | EntranceInfo.World_5_User = 2; 77 | EntranceInfo.World_6_User = 2; 78 | EntranceInfo.World_7_User = 2; 79 | EntranceInfo.World_8_User = 2; 80 | EntranceInfo.World_9_User = 2; 81 | EntranceInfo.World_10_User = 2; 82 | EntranceInfo.World_11_User = 2; 83 | EntranceInfo.World_12_User = 2; 84 | EntranceInfo.World_13_User = 2; 85 | EntranceInfo.World_14_User = 2; 86 | EntranceInfo.World_15_User = 2; 87 | EntranceInfo.World_16_User = 2; 88 | EntranceInfo.World_17_User = 2; 89 | EntranceInfo.World_18_User = 2; 90 | EntranceInfo.World_19_User = 2; 91 | EntranceInfo.World_20_User = 2; 92 | -------------------------------------------------------------------------------- /gadget_html5/js/kcs_content.js: -------------------------------------------------------------------------------- 1 | // コンテンツを開く 2 | function kcsContent_OpenContent(contentId, url, width, height) 3 | { 4 | // 現在開いているコンテンツと同じボタンが押された場合 5 | if(contentId == contentInfo.id) 6 | { 7 | // 現在開いているコンテンツを閉じる。 8 | contentInfo.id = ""; 9 | document.getElementById("contentsWrap").innerHTML = ""; 10 | 11 | // ガジェットの高さを調整する。 12 | gadgets.window.adjustHeight(ConstGadgetInfo.height); 13 | } 14 | else 15 | { 16 | // 指定されたコンテンツを開く。 17 | contentInfo.id = contentId; 18 | document.getElementById("contentsWrap").innerHTML = 19 | ""; 22 | 23 | // ガジェットの高さを調整する。 24 | gadgets.window.adjustHeight(ConstGadgetInfo.height + height); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /gadget_html5/js/kcs_global.js: -------------------------------------------------------------------------------- 1 | // Viewer 情報 2 | var viewerInfo = {}; 3 | viewerInfo.id = ""; 4 | viewerInfo.displayName = ""; 5 | viewerInfo.userType = ""; 6 | 7 | // Flash 情報 8 | var flashInfo = {}; 9 | flashInfo.apiToken = ""; 10 | flashInfo.apiStartTime = ""; 11 | flashInfo.dmmLoginId = ""; 12 | 13 | // Item 情報 14 | var itemInfo = {}; 15 | itemInfo.skuId = ""; 16 | itemInfo.price = ""; 17 | itemInfo.count = ""; 18 | itemInfo.description = ""; 19 | itemInfo.name = ""; 20 | itemInfo.imageUrl = ""; 21 | 22 | // Content 情報 23 | var contentInfo = {}; 24 | contentInfo.id = ""; 25 | 26 | // UserWorld 情報 27 | var userWorldInfo = {}; 28 | userWorldInfo.worldServerAddr = ""; 29 | -------------------------------------------------------------------------------- /gadget_html5/js/kcs_inspection.js: -------------------------------------------------------------------------------- 1 | // 監視テキスト登録(提督名) 2 | function kcsInspection_CreateInspectionNickName(nickName) 3 | { 4 | // 監視テキスト登録パラメータを設定する。 5 | var params = {}; 6 | params[dmm.UserText.Field.DATA] = nickName; 7 | 8 | // 監視テキストを登録する。 9 | dmm.requestCreateInspection(params, function(response) 10 | { 11 | // エラーが発生した場合 12 | if (response.hadError()) 13 | { 14 | // 監視テキスト登録結果を通知する 15 | Inspection_SendMessage(""); 16 | 17 | // 処理を終了する。 18 | return; 19 | } 20 | 21 | // 監視テキストIDを取得する。 22 | var inspectionTextId; 23 | var data = response.getData(); 24 | data.each(function(entry) 25 | { 26 | inspectionTextId = entry.getTextId(); 27 | }); 28 | 29 | // 監視テキスト登録結果を通知する 30 | Inspection_SendMessage(inspectionTextId); 31 | 32 | }); 33 | } 34 | 35 | // 監視テキスト登録(艦隊名) 36 | function kcsInspection_CreateInspectionDeckName(deckName) 37 | { 38 | // 2014/06/23 空白が入力された場合の動作を「更新しない」に変更 39 | if (!deckName.match(/\S/g)) 40 | { 41 | // 監視テキスト登録結果を通知する 42 | Inspection_SendMessage(""); 43 | // 処理を終了する。 44 | return; 45 | } 46 | 47 | // 監視テキスト登録パラメータを設定する。 48 | var params = {}; 49 | params[dmm.UserText.Field.DATA] = deckName; 50 | 51 | // 監視テキストを登録する。 52 | dmm.requestCreateInspection(params, function(response) 53 | { 54 | // エラーが発生した場合 55 | if (response.hadError()) 56 | { 57 | // 監視テキスト登録結果を通知する 58 | Inspection_SendMessage(""); 59 | 60 | // 処理を終了する。 61 | return; 62 | } 63 | 64 | // 監視テキストIDを取得する。 65 | var inspectionTextId; 66 | var data = response.getData(); 67 | data.each(function(entry) 68 | { 69 | inspectionTextId = entry.getTextId(); 70 | }); 71 | 72 | // 監視テキスト登録結果を通知する 73 | Inspection_SendMessage(inspectionTextId); 74 | 75 | }); 76 | } 77 | 78 | // 監視テキスト登録(コメント) 79 | function kcsInspection_CreateInspectionComment(comment) 80 | { 81 | // 2014/06/23 空白が入力された場合の動作を「空白で更新する」よう変更 82 | if (!comment.match(/\S/g)) 83 | { 84 | comment = " "; 85 | } 86 | 87 | // 監視テキスト登録パラメータを設定する。 88 | var params = {}; 89 | params[dmm.UserText.Field.DATA] = comment; 90 | 91 | // 監視テキストを登録する。 92 | dmm.requestCreateInspection(params, function(response) 93 | { 94 | // エラーが発生した場合 95 | if (response.hadError()) 96 | { 97 | // 監視テキスト登録結果を通知する 98 | Inspection_SendMessage(""); 99 | 100 | // 処理を終了する。 101 | return; 102 | } 103 | 104 | // 監視テキストIDを取得する。 105 | var inspectionTextId; 106 | var data = response.getData(); 107 | data.each(function(entry) 108 | { 109 | inspectionTextId = entry.getTextId(); 110 | }); 111 | 112 | // 監視テキスト登録結果を通知する 113 | Inspection_SendMessage(inspectionTextId); 114 | 115 | }); 116 | } 117 | -------------------------------------------------------------------------------- /gadget_html5/js/kcs_login.js: -------------------------------------------------------------------------------- 1 | // check user agent 2 | var $browser = (function (ua) { 3 | var res = function (type) { 4 | var flg = { 5 | ie: false, 6 | mb: false 7 | }; 8 | 9 | switch (type) { 10 | case 'mb': 11 | flg.mb = true; 12 | return flg; 13 | case 'ie': 14 | flg.ie = true; 15 | return flg; 16 | default: 17 | return flg; 18 | } 19 | } 20 | 21 | // mobile 22 | if (/ip(hone|ad|od)/.test(ua) || /android/.test(ua)) return res('mb'); 23 | 24 | // 〜IE 11 25 | if (/msie/.test(ua) || /trident\/7/.test(ua)) return res('ie'); 26 | 27 | return res(null); 28 | })(window.navigator.userAgent.toLowerCase()); 29 | // ログイン 30 | function kcsLogin_StartLogin() 31 | { 32 | // HTML5 非対応ブラウザへの対応 33 | // モバイルの場合 34 | // if ($browser.mb) 35 | // { 36 | // } 37 | // "Internet Explorer 11 以前" の場合 38 | // if ($browser.ie) 39 | // { 40 | // alert("IE11以前のブラウザです。"); 41 | // kcsStartMaintenanceHTML(); 42 | // return; 43 | // } 44 | 45 | // DMM サーバが過負荷な状況にある場合、 46 | // さらなる負荷をかけないよう、ここで STOP する。 47 | if (MaintenanceInfo.IsDoing == 1 && MaintenanceInfo.IsEmergency == 1) 48 | { 49 | // 画面下部の情報セクションを表示する。 50 | document.getElementById("sectionWrap").style.display = "block"; 51 | 52 | // メンテナンス画面を表示する。 53 | kcsStartMaintenanceHTML(); 54 | return; 55 | } 56 | 57 | // 58 | // ユーザ情報取得リクエストを送信する。 59 | // 60 | 61 | // 取得データパラメータを定義する。 62 | var params = {}; 63 | 64 | // (DMM固有)取得データパラメータに userType を設定する。 65 | if (ConstSNSInfo.id == "DMM") 66 | { 67 | params[opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS] = [ 68 | "userType" 69 | ]; 70 | } 71 | 72 | // データリクエストを作成する。 73 | var req = opensocial.newDataRequest(); 74 | 75 | // プロフィール読み取りリクエストを作成し、 76 | // データリクエストに格納する。 77 | // 読み取る対象はアプリを参照しているユーザー(VIEWER) 78 | req.add( 79 | req.newFetchPersonRequest( 80 | opensocial.IdSpec.PersonId.VIEWER, params), "viewer"); 81 | 82 | // データリクエストを送信する。 83 | // (データレスポンス用のコールバック関数を設定) 84 | req.send(function(response) 85 | { 86 | // エラーが発生した場合 87 | if (response.hadError()) 88 | { 89 | // エラー処理へ遷移する。 90 | return; 91 | } 92 | else 93 | { 94 | // データレスポンスから item を取得する。 95 | var item = response.get("viewer"); 96 | // item からデータを取得する。 97 | var viewer = item.getData(); 98 | 99 | // ユーザーID 100 | viewerInfo.id = viewer.getId(); 101 | // ユーザー名 102 | viewerInfo.displayName = viewer.getDisplayName(); 103 | // (DMM固有)ユーザータイプ 104 | if (ConstSNSInfo.id == "DMM") 105 | { 106 | viewerInfo.userType = viewer.getField("userType"); 107 | } 108 | 109 | // 2013/05/09 通常メンテナンス対応 110 | // ※ 一般ユーザーはログインできない。 111 | if (MaintenanceInfo.IsDoing == 1 && MaintenanceInfo.IsEmergency == 0) 112 | { 113 | if(viewerInfo.userType == "developer" || viewerInfo.userType == "staff") 114 | { 115 | // developer, staff の場合、 116 | // ログイン処理を続行する。 117 | } 118 | else 119 | { 120 | // 一般ユーザーの場合、 121 | 122 | // 画面下部の情報セクションを表示する。 123 | document.getElementById("sectionWrap").style.display = "block"; 124 | 125 | // メンテナンス画面を表示する。 126 | kcsStartMaintenanceHTML(); 127 | return; 128 | } 129 | } 130 | 131 | // トークン情報を取得する。 132 | kcsGetLoginToken(); 133 | } 134 | }); 135 | } 136 | 137 | // トークン情報取得 138 | function kcsGetLoginToken() 139 | { 140 | // 過剰リロード検知時 141 | //if(document.cookie.indexOf("kcsReloadDetected=") >= 0) 142 | //{ 143 | // return; 144 | //} 145 | 146 | // 2013/07/04 サーバー振り分け対応 147 | var worldParams = {}; 148 | worldParams[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.GET; 149 | worldParams[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.JSON; 150 | 151 | // リクエストの URL に現在時刻(ミリ秒)を追加する。 152 | // (ガジェットのキャッシュを読み込んでしまわないように) 153 | var date = new Date(); 154 | 155 | // ユーザー所属ワールド取得 156 | gadgets.io.makeRequest( 157 | ConstURLInfo.GetUserWorldURL + viewerInfo.id + "/1/" + date.getTime(), function(worldResponse) 158 | { 159 | // レスポンスデータを JSON デコードする。 160 | var json = eval(worldResponse.text); 161 | 162 | // 取得成功した場合 163 | if(json.api_result == ConstParameterInfo.APIResult_OK) 164 | { 165 | // ワールド ID を取得する。 166 | var userWorldId = json.api_data.api_world_id; 167 | 168 | // ログイン不可の場合 169 | if(kcsCanLogin(viewerInfo, userWorldId) == false) 170 | { 171 | // 画面下部の情報セクションを表示する。 172 | document.getElementById("sectionWrap").style.display = "block"; 173 | 174 | // メンテナンス画面を表示する。 175 | kcsStartMaintenanceHTML(); 176 | return; 177 | } 178 | else 179 | { 180 | // 画面下部の情報セクションを表示する。 181 | document.getElementById("sectionWrap").style.display = "block"; 182 | 183 | // 2023-07-04 メンテナンスのお知らせの下部に追加メッセージを表示する。 184 | //var message = ""; 185 | //document.getElementById("messageWrap").style = "text-align: center"; 186 | //document.getElementById("messageWrap").innerHTML = message; 187 | } 188 | 189 | // 新規ユーザーの場合 190 | if(userWorldId == ConstParameterInfo.GetUserWorld_IsNew) 191 | { 192 | // ワールド選択画面へ 193 | 194 | // トークン 195 | flashInfo.dmmLoginId = viewerInfo.id; 196 | 197 | // ワールド選択画面を表示する。 198 | kcsStartWorldSelectHTML(); 199 | return; 200 | } 201 | // 既存ユーザーの場合 202 | else 203 | { 204 | // ワールドサーバーのアドレスを取得する。 205 | var worldServerAddr = ConstServerInfo["World_" + userWorldId]; 206 | 207 | // アイテム購入処理のため、ワールドサーバーのアドレスを 208 | // グローバル変数に保存しておく 209 | userWorldInfo.worldServerAddr = worldServerAddr.substr(0, worldServerAddr.length - 1); 210 | 211 | // OSAPI サーバとの接続維持を開始する。 212 | kcsStartKeepConnection(); 213 | 214 | // ワールドサーバーにログインする。 215 | 216 | // リクエストパラメータを定義する。 217 | var params = {}; 218 | 219 | // リクエストパラメータを設定する。 220 | params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.GET; 221 | params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.JSON; 222 | params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED; 223 | 224 | // 2022/07/13 鍵更新対応 225 | params[dmm.io.RequestParameters.OAUTH_SIGNATURE_PUBLICKEY] = "key_2032"; 226 | 227 | // リクエストの URL に現在時刻(ミリ秒)を追加する。 228 | // (ガジェットのキャッシュを読み込んでしまわないように) 229 | var date = new Date(); 230 | 231 | // リクエストを実行する。 232 | // (レスポンス用のコールバック関数を設定) 233 | gadgets.io.makeRequest( 234 | worldServerAddr + ConstURLInfo.LoginURL + viewerInfo.id + "/1/" + date.getTime(), function(response) 235 | { 236 | // レスポンスデータを JSON デコードする。 237 | var json = eval(response.text); 238 | 239 | // ログインに成功した場合 240 | if(json.api_result == ConstParameterInfo.APIResult_OK) 241 | { 242 | // ゲームを起動する。 243 | 244 | // トークン 245 | flashInfo.apiToken = json.api_token; 246 | // 起動時刻 247 | flashInfo.apiStartTime = json.api_starttime; 248 | 249 | // トークン取得失敗時、アクセスを拒否する。 250 | if(flashInfo.apiToken == null || flashInfo.apiStartTime == null) 251 | { 252 | return; 253 | } 254 | // ゲーム画面を表示する。 255 | kcsStartHTML(worldServerAddr); 256 | return; 257 | } 258 | if(json.api_result == 301) 259 | { 260 | kcsStartDenyHTML(1); 261 | return; 262 | } 263 | if(json.api_result == 302) 264 | { 265 | kcsStartDenyHTML(2); 266 | return; 267 | } 268 | }, params); 269 | } 270 | } else if (json.api_result == 200) { 271 | // 画面下部の情報セクションを表示する。 272 | document.getElementById("sectionWrap").style.display = "block"; 273 | 274 | // メンテナンス画面を表示する。 275 | kcsStartMaintenanceHTML(); 276 | return; 277 | } 278 | // 過剰リロード検知の場合 279 | if(json.api_result == ConstParameterInfo.APIResult_NG_Reload) 280 | { 281 | // 過剰リロード cookie を設定 282 | document.cookie = "kcsReloadDetected=1"; 283 | return; 284 | } 285 | }, worldParams); 286 | 287 | } 288 | 289 | // ログイン可能か判定 290 | function kcsCanLogin(pViewerInfo, userWorldId) 291 | { 292 | // 入場不可の場合 293 | if((userWorldId == ConstParameterInfo.GetUserWorld_IsNew && EntranceInfo.NewUser == 0) 294 | ||(EntranceInfo["World_" + userWorldId + "_User"] == 0)) 295 | { 296 | // 297 | // スタッフのみログイン可能 298 | // 299 | 300 | // 入場可否フラグ 301 | var canEnter = false; 302 | 303 | if(pViewerInfo.userType == "developer" || pViewerInfo.userType == "staff") 304 | { 305 | // developer, staff の場合、 306 | // 入場可とする。 307 | canEnter = true; 308 | } 309 | return canEnter; 310 | } 311 | // 全員入場可の場合 312 | else if((userWorldId == ConstParameterInfo.GetUserWorld_IsNew && EntranceInfo.NewUser == 2) 313 | ||(EntranceInfo["World_" + userWorldId + "_User"] == 2)) 314 | { 315 | return true; 316 | } 317 | else 318 | { 319 | return false; 320 | } 321 | } 322 | // OSAPI サーバとの接続維持を開始 323 | function kcsStartKeepConnection() 324 | { 325 | // OSAPI サーバーとの通信を維持する。 326 | setInterval("kcsKeepConnection()", ConnectionInfo.Interval_Min * 1000 * 60); 327 | } 328 | // OSAPI サーバーとの通信を維持 329 | function kcsKeepConnection() 330 | { 331 | var params = {}; 332 | params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.GET; 333 | params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.TEXT; 334 | var date = new Date(); 335 | gadgets.io.makeRequest( 336 | ConstURLInfo.ConnectionCheckURL + "?" + date.getTime(), function(response) 337 | { 338 | }, params); 339 | } 340 | 341 | // ゲーム画面の表示 342 | function kcsStartHTML(worldServerAddr) 343 | { 344 | // div ブロックへ高さを設定する。 345 | document.getElementById("flashWrap").style.height = "720px"; 346 | 347 | // ガジェットの高さを自動調整する。 348 | gadgets.window.adjustHeight(ConstGadgetInfo.height); 349 | 350 | // URL を組み立てる。 351 | var url = worldServerAddr 352 | + "kcs2/index.php?" 353 | + "api_root=/kcsapi&" 354 | + "voice_root=/kcs/sound&" 355 | + "osapi_root=" + ConstServerInfo.OSAPI + "&" 356 | + "version=" + VersionInfo.scriptVesion + "&" 357 | + "api_token=" + flashInfo.apiToken + "&" 358 | + "api_starttime=" + flashInfo.apiStartTime; 359 | 360 | // iframe 要素を div ブロックに設定する。 361 | var innerHtml = ""; 362 | document.getElementById("flashWrap").innerHTML = innerHtml; 363 | } 364 | 365 | // ワールド選択画面の表示 366 | function kcsStartWorldSelectHTML() 367 | { 368 | // div ブロックへ高さを設定する。 369 | document.getElementById("flashWrap").style.height = "720px"; 370 | 371 | // ガジェットの高さを自動調整する。 372 | gadgets.window.adjustHeight(ConstGadgetInfo.height); 373 | 374 | // URL を組み立てる。 375 | var url = ConstServerInfo.Gadget 376 | + "kcs2/world.html?" 377 | + "osapi_root=" + ConstServerInfo.OSAPI; 378 | 379 | // iframe 要素を div ブロックに設定する。 380 | var innerHtml = ""; 381 | document.getElementById("flashWrap").innerHTML = innerHtml; 382 | } 383 | 384 | // メンテナンス中画面の表示 385 | function kcsStartMaintenanceHTML() 386 | { 387 | // div ブロックへ高さを設定する。 388 | document.getElementById("flashWrap").style.height = "720px"; 389 | 390 | // ガジェットの高さを自動調整する。 391 | gadgets.window.adjustHeight(ConstGadgetInfo.height); 392 | 393 | // URL を組み立てる。 394 | var url = ConstServerInfo.Gadget + "html/maintenance.html"; 395 | 396 | // iframe 要素を div ブロックに設定する。 397 | var innerHtml = ""; 398 | document.getElementById("flashWrap").innerHTML = innerHtml; 399 | } 400 | 401 | // アクセス拒否画面の表示 402 | function kcsStartDenyHTML(denyType) 403 | { 404 | // div ブロックへ高さを設定する。 405 | document.getElementById("flashWrap").style.height = "720px"; 406 | 407 | // ガジェットの高さを自動調整する。 408 | gadgets.window.adjustHeight(ConstGadgetInfo.height); 409 | 410 | // URL を組み立てる。 411 | var url = ""; 412 | if(denyType == 1) 413 | { 414 | url = ConstServerInfo.Gadget + "html/ban.html"; 415 | } 416 | else 417 | { 418 | url = ConstServerInfo.Gadget + "html/deny.html"; 419 | } 420 | 421 | // iframe 要素を div ブロックに設定する。 422 | var innerHtml = ""; 423 | document.getElementById("flashWrap").innerHTML = innerHtml; 424 | } 425 | -------------------------------------------------------------------------------- /gadget_html5/js/kcs_options.js: -------------------------------------------------------------------------------- 1 | // 設定情報を cookie に保存する 2 | function kcsOptions_Save(options) 3 | { 4 | var sKey = "kcs_options"; 5 | var sValue = options; 6 | var vEnd = 2592000; 7 | var sPath = "/"; 8 | var sDomain = "dmm.com"; 9 | var bSecure = false; 10 | docCookies.setItem(sKey, sValue, vEnd, sPath, sDomain, bSecure); 11 | } 12 | // 設定情報を cookie から取得する 13 | function kcsOptions_Load() 14 | { 15 | var options = ""; 16 | var sKey = "kcs_options"; 17 | if (docCookies.hasItem(sKey)) { 18 | options = docCookies.getItem(sKey); 19 | } 20 | return options; 21 | } 22 | -------------------------------------------------------------------------------- /gadget_html5/js/kcs_payment.js: -------------------------------------------------------------------------------- 1 | // 決済リクエスト送信 2 | function kcsPayment_StartPayment(skuId, price, count, description, name, imageUrl) 3 | { 4 | // DMM OSAPI サーバーとの通信が確立されていることをチェックする。 5 | var params = {}; 6 | params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.GET; 7 | params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.TEXT; 8 | var date = new Date(); 9 | gadgets.io.makeRequest( 10 | ConstURLInfo.ConnectionCheckURL + "?" + date.getTime(), function(response) 11 | { 12 | // レスポンスコードが 400 以上の場合 13 | if(response.rc >= 400) 14 | { 15 | // 通信できていないと判断し、 16 | // アイテムを購入を中止する。 17 | return; 18 | } 19 | 20 | // 購入アイテムを作成 21 | 22 | // 購入アイテムパラメータを設定する。 23 | var billingItemParams = {}; 24 | billingItemParams[opensocial.BillingItem.Field.SKU_ID] = skuId; 25 | billingItemParams[opensocial.BillingItem.Field.PRICE] = price; 26 | billingItemParams[opensocial.BillingItem.Field.COUNT] = count; 27 | billingItemParams[opensocial.BillingItem.Field.DESCRIPTION] = description; 28 | if (ConstSNSInfo.id == "DMM") 29 | { 30 | billingItemParams[dmm.BillingItem.Field.NAME] = name; 31 | billingItemParams[dmm.BillingItem.Field.IMAGE_URL] = imageUrl; 32 | } 33 | 34 | // 購入アイテムを作成する。 35 | var billingItem = 36 | opensocial.newBillingItem(billingItemParams); 37 | 38 | // 決済リクエストを作成 39 | 40 | // 決済リクエストパラメータを設定する。 41 | var paymentParams = {}; 42 | paymentParams[opensocial.Payment.Field.ITEMS] = [billingItem]; 43 | paymentParams[opensocial.Payment.Field.PAYMENT_TYPE] = opensocial.Payment.PaymentType.PAYMENT; 44 | 45 | // 決済リクエストを作成する。 46 | var payment = opensocial.newPayment(paymentParams); 47 | 48 | // 決済リクエストを送信する。 49 | // (決済レスポンス用のコールバック関数を設定) 50 | opensocial.requestPayment(payment, paymentCallBack); 51 | 52 | }, params); 53 | } 54 | 55 | // 決済レスポンス受信 56 | function paymentCallBack(paymentResponse) 57 | { 58 | // ---------------------------------------------------------------- 59 | // アイテムを購入したか、キャンセルしたかの判定 60 | // ---------------------------------------------------------------- 61 | var userCancelled = false; 62 | 63 | // エラーが発生した場合 64 | if(paymentResponse.hadError()) 65 | { 66 | // エラー時はキャンセル扱いとする。 67 | // (エラーは SNS 側でユーザに通知されている) 68 | userCancelled = true; 69 | } 70 | if (userCancelled == false) 71 | { 72 | // レスポンスコードを取得する。 73 | var responseCode = paymentResponse.getData().getField("responseCode"); 74 | 75 | // レスポンスコードが "ok" 以外の場合 76 | if(responseCode != "ok") 77 | { 78 | // キャンセル扱いとする。 79 | userCancelled = true; 80 | } 81 | } 82 | 83 | // ---------------------------------------------------------------- 84 | // ゲーム側へ通知 85 | // ---------------------------------------------------------------- 86 | 87 | // インラインフレームへ購入結果を通知する。 88 | var paymentResult; 89 | if(!userCancelled) 90 | { 91 | paymentResult = ConstParameterInfo.PaymentResult_Paid; 92 | } 93 | else 94 | { 95 | paymentResult = ConstParameterInfo.PaymentResult_Cancel; 96 | } 97 | PaymentResult_SendMessage(paymentResult); 98 | 99 | } 100 | -------------------------------------------------------------------------------- /gadget_html5/script/cookie.js: -------------------------------------------------------------------------------- 1 | /*\ 2 | |*| 3 | |*| :: cookies.js :: 4 | |*| 5 | |*| A complete cookies reader/writer framework with full unicode support. 6 | |*| 7 | |*| https://developer.mozilla.org/en-US/docs/DOM/document.cookie 8 | |*| 9 | |*| Syntaxes: 10 | |*| 11 | |*| * docCookies.setItem(name, value[, end[, path[, domain[, secure]]]]) 12 | |*| * docCookies.getItem(name) 13 | |*| * docCookies.removeItem(name[, path]) 14 | |*| * docCookies.hasItem(name) 15 | |*| * docCookies.keys() 16 | |*| 17 | \*/ 18 | 19 | var docCookies = { 20 | getItem: function (sKey) { 21 | if (!sKey || !this.hasItem(sKey)) { return null; } 22 | return unescape(document.cookie.replace(new RegExp("(?:^|.*;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*"), "$1")); 23 | }, 24 | setItem: function (sKey, sValue, vEnd, sPath, sDomain, bSecure) { 25 | if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) { return; } 26 | var sExpires = ""; 27 | if (vEnd) { 28 | switch (vEnd.constructor) { 29 | case Number: 30 | sExpires = vEnd === Infinity ? "; expires=Tue, 19 Jan 2038 03:14:07 GMT" : "; max-age=" + vEnd; 31 | break; 32 | case String: 33 | sExpires = "; expires=" + vEnd; 34 | break; 35 | case Date: 36 | sExpires = "; expires=" + vEnd.toGMTString(); 37 | break; 38 | } 39 | } 40 | document.cookie = escape(sKey) + "=" + escape(sValue) + sExpires + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "") + (bSecure ? "; secure" : ""); 41 | }, 42 | removeItem: function (sKey, sPath) { 43 | if (!sKey || !this.hasItem(sKey)) { return; } 44 | document.cookie = escape(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT" + (sPath ? "; path=" + sPath : ""); 45 | }, 46 | hasItem: function (sKey) { 47 | return (new RegExp("(?:^|;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie); 48 | }, 49 | keys: /* optional method: you can safely remove it! */ function () { 50 | var aKeys = document.cookie.replace(/((?:^|\s*;)[^\=]+)(?=;|$)|^\s*|\s*(?:\=[^;]*)?(?:\1|$)/g, "").split(/\s*(?:\=[^;]*)?;\s*/); 51 | for (var nIdx = 0; nIdx < aKeys.length; nIdx++) { aKeys[nIdx] = unescape(aKeys[nIdx]); } 52 | return aKeys; 53 | } 54 | }; -------------------------------------------------------------------------------- /gadget_html5/script/jquery.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery v1.9.0 | (c) 2005, 2012 jQuery Foundation, Inc. | jquery.org/license */(function(e,t){"use strict";function n(e){var t=e.length,n=st.type(e);return st.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}function r(e){var t=Tt[e]={};return st.each(e.match(lt)||[],function(e,n){t[n]=!0}),t}function i(e,n,r,i){if(st.acceptData(e)){var o,a,s=st.expando,u="string"==typeof n,l=e.nodeType,c=l?st.cache:e,f=l?e[s]:e[s]&&s;if(f&&c[f]&&(i||c[f].data)||!u||r!==t)return f||(l?e[s]=f=K.pop()||st.guid++:f=s),c[f]||(c[f]={},l||(c[f].toJSON=st.noop)),("object"==typeof n||"function"==typeof n)&&(i?c[f]=st.extend(c[f],n):c[f].data=st.extend(c[f].data,n)),o=c[f],i||(o.data||(o.data={}),o=o.data),r!==t&&(o[st.camelCase(n)]=r),u?(a=o[n],null==a&&(a=o[st.camelCase(n)])):a=o,a}}function o(e,t,n){if(st.acceptData(e)){var r,i,o,a=e.nodeType,u=a?st.cache:e,l=a?e[st.expando]:st.expando;if(u[l]){if(t&&(r=n?u[l]:u[l].data)){st.isArray(t)?t=t.concat(st.map(t,st.camelCase)):t in r?t=[t]:(t=st.camelCase(t),t=t in r?[t]:t.split(" "));for(i=0,o=t.length;o>i;i++)delete r[t[i]];if(!(n?s:st.isEmptyObject)(r))return}(n||(delete u[l].data,s(u[l])))&&(a?st.cleanData([e],!0):st.support.deleteExpando||u!=u.window?delete u[l]:u[l]=null)}}}function a(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(Nt,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:wt.test(r)?st.parseJSON(r):r}catch(o){}st.data(e,n,r)}else r=t}return r}function s(e){var t;for(t in e)if(("data"!==t||!st.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}function u(){return!0}function l(){return!1}function c(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}function f(e,t,n){if(t=t||0,st.isFunction(t))return st.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return st.grep(e,function(e){return e===t===n});if("string"==typeof t){var r=st.grep(e,function(e){return 1===e.nodeType});if(Wt.test(t))return st.filter(t,r,!n);t=st.filter(t,r)}return st.grep(e,function(e){return st.inArray(e,t)>=0===n})}function p(e){var t=zt.split("|"),n=e.createDocumentFragment();if(n.createElement)for(;t.length;)n.createElement(t.pop());return n}function d(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function h(e){var t=e.getAttributeNode("type");return e.type=(t&&t.specified)+"/"+e.type,e}function g(e){var t=nn.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function m(e,t){for(var n,r=0;null!=(n=e[r]);r++)st._data(n,"globalEval",!t||st._data(t[r],"globalEval"))}function y(e,t){if(1===t.nodeType&&st.hasData(e)){var n,r,i,o=st._data(e),a=st._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)st.event.add(t,n,s[n][r])}a.data&&(a.data=st.extend({},a.data))}}function v(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!st.support.noCloneEvent&&t[st.expando]){r=st._data(t);for(i in r.events)st.removeEvent(t,i,r.handle);t.removeAttribute(st.expando)}"script"===n&&t.text!==e.text?(h(t).text=e.text,g(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),st.support.html5Clone&&e.innerHTML&&!st.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Zt.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}function b(e,n){var r,i,o=0,a=e.getElementsByTagName!==t?e.getElementsByTagName(n||"*"):e.querySelectorAll!==t?e.querySelectorAll(n||"*"):t;if(!a)for(a=[],r=e.childNodes||e;null!=(i=r[o]);o++)!n||st.nodeName(i,n)?a.push(i):st.merge(a,b(i,n));return n===t||n&&st.nodeName(e,n)?st.merge([e],a):a}function x(e){Zt.test(e.type)&&(e.defaultChecked=e.checked)}function T(e,t){if(t in e)return t;for(var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=Nn.length;i--;)if(t=Nn[i]+n,t in e)return t;return r}function w(e,t){return e=t||e,"none"===st.css(e,"display")||!st.contains(e.ownerDocument,e)}function N(e,t){for(var n,r=[],i=0,o=e.length;o>i;i++)n=e[i],n.style&&(r[i]=st._data(n,"olddisplay"),t?(r[i]||"none"!==n.style.display||(n.style.display=""),""===n.style.display&&w(n)&&(r[i]=st._data(n,"olddisplay",S(n.nodeName)))):r[i]||w(n)||st._data(n,"olddisplay",st.css(n,"display")));for(i=0;o>i;i++)n=e[i],n.style&&(t&&"none"!==n.style.display&&""!==n.style.display||(n.style.display=t?r[i]||"":"none"));return e}function C(e,t,n){var r=mn.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function k(e,t,n,r,i){for(var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;4>o;o+=2)"margin"===n&&(a+=st.css(e,n+wn[o],!0,i)),r?("content"===n&&(a-=st.css(e,"padding"+wn[o],!0,i)),"margin"!==n&&(a-=st.css(e,"border"+wn[o]+"Width",!0,i))):(a+=st.css(e,"padding"+wn[o],!0,i),"padding"!==n&&(a+=st.css(e,"border"+wn[o]+"Width",!0,i)));return a}function E(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=ln(e),a=st.support.boxSizing&&"border-box"===st.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=un(e,t,o),(0>i||null==i)&&(i=e.style[t]),yn.test(i))return i;r=a&&(st.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+k(e,t,n||(a?"border":"content"),r,o)+"px"}function S(e){var t=V,n=bn[e];return n||(n=A(e,t),"none"!==n&&n||(cn=(cn||st("