您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Check and notify on https://idleontoolbox.com/dashboard with Telegram support
当前为
- // ==UserScript==
- // @name Idleontoolbox Produce Check
- // @namespace http://tampermonkey.net/
- // @version 10.0
- // @description Check and notify on https://idleontoolbox.com/dashboard with Telegram support
- // @author Tiande
- // @match https://idleontoolbox.com/*
- // @grant GM_notification
- // @grant GM_getValue
- // @grant GM_setValue
- // @license MIT
- // ==/UserScript==
- (function() {
- 'use strict';
- var interval = 10 * 60 * 1000; // check status every 5m
- //var interval = 5000 // USE FOR TEST
- var refreshInterval = 8.01 * 60 * 60 * 1000; // auto refresh to Dashboard every 10m
- // Telegram Bot API Token
- var tgbotToken = 'YOUR BOT TOKEN';
- // Telegram user ID to send the message to
- var tguserId = 'YOUR USER ID';
- // CHECK 1: lable text under player's name
- var whichFull = /(production is full|\s[1-5]\sminute)/i; // (worship is full|is full|being full|can equip sth|missing a trap|Crystal CD for Alchemy is 0.00%) etc.
- // CHECK 2: skill to notify
- var skill = /(Refinery000)/i; // (|printer|taste|cranium cooking|Arena|Birthday|Refinery) etc.
- // CHECK 3: bookcount to check
- var bookcount = 999;
- // CHECK 4: AFKTime notify
- var AFKHour = 999;
- var AFKMin = 30;
- // CHECK 5: banner notify. Must use img src
- var bannerRegex = /(blablabla)/i; //img-src
- var bannerLabelRegex = /(crops ready|Equinox bar is full|Max ball capacity has reached)/i; //aria-label |ready to be built|plots reached the threshold|squirrel|shovel|fisheroo Reset|feather restart|
- // exclude 3d printer circle check、happyhour、fishg etc.
- var excludeKeyword = /(printer|happy|building|fisheroo|feather|catch|trap|salt)/i; //
- // worship overflow, pet
- var worship = 'Overflowing charge'; // edit as "Overflowing charge" for notify.
- var pet = 'Go claim!';
- var notificationPermission = GM_getValue('notificationPermission');
- var isFunctionEnabled = true;
- var intervalId; // Store interval ID for pausing and resuming
- // tg send
- function tgsendMessage(message) {
- var tgurl = 'https://api.telegram.org/bot' + tgbotToken + '/sendMessage';
- var tgparams = 'chat_id=' + tguserId + '&text=' + encodeURIComponent(message);
- var tgxhr = new XMLHttpRequest();
- tgxhr.open('POST', tgurl, true);
- tgxhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
- tgxhr.onreadystatechange = function() {
- if (tgxhr.readyState == 4 && tgxhr.status == 200) {
- console.log('Message sent successfully!');
- }
- };
- tgxhr.onerror = function(error) {
- console.error('Error sending message:', error);
- };
- tgxhr.send(tgparams);
- }
- // autorefresh time
- var refreshId;
- // refreshPage
- function refreshPage() {
- if (isFunctionEnabled) {
- location.href = 'https://idleontoolbox.com/dashboard'; // 刷新页面到 dashboard
- } else {
- // 如果不是,则等待下一个刷新时间间隔
- refreshId = setInterval(refreshPage, refreshInterval);
- }
- }
- function toggleRefresh() {
- if (isFunctionEnabled) {
- intervalId = setInterval(startInterval, interval); // 启动定时器
- refreshId = setInterval(refreshPage, refreshInterval);
- } else {
- clearInterval(intervalId); // 清除定时器
- clearInterval(refreshId);
- }
- }
- toggleRefresh(); // 在脚本启动时调用一次,以确保定时器已启动
- // Preload audio
- var audio = new Audio();
- audio.src = 'https://github.com/Tiande/IdelonCheck/raw/main/iphonewake.wav';
- // Add CSS styles
- var style = document.createElement('style');
- style.innerHTML = `
- #toggleButtonContainer {
- position: fixed;
- top: 50%;
- left: calc(50% + 100px);
- transform: translate(-50%, -50%);
- display: flex;
- align-items: center;
- padding: 5px;
- background: green; /* Green color for default enabled state */
- color: white;
- border-radius: 5px;
- font-family: Arial, sans-serif;
- font-size: 14px;
- box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.3);
- z-index: 99999;
- user-select: none;
- cursor: move;
- }
- #toggleButtonContainer.off {
- background: red; /* Red color for disabled state */
- }
- #toggleButton {
- padding: 5px 10px;
- border: none;
- border-radius: 5px;
- background: transparent;
- cursor: pointer;
- outline: none;
- }
- .drag-handle {
- cursor: move;
- }
- #produceCheck {
- background-color: black;
- color: white;
- padding: 5px;
- border-radius: 5px;
- margin-right: 5px;
- }
- `;
- document.head.appendChild(style);
- createToggleButton(); // Create toggle button on script execution
- startInterval(); // Start interval on script execution
- function createToggleButton() {
- var toggleButtonContainer = document.createElement('div');
- toggleButtonContainer.id = 'toggleButtonContainer';
- toggleButtonContainer.classList.add('drag-handle');
- var produceCheck = document.createElement('span');
- produceCheck.id = 'produceCheck';
- produceCheck.textContent = 'Produce Check: ';
- toggleButtonContainer.appendChild(produceCheck);
- var toggleButton = document.createElement('button');
- toggleButton.id = 'toggleButton';
- toggleButton.addEventListener('click', toggleFunction);
- toggleButtonContainer.appendChild(toggleButton);
- document.body.appendChild(toggleButtonContainer);
- updateButtonStyle();
- makeDraggable(toggleButtonContainer);
- }
- function updateButtonStyle() {
- var toggleButtonContainer = document.getElementById('toggleButtonContainer');
- toggleButtonContainer.classList.toggle('off', !isFunctionEnabled);
- var toggleButton = document.getElementById('toggleButton');
- toggleButton.innerHTML = isFunctionEnabled ? 'ON': 'OFF';
- }
- function toggleFunction() {
- isFunctionEnabled = !isFunctionEnabled;
- updateButtonStyle();
- toggleRefresh(); // 根据isFunctionEnabled的值启用或暂停定时器
- }
- function startInterval() {
- // sth is full
- var matchedText = '';
- var prepareelements = document.querySelectorAll('img[aria-label]');
- var elements = Array.from(prepareelements).filter(function(element) {
- var ariaLabel = element.getAttribute('aria-label');
- var matched = ariaLabel.match(whichFull);
- if (matched !== null) {
- // 如果匹配到了,则将匹配项拼接到 matchedText 中
- matchedText += matched[0];
- // 如果还有下一个匹配项,则添加 '&'
- if (matched.index !== whichFull.lastIndex - matched[0].length) {
- matchedText += '&';
- }
- }
- // 返回原有的条件
- return whichFull.test(ariaLabel);
- });
- if (elements.length > 0) {
- var messages = [];
- elements.forEach(function(element) {
- var parentDiv = element.closest('.MuiCardContent-root');
- if (parentDiv) {
- var roleNameElement = parentDiv.querySelector('.MuiTypography-root.MuiTypography-body1.css-9l3uo3');
- if (roleNameElement) {
- var roleName = roleNameElement.textContent.trim();
- var matchedText = ''; // 重新初始化 matchedText
- var matched = element.getAttribute('aria-label').match(whichFull);
- if (matched !== null) {
- matchedText = matched[0]; // 获取匹配文本
- }
- messages.push(roleName + ' : ' + matchedText);
- }
- }
- });
- if (messages.length > 0) {
- var message = messages.join(', ');
- showNotification(message);
- audio.play();
- if (tguserId !== 'your user ID') {
- tgsendMessage(message);
- }
- }
- }
- // skill is ready
- var matchedText = '';
- var prepareelements = document.querySelectorAll('img[aria-label]');
- var elements = Array.from(prepareelements).filter(function(element) {
- var ariaLabel = element.getAttribute('aria-label');
- var matched = ariaLabel.match(skill);
- if (matched !== null) {
- // 如果匹配到了,则将匹配项拼接到 matchedText 中
- matchedText += matched[0];
- // 如果还有下一个匹配项,则添加 '&'
- if (matched.index !== skill.lastIndex - matched[0].length) {
- matchedText += '&';
- }
- }
- // 返回原有的条件
- return skill.test(ariaLabel);
- });
- if (elements.length > 0) {
- var messages = [];
- elements.forEach(function(element) {
- var parentDiv = element.closest('.MuiCardContent-root');
- if (parentDiv) {
- var roleNameElement = parentDiv.querySelector('.MuiTypography-root.MuiTypography-body1.css-9l3uo3');
- if (roleNameElement) {
- var roleName = roleNameElement.textContent.trim();
- var matchedText = ''; // 重新初始化 matchedText
- var matched = element.getAttribute('aria-label').match(skill);
- if (matched !== null) {
- matchedText = matched[0]; // 获取匹配文本
- }
- messages.push(roleName + ' : ' + matchedText);
- }
- }
- });
- if (messages.length > 0) {
- var message = messages.join(', ');
- showNotification(message);
- audio.play();
- if (tguserId !== 'your user ID') {
- tgsendMessage(message);
- }
- }
- }
- // 追踪另一组元素 constuction trap
- var timeElements = document.querySelectorAll('.MuiTypography-root.MuiTypography-inherit');
- var trackedContents = [];
- timeElements.forEach(function(timeElement) {
- var color = getComputedStyle(timeElement).color;
- var matchColor = color.match(/^rgb\((\d+), (\d+), (\d+)\)$/);
- var textContent = timeElement.textContent || '';
- // Check for the color condition or the presence of '-1d' in the text content
- if ((matchColor && matchColor[1] === '249' && matchColor[2] === '29' && matchColor[3] === '29') || textContent.includes('-1d')) {
- //if ((matchColor && matchColor[1] === '999' && matchColor[2] === '999' && matchColor[3] === '999') || textContent.includes('999d')) {
- var parentElement = timeElement.closest('.MuiStack-root');
- if (parentElement && parentElement.getAttribute('aria-label')) {
- var ariaLabel = parentElement.getAttribute('aria-label');
- var splitIndex = ariaLabel.indexOf(':');
- if (splitIndex !== -1) {
- var content = ariaLabel.substring(0, splitIndex).trim(); // Get content before ':' and trim spaces
- // Ensure the content does not include the excludeKeyword
- if (!new RegExp(excludeKeyword).test(content)) {
- trackedContents.push(content);
- }
- }
- }
- }
- });
- if (trackedContents.length > 0) {
- var message = trackedContents.join(', '); // 将数组内容连接成字符串,以逗号分隔
- showNotification(message);
- audio.play();
- if (tguserId !== 'your user ID') {
- tgsendMessage(message + ' is finished.');
- }
- }
- // 追踪另一组元素 worship pet
- var timeElements = document.querySelectorAll('.MuiTypography-root.MuiTypography-body1');
- var trackedContents = [];
- timeElements.forEach(function(timeElement) {
- var color = getComputedStyle(timeElement).color;
- var textContent = timeElement.textContent || '';
- if (textContent.includes(worship) || textContent.includes(pet)) {
- var parentElement = timeElement.closest('.MuiStack-root');
- if (parentElement && parentElement.getAttribute('aria-label')) {
- var ariaLabel = parentElement.getAttribute('aria-label');
- var splitIndex = ariaLabel.indexOf(':');
- if (splitIndex !== -1) {
- var content = ariaLabel.substring(0, splitIndex).trim(); // Get content before ':' and trim spaces
- // Ensure the content does not include the excludeKeyword
- if (!new RegExp(excludeKeyword).test(content)) {
- trackedContents.push(content);
- }
- }
- }
- }
- });
- if (trackedContents.length > 0) {
- var message = trackedContents.join(', '); // 将数组内容连接成字符串,以逗号分隔
- showNotification(message);
- audio.play();
- if (tguserId !== 'your user ID') {
- tgsendMessage(message + ' is finished.');
- }
- }
- // Book count
- var bookCountElements = document.querySelectorAll('.MuiCardContent-root h4');
- // 遍历每个 <h4> 元素
- bookCountElements.forEach(function(element) {
- // 获取文本内容
- var text = element.textContent.trim();
- // 提取数字部分
- var count = parseInt(text.match(/\d+/)[0]);
- // 如果数字大于等于2,则发送通知
- if (count >= bookcount) {
- // 发送通知
- var message = 'The book count has exceeded the limit!';
- showNotification(message);
- audio.play();
- if (tguserId !== 'your user ID') {
- tgsendMessage(message);
- }
- }
- });
- // 追踪另一组元素 AFKTime
- var timeElements = document.querySelectorAll('.MuiTypography-root.MuiTypography-caption.css-deomsi');
- timeElements.forEach(function(timeElement) {
- var parentElement = timeElement.closest('.MuiStack-root');
- if (parentElement) {
- var resetTextElement = parentElement.querySelector('.MuiTypography-body1');
- if (resetTextElement) {
- var resetText = resetTextElement.textContent.trim();
- // 排除含有 Daily Reset 和 Weekly Reset 的模块内容
- if (resetText !== 'Daily Reset' && resetText !== 'Weekly Reset') {
- var timeText = timeElement.textContent.trim();
- var match = timeText.match(/^(\d+)h:(\d+)m:(\d+)s$|^(\d+)d:(\d+)h:(\d+)m$/);
- if (match) {
- var days = match[4] ? parseInt(match[4], 10) : 0;
- var hours = match[1] ? parseInt(match[1], 10) : parseInt(match[2], 10);
- var minutes = match[2] ? parseInt(match[2], 10) : parseInt(match[5], 10);
- var seconds = match[3] ? parseInt(match[3], 10) : parseInt(match[6], 10);
- // 转换成统一的格式
- hours += days * 24;
- if (hours >= AFKHour && minutes >= AFKMin) {
- showNotification(timeText);
- audio.play();
- if (tguserId !== 'your user ID') {
- tgsendMessage(timeText + ' is finished.');
- }
- }
- }
- }
- }
- }
- });
- //check top banner
- var images = document.querySelectorAll('div.css-1eybjch > div.css-79elbk > img'); // 获取页面上所有的img元素
- var matchedImages = Array.from(images).filter(function(image) {
- return bannerRegex.test(image.src); // 测试每个图片的src属性是否匹配正则表达式
- });
- // 遍历匹配到正则的img元素并执行相应的操作
- if (matchedImages.length > 0) {
- var messages = [];
- matchedImages.forEach(function(image) {
- var src = image.src;
- var matchedText = src.match(bannerRegex)[0]; // 获取匹配文本
- messages.push(matchedText); // 将匹配的文本收集起来
- });
- // 将所有匹配的结果合并成一条消息并显示出来
- var message = messages.join(' ');
- showNotification(message);
- audio.play();
- if (tguserId !== 'your user ID') {
- tgsendMessage('Banner check: ' + message);
- }
- }
- // 追踪另一组元素 banner salt garden (aria-label)
- var timeElements = document.querySelectorAll('.MuiStack-root.css-18jqfyr');
- var trackedContents = [];
- timeElements.forEach(function(timeElement) {
- var ariaLabel = timeElement.getAttribute('aria-label');
- var matchResult = bannerLabelRegex.exec(ariaLabel);
- if (ariaLabel && matchResult) {
- var matchedText = matchResult[0]; // 获取匹配到的具体内容
- trackedContents.push(matchedText);
- }
- });
- if (trackedContents.length > 0) {
- var message = trackedContents.join(', '); // 将数组内容连接成字符串,以逗号分隔
- showNotification(message);
- audio.play();
- if (tguserId !== 'your user ID') {
- tgsendMessage(message);
- }
- }
- }//All func end
- function showNotification(message) {
- if (notificationPermission === 'granted') {
- GM_notification({
- text: message,
- title: 'Idleontoolbox Notification',
- timeout: 5000,
- onclick: function() {
- window.focus();
- }
- });
- } else {
- window.Notification.requestPermission().then(function(permission) {
- if (permission === 'granted') {
- GM_notification({
- text: message,
- title: 'Idleontoolbox Notification',
- timeout: 5000,
- onclick: function() {
- window.focus();
- }
- });
- }
- });
- }
- }
- function makeDraggable(element) {
- let pos1 = 0,
- pos2 = 0,
- pos3 = 0,
- pos4 = 0;
- element.onmousedown = dragMouseDown;
- function dragMouseDown(e) {
- e = e || window.event;
- e.preventDefault();
- // get the mouse cursor position at startup:
- pos3 = e.clientX;
- pos4 = e.clientY;
- document.onmouseup = closeDragElement;
- // call a function whenever the cursor moves:
- document.onmousemove = elementDrag;
- }
- function elementDrag(e) {
- e = e || window.event;
- e.preventDefault();
- // calculate the new cursor position:
- pos1 = pos3 - e.clientX;
- pos2 = pos4 - e.clientY;
- pos3 = e.clientX;
- pos4 = e.clientY;
- // set the element's new position:
- element.style.top = (element.offsetTop - pos2) + "px";
- element.style.left = (element.offsetLeft - pos1) + "px";
- }
- function closeDragElement() {
- /* stop moving when mouse button is released:*/
- document.onmouseup = null;
- document.onmousemove = null;
- }
- }
- })();