自动读取社区BUFF并显示剩余时间
当前为
// ==UserScript==
// @name [银河奶牛]社区BUFF显示
// @version 1.0
// @description 自动读取社区BUFF并显示剩余时间
// @match https://www.milkywayidle.com/*
// @match https://test.milkywayidle.com/*
// @icon https://www.milkywayidle.com/favicon.svg
// @author DOUBAO-DiamondMoo
// @license MIT
// @namespace https://gf.qytechs.cn/users/1530578
// ==/UserScript==
(function() {
'use strict';
// 防止重复处理的锁
let isProcessing = false;
/**
* 计算剩余时间并格式化显示文本
* @param {string} expireTimeStr - 过期时间字符串(ISO格式)
* @returns {Object} 包含显示文本和是否小于1天的标识
*/
function calculateRemainingTime(expireTimeStr) {
const expireTime = new Date(expireTimeStr);
const now = new Date();
const diffMs = expireTime - now;
// 过期状态处理
if (diffMs <= 0) return { text: '已过期', isLessThanOneDay: false };
// 计算各时间单位
const diffYears = Math.floor(diffMs / (1000 * 60 * 60 * 24 * 365));
const diffDays = Math.floor((diffMs % (1000 * 60 * 60 * 24 * 365)) / (1000 * 60 * 60 * 24));
const diffHours = Math.floor((diffMs % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const diffMinutes = Math.floor((diffMs % (1000 * 60 * 60)) / (1000 * 60));
const diffSeconds = Math.floor((diffMs % (1000 * 60)) / 1000);
// 按优先级返回格式化文本
if (diffYears > 0) return { text: `${diffYears}y`, isLessThanOneDay: false };
if (diffDays > 0) return { text: `${diffDays}d`, isLessThanOneDay: false };
if (diffHours > 0) return { text: `${diffHours}h`, isLessThanOneDay: true };
if (diffMinutes > 0) return { text: `${diffMinutes}m`, isLessThanOneDay: true };
return { text: `${diffSeconds}s`, isLessThanOneDay: true };
}
/**
* 根据文本长度计算动态字体大小
* @param {string} text - 显示文本
* @returns {number} 字体大小(em)
*/
function getDynamicFontSize(text) {
const baseSize = 1.4; // 基础字体大小
const minSize = 0.6; // 最小字体限制
const textLength = text.length;
if (textLength <= 3) return baseSize;
const reducedSize = baseSize - (textLength - 3) * 0.2;
return Math.max(reducedSize, minSize);
}
/**
* 注入BUFF剩余时间到页面
* 核心功能:读取BUFF数据 -> 计算剩余时间 -> 渲染到页面 -> 过期检测
*/
function injectBuffTime() {
if (isProcessing) return;
isProcessing = true;
try {
// 获取游戏页面根元素及React状态
const gamePageEl = document.querySelector('[class^="GamePage"]');
if (!gamePageEl) return;
const reactFiberKey = Object.keys(gamePageEl).find(k => k.startsWith('__reactFiber$'));
const stateNode = gamePageEl[reactFiberKey]?.return?.stateNode;
const communityBuffs = stateNode?.state?.communityBuffs || [];
if (communityBuffs.length === 0) return;
// 过期检测:若当前时间超过首个BUFF过期时间则刷新页面
const targetExpireTime = new Date(communityBuffs[0].expireTime);
if (new Date() > targetExpireTime) {
window.location.reload();
return;
}
// 匹配BUFF元素并注入时间显示
const buffElements = document.querySelectorAll('.CommunityBuff_communityBuff__1BILG');
if (buffElements.length === 0) return;
buffElements.forEach((el, index) => {
if (index >= communityBuffs.length) return;
const expireTime = communityBuffs[index].expireTime;
const { text, isLessThanOneDay } = calculateRemainingTime(expireTime);
const fontSize = getDynamicFontSize(text);
// 样式定义:区分短期和长期BUFF的显示样式
const baseStyles = `
position: absolute;
bottom: 0px;
right: 0px;
font-weight: bold;
z-index: 10;
pointer-events: none;
font-size: ${fontSize}em;
`;
const styles = isLessThanOneDay
? `${baseStyles} color: #000; text-shadow: -0.5px 0 white, 0 0.5px white, 0.5px 0 white, 0 -0.5px white;`
: `${baseStyles} color: #fff; text-shadow: -1px 0 var(--color-background-game), 0 1px var(--color-background-game), 1px 0 var(--color-background-game), 0 -1px var(--color-background-game);`;
// 更新或创建时间显示元素
const existingTimeEl = el.querySelector('.buff-remaining-time');
if (existingTimeEl) {
if (existingTimeEl.textContent !== text) {
existingTimeEl.textContent = text;
existingTimeEl.style.cssText = styles;
}
return;
}
const timeEl = document.createElement('div');
timeEl.className = 'buff-remaining-time';
timeEl.textContent = text;
timeEl.style.cssText = styles;
el.style.position = 'relative'; // 确保绝对定位生效
el.appendChild(timeEl);
});
} finally {
isProcessing = false;
}
}
/**
* 初始化执行
* 页面加载完成后立即执行一次BUFF时间注入
*/
if (document.readyState === 'complete' || document.readyState === 'interactive') {
injectBuffTime();
} else {
document.addEventListener('DOMContentLoaded', injectBuffTime);
}
/**
* DOM变化监听
* 当BUFF区域发生变化时重新注入时间显示
*/
const targetNode = document.querySelector('.Header_communityBuffs__3x-B2') || document.body;
const observer = new MutationObserver((mutations) => {
if (mutations.some(m => m.addedNodes.length > 0 || m.removedNodes.length > 0)) {
injectBuffTime();
}
});
observer.observe(targetNode, { childList: true, subtree: true });
/**
* 定时刷新
*/
setInterval(injectBuffTime, 60000);
})();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址