Steam Replay total hours

Displays total playing hours in Steam Replay

// ==UserScript==
// @name         Steam Replay total hours
// @version      0.7
// @license      MIT
// @description  Displays total playing hours in Steam Replay
// @author       Wilzzu
// @include      https://store.steampowered.com/replay/*
// @icon         https://www.google.com/s2/favicons?domain=steamcommunity.com
// @namespace    https://gf.qytechs.cn/users/1003364
// ==/UserScript==
// Thanks u/Stardatara for helping with showing hours for all games in the replay!

javascript: (function () {
	const year = window.location.href.split("/").pop().slice(0, 4);
	let data = JSON.parse(
		application_config.dataset[
			`yearinreview_${JSON.parse(application_config.dataset.userinfo).accountid}_${year}`
		]
	).playtime_stats;

	const processedTitle = new WeakSet();
	const processedMostPlayed = new WeakSet();
	const processedOtherGames = new WeakSet();
	const processedButtons = new WeakSet();

	function updateTitle() {
		const element = document.querySelector(".AmQ9dRhZqhOyU0Vgt3nWR");
		if (element && !processedTitle.has(element)) {
			processedTitle.add(element);
			element.innerHTML =
				"You spent " +
				Math.round(data.total_stats.total_playtime_seconds / 3600) +
				" hours playing games this year!<br/><br/>" +
				element.innerHTML;
		}
	}

	function updateMostPlayed() {
		document.querySelectorAll("._2AXFQ4F1EgcZAVJgYC6_KQ").forEach((e) => {
			if (processedMostPlayed.has(e)) return;
			processedMostPlayed.add(e);

			let appID = getAppID(e, "._2UVYU3krJstwNrAYNcRAtq");
			addHoursPlayed(e, "._1fY-Tu9TH4Rv4r_U5vPalT", appID);
		});
	}

	function updateOtherGames() {
		document.querySelectorAll("._1o-OaJLHoJcCZBa1I48gl1").forEach((e) => {
			if (processedOtherGames.has(e)) return;
			processedOtherGames.add(e);

			let appID = getAppID(e, "._1OZ4wvkQU53fcikZxtoS3u", true);
			addHoursPlayed(e, "._3nXdDUZyLDuZxhkbe3WpO8", appID);
		});
	}

	function addHoursPlayed(el, classname, id) {
		if (id.includes("url")) return;
		let mainDiv = el.querySelector(classname);
		let statDiv = mainDiv.childNodes[0].cloneNode(true);
		if (mainDiv.querySelector(".SRTHstats")) mainDiv.querySelector(".SRTHstats").remove();

		let hours = "?";
		if (data.games.find((game) => game.appid == id)) {
			hours = Math.round(
				data.games.find((game) => game.appid == id).stats.total_playtime_seconds / 3600
			);
		} else if (data.game_summary.find((game) => game.appid == id)) {
			hours = Math.round(
				(data.total_stats.total_playtime_seconds *
					(data.game_summary.find((game) => game.appid == id).total_playtime_percentagex100 /
						100 /
						100)) /
					60 /
					60
			);

			if (hours < 1) hours = "<1";
		}

		statDiv.childNodes[0].innerHTML = hours;
		statDiv.childNodes[1].innerHTML = "Hours Played";
		statDiv.classList.add("SRTHstats");
		mainDiv.append(statDiv);
	}

	function getAppID(el, classname, link = false) {
		if (link) return el.querySelector(classname).childNodes[1].href.split("/").pop();
		return el.querySelector(classname).style.backgroundImage.split("apps/").pop().split("/")[0];
	}

	function observeElements(callback) {
		callback();

		const observer = new MutationObserver((mutations) => {
			let shouldRun = false;
			for (const mutation of mutations) {
				if (mutation.addedNodes.length > 0) {
					shouldRun = true;
					break;
				}
			}
			if (shouldRun) callback();
		});

		observer.observe(document.body, { childList: true, subtree: true });
	}

	function updateOnButtonClick() {
		document.querySelectorAll("._1tCO1rmBfntUI0TlpTly1F").forEach((button) => {
			if (processedButtons.has(button)) return;
			processedButtons.add(button);

			button.addEventListener("click", (event) => {
				requestAnimationFrame(() => {
					let appID = getAppID(
						button.closest("._3C4RVE-PZ18y1tGp7HLpP9"),
						"._1OZ4wvkQU53fcikZxtoS3u",
						true
					);
					addHoursPlayed(
						button.closest("._3C4RVE-PZ18y1tGp7HLpP9"),
						"._3nXdDUZyLDuZxhkbe3WpO8",
						appID
					);
				});
			});
		});
	}

	observeElements(updateTitle);
	observeElements(updateMostPlayed);
	observeElements(updateOtherGames);
	observeElements(updateOnButtonClick);
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址