// ==UserScript==
// @name [MWI]personal use
// @name:zh-CN [银河奶牛]自用脚本
// @namespace http://tampermonkey.net/
// @version 0.1.8
// @description 个人脚本,适用于 Milky Way Idle 游戏
// @description:zh-CN 个人专用脚本,适用于 Milky Way Idle 游戏
// @author deric
// @license MIT
// @match https://www.milkywayidle.com/game*
// @grant GM_registerMenuCommand
// ==/UserScript==
(function() {
'use strict';
const MWI_SCRIPT_VERSION = '0.1.7';
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 = `<div style='text-align:right;'><button id='closeMwiSettingPopup'>关闭</button></div><h3 style='margin:8px 0 16px 0;'>设置</h3>
<div style='margin-bottom:12px;'>
<label><input type='checkbox' id='mwiMonitorPlayer'/> 是否启动监控人数</label>
</div>
<div style='margin-bottom:12px;'>
<label><input type='checkbox' id='mwiMonitorNetWorth'/> 是否启动监控净资产</label>
</div>
<div style='margin-bottom:12px;'>
<label><input type='checkbox' id='mwiShowOrderTotalValue'/> 是否显示订单总价</label>
</div>
<div style='color:#888;font-size:12px;'>设置会自动保存</div>`;
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);
localStorage.setItem(key, JSON.stringify(arr));
}
// 修改按钮显示逻辑,支持显示多条记录
function createShowButton() {
// 判断设置
if (localStorage.getItem('mwiMonitorPlayer') === 'false') return;
const 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 || 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 = '<div style="margin-bottom:8px;">';
for(const d of ranges){
rangeBtns += `<button class='rangeBtn' data-days='${d}' style='margin-right:4px;'>${d}天</button>`;
}
rangeBtns += '</div>';
// 生成折线图HTML
let html = rangeBtns;
html += `<button id='managePlayerNumberBtn' style='margin-bottom:8px;'>管理</button>`;
html += `<div id='chartContainer'></div>`;
html += `<div id='managePlayerNumberPanel' style='display:none;margin-top:12px;background:#fff;'></div>`;
// 网页内部弹窗
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 = 'white';
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 = `<div style='text-align:right;'><button id='closePlayerNumberPopup'>关闭</button></div>${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 = `<button id='clearAllPlayerNumber' style='color:red;margin-bottom:8px;'>全部清空</button><br/>`;
html += '<ul style="max-height:200px;overflow:auto;padding-left:0;">';
arr.forEach((item,idx)=>{
html += `<li style='list-style:none;margin-bottom:4px;'>${item.time.replace('T',' ').slice(0,16)} - ${item.number} <button data-idx='${idx}' class='delPlayerNumberBtn' style='color:red;'>删除</button></li>`;
});
html += '</ul>';
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));
renderManagePanel();
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 = `<canvas id='playerNumberChart' width='500' height='300' style='display:block;'></canvas>`;
}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 labels;
if(days <= 3){
labels = times.map(t => `${t.getHours()}:` + (t.getMinutes()<10?`0${t.getMinutes()}`:t.getMinutes()));
}else{
labels = times.map(t => `${t.getMonth()+1}-${t.getDate()}`);
}
// 纵坐标范围,增加上下边距
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';
// 横坐标等比例
const minTime = times[0].getTime();
const maxTime = times[times.length-1].getTime();
const timeSpan = maxTime - minTime || 1;
// 绘制坐标轴
ctx.strokeStyle = '#333';
ctx.beginPath();
ctx.moveTo(padding, padding);
ctx.lineTo(padding, padding + h);
ctx.lineTo(padding + w, padding + h);
ctx.stroke();
// Y轴刻度
ctx.fillStyle = '#333';
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(val, 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';
for(let i=0;i<times.length;i++){
const t = times[i].getTime();
const x = padding + w*(t-minTime)/timeSpan;
ctx.fillStyle = '#333';
// 只显示首、尾、每隔5个点的标签,避免重叠
if(i===0 || i===times.length-1 || (times.length>10 && i%5===0)){
ctx.fillText(labels[i], x, padding+h+5);
}
}
// 折线(等比例)
ctx.strokeStyle = '#007bff';
ctx.beginPath();
for(let i=0;i<numbers.length;i++){
const t = times[i].getTime();
const x = padding + w*(t-minTime)/timeSpan;
const y = padding + h - h*(numbers[i]-minY)/(maxY-minY||1);
if(i===0) ctx.moveTo(x, y);
else ctx.lineTo(x, y);
}
ctx.stroke();
// 点(等比例)
ctx.fillStyle = '#007bff';
for(let i=0;i<numbers.length;i++){
const t = times[i].getTime();
const x = padding + w*(t-minTime)/timeSpan;
const y = padding + h - h*(numbers[i]-minY)/(maxY-minY||1);
ctx.beginPath();
ctx.arc(x, y, 3, 0, 2*Math.PI);
ctx.fill();
}
}, 0);
}
// 默认绘制1天
drawChart(rangeDays);
// 按钮事件
popup.querySelectorAll('.rangeBtn').forEach(btn => {
btn.onclick = function(){
const days = parseInt(this.getAttribute('data-days'));
localStorage.setItem('mwiPlayerNumberRangeDays', days);
drawChart(days);
highlightRangeBtn(days);
};
});
};
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 = '<div style="margin-bottom:8px;">';
for(const d of ranges){
rangeBtns += `<button class='rangeBtnNet' data-days='${d}' style='margin-right:4px;'>${d}天</button>`;
}
rangeBtns += '</div>';
// 生成折线图HTML
let html = rangeBtns;
html += `<button id='manageNetWorthBtn' style='margin-bottom:8px;'>管理</button>`;
html += `<div id='chartNetContainer'></div>`;
html += `<div id='manageNetWorthPanel' style='display:none;margin-top:12px;background:#fff;'></div>`;
// 网页内部弹窗
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 = 'white';
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 = `<div style='text-align:right;'><button id='closeNetWorthPopup'>关闭</button></div><h4 style='margin:8px 0 16px 0;'>净资产记录</h4>${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 = `<button id='clearAllNetWorth' style='color:red;margin-bottom:8px;'>全部清空</button><br/>`;
html += '<ul style="max-height:200px;overflow:auto;padding-left:0;">';
arr.forEach((item,idx)=>{
html += `<li style='list-style:none;margin-bottom:4px;'>${item.time.replace('T',' ').slice(0,16)} - ${Math.round(item.number/1e6)}M <button data-idx='${idx}' class='delNetWorthBtn' style='color:red;'>删除</button></li>`;
});
html += '</ul>';
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 = `<canvas id='netWorthChart' width='550' height='320' style='display:block;'></canvas>`;
}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 labels;
if(days <= 3){
labels = times.map(t => `${t.getHours()}:` + (t.getMinutes()<10?`0${t.getMinutes()}`:t.getMinutes()));
}else{
labels = times.map(t => `${t.getMonth()+1}-${t.getDate()}`);
}
// 纵坐标范围,增加上下边距
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';
// 横坐标等比例
const minTime = times[0].getTime();
const maxTime = times[times.length-1].getTime();
const timeSpan = maxTime - minTime || 1;
// 绘制坐标轴
ctx.strokeStyle = '#333';
ctx.beginPath();
ctx.moveTo(padding, padding);
ctx.lineTo(padding, padding + h);
ctx.lineTo(padding + w, padding + h);
ctx.stroke();
// Y轴刻度
ctx.fillStyle = '#333';
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';
for(let i=0;i<times.length;i++){
const t = times[i].getTime();
const x = padding + w*(t-minTime)/timeSpan;
ctx.fillStyle = '#333';
// 只显示首、尾、每隔5个点的标签,避免重叠
if(i===0 || i===times.length-1 || (times.length>10 && i%5===0)){
ctx.fillText(labels[i], x, padding+h+5);
}
}
// 折线(等比例)
ctx.strokeStyle = '#28a745';
ctx.beginPath();
for(let i=0;i<numbers.length;i++){
const t = times[i].getTime();
const x = padding + w*(t-minTime)/timeSpan;
const y = padding + h - h*(numbers[i]-minY)/(maxY-minY||1);
if(i===0) ctx.moveTo(x, y);
else ctx.lineTo(x, y);
}
ctx.stroke();
// 点(等比例)
ctx.fillStyle = '#28a745';
for(let i=0;i<numbers.length;i++){
const t = times[i].getTime();
const x = padding + w*(t-minTime)/timeSpan;
const y = padding + h - h*(numbers[i]-minY)/(maxY-minY||1);
ctx.beginPath();
ctx.arc(x, y, 3, 0, 2*Math.PI);
ctx.fill();
}
}, 0);
}
// 默认绘制1天
drawChart(rangeDays);
// 高亮当前按钮
function highlightRangeBtnNet(days) {
popup.querySelectorAll('.rangeBtnNet').forEach(btn => {
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);
}
// 工具函数:带单位字符串转数字
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) {
if (num >= 1e6) {
let n = num / 1e6;
return (n % 1 === 0 ? n : n.toFixed(1)) + 'M';
} 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);
}
});
}
// 修改定时器和延时调用,根据设置决定是否监控
setTimeout(() => {
if(localStorage.getItem('mwiMonitorPlayer') !== 'false') savePlayerNumber();
if(localStorage.getItem('mwiMonitorNetWorth') === 'true') saveNetWorth();
}, 5000);
setInterval(() => {
if(localStorage.getItem('mwiMonitorPlayer') !== 'false') savePlayerNumber();
if(localStorage.getItem('mwiMonitorNetWorth') === 'true') saveNetWorth();
}, 30 * 60 * 1000);
// 页面加载后添加按钮
window.addEventListener('DOMContentLoaded', () => {
createShowButton();
createShowNetWorthButton();
});
setTimeout(() => {
createShowButton();
createShowNetWorthButton();
}, 5000);
// 首次安装时默认开启所有功能
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 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?'+':'') + formatNumberWithUnit(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);
}
// 页面加载后和按钮生成后调用
setTimeout(() => {
showNetWorthDayCompare();
}, 5500);
// 监听按钮生成后再插入
const observerNetBtn = new MutationObserver(() => {
showNetWorthDayCompare();
});
observerNetBtn.observe(document.body, { childList: true, subtree: true });
// 自动弹出设置面板(仅脚本更新后第一次)
setTimeout(() => {
if (localStorage.getItem('mwiSettingPanelLastVersion') !== MWI_SCRIPT_VERSION) {
showSettingPanel();
}
}, 1200);
})();