// ==UserScript== // @name [MWI]personal use // @name:zh-CN [银河奶牛]自用脚本 // @namespace http://tampermonkey.net/ // @version 0.1.14 // @description 个人脚本,适用于 Milky Way Idle 游戏 // @description:zh-CN 个人专用脚本,适用于 Milky Way Idle 游戏 // @author deric // @license MIT // @match https://www.milkywayidle.com/game* // @grant GM_registerMenuCommand // @downloadURL https://update.greasyfork.icu/scripts/542553/%5BMWI%5Dpersonal%20use.user.js // @updateURL https://update.greasyfork.icu/scripts/542553/%5BMWI%5Dpersonal%20use.meta.js // ==/UserScript== (function() { 'use strict'; const MWI_SCRIPT_VERSION = (typeof GM_info !== 'undefined' && GM_info.script && GM_info.script.version) ? GM_info.script.version : 'unknown'; function showSettingPanel() { let exist = document.getElementById('mwiSettingPopup'); if (exist) exist.remove(); const popup = document.createElement('div'); popup.id = 'mwiSettingPopup'; popup.style.position = 'fixed'; popup.style.top = '120px'; popup.style.left = '50%'; popup.style.transform = 'translateX(-50%)'; popup.style.background = 'white'; popup.style.border = '2px solid #888'; popup.style.boxShadow = '0 2px 12px rgba(0,0,0,0.2)'; popup.style.zIndex = 99999; popup.style.padding = '24px 32px'; popup.style.minWidth = '300px'; popup.innerHTML = `

设置

