玩家数据解析真麻烦

This commit is contained in:
枫谷剑仙 2021-09-05 06:41:42 +08:00
parent 88912585c7
commit 67fa292467
8 changed files with 320 additions and 123 deletions

View File

@ -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 上传数据";
}

View File

@ -66,6 +66,7 @@ var formation = new Formation(teamsCount,5);
<button class="btn-qrcode"></button>
<button class="btn-capture" onclick="capture();"></button>
<a class="down-capture display-none" target="_blank"></a>
<button class="btn-player-data"></button>
<a class="help-link" target="_blank" href="https://github.com/Mapaler/PADDashFormation/blob/master/help.md"></a>
</div>
<div>

View File

@ -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 = [

View File

@ -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):

316
script.js
View File

@ -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");

View File

@ -46,6 +46,7 @@ var formation = new Formation(teamsCount,6);
<button class="btn-qrcode"></button>
<button class="btn-capture" onclick="capture();"></button>
<a class="down-capture display-none" target="_blank"></a>
<button class="btn-player-data"></button>
<a class="help-link" target="_blank" href="https://github.com/Mapaler/PADDashFormation/blob/master/help.md"></a>
</div>
<div>
@ -1093,8 +1094,17 @@ var formation = new Formation(teamsCount,6);
</div>
<div class="dialog-control"><button class="dialog-clear brown-button"></button><button class="dialog-confirm brown-button"></button></div>
</div>
<script type="text/javascript">
document.querySelector('input[name="ptype"][value="1"]').checked=true;
</script>
<div id="player-data-frame" class="mask">
<div class="player-box-title"><!--玩家数据子--></div>
<div class="control-button-box">
<button class="mask-close brown-button"></button>
<button class="upload-data brown-button"></button>
<input type="file" class="file-select display-none" />
</div>
<div class="mask-content">
<ul class="player-datas-list"></ul>
</div>
</div>
</body>
</html>

View File

@ -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
{

View File

@ -60,6 +60,7 @@ var formation = new Formation(teamsCount,6);
<button class="btn-qrcode"></button>
<button class="btn-capture" onclick="capture();"></button>
<a class="down-capture display-none" target="_blank"></a>
<button class="btn-player-data"></button>
<a class="help-link" target="_blank" href="https://github.com/Mapaler/PADDashFormation/blob/master/help.md"></a>
</div>
<div>