Greasy Fork is available in English.
原名GBF周回本胜利跳过。已重构。现支持:1.关闭左/右侧边栏,2.攻击后刷新,3.胜利跳过,4.帝王指令自动刷新,5.太阳自动刷新 待追加:6.五神复活增益显示。
当前为
// ==UserScript==
// @name 榭洛科特的背包
// @version 1.7.0.1
// @author Alk
// @license GPL 3.0
// @description 原名GBF周回本胜利跳过。已重构。现支持:1.关闭左/右侧边栏,2.攻击后刷新,3.胜利跳过,4.帝王指令自动刷新,5.太阳自动刷新 待追加:6.五神复活增益显示。
// @match *.granbluefantasy.jp
// @grant unsafeWindow
// @grant GM_registerMenuCommand
// @grant GM_setValue
// @grant GM_getValue
// @run-at document-start
// @namespace http://greasyfork.icu/users/1455240
// @icon https://raw.githubusercontent.com/enorsona/thirdparty/refs/heads/master/sherurotes_carrybag.ico
// ==/UserScript==
// ========== 设置项 ==========
const battle_json_names = ['normal_attack_result.json', 'ability_result.json', 'fatal_chain_result.json', 'summon_result.json']
const settings_strings = {
refresh_attack: 'AttackRefresh',
hide_left_sb: 'HideLeftSidebar',
hide_right_sb: 'HideRightSidebar',
refresh_koenig_dekret: 'KoenigDekretRefresh',
refresh_coronal_ejection: 'CoronalEjection',
replace_refresh_with_back: 'ReplaceRefreshWithBack',
allow_auto_redirect: 'AllowAutoRedirect',
auto_redirect_url: 'AutoRedirectURL',
}
// ========== 状态读取 ==========
const checkEnabledAttackRefresh = () => {
return GM_getValue(settings_strings.refresh_attack, true);
};
const checkEnabledHideLeftSidebar = () => {
return GM_getValue(settings_strings.hide_left_sb, false);
};
const checkEnabledHideRightSidebar = () => {
return GM_getValue(settings_strings.hide_right_sb, false);
};
const checkEnabledKoenigDekretAutoRefresh = () => {
return GM_getValue(settings_strings.refresh_koenig_dekret, true);
};
const checkEnabledCoronalEjectionAutoRefresh = () => {
return GM_getValue(settings_strings.refresh_coronal_ejection, true);
};
const checkEnabledReplaceRefreshWithBack = () => {
return GM_getValue(settings_strings.replace_refresh_with_back, false);
}
const checkAllowAutoRedirect = () => {
return GM_getValue(settings_strings.allow_auto_redirect, false);
}
const checkAutoRedirectURL = () => {
return GM_getValue(settings_strings.auto_redirect_url, 0);
}
let rrwb_enabled = checkEnabledReplaceRefreshWithBack();
let ar_enabled = checkEnabledAttackRefresh();
let kdr_enabled = checkEnabledKoenigDekretAutoRefresh();
let cer_enabled = checkEnabledCoronalEjectionAutoRefresh();
let aar_enabled = checkAllowAutoRedirect();
// ========== 切换刷新功能 ==========
const switchEnabledAttackRefresh = () => {
const current = checkEnabledAttackRefresh();
GM_setValue(settings_strings.refresh_attack, !current);
reload();
};
const switchEnabledHideLeftSidebar = () => {
const current = checkEnabledHideLeftSidebar();
GM_setValue(settings_strings.hide_left_sb, !current);
reload();
};
const switchEnabledHideRightSidebar = () => {
const current = checkEnabledHideRightSidebar();
GM_setValue(settings_strings.hide_right_sb, !current);
reload();
};
const switchEnabledKoenigDekretAutoRefresh = () => {
const current = checkEnabledKoenigDekretAutoRefresh();
GM_setValue(settings_strings.refresh_koenig_dekret, !current);
reload();
};
const switchEnabledCoronalEjectionAutoRefresh = () => {
const current = checkEnabledCoronalEjectionAutoRefresh();
GM_setValue(settings_strings.refresh_coronal_ejection, !current);
reload();
};
const switchEnabledReplaceRefreshWithBack = () => {
const current = checkEnabledReplaceRefreshWithBack();
GM_setValue(settings_strings.replace_refresh_with_back, !current);
reload();
};
const switchAllowAutoRedirect = () => {
const current = checkAllowAutoRedirect();
GM_setValue(settings_strings.allow_auto_redirect, !current);
reload();
};
const getAutoRedirectURL = () => {
const current = location.hash;
GM_setValue(settings_strings.auto_redirect_url, current);
reload();
}
// ========== 注册菜单 ==========
const registerMenu = () => {
GM_registerMenuCommand(
`启用替换刷新为后退:${checkEnabledReplaceRefreshWithBack() ? '已开启' : '已关闭'}`,
switchEnabledReplaceRefreshWithBack
);
GM_registerMenuCommand(
`启用自动跳转至召唤选择界面:${checkAllowAutoRedirect() ? '已开启' : '已关闭'}`,
switchAllowAutoRedirect
);
GM_registerMenuCommand(
`当前召唤石选择界面URL:${checkAutoRedirectURL()}`,
getAutoRedirectURL
);
GM_registerMenuCommand(
`攻击后自动刷新:${checkEnabledAttackRefresh() ? '已开启' : '已关闭'}`,
switchEnabledAttackRefresh
);
GM_registerMenuCommand(
`关闭左侧边栏:${checkEnabledHideLeftSidebar() ? '已开启' : '已关闭'}`,
switchEnabledHideLeftSidebar
);
GM_registerMenuCommand(
`关闭右侧边栏:${checkEnabledHideRightSidebar() ? '已开启' : '已关闭'}`,
switchEnabledHideRightSidebar
);
GM_registerMenuCommand(
`启用帝王指令刷新:${checkEnabledKoenigDekretAutoRefresh() ? '已开启' : '已关闭'}`,
switchEnabledKoenigDekretAutoRefresh
);
GM_registerMenuCommand(
`启用太阳召唤刷新:${checkEnabledCoronalEjectionAutoRefresh() ? '已开启' : '已关闭'}`,
switchEnabledCoronalEjectionAutoRefresh
);
};
registerMenu();
// ========== 工具 ==========
const checkIsMobile = () => {
const userAgent = navigator.userAgent.toLowerCase();
return /iphone|ipad|android|mobile|windows phone|blackberry/.test(userAgent);
};
const getRandomInt = (min, max) => {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// ========== URL 与 JSON 解析 ==========
const tryParseJSON = (response) => {
try {
return JSON.parse(response);
} catch (e) {
return response;
}
};
const checkURL = (base) => {
const url = new URL(base);
const parts = url.pathname.split('/');
return {
is_battle: battle_json_names.includes(parts[3]),
is_attack: parts[3] === battle_json_names[0],
is_skill: parts[3] === battle_json_names[1],
is_fc: parts[3] === battle_json_names[2],
is_summon: parts[3] === battle_json_names[3],
};
};
const checkWin = (scenario) => {
const win = scenario.find(s => s.cmd === "win");
if (win) {
return win.is_last_raid === 1 ? 1 : 2;
}
return 0;
};
const checkIsKoenigDekret = (scenario) => {
return (
scenario[0].cmd === 'ability'
&& scenario[0].voice === 'voice/3040425000_ability_us2.mp3'
&& scenario[0].name === 'ケーニヒ・ベシュテレン'
) || false;
}
const checkIsCoronalEjection = (scenario) => {
return (
scenario[2].cmd === 'ability'
&& scenario[2].name === '火属性ダメージ/3番目までに配置された火属性キャラがターン進行時に攻撃行動を2回行う'
) || false;
}
// ========== 页面控制函数 ==========
const reload = () => {
if (rrwb_enabled) {
goback();
} else {
setTimeout(() => {
location.reload(true);
}, getRandomInt(0, 200))
}
}
const goback = () => {
setTimeout(() => {
history.go(-1);
}, getRandomInt(0, 200))
}
const aar = () => {
const hash = location.hash.split('/')[0];
const target = '#result_multi';
console.log(hash, target);
if(hash === target) {
const aru = checkAutoRedirectURL();
if (aru !== 0) {
location.href = location.origin + '/' + aru;
}
}
}
// ========== 拦截并处理XHR ==========
const customLoad = (xhr, result) => {
const response = tryParseJSON(xhr.response);
const status = checkWin(response.scenario);
if (status === 1) {
goback();
} else if (status === 0) {
if (result.is_attack && ar_enabled) {
reload();
} else if (kdr_enabled && checkIsKoenigDekret(response.scenario)) {
reload()
} else if (cer_enabled && checkIsCoronalEjection(response.scenario)) {
reload();
}
} else {
reload();
}
};
// ========== Hook XMLHttpRequest ==========
const origSend = unsafeWindow.XMLHttpRequest.prototype.send;
unsafeWindow.XMLHttpRequest.prototype.send = function (...args) {
this.addEventListener('load', () => {
const checkURLResult = checkURL(this.responseURL);
const process_needed = checkURLResult.is_battle;
if (process_needed) {
customLoad(this, checkURLResult);
}
});
origSend.apply(this, args);
};
// ========== 隐藏左侧边栏 ==========
(() => {
if (checkIsMobile()) return;
if (checkEnabledHideLeftSidebar()) {
window.addEventListener('load', () => {
try {
const target = document.body.firstElementChild;
if (target && target.firstElementChild) {
target.removeChild(target.firstElementChild);
}
} catch (e) {
console.warn('隐藏左边栏失败:', e);
}
});
}
})();
(() => {
if (checkEnabledHideRightSidebar()) {
window.addEventListener('load', () => {
try {
const target = document.querySelector('div#submenu');
if (target) {
target.remove();
}
} catch (e) {
console.warn('隐藏右边栏失败:', e);
}
});
}
})();
(() => {
if(aar_enabled) {
window.onload = () => {
aar()
}
window.addEventListener('popstate', () =>
{
if(checkAllowAutoRedirect()) {
setTimeout(aar, getRandomInt(0, 200))
}
}
)
}
})();