// ==UserScript== // @name 榭洛科特的背包 // @version 1.6.1 // @author Alk // @license GPL3.0 // @description 原名GBF周回本胜利跳过。已重构。现支持:1.关闭左/右侧边栏,2.攻击后刷新,3.胜利跳过,待追加:4.五神复活增益显示。 // @match *.granbluefantasy.jp // @grant unsafeWindow // @grant GM_registerMenuCommand // @grant GM_setValue // @grant GM_getValue // @run-at document-start // @namespace https://greasyfork.org/users/1455240 // @icon https://raw.githubusercontent.com/enorsona/thirdparty/refs/heads/master/sherurotes_carrybag.ico // @downloadURL none // ==/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', } // ========== 状态读取 ========== 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); }; let ar_enabled = checkEnabledAttackRefresh(); // ========== 切换刷新功能 ========== 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 registerMenu = () => { GM_registerMenuCommand( `攻击后自动刷新:${checkEnabledAttackRefresh() ? '已开启' : '已关闭'}`, switchEnabledAttackRefresh ); GM_registerMenuCommand( `关闭左侧边栏:${checkEnabledHideLeftSidebar() ? '已开启' : '已关闭'}`, switchEnabledHideLeftSidebar ); GM_registerMenuCommand( `关闭右侧边栏:${checkEnabledHideRightSidebar() ? '已开启' : '已关闭'}`, switchEnabledHideRightSidebar ); }; registerMenu(); // ========== 设备判断 ========== const detectDeviceType = () => { const userAgent = navigator.userAgent.toLowerCase(); const isMobile = /iphone|ipad|android|mobile|windows phone|blackberry/.test(userAgent); const width = window.innerWidth || document.documentElement.clientWidth; const height = window.innerHeight || document.documentElement.clientHeight; const aspectRatio = width / height; if (!isMobile && aspectRatio < 1) { return 'mobile'; } return isMobile ? 'mobile' : 'desktop'; }; // ========== 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 reload = () => location.reload(true); const goback = () => history.go(-1); // ========== 拦截并处理XHR ========== const customLoad = (xhr, result) => { const response = tryParseJSON(xhr.response); const status = checkWin(response.scenario); if (ar_enabled && result.is_attack) { if (status === 0 || status === 2) { reload(); } else if (status === 1) { goback(); } } else { if (status === 1) { goback(); } else if (status === 2) { reload(); } } }; // ========== Hook XMLHttpRequest ========== const origSend = unsafeWindow.XMLHttpRequest.prototype.send; unsafeWindow.XMLHttpRequest.prototype.send = function (...args) { this.addEventListener('load', () => { const process_needed = checkURL(this.responseURL); if (process_needed) { customLoad(this); } }); origSend.apply(this, args); }; // ========== 隐藏左侧边栏 ========== (() => { if (detectDeviceType() === 'desktop' || 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); } }); } })();