itch.io Automated add bundle to library

This adds a handy button to an itch.io bundle to add all games in the bundle to your library quickly (including automatically moving to the next page once started).

Dovrai installare un'estensione come Tampermonkey, Greasemonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Userscripts per installare questo script.

Dovrai installare un'estensione come ad esempio Tampermonkey per installare questo script.

Dovrai installare un gestore di script utente per installare questo script.

(Ho già un gestore di script utente, lasciamelo installare!)

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

(Ho già un gestore di stile utente, lasciamelo installare!)

// ==UserScript==
// @name        itch.io Automated add bundle to library
// @description This adds a handy button to an itch.io bundle to add all games in the bundle to your library quickly (including automatically moving to the next page once started).
// @namespace   https://greasyfork.org/en/users/924198-saizai
// @match       https://itch.io/bundle/download/*
// @grant       GM.setValue
// @grant       GM.getValue
// @license MIT
// @version     2.0
// @author      Ceremony, Wertible, saizai
// ==/UserScript==

/*jshint esversion: 8 */
async function postData(game) {
	const response = await fetch(window.location.href, {
		method: 'POST',
		headers: {
			'Content-Type': 'application/x-www-form-urlencoded',
		},
		redirect: 'manual',
		body: game
	});

	await next();
}

async function next() {
	let game = null;
	if (await GM.getValue("itch.io autorun")) {
		if (game = games.pop()) {
			button.textContent = "Adding " + (games.length + 1) + " game(s) to your library! Please wait; click here to stop auto-adding.";
			postData(game);
		} else if (document.querySelector(".next_page.button")) {
			document.querySelector(".next_page.button").click();
		} else {
			await GM.setValue("itch.io autorun", false);
			button.textContent = "Found " + games.length + " game(s) on this page not yet added to your library. Click to auto-add!";
			button.addEventListener("click", async () => {
				button.style.cursor = "";
				await GM.setValue("itch.io autorun", true);
				await next();
			}, { once: true });
		}
	} else {
		button.textContent = "Added all games on this page!";
	}
}

var games = [];
var button = document.createElement("a");
button.style.cursor = "pointer";
button.className = "button";

async function getGames() {
	document.querySelectorAll(".game_row form.form").forEach((form) => {
		let data = [];
		form.querySelectorAll("*[name]").forEach((el) => {
			data.push(encodeURIComponent(el.name) + "=" + encodeURIComponent(el.value));
		})
		games.push(data.join("&"));
	});
}

async function setup() {
	if (! (await GM.getValue("itch.io autorun"))) {
		await GM.setValue("itch.io autorun", false);
	}

	if (await GM.getValue("itch.io autorun")) {
		button.addEventListener("click", async () => {
			button.textContent = "Auto-add stopped.";
			await GM.setValue("itch.io autorun", false);
		}, { once: true });
		button.textContent = "Click here to stop auto-adding.";
		document.querySelector(".game_outer").insertBefore(button, document.querySelector(".game_outer p:not([class])"));
		await getGames();
		if (games.length) {
			button.textContent = "Adding " + (games.length + 1) + " game(s) to your library! Please wait; click here to stop auto-adding.";
			await next();
		} else if (document.querySelector(".next_page.button")) {
			button.textContent = "No new games found on this page; continuing auto-adding to next page. Click here to stop auto-adding.";
			document.querySelector(".next_page.button").click();
		} else {
			await GM.setValue("itch.io autorun", false);
			button.textContent = "Added all games in this bundle! Auto-adding turned off.";
		}
	} else {
		button.addEventListener("click", async () => {
			button.style.cursor = "";
			await GM.setValue("itch.io autorun", true);
			await next();
		}, { once: true });
		button.textContent = "Click here to auto-add everything in the bundle!";
		document.querySelector(".game_outer").insertBefore(button, document.querySelector(".game_outer p:not([class])"));
		await getGames();
		if (games.length) {
			button.textContent = "Found " + games.length + " game(s) on this page not yet added to your library. Click here to auto-add everything in the bundle!";
		} else if (document.querySelector(".next_page.button")) {
			button.textContent = "No new games found on this page. Click here to start auto-adding from next page.";
		} else {
			await GM.setValue("itch.io autorun", false);
			button.textContent = "No more games to add in this bundle!";
		}
	}
}

setup();