diff --git a/languages/zh.css b/languages/zh.css index acbc440d..a0890ae9 100644 --- a/languages/zh.css +++ b/languages/zh.css @@ -246,6 +246,9 @@ label[for="merge-skill"]::after{ .control-box .btn-capture::before{ content: "📷截图"; } +.control-box .btn-player-data::before{ + content: "📦我的箱子"; +} .control-box .btn-swap-AB-team::before{ content: "🔄交换AB队"; @@ -565,4 +568,13 @@ label[for="qr-data-type-pdchu"]::before { .dialog-dungeon-enchance .stats-list::before { content: "強化倍率:"; +} + +#player-data-frame .player-box-title::before +{ + content: "\f2bd\A 玩家数据"; +} +#player-data-frame .upload-data::before +{ + content: "\f574 上传数据"; } \ No newline at end of file diff --git a/multi.html b/multi.html index 8158af98..acf4e852 100644 --- a/multi.html +++ b/multi.html @@ -66,6 +66,7 @@ var formation = new Formation(teamsCount,5); +
diff --git a/script-json_data.js b/script-json_data.js index fec15953..4e925e4c 100644 --- a/script-json_data.js +++ b/script-json_data.js @@ -399,24 +399,24 @@ const official_awoken_sorting = [ //pdc的徽章对应数字 const pdcBadgeMap = [ {pdf:0,pdc:10}, //无限cost - {pdf:1,pdc:12}, //小手指 - {pdf:2,pdc:9}, //全体攻击 - {pdf:3,pdc:5}, //小回复 - {pdf:4,pdc:1}, //小血量 - {pdf:5,pdc:3}, //小攻击 - {pdf:6,pdc:8}, //SB - {pdf:7,pdc:18}, //队长防封 - {pdf:8,pdc:19}, //SX - {pdf:9,pdc:7}, //无天降 - {pdf:10,pdc:6}, //大回复 - {pdf:11,pdc:2}, //大血量 - {pdf:12,pdc:4}, //大攻击 - {pdf:13,pdc:13}, //大手指 - {pdf:14,pdc:11}, //加经验 - {pdf:15,pdc:15}, //墨镜 - {pdf:16,pdc:17}, //防废 - {pdf:17,pdc:16}, //防毒 - {pdf:18,pdc:14}, //月卡 + {pdf:2,pdc:12}, //小手指 + {pdf:3,pdc:9}, //全体攻击 + {pdf:4,pdc:5}, //小回复 + {pdf:5,pdc:1}, //小血量 + {pdf:6,pdc:3}, //小攻击 + {pdf:7,pdc:8}, //SB + {pdf:8,pdc:18}, //队长防封 + {pdf:9,pdc:19}, //SX + {pdf:10,pdc:7}, //无天降 + {pdf:17,pdc:6}, //大回复 + {pdf:18,pdc:2}, //大血量 + {pdf:19,pdc:4}, //大攻击 + {pdf:21,pdc:13}, //大手指 + {pdf:10,pdc:11}, //加经验 + {pdf:12,pdc:15}, //墨镜 + {pdf:13,pdc:17}, //防废 + {pdf:14,pdc:16}, //防毒 + {pdf:1,pdc:14}, //月卡 ]; //pdc的潜觉对应数字 const pdcLatentMap = [ diff --git a/script-universal_function.js b/script-universal_function.js index 620df13e..c5f7aba4 100644 --- a/script-universal_function.js +++ b/script-universal_function.js @@ -248,6 +248,31 @@ function loadImage(url) { }); } +//代码来自 https://segmentfault.com/a/1190000004451095 +function fileReader (file, options = {}) { + return new Promise(function (resolve, reject) { + const reader = new FileReader(); + + reader.onload = function () { + resolve(reader); + }; + reader.onerror = reject; + + if (options.accept && !new RegExp(options.accept).test(file.type)) { + reject({ + code: 1, + msg: 'wrong file type' + }); + } + + if (!file.type || /^text\//i.test(file.type) || options.readType == "text") { + reader.readAsText(file); + } else { + reader.readAsDataURL(file); + } + }); +} + function latentUseHole(latentId) { switch (true) { case (latentId === 12): diff --git a/script.js b/script.js index 216c0e96..e5748171 100644 --- a/script.js +++ b/script.js @@ -92,32 +92,21 @@ DBOpenRequest.onupgradeneeded = function(event) { }; }; -/*class Member2 +class Member2 { - constructor(oldMenber = null,isAssist = false) + constructor(oldMenber, isAssist) { - if (oldMenber) - { //Copy一个 - this.id = oldMenber.id; - this.level = oldMenber.level; - this.plus = [...oldMenber.plus]; - this.awoken = oldMenber.awoken; - this.sAwoken = oldMenber.sAwoken; - this.latent = [...oldMenber.latent]; - this.skilllevel = oldMenber.sAwoken; - this.assist = oldMenber.assist; - }else - { //全新的 - this.id = 0; - this.level = 1; - this.plus = [0,0,0]; - this.awoken = 0; - this.sAwoken = null; - this.latent = []; - this.skilllevel = null; - this.assist = null; - } - this.isAssist = isAssist; + //this.index = oldMenber?.index ?? 0; + this.id = oldMenber?.id ?? 0; + //this.exp = oldMenber?.exp ?? 0; + this.level = oldMenber?.level ?? 1; + this.plus = oldMenber?.plus ?? {hp:0,atk:0,rcv:0}; + this.awoken = oldMenber.awoken ?? 0; + this.superAwoken = oldMenber.superAwoken ?? null; + this.latent = oldMenber?.latent.concat() ?? []; + this.skillLevel = oldMenber.skillLevel ?? 0; + this.assist = oldMenber.assist ?? null; + this.isAssist = Boolean(isAssist !== undefined ? isAssist : oldMenber?.isAssist); } calculateAbility(solo,teamCount){ const card = Cards[this.id]; @@ -133,7 +122,7 @@ DBOpenRequest.onupgradeneeded = function(event) { toJSON(){ } -}*/ +} //队员基本的留空 var Member = function() { @@ -712,73 +701,6 @@ function turnPage(toPage, e = null) { location.href = newURL; } } -window.onload = function(event) { - - qrcodeReader = new ZXing.BrowserQRCodeReader(); //二维码读取 - qrcodeWriter = new ZXing.BrowserQRCodeSvgWriter(); //二维码生成 - - controlBox = document.body.querySelector(".control-box"); - statusLine = controlBox.querySelector(".status"); //显示当前状态的 - formationBox = document.body.querySelector(".formation-box"); - editBox = document.body.querySelector(".edit-box"); - - if (isGuideMod) { - console.info('现在是 怪物图鉴 模式'); - document.body.classList.add('guide-mod'); - } - - //const helpLink = controlBox.querySelector(".help-link"); - //if (location.hostname.includes("gitee")) { helpLink.hostname = "gitee.com"; } - - //▼添加语言列表开始 - const langSelectDom = controlBox.querySelector(".languages"); - languageList.forEach(lang => - langSelectDom.options.add(new Option(lang.name, lang.i18n)) - ); - - const langOptionArray = Array.from(langSelectDom.options); - langOptionArray.find(langOpt => langOpt.value == currentLanguage.i18n).selected = true; - - //▲添加语言列表结束 - //▼添加数据来源列表开始 - const dataSelectDom = controlBox.querySelector(".datasource"); - dataSourceList.forEach(ds => - dataSelectDom.options.add(new Option(ds.source, ds.code)) - ); - - const dataSourceOptionArray = Array.from(dataSelectDom.options); - dataSourceOptionArray.find(dataOpt => dataOpt.value == currentDataSource.code).selected = true; - //添加数据class - document.body.classList.add("ds-" + currentDataSource.code); - //▲添加数据来源列表结束 - - //设定初始的显示设置 - toggleDomClassName(controlBox.querySelector("#show-mon-id"), 'not-show-mon-id', false); - - //记录显示CD开关的状态 - const showMonSkillCd_id = "show-mon-skill-cd"; - const btnShowMonSkillCd = controlBox.querySelector(`#btn-${showMonSkillCd_id}`); - btnShowMonSkillCd.checked = Boolean(Number(localStorage.getItem(cfgPrefix + showMonSkillCd_id))); - btnShowMonSkillCd.onclick = function(e){ - toggleDomClassName(this, showMonSkillCd_id); - if (e) localStorage.setItem(cfgPrefix + showMonSkillCd_id, Number(this.checked)); - }; - btnShowMonSkillCd.onclick(false); - - //记录显示觉醒开关的状态 - const showMonAwoken_id = "show-mon-awoken"; - const btnShowMonAwoken = controlBox.querySelector(`#btn-${showMonAwoken_id}`); - btnShowMonAwoken.checked = Boolean(Number(localStorage.getItem(cfgPrefix + showMonAwoken_id))); - btnShowMonAwoken.onclick = function(e){ - toggleDomClassName(this, showMonAwoken_id); - if (e) localStorage.setItem(cfgPrefix + showMonAwoken_id, Number(this.checked)); - }; - btnShowMonAwoken.onclick(false); - - toggleDomClassName(controlBox.querySelector("#btn-show-awoken-count"), 'not-show-awoken-count', false); - - initialize(); //界面初始化 -}; function loadData(force = false) { @@ -1104,7 +1026,6 @@ function creatNewUrl(arg) { } } } - //解析从QR图里获取的字符串 function inputFromQrString(string) { @@ -1314,8 +1235,74 @@ function capture() { //document.body.appendChild(canvas); }); } + +window.onload = initialize; //界面初始化 + //初始化 -function initialize() { +function initialize(event) { + + qrcodeReader = new ZXing.BrowserQRCodeReader(); //二维码读取 + qrcodeWriter = new ZXing.BrowserQRCodeSvgWriter(); //二维码生成 + + controlBox = document.body.querySelector(".control-box"); + statusLine = controlBox.querySelector(".status"); //显示当前状态的 + formationBox = document.body.querySelector(".formation-box"); + editBox = document.body.querySelector(".edit-box"); + + if (isGuideMod) { + console.info('现在是 怪物图鉴 模式'); + document.body.classList.add('guide-mod'); + } + + //const helpLink = controlBox.querySelector(".help-link"); + //if (location.hostname.includes("gitee")) { helpLink.hostname = "gitee.com"; } + + //▼添加语言列表开始 + const langSelectDom = controlBox.querySelector(".languages"); + languageList.forEach(lang => + langSelectDom.options.add(new Option(lang.name, lang.i18n)) + ); + + const langOptionArray = Array.from(langSelectDom.options); + langOptionArray.find(langOpt => langOpt.value == currentLanguage.i18n).selected = true; + + //▲添加语言列表结束 + //▼添加数据来源列表开始 + const dataSelectDom = controlBox.querySelector(".datasource"); + dataSourceList.forEach(ds => + dataSelectDom.options.add(new Option(ds.source, ds.code)) + ); + + const dataSourceOptionArray = Array.from(dataSelectDom.options); + dataSourceOptionArray.find(dataOpt => dataOpt.value == currentDataSource.code).selected = true; + //添加数据class + document.body.classList.add("ds-" + currentDataSource.code); + //▲添加数据来源列表结束 + + //设定初始的显示设置 + toggleDomClassName(controlBox.querySelector("#show-mon-id"), 'not-show-mon-id', false); + + //记录显示CD开关的状态 + const showMonSkillCd_id = "show-mon-skill-cd"; + const btnShowMonSkillCd = controlBox.querySelector(`#btn-${showMonSkillCd_id}`); + btnShowMonSkillCd.checked = Boolean(Number(localStorage.getItem(cfgPrefix + showMonSkillCd_id))); + btnShowMonSkillCd.onclick = function(e){ + toggleDomClassName(this, showMonSkillCd_id); + if (e) localStorage.setItem(cfgPrefix + showMonSkillCd_id, Number(this.checked)); + }; + btnShowMonSkillCd.onclick(false); + + //记录显示觉醒开关的状态 + const showMonAwoken_id = "show-mon-awoken"; + const btnShowMonAwoken = controlBox.querySelector(`#btn-${showMonAwoken_id}`); + btnShowMonAwoken.checked = Boolean(Number(localStorage.getItem(cfgPrefix + showMonAwoken_id))); + btnShowMonAwoken.onclick = function(e){ + toggleDomClassName(this, showMonAwoken_id); + if (e) localStorage.setItem(cfgPrefix + showMonAwoken_id, Number(this.checked)); + }; + btnShowMonAwoken.onclick(false); + + toggleDomClassName(controlBox.querySelector("#btn-show-awoken-count"), 'not-show-awoken-count', false); //触屏使用的切换显示的线条 interchangeSVG = document.body.querySelector("#interchange-line"); @@ -1617,6 +1604,147 @@ function initialize() { }); } + const playerDataFrame = document.body.querySelector("#player-data-frame"); + const btnPlayerData = controlBox.querySelector(`.btn-player-data`); + btnPlayerData.onclick = function(){ + playerDataFrame.show(); + }; + playerDataFrame.uploadData = playerDataFrame.querySelector(".upload-data"); + playerDataFrame.filePicker = playerDataFrame.querySelector(".file-select"); + playerDataFrame.uploadData.onclick = function(){ playerDataFrame.filePicker.click(); }; + playerDataFrame.filePicker.onchange = function(){ uploadPlayerData(this.files); }; + + async function uploadPlayerData(myFiles) { + if (myFiles.length < 1) return; + + for (const myFile of myFiles) + { + try { + const reader = await fileReader(myFile, {readType: "text"}); + const data = JSON.parse(reader.result); + const playerData = new PlayerData(data); + console.log(playerData,data); + } catch (error) { + console.error(error); + } + + } + } + class PlayerData + { + constructor(data) + { + Object.assign(this, data); + this.card_parsed = data.card.map(ocard=>new PlayerDataCard(ocard)); + for (const mon of this.card_parsed) + { + mon.assist = mon.assistIndex === 0 ? null : this.card_parsed.find(m=>m.index === mon.assistIndex); + } + this.teams = data.decksb.decks.concat(data.decksbs.decks || []) + .map(deck=>new PlayerDataDeck(deck)); + for (const team of this.teams) + { + team.members = team.membersId.map(id=>id===0 ? null : this.card_parsed.find(m=>m.index === id)); + } + } + } + class PlayerDataDeck { + constructor(data) { + const e = data.entries(); + this.membersId = [ + e.next().value[1], + e.next().value[1], + e.next().value[1], + e.next().value[1], + e.next().value[1], + ]; + this.badge = e.next().value[1]; + this.membersId.push(e.next().value[1]); + e.next(); //未知 + e.next(); //未知 + if (!e.next().done) + { + console.warn("出现未知的用户队伍数据"); + } + } + } + class PlayerDataCard { + constructor(data) { + const e = data.entries(); + this.index = e.next().value[1]; + this.exp = e.next().value[1]; + this.level = e.next().value[1]; + e.next(); //未知 + e.next(); //未知 + this.id = e.next().value[1]; + this.plus = { + hp : e.next().value[1], + atk: e.next().value[1], + rcv: e.next().value[1] + }; + this.awoken = e.next().value[1]; + + let parsedLatent = this.parseLatent(e.next().value[1]); + this.latentMaxCount = parsedLatent.latentCount; + this.latent = this.deleteRepeatLatent(parsedLatent.latent.reverse()); + + this.assistIndex = e.next().value[1]; + e.next(); //未知 + this.superAwoken = e.next().value[1]; + e.next(); //未知 + if (!e.next().done) + { + console.warn("出现未知的用户箱子卡片数据"); + } + //console.log(b); + } + parseLatent(number) + { + let latentNumber = BigInt(number); + let obj = { + latent: [], + latentCount: 6, + }; + //console.log("原始数字",latentNumber.toString(2)); + let latentVersion = latentNumber & 7n; //记录版本,111是用几位来做记录 + latentNumber >>= 3n; + //console.log("读取潜觉记录位数",latentNumber.toString(2)); + let changeLatentCount = Boolean(latentNumber & 1n); //1时就是增加格子数 + latentNumber >>= 1n; + //console.log("读取潜觉格子数是否改变",latentNumber.toString(2)); + if (changeLatentCount) + { + obj.latentCount = Number(latentNumber & 15n); + latentNumber >>= 4n; + //console.log("读取潜觉格子数",latentNumber.toString(2)); + } + const getbnum = latentVersion > 6 ? 127n : 31n; + const rightbnum = latentVersion > 6 ? 7n : 5n; + while (latentNumber>0) + { + obj.latent.push(Number(latentNumber & getbnum)); + latentNumber >>= rightbnum; + //console.log("读取一个潜觉",latentNumber.toString(2)); + } + return obj; + } + deleteRepeatLatent(olatents) + { + let latents = olatents.concat(); + for (let ai = 0; ai < latents.length; ai++) + { + let useHole = latentUseHole(latents[ai]); + if (useHole > 1) + { + latents.splice(ai+1, useHole-1); + } + } + return latents; + } + } + + playerDataFrame.initialize = function(){ + }; //标题和介绍文本框 const titleBox = formationBox.querySelector(".title-box"); diff --git a/solo.html b/solo.html index 095fde74..50827702 100644 --- a/solo.html +++ b/solo.html @@ -46,6 +46,7 @@ var formation = new Formation(teamsCount,6); +
@@ -1093,8 +1094,17 @@ var formation = new Formation(teamsCount,6);
- + +
+
+
+ + + +
+
+ +
+
diff --git a/style.css b/style.css index 40c62660..22d5b26d 100644 --- a/style.css +++ b/style.css @@ -61,6 +61,7 @@ body{ --team-2-color : blue; --team-3-color : green; --font-family : "Microsoft Yahei","Microsoft JhengHei","Source Han Sans",Arial, Helvetica, sans-serif, "Malgun Gothic", "맑은 고딕", "Gulim", AppleGothic; + --icon-font-family : 'Font Awesome 5 Free', "Microsoft Yahei","Microsoft JhengHei","Source Han Sans",Arial, Helvetica, sans-serif, "Malgun Gothic", "맑은 고딕", "Gulim", AppleGothic; --game-font-family : 'FOT-KurokaneStd-EB',"Microsoft Yahei","Microsoft JhengHei","Source Han Sans",Arial, Helvetica, sans-serif, "Malgun Gothic", "맑은 고딕", "Gulim", AppleGothic; --border-width: 2px; @@ -261,7 +262,7 @@ ul{ { display: inline-block; box-sizing: border-box; - width: 100px; + min-width: 100px; padding: 5px; background-color: #956A42; background-image: url(images/slate.svg); @@ -2573,6 +2574,10 @@ icon.inflicts::after .control-box{ margin-bottom: 10px; } +.control-box>div +{ + margin-bottom: 2px; +} .control-box .languages-label::before{ content: "🌐Lanuage:"; } @@ -2944,14 +2949,12 @@ table .orb-icon -webkit-text-stroke: 3px black; } -.control-box .btn-set-dungeon-enchance::before{ - font-family: 'Font Awesome 5 Free'; - font-weight: normal; -} -.control-box .btn-qrcode::before{ - font-family: 'Font Awesome 5 Free'; - font-weight: normal; +.control-box, +.control-box button +{ + font-family: var(--icon-font-family); } + #qr-code-frame { color: white; @@ -3018,6 +3021,23 @@ table .orb-icon font-size: 20px; padding: 5px; } + +#player-data-frame .player-box-title +{ + color: white; + text-align: center; + font-size: 2em; + font-family: var(--icon-font-family); +} +#player-data-frame .brown-button::before +{ + font-family: var(--icon-font-family); +} +#player-data-frame .upload-data +{ + float: right; + margin-right: 5px; +} /*.base .evo-type::before, .base .evo-type::after { diff --git a/triple.html b/triple.html index ad94cd49..89474fee 100644 --- a/triple.html +++ b/triple.html @@ -60,6 +60,7 @@ var formation = new Formation(teamsCount,6); +