Greasy Fork is available in English.
原名GBF周回本胜利跳过。已重构。现支持:1.关闭左/右侧边栏,2.攻击后刷新,3.胜利跳过,4.帝王指令自动刷新,5.太阳自动刷新 待追加:6.五神复活增益显示。
当前为
// ==UserScript==
// @name 榭洛科特的背包
// @version 1.6.8.1
// @author Alk
// @license GPL3.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',
}
// ========== 状态读取 ==========
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);
}
let rrwb_enabled = checkEnabledReplaceRefreshWithBack();
let ar_enabled = checkEnabledAttackRefresh();
let kdr_enabled = checkEnabledKoenigDekretAutoRefresh();
let cer_enabled = checkEnabledCoronalEjectionAutoRefresh();
// ========== 切换刷新功能 ==========
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 = checkEnabledCoronalEjectionAutoRefresh();
GM_setValue(settings_strings.replace_refresh_with_back, !current);
reload();
};
// ========== 注册菜单 ==========
const registerMenu = () => {
GM_registerMenuCommand(
`启用替换刷新为后退:${checkEnabledReplaceRefreshWithBack() ? '已开启' : '已关闭'}`,
switchEnabledReplaceRefreshWithBack
);
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);
};
// ========== 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 {
location.reload(true);
}
}
const goback = () => history.go(-1);
// ========== 拦截并处理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);
}
});
}
})();