您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
个人专用脚本,适用于 Milky Way Idle 游戏
当前为
// ==UserScript== // @name [MWI]personal use // @name:zh-CN [银河奶牛]自用脚本 // @namespace http://tampermonkey.net/ // @version 0.1.3 // @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'; // Tampermonkey插件管理界面显示“设置”按钮 if (typeof GM_registerMenuCommand !== 'undefined') { // 用setTimeout确保页面环境已加载 setTimeout(() => { GM_registerMenuCommand('设置', function() { // 网页内弹窗 try { 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='color:#888;font-size:12px;'>设置会自动保存</div>`; document.body.appendChild(popup); document.getElementById('closeMwiSettingPopup').onclick = function() { popup.remove(); }; // 初始化复选框状态 document.getElementById('mwiMonitorPlayer').checked = localStorage.getItem('mwiMonitorPlayer') !== 'false'; document.getElementById('mwiMonitorNetWorth').checked = localStorage.getItem('mwiMonitorNetWorth') === 'true'; // 监听变更 document.getElementById('mwiMonitorPlayer').onchange = function() { localStorage.setItem('mwiMonitorPlayer', this.checked); }; document.getElementById('mwiMonitorNetWorth').onchange = function() { localStorage.setItem('mwiMonitorNetWorth', this.checked); }; } catch(e) { alert('弹窗创建失败,请刷新页面重试!'); } }); }, 1000); } // 你的代码写在这里 function savePlayerNumber() { const el = document.querySelector('div.Header_playerCount__1TDTK'); if (!el) return; const number = parseInt(el.textContent.replace(/\D/g, ''), 10); 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; } 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.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 += `<div id='chartContainer'></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(); }; // 绘制折线图函数 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.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 += `<div id='chartNetContainer'></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(); }; // 绘制折线图函数 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); } // 修改定时器和延时调用,根据设置决定是否监控 setTimeout(() => { if(localStorage.getItem('mwiMonitorPlayer') !== 'false') savePlayerNumber(); if(localStorage.getItem('mwiMonitorNetWorth') === 'true') saveNetWorth(); }, 3000); setInterval(() => { if(localStorage.getItem('mwiMonitorPlayer') !== 'false') savePlayerNumber(); if(localStorage.getItem('mwiMonitorNetWorth') === 'true') saveNetWorth(); }, 30 * 60 * 1000); // 页面加载后添加按钮 window.addEventListener('DOMContentLoaded', () => { createShowButton(); createShowNetWorthButton(); }); setTimeout(() => { createShowButton(); createShowNetWorthButton(); }, 2000); // 首次安装时默认开启所有功能 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(); } }); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址