设置会自动保存
`; document.body.appendChild(popup); document.getElementById('closeMwiSettingPopup').onclick = function() { popup.remove(); // 关闭时记录当前版本号 localStorage.setItem('mwiSettingPanelLastVersion', MWI_SCRIPT_VERSION); }; // 初始化复选框状态 document.getElementById('mwiMonitorPlayer').checked = localStorage.getItem('mwiMonitorPlayer') !== 'false'; document.getElementById('mwiMonitorNetWorth').checked = localStorage.getItem('mwiMonitorNetWorth') === 'true'; document.getElementById('mwiShowOrderTotalValue').checked = localStorage.getItem('mwiShowOrderTotalValue') !== 'false'; // 监听变更 document.getElementById('mwiMonitorPlayer').onchange = function() { localStorage.setItem('mwiMonitorPlayer', this.checked); }; document.getElementById('mwiMonitorNetWorth').onchange = function() { localStorage.setItem('mwiMonitorNetWorth', this.checked); }; document.getElementById('mwiShowOrderTotalValue').onchange = function() { localStorage.setItem('mwiShowOrderTotalValue', this.checked); window.dispatchEvent(new Event('mwiShowOrderTotalValueChanged')); }; } // 你的代码写在这里 function savePlayerNumber() { const el = document.querySelector('div.Header_playerCount__1TDTK'); if (!el) return; const number = parseInt(el.textContent.replace(/\D/g, ''), 10); if (isNaN(number)) { setTimeout(savePlayerNumber, 3000); return; } const now = new Date().toISOString(); const data = { time: now, number }; let arr = []; try { arr = JSON.parse(localStorage.getItem('playernumber') || '[]'); if (!Array.isArray(arr)) arr = []; } catch(e) { arr = []; } arr.push(data); localStorage.setItem('playernumber', JSON.stringify(arr)); } // 新增:根据当前网址获取key function getNetWorthKey() { const url = window.location.href; const match = url.match(/(\d{6})(?!.*\d)/); return match ? match[1] : 'default'; } // 新增:保存净资产(分key) function saveNetWorth() { const el = document.querySelector('#toggleNetWorth'); if (!el) return; // 提取数字和单位 const match = el.textContent.replace(/,/g, '').match(/([\d.]+)\s*([KMBT]?)/i); let number = null; if (match) { number = parseFloat(match[1]); const unit = match[2]?.toUpperCase(); if (unit === 'K') number *= 1e3; else if (unit === 'M') number *= 1e6; else if (unit === 'B') number *= 1e9; else if (unit === 'T') number *= 1e12; } if (!number || isNaN(number)) { setTimeout(saveNetWorth, 3000); return; } const now = new Date().toISOString(); const data = { time: now, number }; let arr = []; const key = 'networth_' + getNetWorthKey(); try { arr = JSON.parse(localStorage.getItem(key) || '[]'); if (!Array.isArray(arr)) arr = []; } catch(e) { arr = []; } arr.push(data); // 只保留最新50条 if(arr.length > 50) arr = arr.slice(-50); localStorage.setItem(key, JSON.stringify(arr)); } // 修改按钮显示逻辑,支持显示多条记录 function createShowButton() { // 判断设置 if (localStorage.getItem('mwiMonitorPlayer') === 'false') return; // 兼容新版class,优先用用户指定的选择器 let target = document.querySelector("#root > div > div > div.GamePage_headerPanel__1T_cA > div > div.Header_leftHeader__PkRWX > div.Header_navLogoAndPlayerCount__2earI > div.Header_playerCount__1TDTK"); if (!target) { // 兼容旧class target = document.querySelector("#root > div > div > div.GamePage_headerPanel__3uNKN > div > div.Header_leftHeader__PkRWX > div.Header_navLogoAndPlayerCount__2earI > div.Header_playerCount__1TDTK"); } if (!target || document.getElementById('showPlayerNumberBtn')) return; const btn = document.createElement('button'); btn.id = 'showPlayerNumberBtn'; btn.textContent = '显示玩家人数记录'; btn.style.marginLeft = '8px'; btn.style.background = 'rgb(69,71,113)'; btn.style.color = '#fff'; btn.style.border = 'none'; btn.style.borderRadius = '4px'; btn.style.padding = '4px 10px'; btn.onclick = function() { let data = localStorage.getItem('playernumber'); let arr = []; if (data) { try { arr = JSON.parse(data); if (!Array.isArray(arr)) arr = []; } catch(e) { arr = []; } } // 默认时间范围(天) let rangeDays = parseInt(localStorage.getItem('mwiPlayerNumberRangeDays')) || 1; // 生成时间范围按钮 const ranges = [1, 3, 7, 14, 30]; let rangeBtns = '
'; for(const d of ranges){ rangeBtns += ``; } rangeBtns += '
'; // 生成折线图HTML let html = rangeBtns; html += ``; html += `
`; html += ``; // 网页内部弹窗 let exist = document.getElementById('playerNumberPopup'); if (exist) exist.remove(); const popup = document.createElement('div'); popup.id = 'playerNumberPopup'; popup.style.position = 'fixed'; popup.style.top = '80px'; popup.style.left = '40px'; popup.style.background = 'rgb(69,71,113)'; popup.style.border = '2px solid #888'; popup.style.boxShadow = '0 2px 12px rgba(0,0,0,0.2)'; popup.style.zIndex = 9999; popup.style.padding = '16px'; popup.style.maxHeight = '500px'; popup.style.overflow = 'auto'; popup.innerHTML = `
${html}
`; document.body.appendChild(popup); document.getElementById('closePlayerNumberPopup').onclick = function() { popup.remove(); }; // 管理按钮逻辑 document.getElementById('managePlayerNumberBtn').onclick = function() { const panel = document.getElementById('managePlayerNumberPanel'); if(panel.style.display==='none'){ renderManagePanel(); panel.style.display='block'; }else{ panel.style.display='none'; } }; function renderManagePanel(){ const panel = document.getElementById('managePlayerNumberPanel'); if(arr.length===0){ panel.innerHTML = '暂无记录'; return; } let html = `
`; html += ''; panel.innerHTML = html; // 单条删除 panel.querySelectorAll('.delPlayerNumberBtn').forEach(btn=>{ btn.onclick = function(){ arr.splice(parseInt(this.getAttribute('data-idx')),1); localStorage.setItem('playernumber', JSON.stringify(arr)); drawChart(rangeDays); }; }); // 全部清空 panel.querySelector('#clearAllPlayerNumber').onclick = function(){ if(confirm('确定要清空所有记录吗?')){ arr.length=0; localStorage.setItem('playernumber', '[]'); renderManagePanel(); drawChart(rangeDays); } }; } // 绘制折线图函数 function drawChart(days) { const now = Date.now(); const ms = days * 24 * 60 * 60 * 1000; const filtered = arr.filter(item => { const t = new Date(item.time).getTime(); return t >= now - ms; }).sort((a, b) => new Date(a.time) - new Date(b.time)); const container = document.getElementById('chartContainer'); if(filtered.length > 1){ container.innerHTML = ``; }else if(filtered.length === 1){ container.innerHTML = `仅有一条数据:${filtered[0].time} - ${filtered[0].number}`; return; }else{ container.innerHTML = '暂无数据'; return; } setTimeout(() => { const canvas = document.getElementById('playerNumberChart'); if (!canvas) return; const ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, canvas.width, canvas.height); // 处理数据 const times = filtered.map(item => new Date(item.time)); const numbers = filtered.map(item => item.number); // 横坐标锚点:每小时/每天 let anchorTimes = []; let anchorLabels = []; const minTime = times[0].getTime(); const maxTime = times[times.length-1].getTime(); if(days <= 1){ // 每小时 let t = new Date(times[0]); t.setMinutes(0,0,0); while (t.getTime() <= maxTime) { anchorTimes.push(new Date(t)); anchorLabels.push(`${t.getHours()}:00`); t.setHours(t.getHours()+1); } } else { // 每天 let t = new Date(times[0]); t.setHours(0,0,0,0); while (t.getTime() <= maxTime) { anchorTimes.push(new Date(t)); anchorLabels.push(`${t.getMonth()+1}-${t.getDate()}`); t.setDate(t.getDate()+1); } } // 纵坐标范围,增加上下边距 let minY = Math.min(...numbers); let maxY = Math.max(...numbers); const steps = 5; const step = (maxY - minY) / steps || 1; minY = Math.max(0, minY - step); maxY = maxY + step; const padding = 55; const w = canvas.width - padding*2; const h = canvas.height - padding*2; ctx.font = '12px sans-serif'; ctx.fillStyle = '#fff'; ctx.strokeStyle = '#fff'; // 横坐标等比例 const timeSpan = maxTime - minTime || 1; // 绘制坐标轴 ctx.strokeStyle = '#fff'; ctx.beginPath(); ctx.moveTo(padding, padding); ctx.lineTo(padding, padding + h); ctx.lineTo(padding + w, padding + h); ctx.stroke(); // Y轴刻度 ctx.fillStyle = '#fff'; ctx.textAlign = 'right'; ctx.textBaseline = 'middle'; for(let i=0;i<=5;i++){ const y = padding + h - h*i/5; const val = Math.round(minY + (maxY-minY)*i/5); ctx.fillText(Math.round(val)+'M', padding-5, y); ctx.strokeStyle = '#eee'; ctx.beginPath(); ctx.moveTo(padding, y); ctx.lineTo(padding+w, y); ctx.stroke(); } // X轴刻度(只显示锚点,自动间隔) ctx.textAlign = 'center'; ctx.textBaseline = 'top'; let anchorStep = 1; if(anchorTimes.length > 10) anchorStep = Math.ceil(anchorTimes.length / 10); for(let i=0;i { btn.onclick = function(){ const days = parseInt(this.getAttribute('data-days')); localStorage.setItem('mwiPlayerNumberRangeDays', days); drawChart(days); highlightRangeBtn(days); }; }); }; // 插入到目标元素下方 if (target.nextSibling) { target.parentNode.insertBefore(btn, target.nextSibling); } else { target.parentNode.appendChild(btn); } } // 新增:显示净资产历史折线图按钮(分key) function createShowNetWorthButton() { // 判断设置 if (localStorage.getItem('mwiMonitorNetWorth') !== 'true') return; const target = document.querySelector("#toggleNetWorth"); if (!target || document.getElementById('showNetWorthBtn')) return; const btn = document.createElement('button'); btn.id = 'showNetWorthBtn'; const key = getNetWorthKey(); btn.textContent = '显示净资产记录'; btn.style.marginLeft = '8px'; btn.style.background = 'rgb(69,71,113)'; btn.style.color = '#fff'; btn.style.border = 'none'; btn.style.borderRadius = '4px'; btn.style.padding = '4px 10px'; btn.onclick = function() { const key = 'networth_' + getNetWorthKey(); let data = localStorage.getItem(key); let arr = []; if (data) { try { arr = JSON.parse(data); if (!Array.isArray(arr)) arr = []; } catch(e) { arr = []; } } // 默认时间范围(天) let rangeDays = parseInt(localStorage.getItem('mwiNetWorthRangeDays')) || 1; // 生成时间范围按钮 const ranges = [1, 3, 7, 14, 30]; let rangeBtns = '
'; for(const d of ranges){ rangeBtns += ``; } rangeBtns += '
'; // 生成折线图HTML let html = rangeBtns; html += ``; html += `
`; html += ``; // 网页内部弹窗 let exist = document.getElementById('netWorthPopup'); if (exist) exist.remove(); const popup = document.createElement('div'); popup.id = 'netWorthPopup'; popup.style.position = 'fixed'; popup.style.top = '80px'; popup.style.left = '40px'; popup.style.background = 'rgb(69,71,113)'; popup.style.border = '2px solid #888'; popup.style.boxShadow = '0 2px 12px rgba(0,0,0,0.2)'; popup.style.zIndex = 9999; popup.style.padding = '16px'; popup.style.maxHeight = '500px'; popup.style.overflow = 'visible'; popup.innerHTML = `

