您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Fetch uncompleted games from showcases and export to CSV
// ==UserScript== // @name Uncompleted Steam Games // @namespace Violentmonkey Scripts // @version 0.1.1 // @description Fetch uncompleted games from showcases and export to CSV // @author Rejedai // @match https://steamcommunity.com/id/* // @match https://steamcommunity.com/profiles/* // @license MIT // @grant none // ==/UserScript== /*jshint esversion: 6 */ (function () { 'use strict'; // always uncompleted games, even if you complete it previously. const completely_removed_games = new Set([ 1541780 ]); const lang = document.documentElement.lang || 'en'; function getAvatarHref() { // from pc interface let link = document.querySelector('a.user_avatar.playerAvatar'); if (link && link.href) { return link.href.replace(/\/$/, ""); } // from mobile interface link = document.querySelector('.playerAvatar a'); if (link && link.href) { return link.href.replace(/\/$/, ""); } return null; } const userUrl = getAvatarHref(); if (!userUrl) { console.log("Can't get user url"); return; } const currentUrl = location.href; if (!currentUrl.startsWith(userUrl)) { console.log('Not main user.'); return; } const menu = document.querySelector('#global_action_menu'); if (!menu) { console.log("Can't find #global_action_menu."); return; } const button = document.createElement('a'); if (lang === "en") { button.textContent = 'Uncompleted games'; } else { button.textContent = 'Незаконченные игры'; } button.style.cssText = 'margin-left:10px;padding:5px 10px;background:#5c7e10;color:#fff;border:none;'; button.href = '#'; button.classList.add('global_action_link'); // чтобы стиль совпадал с остальными button.style.color = '#fff'; menu.prepend(button); button.addEventListener('click', async () => { const targetUrl = `${userUrl}/edit/showcases`; try { const response = await fetch(targetUrl, {credentials: 'include'}); if (!response.ok) { alert("Can't load page"); return; } const html = await response.text(); const parser = new DOMParser(); const doc = parser.parseFromString(html, 'text/html'); const scripts = doc.querySelectorAll('script'); let achievedScript = null; let completeScript = null; for (const script of scripts) { if (script.textContent.includes('g_rgAchievementShowcaseGamesWithAchievements')) { achievedScript = script.textContent; } if (script.textContent.includes('g_rgAchievementsCompletionshipShowcasePerfectGames')) { completeScript = script.textContent; } if (achievedScript && completeScript) break; } if (!achievedScript || !completeScript) { alert("Can't find games data."); return; } function extractVar(scriptText, varName) { const regex = new RegExp(`${varName}\\s*=\\s*(\\[.*?\\]);`, 's'); const match = scriptText.match(regex); if (match && match[1]) { try { return JSON.parse(match[1]); } catch (e) { console.error('JSON parsing error:', e); } } return []; } const achievedList = extractVar(achievedScript, 'g_rgAchievementShowcaseGamesWithAchievements'); const completedList = extractVar(completeScript, 'g_rgAchievementsCompletionshipShowcasePerfectGames'); const completedAppids = new Set(completedList.map(game => game.appid)); const filteredGames = achievedList.filter(game => !completedAppids.has(game.appid) && !completely_removed_games.has(game.appid)); if (filteredGames.length === 0) { alert('Have no 10 level or no games found.'); return; } let csvContent = 'appid,name\n'; filteredGames.forEach(game => { const name = game.name.replace(/"/g, '""'); csvContent += `${game.appid},"${name}"\n`; }); // Скачиваем CSV const blob = new Blob([csvContent], {type: 'text/csv;charset=utf-8;'}); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'uncompleted.csv'; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); } catch (err) { console.error('Error:', err); alert('Data fetch error.'); } }); })();