支持sanbon的上传

This commit is contained in:
枫谷剑仙 2024-03-10 04:22:06 +08:00
parent 28f51880a0
commit 160e7cfab9
11 changed files with 222 additions and 68 deletions

View File

@ -648,7 +648,19 @@ label[for="paddb-team-id"]::before
}
body:not(.external-link-support) #external-support::after
{
content: "Install helper scripts to use PADDB-related features";
content: "Install helper scripts to use PADDB/SANBON-related features";
}
#qr-code-frame .sanbon-team-edit::before
{
content: "Upload Team Data to sanbon.me";
}
label[for="sanbon-team-id"]::before
{
content: "sanbon.me Team Link:";
}
#sanbon-save-or-upload-team::before {
content: "Upload new Team";
}
label[for="qr-data-type-pdf"]::before

View File

@ -606,7 +606,19 @@ label[for="paddb-team-id"]::before
}
body:not(.external-link-support) #external-support::after
{
content: "PADDB 関連機能を使用するセカンダリ スクリプトをインストール";
content: "PADDB/SANBON 関連機能を使用するセカンダリ スクリプトをインストール";
}
#qr-code-frame .sanbon-team-edit::before
{
content: "チーム データを sanbon.me にアップロード:";
}
label[for="sanbon-team-id"]::before
{
content: "sanbon.me チームリンク:";
}
#sanbon-save-or-upload-team::before {
content: "新しいチームをアップロード";
}
label[for="qr-data-type-pdf"]::before

View File

@ -586,7 +586,19 @@ label[for="paddb-team-id"]::before
}
body:not(.external-link-support) #external-support::after
{
content: "PADDB 관련 기능을 사용하도록 보조 스크립트를 설치";
content: "PADDB/SANBON 관련 기능을 사용하도록 보조 스크립트를 설치";
}
#qr-code-frame .sanbon-team-edit::before
{
content: "팀 데이터를 sanbon.me에 업로드하려면 다음을 수행.";
}
label[for="sanbon-team-id"]::before
{
content: "sanbon.me 팀 링크:";
}
#sanbon-save-or-upload-team::before {
content: "새 팀을 업로드";
}
label[for="qr-data-type-pdf"]::before

View File

@ -537,9 +537,9 @@ label[for="real-time-change-card"]::after
{
content: "生成二维码:";
}
.sanbon-me-transfer::before
.sanbon-transfer::before
{
content: "Sanbon.me";
content: "Sanbon.me(有缺陷的测试功能)";
}
.read-qr-box .result-code::before {
@ -599,9 +599,22 @@ label[for="paddb-team-id"]::before
#paddb-team-id:placeholder-shown+#paddb-save-or-upload-team::before {
content: "上传新队伍";
}
body:not(.external-link-support) #external-support::after
{
content: "安装辅助脚本以使用 PADDB 相关功能";
content: "安装辅助脚本以使用 PADDB/SANBON 相关功能";
}
#qr-code-frame .sanbon-team-edit::before
{
content: "将队伍数据上传至 sanbon.me";
}
label[for="sanbon-team-id"]::before
{
content: "sanbon.me 队伍链接:";
}
#sanbon-save-or-upload-team::before {
content: "上传新队伍";
}
label[for="qr-data-type-pdf"]::before

View File

@ -598,7 +598,19 @@ label[for="paddb-team-id"]::before
}
body:not(.external-link-support) #external-support::after
{
content: "安裝輔助腳本以使用 PADDB 相關功能";
content: "安裝輔助腳本以使用 PADDB/SANBON 相關功能";
}
#qr-code-frame .sanbon-team-edit::before
{
content: "將隊伍數據上傳至 sanbon.me";
}
label[for="sanbon-team-id"]::before
{
content: "sanbon.me 隊伍鏈接:";
}
#sanbon-save-or-upload-team::before {
content: "上傳新隊伍";
}
label[for="qr-data-type-pdf"]::before

View File

@ -1479,7 +1479,17 @@ const teamsCount = 2;
<div class="qr-box"><img class="qr-code-image" /></div>
<a download="" class="save-qr-img brown-button fa"><!--保存QR 图片--></a>
</div>
<div class="sanbon-me-transfer">
<div class="sanbon-team-edit">
<!--<div class="user">
<label for="sanbon-username"></label><input id="sanbon-username" type="text" placeholder="ID (2~12)">
<label for="sanbon-password"></label><input id="sanbon-password" type="password" placeholder="password (4~20)">
</div>-->
<div class="action">
<label for="sanbon-team-id"></label><input id="sanbon-team-id" type="text" placeholder="Team URL" readonly>
<button id="sanbon-save-or-upload-team" class="brown-button"></button>
</div>
</div>
<div class="sanbon-transfer">
<div class="sanbon-v2">
<label for="sanbon-v2-script"><a id="sanbon-v2-link" href="https://sanbon.me/v2/en-jp/team-builder" target="_blank">Sanbon Team Builder</a> JavaScript (Test function, paste in Browser Console | 测试功能,粘贴到浏览器控制台)</label><br><textarea id="sanbon-v2-script"></textarea>
</div>

