您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Twitch Auto Claim, Drop, change channel and auto track progress
当前为
// ==UserScript== // @name Twitch Drop bot // @namespace http://tampermonkey.net/ // @version 1.1 // @description Twitch Auto Claim, Drop, change channel and auto track progress // @author gig4d3v // @match https://www.twitch.tv/* // @icon https://www.google.com/s2/favicons?domain=mozilla.org // @grant none // @license GPLv3 // ==/UserScript== const claimBonusButton = '[aria-label="Claim Bonus"]'; const twitchLogo = '[aria-label="Twitch Home"]'; const dropNumber = 1; var allStreamersNickames = [ "GENERAL", "TWITCHRIVALS", "BUDDHA", "MENDO", "COCONUTB", "EROBB221", "DHALUCARD", "WILLJUM", "HJUNE", "DISGUISEDTOAST", "JLTOMY", "KROLAY", "PANPOTS", "ISVOLCANO", "POW3R", "KESI__", "WELYN", "ZCHUM", ]; var timeCheck = 1; var tempCurrentStreamer = ""; var tempStreamerList = []; const config = { attributes: true, childList: true, subtree: true }; const notification = document.createElement("div"); notification.style.cssText = "position:fixed;top:10px;right:10px;background:#f2f2f2;padding:10px;border:1px solid #ccc;border-radius:4px;z-index:9999;font-family:Arial;font-size:14px;display:flex;justify-content:center;align-items:center;color:black;"; const notificationText = document.createElement("p"); notificationText.innerText = "This is a notification!"; notificationText.style.cssText = "margin:0; color:black;"; const closeNotificationButton = document.createElement("button"); closeNotificationButton.innerText = "X"; closeNotificationButton.style.cssText = "width:30px;text-align:center;margin-left:10px;border:none;background:#ccc;padding:5px;border-radius:4px;cursor:pointer;"; closeNotificationButton.addEventListener("click", function () { notification.remove(); }); closeNotificationButton.addEventListener("mouseover", function () { closeNotificationButton.style.background = "#aaa"; }); closeNotificationButton.addEventListener("mouseout", function () { closeNotificationButton.style.background = "#ccc"; }); notification.appendChild(notificationText); notification.appendChild(closeNotificationButton); var nextStreamerButton = document.createElement("button"); nextStreamerButton.innerText = "Next Streamer"; nextStreamerButton.style.cssText = "position:fixed;bottom:10px;left:10px;border:none;background:#9147ff;padding:5px;border-radius:4px;cursor:pointer;color:#efeff1;height:57px;font-family:Roobert,Inter,Helvetica Neue,Helvetica,Arial,sans-serif;font-weight:600"; nextStreamerButton.addEventListener("click", function () { selectNextStreamer(); var currentStreamer = JSON.parse(localStorage.getItem("currentStreamer")); awokeNotification("Switched to " + currentStreamer, 3000); setTimeout(function () { notification.remove(); }, 3000); }); var changeStreamersButton = document.createElement("button"); changeStreamersButton.innerText = "Change Streamers"; changeStreamersButton.style.cssText = "position:fixed;bottom:10px;left:120px;border:none;background:#9147ff;padding:5px;border-radius:4px;cursor:pointer;color:#efeff1;height:57px;font-family:Roobert,Inter,Helvetica Neue,Helvetica,Arial,sans-serif;font-weight:600"; changeStreamersButton.addEventListener("click", function () { localStorage.setItem("streamerList", JSON.stringify([])); localStorage.setItem("currentStreamer", JSON.stringify("")); chooseStreamersNotification(); }); var statsBar = document.getElementById("statsBar"); statsBar = document.createElement("div"); statsBar.id = "statsBar"; statsBar.style.cssText = "display:flex;flex-direction:row;justify-content:center;align-items:center;padding: 10px 0;background:#18181B;box-shadow:0 1px 2px rgba(0,0,0,.9),0 0px 2px rgba(0,0,0,.9);"; function getClaimButton() { var xpathExpression = "//div[text()='Claim Now']"; var result = document.evaluate( xpathExpression, document, null, XPathResult.ANY_TYPE, null ); var divElement = result.iterateNext(); var grandparentElement = null; if (divElement) { var parentElement = divElement.parentNode; grandparentElement = parentElement.parentNode; } return grandparentElement; } function isOnline() { var xpathExpression = "//p[text()='Offline']"; var result = document.evaluate( xpathExpression, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ); var element = result.singleNodeValue; if (!element) return true; return false; } function selectNextStreamer() { var streamerList = JSON.parse(localStorage.getItem("streamerList")); var currentStreamer = JSON.parse(localStorage.getItem("currentStreamer")); var index; for (var i = 0; i < streamerList.length; i++) { if (streamerList[i][0] == currentStreamer) { index = i; break; } } var nextStreamer = streamerList[index + 1]; if (nextStreamer == undefined) { nextStreamer = streamerList[0]; } awokeNotification("Switched to " + nextStreamer[0], 3000); currentStreamer = nextStreamer[0]; localStorage.setItem("currentStreamer", JSON.stringify(currentStreamer)); if (JSON.parse(localStorage.getItem("streamerList")).length === 0) { chooseStreamersNotification(); } } function updateStreamerList() { var attributeValue = "DropsCampaignInProgressDescription-two-channels-hint-text"; var attributeValue2 = "DropsCampaignInProgressDescription-multi-channels-hint-text"; [attributeValue, attributeValue2].forEach(function (attributeValue) { var elements = document.querySelectorAll( "[data-test-selector='" + attributeValue + "']" ); var rivalsGeneral = document.querySelector("div.inventory-campaign-info"); var flag = false; if (rivalsGeneral !== null && flag === false) { flag = true; elements = Array.prototype.slice.call(elements); elements.push(rivalsGeneral); } elements.forEach(function (element) { var streamerName = element.innerText; if (element == rivalsGeneral) streamerName = "/general"; var allItems = 0; var obtaind = 0; var pElement = element; while (pElement.querySelector("div.inventory-campaign-info") === null) { pElement = pElement.parentNode; } pElement = pElement.children[1].children[0]; var progress = null; var isLocked = true; for (var i = 0; i < pElement.children.length; i++) { var child = pElement.children[i]; // if child has any children if (child.children.length > 0) { for (var j = 0; j < child.children.length; j++) { if (j === 0) { var img = child.children[j].children[0].children[0].children[0] .children[0].children[0]; // get opacity of image var opacity = window .getComputedStyle(img) .getPropertyValue("opacity"); isLocked = opacity === "0.2"; isLocked = child.children[j].children[0].children[0].children[0] .children[1] !== undefined; } else if (j === 1) { if (child.children[j].querySelector("[aria-valuenow]") !== null) { progress = child.children[j] .querySelector("[aria-valuenow]") .getAttribute("aria-valuenow"); } else { progress = null; } } } if (isLocked === false && progress === "0") { obtaind++; allItems++; } else if (isLocked || progress !== "0") { allItems++; } } } var streamerList = JSON.parse(localStorage.getItem("streamerList")); streamerList.forEach(function (streamer) { console.log(streamer); if (streamer[0] === streamerName.split("/")[1]) { streamer[1] = obtaind + "/" + allItems; } if (streamer[0] === "general" && streamerName === "/general") { streamer[1] = 5 + "/" + 5; } }); localStorage.setItem("streamerList", JSON.stringify(streamerList)); }); }); } function setCurrentStreamerOffline() { var currentStreamer = JSON.parse(localStorage.getItem("currentStreamer")); var streamerList = JSON.parse(localStorage.getItem("streamerList")); streamerList.forEach(function (streamer) { if (streamer[0] === currentStreamer) { streamer[2] = "offline"; } }); localStorage.setItem("streamerList", JSON.stringify(streamerList)); } function setCurrentStreamerOnline() { var currentStreamer = JSON.parse(localStorage.getItem("currentStreamer")); var streamerList = JSON.parse(localStorage.getItem("streamerList")); streamerList.forEach(function (streamer) { if (streamer[0] === currentStreamer) { streamer[2] = "online"; } }); localStorage.setItem("streamerList", JSON.stringify(streamerList)); } function awokeNotification(data, time) { console.log("awokeNotification: ", data); if (data == "[object HTMLDivElement]") { notificationText.parentNode.appendChild(data); } else { notificationText.innerText = data; } document.body.appendChild(notification); setTimeout(function () { notification.remove(); }, time); } function selectStreamer(streamerName) { localStorage.setItem("currentStreamer", JSON.stringify(streamerName)); } function chooseStreamersNotification() { var chooseStreamersNotificationContainer = document.createElement("div"); chooseStreamersNotificationContainer.style.cssText = "position:fixed;top:0;left:0;width:100%;height:100%;background-color:rgba(0,0,0,0.5);display:flex;justify-content:center;align-items:center;z-index:9999999999; flex-direction:column; color:white; font-size:20px; font-weight:bold; padding:20px; box-sizing:border-box;"; var innerContainer = document.createElement("div"); innerContainer.style.cssText = "background-color:#18181B; padding:20px; box-sizing:border-box; border-radius:10px; display:flex; flex-direction:column; justify-content:center; align-items:left; width: 400px;"; allStreamersNickames.forEach((element) => { element = element.toLowerCase(); var checkbox = document.createElement("input"); checkbox.type = "checkbox"; checkbox.name = "name"; checkbox.value = "value"; checkbox.id = element; checkbox.checked = false; checkbox.style.cssText = "margin:0 10px"; var label = document.createElement("label"); label.htmlFor = element; label.appendChild(document.createTextNode(element)); label.style.cssText = "margin:0 10px"; var group = document.createElement("div"); group.style.cssText = "display:flex;"; group.appendChild(checkbox); group.appendChild(label); innerContainer.appendChild(group); }); chooseStreamersNotificationContainer.appendChild(innerContainer); var readyButton = document.createElement("button"); readyButton.innerText = "Ready"; readyButton.id = "readyButton"; readyButton.style.cssText = "margin:0 10px; padding:10px; background-color:purple; color:white; border:none; border-radius:5px;margin-top:40px;width: 400px; text-align:center;"; chooseStreamersNotificationContainer.appendChild(readyButton); awokeNotification(chooseStreamersNotificationContainer, 99999); document.querySelector("#readyButton").addEventListener("click", function () { var streamerList = []; var checkboxes = chooseStreamersNotificationContainer.querySelectorAll( "input[type=checkbox]:checked" ); for (var i = 0; i < checkboxes.length; i++) { streamerList.push([checkboxes[i].id, "not started yet", "on/off-line"]); } chooseStreamersNotificationContainer.remove(); localStorage.setItem("streamerList", JSON.stringify(streamerList)); }); } function refreshStatBar() { var streamerList = JSON.parse(localStorage.getItem("streamerList")); var currentStreamer = JSON.parse(localStorage.getItem("currentStreamer")); statsBar.innerHTML = ""; streamerList.forEach(function (streamer) { var streamerNameOrginal = streamer[0]; var streamerName = streamer[0]; var streamerDrops = streamer[1]; var streamerStatus = streamer[2]; var streamerElement = document.createElement("a"); streamerElement.href = "https://www.twitch.tv/" + streamerNameOrginal; streamerElement.style.cssText = "display:flex;flex-direction:column;justify-content:center;align-items:center;margin:0 10px;text-decoration:none;color:#d1d1d1;"; var streamerNameElement = document.createElement("div"); streamerNameElement.style.cssText = "font-weight:bold;" + (streamer[0] == currentStreamer ? "color:purple;" : "color:#d1d1d1;"); streamerNameElement.innerText = streamerName; var streamerDropsElement = document.createElement("div"); streamerDropsElement.innerText = streamerDrops; var streamerStatusElement = document.createElement("div"); streamerStatusElement.innerText = streamerStatus; streamerElement.appendChild(streamerNameElement); streamerElement.appendChild(streamerDropsElement); streamerElement.appendChild(streamerStatusElement); streamerElement.addEventListener("mouseover", function () { closeNotificationButton.style.background = "#a9a9a9"; }); streamerElement.addEventListener("mouseout", function () { closeNotificationButton.style.background = "transparent"; }); streamerElement.addEventListener("click", function () { selectStreamer(streamerName); awokeNotification("Streamer changed to " + streamerName, 2000); refreshStatBar(); }); statsBar.appendChild(streamerElement); }); } if (window.location.pathname === "/drops/inventory") { let checkChanges = (mutationsList) => { window.addEventListener("storage", (e) => { if (e.key === "streamerList" || e.key === "currentStreamer") { console.log("refreshing stats bar from inventory page"); refreshStatBar(); } }); function initializeLocalStorage() { var currentStreamer = localStorage.getItem("currentStreamer"); var streamerList = localStorage.getItem("streamerList"); if (!currentStreamer || !streamerList) { localStorage.setItem( "currentStreamer", JSON.stringify(tempCurrentStreamer) ); localStorage.setItem("streamerList", JSON.stringify(tempStreamerList)); } } initializeLocalStorage(); for (const mutation of mutationsList) { var currentStreamer = JSON.parse(localStorage.getItem("currentStreamer")); var claimDropButton = getClaimButton(); if (claimDropButton !== null) { var streamerDropsLeft = 0; claimDropButton.click(); awokeNotification( `Congratulations, you have received a gift from ${currentStreamer} (${streamerDropsLeft} left) !`, 3000 ); return true; } updateStreamerList(); var streamerList = JSON.parse(localStorage.getItem("streamerList")); streamerList.forEach(function (streamer) { if (streamer[0] === currentStreamer) { if (streamer[1] === "0/0") { selectNextStreamer(); } } }); } }; let verifyChanges = new MutationObserver(checkChanges); verifyChanges.observe(document.body, config); setInterval(function () { window.location.reload(); }, timeCheck * 60000); } else { window.addEventListener("storage", (e) => { if (e.key === "streamerList" || e.key === "currentStreamer") { console.log("refreshing stat bar from stream"); refreshStatBar(); } }); function initializeLocalStorage() { var currentStreamer = localStorage.getItem("currentStreamer"); var streamerList = localStorage.getItem("streamerList"); if (!currentStreamer || !streamerList) { localStorage.setItem( "currentStreamer", JSON.stringify(tempCurrentStreamer) ); localStorage.setItem("streamerList", JSON.stringify(tempStreamerList)); } } initializeLocalStorage(); document.body.appendChild(nextStreamerButton); document.body.appendChild(statsBar); document.body.appendChild(changeStreamersButton); if ( JSON.parse(localStorage.getItem("streamerList")).length === 0 && JSON.parse(localStorage.getItem("currentStreamer")).length === 0 ) { chooseStreamersNotification(); } setInterval(function () { var currentStreamer = JSON.parse(localStorage.getItem("currentStreamer")); var streamerList = JSON.parse(localStorage.getItem("streamerList")); if (window.location.pathname === "/" + "general") { console.log("redirecting to " + currentStreamer); var randomStreamer = allStreamersNickames[ Math.floor(Math.random() * allStreamersNickames.length) ].toLowerCase(); selectStreamer(randomStreamer); localStorage.setItem("currentStreamer", JSON.stringify(randomStreamer)); window.location.pathname = "/" + randomStreamer; } if (window.location.pathname != "/" + currentStreamer) { console.log("redirecting to " + currentStreamer); window.location.pathname = "/" + currentStreamer; } streamerList.forEach((streamer) => { if (streamer[1].split("/")[0] == streamer[1].split("/")[1]) { console.log("streamer " + streamer[0] + " has completed all drops"); awokeNotification( "Streamer " + streamer[0] + " has completed all drops", 3000 ); selectNextStreamer(); localStorage.setItem( "currentStreamer", JSON.stringify(currentStreamer) ); } }); var onlineStatus = isOnline() ? "online" : "offline"; if (onlineStatus === "offline") { setCurrentStreamerOffline(); selectNextStreamer(); currentStreamer = JSON.parse(localStorage.getItem("currentStreamer")); console.log("streamer is offline redirecting to" + currentStreamer); } else { setCurrentStreamerOnline(); } refreshStatBar(); if (document.querySelector(claimBonusButton) !== null) { document.querySelector(claimBonusButton).click(); } }, 1000); }