Greasy Fork is available in English.
榭洛科特的背包测试版
当前为
// ==UserScript==
// @name 榭洛科特的背包 Beta
// @version 0.1.1
// @author Alk
// @license GPL-3.0
// @description 榭洛科特的背包测试版
// @description 仅控制浏览器,不对游戏进行任何操作。
// @description Sierokarte's BackPack Beta Version. This script only affects the browser, does nothing to GBF game.
// @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==
(function () {
'use strict';
// 战斗结果 JSON 文件名集合
const battleSet = new Set([
'normal_attack_result.json',
'ability_result.json',
'fatal_chain_result.json',
'summon_result.json'
]);
// 配置默认值
const defaults = {
refresh_attack: true,
hide_left_sb: false,
hide_right_sb: false,
refresh_koenig_dekret: true,
refresh_coronal_ejection: false,
refresh_secret_triad: false,
hunter_mode: false,
replace_refresh_with_back: false,
allow_auto_redirect: false,
auto_redirect_hash: ''
};
// 获取配置值
function getCfg(key) {
return GM_getValue(key, defaults[key]);
}
// 切换配置并刷新页面
function toggleCfg(key) {
const val = !getCfg(key);
GM_setValue(key, val);
// 切换后立即刷新以生效
window.location.reload();
}
// 注册右键菜单
const labels = {
refresh_attack: '攻击后自动刷新',
hide_left_sb: '关闭左侧边栏',
hide_right_sb: '关闭右侧边栏',
refresh_koenig_dekret: '帝王法令刷新',
refresh_coronal_ejection: '日冕喷发刷新',
refresh_secret_triad: '万事皆三刷新',
hunter_mode: '猎金模式',
replace_refresh_with_back: '替换刷新为后退',
allow_auto_redirect: '自动跳转'
};
Object.entries(labels).forEach(([key, label]) => {
GM_registerMenuCommand(
`${label}:${getCfg(key) ? '已开启' : '已关闭'}`,
() => toggleCfg(key)
);
});
// 页面加载后隐藏侧栏
window.addEventListener('load', () => {
if (!/mobile/.test(navigator.userAgent.toLowerCase())) {
if (getCfg('hide_left_sb')) {
document.body.firstElementChild?.firstElementChild?.remove();
}
}
if (getCfg('hide_right_sb')) {
document.querySelector('#submenu')?.remove();
}
});
// 自动跳转
if (getCfg('allow_auto_redirect')) {
const doRedirect = () => {
if (location.hash.startsWith('#result_multi')) {
const target = GM_getValue('auto_redirect_hash', defaults.auto_redirect_hash);
if (target) location.href = `${location.origin}/${target}`;
}
};
window.addEventListener('load', () => setTimeout(doRedirect, Math.random() * 1000 + 100));
window.addEventListener('popstate', () => setTimeout(doRedirect, Math.random() * 1000 + 100));
}
// 跳转控制
function reload() {
if (getCfg('replace_refresh_with_back')) return goBack();
setTimeout(() => location.reload(), Math.random() * 150 + 50);
}
function goBack() {
setTimeout(() => history.go(-1), Math.random() * 150 + 50);
}
// 战斗处理逻辑
function handleBattle(scenario, urlKey) {
const winObj = scenario.find(o => o.cmd === 'win');
const winStatus = winObj
? (winObj.is_last_raid === 1 ? 'raid' : 'battle')
: 'continue';
if (winStatus === 'raid') return goBack();
if (winStatus === 'battle') return reload();
if (urlKey === 'normal_attack_result.json' && getCfg('refresh_attack')) return reload();
if (urlKey === 'ability_result.json') {
const ability = scenario.find(o => o.cmd === 'ability');
if (ability) {
if ((getCfg('refresh_koenig_dekret') && ability.name === 'ケーニヒ・ベシュテレン') ||
(getCfg('refresh_coronal_ejection') && ability.name.includes('攻撃行動') && ability.name.includes('2回')) ||
(getCfg('refresh_secret_triad') && ability.name === 'シークレットトライアド')) {
return reload();
}
}
}
if ((urlKey === 'fatal_chain_result.json' || urlKey === 'summon_result.json') && getCfg('refresh_attack')) {
return reload();
}
}
// 拦截 XHR
const origSend = unsafeWindow.XMLHttpRequest.prototype.send;
unsafeWindow.XMLHttpRequest.prototype.send = function (...args) {
this.addEventListener('load', () => {
try {
const url = new URL(this.responseURL);
const key = url.pathname.split('/')[3];
if (!battleSet.has(key)) return;
const resp = JSON.parse(this.responseText);
const scenario = resp.scenario || resp;
handleBattle(scenario, key);
} catch (e) {
console.warn('脚本出错:', e);
}
});
origSend.apply(this, args);
};
})();