净资产记录

${html}
`; document.body.appendChild(popup); document.getElementById('closeNetWorthPopup').onclick = function() { popup.remove(); }; // 管理按钮逻辑 document.getElementById('manageNetWorthBtn').onclick = function() { const panel = document.getElementById('manageNetWorthPanel'); if(panel.style.display==='none'){ renderManagePanelNet(); panel.style.display='block'; }else{ panel.style.display='none'; } }; function renderManagePanelNet(){ const panel = document.getElementById('manageNetWorthPanel'); const key = 'networth_' + getNetWorthKey(); let arr = []; try { arr = JSON.parse(localStorage.getItem(key) || '[]'); if (!Array.isArray(arr)) arr = []; } catch(e) { arr = []; } const rangeDays = parseInt(localStorage.getItem('mwiNetWorthRangeDays')) || 1; if(arr.length===0){ panel.innerHTML = '暂无记录'; drawChart(rangeDays); return; } let html = `
`; html += ''; panel.innerHTML = html; // 单条删除 panel.querySelectorAll('.delNetWorthBtn').forEach(btn=>{ btn.onclick = function(){ const idx = parseInt(this.getAttribute('data-idx')); arr.splice(idx,1); localStorage.setItem(key, JSON.stringify(arr)); renderManagePanelNet(); }; }); // 全部清空 panel.querySelector('#clearAllNetWorth').onclick = function(){ if(confirm('确定要清空所有记录吗?')){ arr = []; localStorage.setItem(key, '[]'); renderManagePanelNet(); } }; } // 绘制折线图函数 function drawChart(days) { const now = Date.now(); const ms = days * 24 * 60 * 60 * 1000; const filtered = arr.filter(item => { const t = new Date(item.time).getTime(); return t >= now - ms; }).sort((a, b) => new Date(a.time) - new Date(b.time)); const container = document.getElementById('chartNetContainer'); if(filtered.length > 1){ container.innerHTML = ``; }else if(filtered.length === 1){ container.innerHTML = `仅有一条数据:${(filtered[0].time)} - ${Math.round(filtered[0].number/1e6)}M`; return; }else{ container.innerHTML = '暂无数据'; return; } setTimeout(() => { const canvas = document.getElementById('netWorthChart'); if (!canvas) return; const ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, canvas.width, canvas.height); // 处理数据 const times = filtered.map(item => new Date(item.time)); const numbers = filtered.map(item => item.number/1e6); // 以M为单位 // 横坐标锚点:每小时/每天 let anchorTimes = []; let anchorLabels = []; const minTime = times[0].getTime(); const maxTime = times[times.length-1].getTime(); if(days <= 1){ // 每小时 let t = new Date(times[0]); t.setMinutes(0,0,0); while (t.getTime() <= maxTime) { anchorTimes.push(new Date(t)); anchorLabels.push(`${t.getHours()}:00`); t.setHours(t.getHours()+1); } } else { // 每天 let t = new Date(times[0]); t.setHours(0,0,0,0); while (t.getTime() <= maxTime) { anchorTimes.push(new Date(t)); anchorLabels.push(`${t.getMonth()+1}-${t.getDate()}`); t.setDate(t.getDate()+1); } } // 纵坐标范围,增加上下边距 let minY = Math.min(...numbers); let maxY = Math.max(...numbers); const steps = 5; const step = (maxY - minY) / steps || 1; minY = Math.max(0, minY - step); maxY = maxY + step; const padding = 55; const w = canvas.width - padding*2; const h = canvas.height - padding*2; ctx.font = '12px sans-serif'; ctx.fillStyle = '#fff'; ctx.strokeStyle = '#fff'; // 横坐标等比例 const timeSpan = maxTime - minTime || 1; // 绘制坐标轴 ctx.strokeStyle = '#fff'; ctx.beginPath(); ctx.moveTo(padding, padding); ctx.lineTo(padding, padding + h); ctx.lineTo(padding + w, padding + h); ctx.stroke(); // Y轴刻度 ctx.fillStyle = '#fff'; ctx.textAlign = 'right'; ctx.textBaseline = 'middle'; for(let i=0;i<=5;i++){ const y = padding + h - h*i/5; const val = minY + (maxY-minY)*i/5; ctx.fillText(Math.round(val)+'M', padding-5, y); ctx.strokeStyle = '#eee'; ctx.beginPath(); ctx.moveTo(padding, y); ctx.lineTo(padding+w, y); ctx.stroke(); } // X轴刻度(只显示锚点,自动间隔) ctx.textAlign = 'center'; ctx.textBaseline = 'top'; let anchorStep = 1; if(anchorTimes.length > 10) anchorStep = Math.ceil(anchorTimes.length / 10); for(let i=0;i { if(parseInt(btn.getAttribute('data-days')) === days){ btn.style.background = '#e0e0e0'; }else{ btn.style.background = ''; } }); } highlightRangeBtnNet(rangeDays); // 按钮事件 popup.querySelectorAll('.rangeBtnNet').forEach(btn => { btn.onclick = function(){ const days = parseInt(this.getAttribute('data-days')); localStorage.setItem('mwiNetWorthRangeDays', days); drawChart(days); highlightRangeBtnNet(days); }; }); }; target.parentNode.appendChild(btn); // 调用净资产对比显示 showNetWorthDayCompare(); } // 工具函数:带单位字符串转数字 function parseNumberWithUnit(str) { const match = str.replace(/,/g, '').match(/([\d.]+)\s*([KMBT]?)/i); let num = null; if (match) { num = parseFloat(match[1]); const unit = match[2]?.toUpperCase(); if (unit === 'K') num *= 1e3; else if (unit === 'M') num *= 1e6; else if (unit === 'B') num *= 1e9; else if (unit === 'T') num *= 1e12; } return num; } // 工具函数:大数字格式化为K/M/B,保留1位小数,无小数不显示 function formatNumberWithUnit(num) { if (num >= 1e9) { let n = num / 1e9; return (n % 1 === 0 ? n : n.toFixed(1)) + 'B'; } else if (num >= 1e6) { let n = num / 1e6; return (n % 1 === 0 ? n : n.toFixed(1)) + 'M'; } else if (num >= 1e3) { let n = num / 1e3; return (n % 1 === 0 ? n : n.toFixed(1)) + 'K'; } else { return num.toString(); } } // 工具函数:最大值只显示到M为单位 function formatNumberToM(num) { let n = num / 1e6; return (n % 1 === 0 ? n : n.toFixed(2)) + 'M'; } // 优化:库存面板数字显示,超过1万显示为K,超过1百万显示为M,超过1亿显示为B,低于1万正常显示 function formatNumberSmartUnit(num) { if (num >= 1e8) { let n = num / 1e8; return (n % 1 === 0 ? n : n.toFixed(2)) + 'B'; } else if (num >= 1e6) { let n = num / 1e6; return (n % 1 === 0 ? n : n.toFixed(2)) + 'M'; } else if (num >= 1e4) { let n = num / 1e3; return (n % 1 === 0 ? n : n.toFixed(1)) + 'K'; } else { return num.toString(); } } // 读取所有订单行的数量(取"/"后面的数字) function getAllOrderQuantities() { const nodes = document.querySelectorAll('div.MarketplacePanel_myListingsTableContainer__2s6pm > table > tbody > tr > td:nth-child(3) > div > div:nth-child(2)'); const quantities = []; nodes.forEach(node => { const text = node.textContent.trim(); const parts = text.split('/'); if(parts.length === 2) { const qty = parseNumberWithUnit(parts[1]); if(!isNaN(qty)) quantities.push(qty); } }); console.log('所有订单数量:', quantities); return quantities; } // 读取所有订单行的价格 function getAllOrderPrices() { const nodes = document.querySelectorAll('td.MarketplacePanel_price__hIzrY > span'); const prices = []; nodes.forEach(node => { const text = node.textContent.trim(); const price = parseNumberWithUnit(text); if(!isNaN(price)) prices.push(price); }); console.log('所有订单价格:', prices); return prices; } // 在每个订单价格下方插入总价值 function showOrderTotalValues() { // 获取所有订单行 const rows = document.querySelectorAll('div.MarketplacePanel_myListingsTableContainer__2s6pm > table > tbody > tr'); rows.forEach(row => { // 获取数量 const qtyNode = row.querySelector('td:nth-child(3) > div > div:nth-child(2)'); let qty = 0; if(qtyNode) { const text = qtyNode.textContent.trim(); const parts = text.split('/'); if(parts.length === 2) { qty = parseNumberWithUnit(parts[1]); } } // 获取价格 const priceNode = row.querySelector('td.MarketplacePanel_price__hIzrY > span'); let price = 0; if(priceNode) { const text = priceNode.textContent.trim(); price = parseNumberWithUnit(text); } // 计算总价值 const total = (!isNaN(qty) && !isNaN(price)) ? qty * price : 0; // 插入显示div if(priceNode) { // 避免重复插入 if(priceNode.nextSibling && priceNode.nextSibling.className === 'orderTotalValue') return; const div = document.createElement('div'); div.className = 'orderTotalValue'; div.style.fontSize = '12px'; div.style.color = '#28a745'; div.textContent = `总价值:${formatNumberWithUnit(total)}`; priceNode.parentNode.appendChild(div); } }); } // 读取仓库内所有物品及数量(初步实现,具体功能待定) function getWarehouseItems() { // 假设仓库表格选择器如下(如有变动可调整): // 例:div.WarehousePanel_tableContainer__xxx > table > tbody > tr const rows = document.querySelectorAll('div.WarehousePanel_tableContainer__2Qw2d table tbody tr'); const items = []; rows.forEach(row => { // 假设第1列为物品名,第2列为数量 const nameCell = row.querySelector('td:nth-child(1)'); const qtyCell = row.querySelector('td:nth-child(2)'); if(nameCell && qtyCell) { const name = nameCell.textContent.trim(); const qty = qtyCell.textContent.trim().replace(/,/g, ''); items.push({ name, qty }); } }); console.log('仓库物品及数量:', items); return items; } // 重构:读取背包所有物品及数量(Inventory_items__6SXv0.script_buildScore_added.script_invSort_added) function getInventoryItems() { const items = []; const itemDivs = document.querySelectorAll('#root > div > div > div.GamePage_gamePanel__3uNKN > div.GamePage_contentPanel__Zx4FH > div.GamePage_characterManagementPanel__3OYQL > div > div > div > div.TabsComponent_tabPanelsContainer__26mzo > div:nth-child(1) > div > div.Inventory_items__6SXv0.script_buildScore_added.script_invSort_added > div > div > div'); itemDivs.forEach(div => { const svg = div.querySelector('div.Item_iconContainer__5z7j4 > svg'); let name = ''; let icon_url = ''; if(svg) { name = svg.getAttribute('aria-label') || ''; const use = svg.querySelector('use'); if(use) icon_url = use.getAttribute('href') || ''; } // 新增:查找强化等级 let enhance = ''; // 兼容不同class写法,优先找Item_enhancementLevel__19g-e let enhanceDiv = div.querySelector('div.Item_enhancementLevel__19g-e'); if (!enhanceDiv) { // 兜底:查找包含enhancementLevel的div enhanceDiv = Array.from(div.querySelectorAll('div')).find(d => d.className && d.className.includes('enhancementLevel')); } if (enhanceDiv) { enhance = enhanceDiv.textContent.trim(); } // 拼接到名称 let displayName = name; if (enhance) { displayName += enhance; } const countDiv = div.querySelector('div.Item_count__1HVvv'); if(!countDiv) return; const txt = countDiv.textContent.trim(); let qty = parseNumberWithUnit(txt); if(!qty || isNaN(qty)) return; // 查找物品种类 let category = ''; let parent = div.parentElement; while(parent && !category) { const labelDiv = parent.querySelector('div.Inventory_label__XEOAx > span.Inventory_categoryButton__35s1x'); if(labelDiv) category = labelDiv.textContent.trim(); parent = parent.parentElement; } if(name) items.push({ name: displayName, qty, category, icon_url, enhance: enhance || '' }); }); const now = new Date().toLocaleString(); const key = 'inventory_' + getNetWorthKey(); let arr = []; try { arr = JSON.parse(localStorage.getItem(key) || '[]'); if (!Array.isArray(arr)) arr = []; } catch(e) { arr = []; } arr.push({ time: now, items }); // 只保留最新50条 if(arr.length > 50) arr = arr.slice(-50); localStorage.setItem(key, JSON.stringify(arr)); console.log('背包物品及数量:', items); return items; } // 修改定时器和延时调用,根据设置决定是否监控 setInterval(() => { if(localStorage.getItem('mwiMonitorPlayer') !== 'false') savePlayerNumber(); if(localStorage.getItem('mwiMonitorNetWorth') === 'true') saveNetWorth(); }, 30 * 60 * 1000); // 监听#toggleNetWorth出现后0.5秒再显示按钮 function waitForNetWorthAndShowBtns() { const check = () => { const el = document.querySelector('#toggleNetWorth'); if(el) { setTimeout(() => { // 先插入玩家人数按钮,再插入净资产和库存按钮,避免被覆盖 createShowButton(); createShowNetWorthButton(); createShowInventoryHistoryButton(); }, 500); return true; } return false; }; if(!check()) { const observer = new MutationObserver(() => { if(check()) observer.disconnect(); }); observer.observe(document.body, { childList: true, subtree: true }); } } waitForNetWorthAndShowBtns(); // 首次安装时默认开启所有功能 if (localStorage.getItem('mwiMonitorPlayer') === null) { localStorage.setItem('mwiMonitorPlayer', 'true'); } if (localStorage.getItem('mwiMonitorNetWorth') === null) { localStorage.setItem('mwiMonitorNetWorth', 'true'); } // 设置变更时刷新按钮显示 window.addEventListener('storage', function(e) { if (e.key === 'mwiMonitorPlayer' || e.key === 'mwiMonitorNetWorth') { // 移除旧按钮 const btn1 = document.getElementById('showPlayerNumberBtn'); if (btn1) btn1.remove(); const btn2 = document.getElementById('showNetWorthBtn'); if (btn2) btn2.remove(); // 重新判断并添加 createShowButton(); createShowNetWorthButton(); } }); // 监听TabPanel_hidden出现时自动显示订单总价值 let orderTotalValueObserver = null; function observeOrderTabAndShowTotal() { if(orderTotalValueObserver) orderTotalValueObserver.disconnect(); if(localStorage.getItem('mwiShowOrderTotalValue') === 'false') return; orderTotalValueObserver = new MutationObserver(() => { const tab = document.querySelector('div.TabPanel_tabPanel__tXMJF.TabPanel_hidden__26UM3'); if(tab) { showOrderTotalValues(); } }); orderTotalValueObserver.observe(document.body, { childList: true, subtree: true }); } // 页面加载后自动监听 setTimeout(() => { observeOrderTabAndShowTotal(); }, 5000); // 响应设置变更 window.addEventListener('mwiShowOrderTotalValueChanged', () => { observeOrderTabAndShowTotal(); // 清理已显示的总价值 document.querySelectorAll('.orderTotalValue').forEach(e=>e.remove()); }); // 首次安装时默认开启 if (localStorage.getItem('mwiShowOrderTotalValue') === null) { localStorage.setItem('mwiShowOrderTotalValue', 'true'); } // 在"显示净资产记录"按钮左侧添加"显示库存记录"按钮 function createShowInventoryHistoryButton() { const netBtn = document.getElementById('showNetWorthBtn'); if (!netBtn || document.getElementById('showInventoryHistoryBtn')) return; // 按钮加载时保存一次库存 getInventoryItems(); const btn = document.createElement('button'); btn.id = 'showInventoryHistoryBtn'; btn.textContent = '显示库存记录'; btn.style.marginRight = '8px'; btn.style.background = 'rgb(69,71,113)'; btn.style.color = '#fff'; btn.style.border = 'none'; btn.style.borderRadius = '4px'; btn.style.padding = '4px 10px'; btn.onclick = function() { getInventoryItems(); // 点击时保存一次库存 showInventoryHistory(); }; netBtn.parentNode.insertBefore(btn, netBtn); } // 监听净资产按钮生成后插入库存按钮 if (typeof observerInvBtn === 'undefined') { var observerInvBtn = new MutationObserver(() => { createShowInventoryHistoryButton(); }); observerInvBtn.observe(document.body, { childList: true, subtree: true }); } // 显示库存记录弹窗(左侧时间点,右侧物品分类) function showInventoryHistory() { // 只刷新面板,不再自动保存库存 const key = 'inventory_' + getNetWorthKey(); let arr = []; try { arr = JSON.parse(localStorage.getItem(key) || '[]'); if (!Array.isArray(arr)) arr = []; } catch(e) { arr = []; } arr = arr.slice(-300); let exist = document.getElementById('inventoryHistoryPopup'); if (exist) exist.remove(); const popup = document.createElement('div'); popup.id = 'inventoryHistoryPopup'; popup.style.position = 'fixed'; popup.style.top = '120px'; popup.style.left = '50%'; popup.style.transform = 'translateX(-50%)'; popup.style.background = 'rgb(69,71,113)'; popup.style.border = '2px solid #888'; popup.style.boxShadow = '0 2px 12px rgba(0,0,0,0.2)'; popup.style.zIndex = 99999; popup.style.padding = '24px 32px'; popup.style.minWidth = '600px'; popup.innerHTML = `