112
script.js
View File

@ -787,25 +787,6 @@ Formation.prototype.getPaddbQrObj = function(keepDataSource = true)
};
return qrObj;
}
Formation.prototype.getSanbonV1Url = function()
{
const region = sanbonTranslateRegion(currentDataSource.code);
const sanbonUrl = new URL(`https://sanbon.me/${region}/team-builder`);
const search = sanbonUrl.searchParams;
//sanbon目前只支持单人队伍
const [members,assists,badge] = this.teams[0];
for (let i = 0; i < members.length; i++) {
const m = members[i], a = assists[i];
m.id > 0 && search.set(`${i}`, m.id);
m.sawoken > 0 && search.set(`${i}s`, m.sawoken);
m?.latent?.length > 0 && search.set(`${i}l`, m.latent.join());
a.id > 0 && search.set(`${i}a`, a.id);
}
badge > 0 && search.set(`badge`, badge & 0x7f);
return sanbonUrl;
}
function sanbonTranslateRegion(code) {
switch (code) {
case "ja": return "jp";
@ -903,7 +884,39 @@ scriptLines.push(`sessionStorage.setItem("team-build-store", JSON.stringify(tbs)
location.reload();
})();`);
return scriptLines.join('\n');
};
Formation.prototype.getSanbonQrObj = function()
{
//sanbon目前只支持单人队伍
const [members,assists,badge] = this.teams[0];
const obj = {
title: this.title,
content: this.detail,
mons: members.map(m=>m.id).concat(assists.map(m=>m.id)),
data: {
badge: badge || 1,
members: {},
},
};
for (let i = 0; i < members.length; i++) {
const m = members[i], a = assists[i];
const _m = {
num: m.id,
level: m.level,
superAwoken: m.sawoken,
latentAwokens: m.latent.concat(),
awokenCount: m.awoken,
hpPlus: m.plus[0],
atkPlus: m.plus[1],
rcvPlus: m.plus[2],
assistNum: a.id,
assistLevel: a.level,
assistPlus: a?.plus?.every(p=>p>=99) ?? false,
}
obj.data.members[i] = _m;
}
return obj;
};
//paddb的徽章对应数字
Formation.daddbBadgeMap = [
@ -1007,18 +1020,9 @@ Formation.prototype.getQrStr = function(type)
case 'paddf': {
return JSON.stringify(this.getPdfQrObj());
}
case 'paddb': {
return JSON.stringify(this.getPaddbQrObj());
}
case 'daddb': {
return JSON.stringify(this.getDaddbQrObj());
}
case 'sanbon-v1': {
return this.getSanbonV1Url();
}
case 'sanbon-v2': {
return this.getSanbonV2Script();
}
case 'pdc':
default: {
return this.getPdcQrStr();
@ -1940,7 +1944,7 @@ function qrObjToUrl(obj)
{
newUrl.searchParams.set("l", l);
}
//数据服版本
//PADDB的ID
if (obj.paddbId)
{
newUrl.searchParams.set("_id", obj.paddbId);
@ -2845,6 +2849,50 @@ function initialize() {
this.disabled = false;
}
//sanbon.me数据上传
//const sanbonTeamEdit = qrContent.querySelector(".sanbon-team-edit");
const sanbonTeamId = document.querySelector("#sanbon-team-id");
const sanbonSaveOrUpload = document.querySelector("#sanbon-save-or-upload-team");
sanbonSaveOrUpload.onclick = async function(){
this.disabled = true;
if (!btnExternalSupport?.asyncGM_xmlhttpRequest) {
alert(localTranslating.link_read_message.need_user_script);
return;
}
let obj = formation.getSanbonQrObj();
let postBody = JSON.stringify(obj);
const options = {
method: "POST",
url: `https://sanbon.me/api/${sanbonTranslateRegion(currentDataSource.code)}/upload-team`,
data: postBody,
headers: {
"Content-Type": "application/json",
//如果只有ascii字符可以用postBody.length
"Content-Length": new Blob([postBody], {type: "application/json"}).size,
}
};
const response = await btnExternalSupport.asyncGM_xmlhttpRequest(options);
if (response.status === 401) {
alert(localTranslating.link_read_message.paddb_unauthorized);
} else if (response.status === 200) {
try {
const result = JSON.parse(response.response);
console.debug("数据上传返回结果:%o",result);
if (result.success) {
sanbonTeamId.value = `https://sanbon.me/${sanbonTranslateRegion(currentDataSource.code)}/team/${result.code}`;
alert(localTranslating.link_read_message.paddb_success);
} else {
alert(result.message);
}
} catch(e) {
alert(localTranslating.link_read_message.error[3]);
}
} else {
alert(localTranslating.link_read_message.error[0]);
}
this.disabled = false;
}
const playerDataFrame = document.body.querySelector("#player-data-frame");
const btnPlayerData = controlBox.querySelector(`.btn-player-data`);
btnPlayerData.onclick = function(){
@ -6941,18 +6989,18 @@ function refreshFormationTotalHP(totalDom, teams) {
const teamHPArr = countTeamHp(team, leader1id, leader2id, solo);
const teamHPAwoken = awokenCountInTeam(team, 46, solo, teamsCount), teamHPAwokenScale = (1 + 0.05 * teamHPAwoken); //全队大血包个数
const teamTHP = teamHPArr.reduce((pv, v) => pv + Math.round(v * teamHPAwokenScale + 1e-12)); //队伍计算的总HP
const teamTHP = teamHPArr.reduce((pv, v) => pv + Math.round(v * teamHPAwokenScale + 1e-12), 0); //队伍计算的总HP
return teamTHP;
});
const tHPNoAwokenArr = teams.map(team=>{
const teamHPArr = countTeamHp(team, leader1id, leader2id, solo, true);
const teamTHP = teamHPArr.reduce((pv, v) => pv + v); //队伍计算的总HP
const teamTHP = teamHPArr.reduce((pv, v) => pv + v, 0); //队伍计算的总HP
return Math.round(teamTHP);
});
const tHP = tHPArr.reduce((pv, v) => pv + v);
const tHPNoAwoken = tHPNoAwokenArr.reduce((pv, v) => pv + v);
const tHPNoAwoken = tHPNoAwokenArr.reduce((pv, v) => pv + v, 0);
//记录到bar中方便打开详情时调用
hpBar.reduceAttrRanges = reduceAttrRanges;

View File

@ -24039,7 +24039,7 @@ const cachesMap = new Map([
],
[
"multi.html",
"af2ec4092425b8aa60ca5a3e83132dec"
"8759dfb57877383ab9e333dc84461144"
],
[
"script-custom_elements.js",
@ -24047,7 +24047,7 @@ const cachesMap = new Map([
],
[
"script-json_data.js",
"6d0626ffc2851830c4a6bc7ee34d5480"
"027f128278109743141290336f3005b7"
],
[
"script-skill-parser.js",
@ -24059,11 +24059,11 @@ const cachesMap = new Map([
],
[
"script.js",
"8c120aa4d1f7609f4070907679c90ada"
"42cf414b9c5bf0ca0a9cf284879c4760"
],
[
"solo.html",
"a03e850df95eea9dad7c935806968d17"
"b33f3ef94739addfc99ccfeeedebefcd"
],
[
"style-monsterimages.css",
@ -24071,7 +24071,7 @@ const cachesMap = new Map([
],
[
"style.css",
"a00c9cdd0da151d4f5b1d3048fc6967b"
"b24c651e9eda3c2cb5a62f264e339c07"
],
[
"temp.js",
@ -24079,11 +24079,11 @@ const cachesMap = new Map([
],
[
"triple.html",
"0f7e8bac34ea2f17ac814ca45c38d916"
"6d23f002561365f9e124d91f4b4ae5fe"
],
[
"languages/en.css",
"2ead48b05d01156478ccc5d05591bf07"
"6b8f1061663589291d88783de4d45487"
],
[
"languages/en.js",
@ -24091,7 +24091,7 @@ const cachesMap = new Map([
],
[
"languages/ja.css",
"80ac0fe1f0da5c4e15b60afb3c20c6e9"
"16fb2ff4e2c0182bb00a9a190013f512"
],
[
"languages/ja.js",
@ -24099,7 +24099,7 @@ const cachesMap = new Map([
],
[
"languages/ko.css",
"fe096e4fdfa29fca334852e66f7e6dae"
"7c0111768890372ccf417d5b9ec86be4"
],
[
"languages/ko.js",
@ -24107,23 +24107,23 @@ const cachesMap = new Map([
],
[
"languages/language-list.js",
"a1c0271043e0c6e15dec8ba468d25949"
"b15a6e0512c5b47b1b15fc62c4ed70ad"
],
[
"languages/zh-TW.css",
"a573e318265b8eceb7496fcf258c0daa"
"languages/zh-hans.css",
"d7fe51f3561d030f8023b3be04e6d02d"
],
[
"languages/zh-TW.js",
"79f8db66f79d0f3f6351a47d797dfe5d"
"languages/zh-hans.js",
"1cb9427d980613750be284b683b6c965"
],
[
"languages/zh.css",
"eb05f11f197eb969907eb5221f7aaf64"
"languages/zh-hant.css",
"29e5a64d600eefb8430f93236ff3cec5"
],
[
"languages/zh.js",
"1514e5ac0e809c068a62c6a9f12f3039"
"languages/zh-hant.js",
"2d62a0b2c437f20580881351ed0f2faf"
],
[
"images/attrs.png",

View File

@ -1243,7 +1243,17 @@ const teamsCount = 1;
<div class="qr-box"><img class="qr-code-image" /></div>
<a download="" class="save-qr-img brown-button fa"><!--保存QR 图片--></a>
</div>
<div class="sanbon-me-transfer">
<div class="sanbon-team-edit">
<!--<div class="user">
<label for="sanbon-username"></label><input id="sanbon-username" type="text" placeholder="ID (2~12)">
<label for="sanbon-password"></label><input id="sanbon-password" type="password" placeholder="password (4~20)">
</div>-->
<div class="action">
<label for="sanbon-team-id"></label><input id="sanbon-team-id" type="text" placeholder="Team URL" readonly>
<button id="sanbon-save-or-upload-team" class="brown-button"></button>
</div>
</div>
<div class="sanbon-transfer">
<div class="sanbon-v2">
<label for="sanbon-v2-script"><a id="sanbon-v2-link" href="https://sanbon.me/v2/en-jp/team-builder" target="_blank">Sanbon Team Builder</a> JavaScript (Test function, paste in Browser Console | 测试功能,粘贴到浏览器控制台)</label><br><textarea id="sanbon-v2-script"></textarea>
</div>

View File

@ -3542,25 +3542,40 @@ body:not(.external-link-support) #external-support::before
resize: vertical;
}
#qr-code-frame .read-qr-box::before,
#qr-code-frame .save-qr-box::before,
#qr-code-frame .sanbon-me-transfer::before,
#qr-code-frame .paddb-team-edit::before
{
#qr-code-frame :where(
.read-qr-box,
.save-qr-box,
.paddb-team-edit,
.sanbon-transfer,
.sanbon-team-edit,
)::before {
display: block;
text-align: left;
}
body:not(.solo.external-link-support) .paddb-team-edit{
body:not(.solo.external-link-support) :where(
.paddb-team-edit,
.sanbon-team-edit,
) {
/*没有装插件的不显示PADDB上传功能*/
display: none;
}
body.external-link-support .sanbon-transfer {
/*装了插件的不显示sanbon测试功能*/
display: none;
}
body.external-link-support #external-support{
/*装了插件的不显示请求装插件的消息*/
display: none;
}
#paddb-team-id {
#paddb-team-id,
#sanbon-team-id {
width: 350px;
}
.sanbon-transfer::before
{
content: "Sanbon.me(Defective test functionality)";
}
.qr-data-type-ul {
display: flex;

View File

@ -2233,7 +2233,17 @@ const teamsCount = 3;
<div class="qr-box"><img class="qr-code-image" /></div>
<a download="" class="save-qr-img brown-button fa"><!--保存QR 图片--></a>
</div>
<div class="sanbon-me-transfer">
<div class="sanbon-team-edit">
<!--<div class="user">
<label for="sanbon-username"></label><input id="sanbon-username" type="text" placeholder="ID (2~12)">
<label for="sanbon-password"></label><input id="sanbon-password" type="password" placeholder="password (4~20)">
</div>-->
<div class="action">
<label for="sanbon-team-id"></label><input id="sanbon-team-id" type="text" placeholder="Team URL" readonly>
<button id="sanbon-save-or-upload-team" class="brown-button"></button>
</div>
</div>
<div class="sanbon-transfer">
<div class="sanbon-v2">
<label for="sanbon-v2-script"><a id="sanbon-v2-link" href="https://sanbon.me/v2/en-jp/team-builder" target="_blank">Sanbon Team Builder</a> JavaScript (Test function, paste in Browser Console | 测试功能,粘贴到浏览器控制台)</label><br><textarea id="sanbon-v2-script"></textarea>
</div>