// ==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);
}