库存历史记录

`; document.body.appendChild(popup); document.getElementById('closeInventoryHistoryPopup').onclick = function() { popup.remove(); }; // 读取上次位置和尺寸 let popupLeft = parseInt(localStorage.getItem('mwiInvPopupLeft')) || window.innerWidth/2-320; let popupTop = parseInt(localStorage.getItem('mwiInvPopupTop')) || 120; let popupWidth = parseInt(localStorage.getItem('mwiInvPopupWidth')) || 640; let popupHeight = parseInt(localStorage.getItem('mwiInvPopupHeight')) || 420; popup.style.left = popupLeft + 'px'; popup.style.top = popupTop + 'px'; popup.style.width = popupWidth + 'px'; popup.style.height = popupHeight + 'px'; popup.style.minWidth = '480px'; popup.style.minHeight = '320px'; popup.style.resize = 'none'; // 禁用原生resize popup.style.boxSizing = 'border-box'; // 拖动功能 let isDragging = false, dragOffsetX = 0, dragOffsetY = 0; const dragHeader = popup.querySelector('h3'); dragHeader.style.cursor = 'move'; dragHeader.addEventListener('mousedown', function(e){ isDragging = true; dragOffsetX = e.clientX - popup.offsetLeft; dragOffsetY = e.clientY - popup.offsetTop; document.body.style.userSelect = 'none'; }); document.addEventListener('mousemove', function(e){ if(isDragging){ let newLeft = e.clientX - dragOffsetX; let newTop = e.clientY - dragOffsetY; // 限制范围 newLeft = Math.max(0, Math.min(window.innerWidth-popup.offsetWidth, newLeft)); newTop = Math.max(0, Math.min(window.innerHeight-popup.offsetHeight, newTop)); popup.style.left = newLeft + 'px'; popup.style.top = newTop + 'px'; } }); document.addEventListener('mouseup', function(e){ if(isDragging){ isDragging = false; localStorage.setItem('mwiInvPopupLeft', parseInt(popup.style.left)); localStorage.setItem('mwiInvPopupTop', parseInt(popup.style.top)); document.body.style.userSelect = ''; } }); // 右下角拖拽大小 const resizeHandle = document.createElement('div'); resizeHandle.style.position = 'absolute'; resizeHandle.style.right = '2px'; resizeHandle.style.bottom = '2px'; resizeHandle.style.width = '22px'; resizeHandle.style.height = '22px'; resizeHandle.style.cursor = 'nwse-resize'; resizeHandle.style.zIndex = '11'; resizeHandle.innerHTML = ``; popup.appendChild(resizeHandle); let isResizing = false, resizeStartX=0, resizeStartY=0, startW=0, startH=0; resizeHandle.addEventListener('mousedown', function(e){ isResizing = true; resizeStartX = e.clientX; resizeStartY = e.clientY; startW = popup.offsetWidth; startH = popup.offsetHeight; e.stopPropagation(); document.body.style.userSelect = 'none'; // 只监听window,避免多次绑定 window.addEventListener('mousemove', doResize, true); window.addEventListener('mouseup', stopResize, true); }); function doResize(e) { if (!isResizing) return; let newW = Math.max(340, startW + (e.clientX - resizeStartX)); let newH = Math.max(260, startH + (e.clientY - resizeStartY)); popup.style.width = newW + 'px'; popup.style.height = newH + 'px'; setPanelSize(); } function stopResize(e) { if (!isResizing) return; isResizing = false; document.body.style.userSelect = ''; window.removeEventListener('mousemove', doResize, true); window.removeEventListener('mouseup', stopResize, true); // 保存尺寸 localStorage.setItem('mwiInvPopupWidth', parseInt(popup.style.width)); localStorage.setItem('mwiInvPopupHeight', parseInt(popup.style.height)); } // 让内容区自适应弹窗 const invPanel = popup.querySelector('#invHistoryPanel'); invPanel.style.height = (popupHeight-110) + 'px'; invPanel.style.maxHeight = 'none'; invPanel.style.minHeight = '180px'; invPanel.style.flex = '1 1 auto'; // 右侧内容区和左侧栏自适应 const setPanelSize = () => { const h = popup.offsetHeight-110; const w = popup.offsetWidth; invPanel.style.height = h + 'px'; // 左侧栏高度 const leftCol = popup.querySelector('#invHistoryLeftCol'); if(leftCol) { leftCol.style.maxHeight = h-10 + 'px'; leftCol.style.height = h-10 + 'px'; } // 右侧栏宽高 const rightCol = popup.querySelector('#invHistoryRightCol'); if(rightCol) { rightCol.style.maxHeight = h-10 + 'px'; rightCol.style.height = h-10 + 'px'; rightCol.style.width = (w-220) + 'px'; rightCol.style.maxWidth = ''; } }; setPanelSize(); // 打开面板时立即自适应内容区和图标排列 // 左侧时间点 const panel = document.getElementById('invHistoryPanel'); if(arr.length === 0) { panel.innerHTML = `
暂无库存记录
`; return; } let selectedIdx = null; // 首次打开不选中任何记录 // 处理日期分组 const dateMap = {}; arr.forEach((entry, idx) => { const dateStr = entry.time.slice(0,10); // yyyy-mm-dd if(!dateMap[dateStr]) dateMap[dateStr] = []; dateMap[dateStr].push({entry, idx}); }); const allDates = Object.keys(dateMap).sort((a,b)=>b.localeCompare(a)); let selectedDate = allDates[0]; // 下拉栏HTML let dateSelectHtml = ``; // 生成左侧栏内容函数 function renderLeftCol(dateStr, activeIdx) { let leftHtml = dateSelectHtml; // 新到旧排序,时间字符串降序 const records = (dateMap[dateStr]||[]).slice().sort((a,b)=>b.entry.time.localeCompare(a.entry.time)); records.forEach(({entry, idx}) => { // 拆分时间 const t = new Date(entry.time); const monthDay = `${t.getMonth()+1}/${t.getDate()}`; const hms = `${t.getHours().toString().padStart(2,'0')}:${t.getMinutes().toString().padStart(2,'0')}:${t.getSeconds().toString().padStart(2,'0')}`; let highlight = (idx === activeIdx) ? "background:#444;border-radius:4px;" : ""; leftHtml += `
`; leftHtml += `
`; leftHtml += `
${monthDay}
${hms}
`; leftHtml += `
`; leftHtml += `
`; leftHtml += ``; leftHtml += ``; leftHtml += `
`; }); return leftHtml; } // 初始渲染,默认高亮最新一条 let activeIdx = (dateMap[selectedDate] && dateMap[selectedDate].length) ? dateMap[selectedDate][0].idx : 0; let leftColHtml = `
`; leftColHtml += renderLeftCol(selectedDate, activeIdx); leftColHtml += `
`; panel.innerHTML = `
${leftColHtml}
`; setPanelSize(); // 渲染右侧内容,默认显示最新一条 // renderRight(activeIdx); // 不再默认渲染右侧 // 监听日期下拉栏切换 panel.querySelector('#invHistoryDateSelect').onchange = function(){ selectedDate = this.value; panel.querySelector('#invHistoryLeftCol').innerHTML = renderLeftCol(selectedDate, -1); // 不自动高亮和切换右侧 bindLeftColEvents(); }; // 事件绑定函数 function bindLeftColEvents() { panel.querySelectorAll('.invHistoryItem').forEach(itemDiv => { itemDiv.addEventListener('click', function(e) { if (e.target.tagName === 'BUTTON') return; const idx = parseInt(this.getAttribute('data-idx')); panel.querySelector('#invHistoryLeftCol').innerHTML = renderLeftCol(selectedDate, idx); renderRight(idx); // 修正:点击后显示右侧库存 bindLeftColEvents(); }); }); // 对比按钮 panel.querySelectorAll('.invBtn1').forEach(btn => { btn.onclick = function(e) { e.stopPropagation(); const idx = parseInt(this.getAttribute('data-idx')); // 当前右侧显示的selectedIdx const curIdx = selectedIdx; if(idx === curIdx) return; // 对比自己无意义 const baseItems = arr[idx].items; const curItems = arr[curIdx].items; // 以物品名+分类为key(不含强化) const getKey = item => (item.name||'')+'|'+(item.category||''); // 构建分组:同名同类不同强化的物品分别统计 function groupByEnhance(items) { const map = {}; items.forEach(item => { const k = (item.name||'')+'|'+(item.category||'')+'|'+(item.enhance||''); if (!map[k]) map[k] = { ...item }; else map[k].qty += item.qty; }); return Object.values(map); } const baseMap = {}; groupByEnhance(baseItems).forEach(item=>{ baseMap[getKey(item)+(item.enhance||'')] = item; }); const curMap = {}; groupByEnhance(curItems).forEach(item=>{ curMap[getKey(item)+(item.enhance||'')] = item; }); // 分类分组(先用当前的) const group = {}; groupByEnhance(curItems).forEach(item => { const cat = item.category || '未分类'; if(!group[cat]) group[cat] = []; group[cat].push(item); }); // 把历史有但当前没有的物品也加进去 groupByEnhance(baseItems).forEach(item => { const key = getKey(item)+(item.enhance||''); if(!curMap[key]){ const cat = item.category || '未分类'; if(!group[cat]) group[cat] = []; // 构造一个qty为0的当前物品,icon等用历史的 group[cat].push({ name: item.name, category: item.category, icon_url: item.icon_url, qty: 0, enhance: item.enhance, _baseQty: item.qty // 方便后面diff }); } }); // 记录本次对比分组和diff lastCompareData = { group, baseMap, getKey }; // 渲染 renderCompareGroup(group, baseMap, getKey, false); } }); // 删除按钮 panel.querySelectorAll('.invBtn2').forEach(btn => { btn.onclick = function(e) { e.stopPropagation(); const idx = parseInt(this.getAttribute('data-idx')); showMwiConfirm('确定要删除该条库存历史记录吗?', function(ok){ if(!ok) return; arr.splice(idx, 1); localStorage.setItem(key, JSON.stringify(arr)); showInventoryHistory(); }); } }); } bindLeftColEvents(); // 右侧渲染函数 function renderRight(idx) { selectedIdx = idx; let rightHtml = ''; const items = arr[selectedIdx].items; // 分类分组 const group = {}; items.forEach(item => { const cat = item.category || '未分类'; if(!group[cat]) group[cat] = []; group[cat].push(item); }); for(const cat in group) { rightHtml += `
${cat}
    `; group[cat].forEach(item => { rightHtml += `
  • `; if(item.icon_url) { rightHtml += ``; } // 强化等级左上角 if(item.enhance) { rightHtml += `${item.enhance}`; } rightHtml += `${formatNumberSmartUnit(item.qty)}
  • `; }); rightHtml += '
'; } panel.querySelector('#invHistoryRightCol').innerHTML = rightHtml; setPanelSize(); // 渲染后立即自适应 } // 默认渲染最新一条 // renderRight(0); // 不再默认渲染右侧 setPanelSize(); // 内容生成后立即自适应 // 默认高亮最新一条 // panel.querySelectorAll('.invTimeBtn')[0].style.background = '#444'; // 注释掉 // panel.querySelectorAll('.invTimeBtn')[0].style.borderRadius = '4px'; // 注释掉 // 绑定按钮1对比功能 let lastCompareData = null; // 存储上次对比渲染的分组和diff panel.querySelectorAll('.invBtn1').forEach(btn => { btn.onclick = function(e) { e.stopPropagation(); const idx = parseInt(this.getAttribute('data-idx')); // 当前右侧显示的selectedIdx const curIdx = selectedIdx; if(idx === curIdx) return; // 对比自己无意义 const baseItems = arr[idx].items; const curItems = arr[curIdx].items; // 以物品名+分类为key(不含强化) const getKey = item => (item.name||'')+'|'+(item.category||''); // 构建分组:同名同类不同强化的物品分别统计 function groupByEnhance(items) { const map = {}; items.forEach(item => { const k = (item.name||'')+'|'+(item.category||'')+'|'+(item.enhance||''); if (!map[k]) map[k] = { ...item }; else map[k].qty += item.qty; }); return Object.values(map); } const baseMap = {}; groupByEnhance(baseItems).forEach(item=>{ baseMap[getKey(item)+(item.enhance||'')] = item; }); const curMap = {}; groupByEnhance(curItems).forEach(item=>{ curMap[getKey(item)+(item.enhance||'')] = item; }); // 分类分组(先用当前的) const group = {}; groupByEnhance(curItems).forEach(item => { const cat = item.category || '未分类'; if(!group[cat]) group[cat] = []; group[cat].push(item); }); // 把历史有但当前没有的物品也加进去 groupByEnhance(baseItems).forEach(item => { const key = getKey(item)+(item.enhance||''); if(!curMap[key]){ const cat = item.category || '未分类'; if(!group[cat]) group[cat] = []; // 构造一个qty为0的当前物品,icon等用历史的 group[cat].push({ name: item.name, category: item.category, icon_url: item.icon_url, qty: 0, enhance: item.enhance, _baseQty: item.qty // 方便后面diff }); } }); // 记录本次对比分组和diff lastCompareData = { group, baseMap, getKey }; // 渲染 renderCompareGroup(group, baseMap, getKey, false); } }); // 渲染对比分组的函数,支持只显示有变动的物品 function renderCompareGroup(group, baseMap, getKey, onlyChanged) { let rightHtml = ''; for(const cat in group) { let items = group[cat]; if(onlyChanged) { items = items.filter(item => { const baseQty = (baseMap[getKey(item)+(item.enhance||'')] && baseMap[getKey(item)+(item.enhance||'')].qty) || 0; const diff = (item.qty||0) - baseQty; return diff !== 0; }); if(items.length === 0) continue; } rightHtml += `
${cat}
    `; items.forEach(item => { rightHtml += `
  • `; if(item.icon_url) { rightHtml += ``; } // 强化等级左上角 if(item.enhance) { rightHtml += `${item.enhance}`; } // 数量 rightHtml += `${formatNumberSmartUnit(item.qty)}`; // 对比增减 const baseQty = (baseMap[getKey(item)+(item.enhance||'')] && baseMap[getKey(item)+(item.enhance||'')].qty) || 0; const diff = (item.qty||0) - baseQty; if(diff!==0){ rightHtml += `${diff>0?'+':''}${formatNumberSmartUnit(diff)}`; } rightHtml += `
  • `; }); rightHtml += '
'; } panel.querySelector('#invHistoryRightCol').innerHTML = rightHtml; setPanelSize(); // 渲染后立即自适应 } // 绑定"显示变动物品"按钮功能 const showChangedBtn = document.getElementById('showChangedItemsBtn'); let onlyShowChanged = false; showChangedBtn.onclick = function() { if(!lastCompareData) return; onlyShowChanged = !onlyShowChanged; renderCompareGroup(lastCompareData.group, lastCompareData.baseMap, lastCompareData.getKey, onlyShowChanged); showChangedBtn.textContent = onlyShowChanged ? '显示全部物品' : '显示变动物品'; }; // 绑定删除按钮功能 panel.querySelectorAll('.invBtn2').forEach(btn => { btn.onclick = function(e) { e.stopPropagation(); const idx = parseInt(this.getAttribute('data-idx')); showMwiConfirm('确定要删除该条库存历史记录吗?', function(ok){ if(!ok) return; arr.splice(idx, 1); localStorage.setItem(key, JSON.stringify(arr)); showInventoryHistory(); }); } }); // 绑定"记录当前库存"按钮功能 document.getElementById('recordCurrentInventoryBtn').onclick = function() { // 只在此处保存库存 const items = getInventoryItems(); if(!items || items.length===0){ showMwiTip('未检测到背包物品', false); return; } showMwiTip('已记录当前库存!', true); showInventoryHistory(); }; // 内部弹窗提示函数 function showMwiTip(msg, success) { let tip = document.createElement('div'); tip.style.position = 'fixed'; tip.style.left = '50%'; tip.style.top = '18%'; tip.style.transform = 'translateX(-50%)'; tip.style.background = 'rgba(60,60,60,0.85)'; tip.style.color = '#fff'; tip.style.fontSize = '18px'; tip.style.padding = '18px 36px'; tip.style.borderRadius = '10px'; tip.style.zIndex = 100000; tip.style.boxShadow = '0 2px 12px rgba(0,0,0,0.18)'; tip.style.textAlign = 'center'; tip.textContent = msg; if(success) tip.style.border = '2px solid #28a745'; else tip.style.border = '2px solid #d33'; document.body.appendChild(tip); setTimeout(()=>{ tip.remove(); }, 1000); } // 游戏内弹窗确认函数 function showMwiConfirm(msg, callback) { let tip = document.createElement('div'); tip.style.position = 'fixed'; tip.style.left = '50%'; tip.style.top = '22%'; tip.style.transform = 'translateX(-50%)'; tip.style.background = 'rgba(60,60,60,0.92)'; tip.style.color = '#fff'; tip.style.fontSize = '18px'; tip.style.padding = '18px 36px'; tip.style.borderRadius = '10px'; tip.style.zIndex = 100000; tip.style.boxShadow = '0 2px 12px rgba(0,0,0,0.18)'; tip.style.textAlign = 'center'; tip.style.border = '2px solid #d33'; tip.innerHTML = `
${msg}
`; document.body.appendChild(tip); document.getElementById('mwiConfirmYes').onclick = function(){ tip.remove(); callback(true); }; document.getElementById('mwiConfirmNo').onclick = function(){ tip.remove(); callback(false); }; } } // 在"显示净资产记录"按钮左侧添加"显示库存记录"按钮 function createShowInventoryHistoryButton() { const netBtn = document.getElementById('showNetWorthBtn'); if (!netBtn || document.getElementById('showInventoryHistoryBtn')) return; // 按钮加载时保存一次库存 getInventoryItems(); const btn = document.createElement('button'); btn.id = 'showInventoryHistoryBtn'; btn.textContent = '显示库存记录'; btn.style.marginRight = '8px'; btn.style.background = 'rgb(69,71,113)'; btn.style.color = '#fff'; btn.style.border = 'none'; btn.style.borderRadius = '4px'; btn.style.padding = '4px 10px'; btn.onclick = function() { getInventoryItems(); // 点击时保存一次库存 showInventoryHistory(); }; netBtn.parentNode.insertBefore(btn, netBtn); } // 监听净资产按钮生成后插入库存按钮 if (typeof observerInvBtn === 'undefined') { var observerInvBtn = new MutationObserver(() => { createShowInventoryHistoryButton(); }); observerInvBtn.observe(document.body, { childList: true, subtree: true }); } // 自动弹出设置面板(仅脚本更新后第一次) setTimeout(() => { if (localStorage.getItem('mwiSettingPanelLastVersion') !== MWI_SCRIPT_VERSION) { showSettingPanel(); } }, 1200); // Tampermonkey菜单始终注册"设置"按钮 if (typeof GM_registerMenuCommand !== 'undefined') { setTimeout(() => { GM_registerMenuCommand('设置', showSettingPanel); }, 1000); } // 监听人数元素出现并有数字后,延迟3秒再执行相关操作(包括自动读取背包物品) let lastInitUrl = location.href; let playerCountInitObserver = null; function waitForPlayerCountAndInit() { if(playerCountInitObserver) playerCountInitObserver.disconnect(); let inited = false; playerCountInitObserver = new MutationObserver(() => { const el = document.querySelector('div.Header_playerCount__1TDTK'); if (el) { const number = parseInt(el.textContent.replace(/\D/g, ''), 10); if (!isNaN(number) && !inited) { inited = true; setTimeout(() => { if(localStorage.getItem('mwiMonitorPlayer') !== 'false') savePlayerNumber(); if(localStorage.getItem('mwiMonitorNetWorth') === 'true') saveNetWorth(); // createShowButton(); // 删除自动调用 // createShowNetWorthButton(); // 删除自动调用 // getInventoryItems(); // 删除自动调用 }, 3000); playerCountInitObserver.disconnect(); } } }); playerCountInitObserver.observe(document.body, { childList: true, subtree: true }); } waitForPlayerCountAndInit(); // 监听网址变化 function onUrlChangeForPlayerCountInit() { if(location.href !== lastInitUrl) { lastInitUrl = location.href; waitForPlayerCountAndInit(); waitForNetWorthAndShowBtns(); // 新增:切换账号后自动重建按钮 } } window.addEventListener('popstate', onUrlChangeForPlayerCountInit); window.addEventListener('hashchange', onUrlChangeForPlayerCountInit); // 兼容部分SPA主动pushState let oldPushState = history.pushState; history.pushState = function() { oldPushState.apply(this, arguments); setTimeout(onUrlChangeForPlayerCountInit, 10); }; // 在"显示净资产记录"按钮旁显示前一天最大净资产和当前差值 function showNetWorthDayCompare() { const btn = document.getElementById('showNetWorthBtn'); if (!btn || document.getElementById('netWorthDayCompare')) return; const key = 'networth_' + getNetWorthKey(); let arr = []; try { arr = JSON.parse(localStorage.getItem(key) || '[]'); if (!Array.isArray(arr)) arr = []; } catch(e) { arr = []; } if(arr.length < 2) return; const now = new Date(); const today0 = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0, 0).getTime(); const prevDayStart = today0 - 24 * 60 * 60 * 1000; const prevDayEnd = today0; const prevDayArr = arr.filter(item => { const t = new Date(item.time).getTime(); return t >= prevDayStart && t < prevDayEnd && item.number; }); if(prevDayArr.length === 0) return; const maxPrevDay = Math.max(...prevDayArr.map(item => item.number)); const latest = arr[arr.length-1].number; const diff = latest - maxPrevDay; // 格式化 const maxPrevDayStr = formatNumberToM(maxPrevDay); const diffStr = (diff>=0?'+':'') + formatNumberToM(diff); // 插入元素 const span = document.createElement('span'); span.id = 'netWorthDayCompare'; span.style.marginLeft = '12px'; span.style.fontSize = '13px'; span.style.color = diff>=0 ? '#28a745' : '#d33'; span.textContent = `前一天最大值:${maxPrevDayStr} 当前差值:${diffStr}`; btn.parentNode.insertBefore(span, btn.nextSibling); } })();