// ==UserScript== // @name Steam 家庭库已有游戏标记 // @namespace http://tampermonkey.net/ // @version 2024-04-07v1 // @description 能够自动扫描你的家庭库库存,并在Steam游戏页面标记,并支持一键安装游戏 // @author Cliencer Goge // @match https://store.steampowered.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=steampowered.com // @grant GM_getValue // @grant GM_setValue // @grant GM_deleteValue // @license GPLv3 // @downloadURL none // ==/UserScript== var dialog,appid,observer var saves = readstorage() const url = window.location.pathname; (function() { 'use strict'; init() if(url=='/account/familymanagement' && saves.isStartDump){ observer_1(); }else{ if(g_ServerTime-saves.lastupDateTime>2592000){ let innerText if(saves.familyGameList.length == 0){ innerText="您似乎没有家庭库的游戏记录,是否现在扫描家庭库游戏并记录呢?" }else{ innerText="您已经超过1个月没有更新家庭库的游戏记录了,是否现在去扫描?" } ShowConfirmDialog('脚本提示',innerText,'扫描家庭库','取消').done(scan).fail(()=>{ ShowAlertDialog('脚本提示','如果需要手动扫描,可以在Steam主页右上角进入进行扫描','好的') }) } var search_suggestion = document.getElementById('search_suggestion_contents') var observer_search = new MutationObserver((mutations, obs) => { mutations.forEach(function(mutation) { if (mutation.addedNodes && mutation.addedNodes.length > 0) { mutation.addedNodes.forEach(function(node) { // 确保是元素节点 if (node.nodeType === Node.ELEMENT_NODE) { // 检查新节点是否有指定的类 if (node.classList.contains('match_app')) { addflag(node) } } }); } }) }); observer_search.observe(search_suggestion, {childList: true, subtree: true}); } if(url == "/"){ observer_3() observer = new MutationObserver((mutations, obs) => { mutations.forEach(function(mutation) { if (mutation.addedNodes && mutation.addedNodes.length > 0) { mutation.addedNodes.forEach(function(node) { // 确保是元素节点 if (node.nodeType === Node.ELEMENT_NODE) { if(node.classList.contains('live_streams_ctn')){return;} node.querySelectorAll("div").forEach((node)=>{ addflag(node) }) node.querySelectorAll("a").forEach((node)=>{ if(node.classList.contains('screenshot')){return;} if(node.querySelector('div.broadcast_live_stream_icon')){return;} addflag(node) }) } }) } }) }) observer.observe(document, {childList: true, subtree: true}); } if(url.startsWith('/app/')&&g_AccountID != 0){ //addBanner(document.querySelector('div.block.game_media_and_summary_ctn')) observer_2(); } if(url.startsWith('/search/')&&g_AccountID != 0){ observer_4() var search_results = document.getElementById('search_results') observer = new MutationObserver((mutations, obs) => { mutations.forEach(function(mutation) { if (mutation.addedNodes && mutation.addedNodes.length > 0) { mutation.addedNodes.forEach(function(node) { // 确保是元素节点 if (node.nodeType === Node.ELEMENT_NODE) { console.log(node) if (node.classList.contains('search_result_row') && node.classList.contains('ds_collapse_flag') && !node.classList.contains('ds_owned')) { addflag(node,"clear: left;") }else{ let lists = node.querySelectorAll("a.search_result_row.ds_collapse_flag") lists.forEach(function(bar){ addflag(bar,"clear: left;") }) } } }); } }) }); observer.observe(search_results, {childList: true, subtree: true}); } function init(){ let setting_btn = document.createElement('span'); setting_btn.id = "setting_btn" setting_btn.style = "position:relative;background:linear-gradient(to right, rgb(6 207 199 / 60%) 0%, rgb(33 105 106 / 60%) 100%)" setting_btn.innerHTML = `家庭游戏标记 脚本设置` setting_btn.onclick = btnonclick plug(); function plug(){ let headding = document.getElementById('global_action_menu') if(headding){ headding.insertBefore(setting_btn, headding.firstChild); }else{ setTimeout(plug,200) } } function btnonclick(){ ShowConfirmDialog('脚本设置',`目前你的家庭库一共记录了${saves.familyGameList.length}个游戏。\n上次扫描时间:${timestampToTime(saves.lastupDateTime)}`,'扫描家庭库',null,'清空库记录').done(function(arg){ if(arg == 'SECONDARY'){ ShowConfirmDialog('再次确认','你即将清空当前保存的家庭库列表,该行为无法撤销!','好的','算了').done(() =>{ saves = { isStartDump:false, familyGameList:[], lastupDateTime:0 } savestorage() ShowAlertDialog('完成','已经清除所有的缓存','好的') }) }else{ scan() } }) } } function scan(){ ShowAlertDialog('提示','即将打开家庭库页面进行扫描,请确认已加入一个有效的家庭组,否则脚本可能会出错,扫描期间不要关闭浏览器,耐心等待进度条结束!','好的,开始扫描').done(()=>{ var windowFeatures = "width=1000,height=700,resizable=no,scrollbars=yes,status=yes"; var newWindow = window.open('https://store.steampowered.com/account/familymanagement?tab=library', '家庭库扫描窗口---不要关闭!', windowFeatures); saves.isStartDump=true; savestorage() // 检查窗口是否成功打开 if (newWindow) { newWindow.focus(); } else { // 弹窗被阻止的情况 alert("打开新窗口被阻止,请在浏览器设置中允许打开新窗口!"); } }) } function observer_4(){ let block = document.getElementById('search_result_container') if(block){ let lists = block.querySelectorAll("a.search_result_row.ds_collapse_flag") lists.forEach(function(bar){ addflag(bar,"clear: left;") }) }else{ setTimeout(observer_4,200) } } function observer_3(){ let block = document.querySelector('div.home_tabs_content') if(block){ let lists = block.querySelectorAll("a.tab_item") lists.forEach(function(bar){ addflag(bar,"clear: both;") }) block = document.querySelector('div.carousel_container.maincap') lists = block.querySelectorAll("a.store_main_capsule") lists.forEach(function(bar){ addflag(bar) }) block = document.querySelector('div.carousel_container.spotlight') lists = block.querySelectorAll("div.home_area_spotlight") lists.forEach(function(bar){ addflag(bar) }) lists = block.querySelectorAll("a.store_capsule") lists.forEach(function(bar){ addflag(bar) }) block = document.getElementById('module_deep_dive') lists = block.querySelectorAll("a.store_capsule") lists.forEach(function(bar){ addflag(bar) }) block = document.getElementById('module_recommender') lists = block.querySelectorAll("a.store_capsule") lists.forEach(function(bar){ addflag(bar) }) block = document.getElementById('recommended_creators_carousel') lists = block.querySelectorAll("a.store_capsule") lists.forEach(function(bar){ addflag(bar) }) block = document.querySelector('div.specials_under10_content') lists = block.querySelectorAll("a.store_capsule") lists.forEach(function(bar){ addflag(bar) }) block = document.querySelector('div.marketingmessage_area') lists = block.querySelectorAll("a.home_marketing_message") lists.forEach(function(bar){ addflag(bar) }) }else{ setTimeout(observer_3,200) } } function observer_2(){ let block = document.querySelector('div.block.game_media_and_summary_ctn') if(block){ appid = Number(url.split('/')[2]) if(saves.familyGameList.includes(appid)){ addBanner(block) } }else{ setTimeout(observer_2,200) } } function addflag(node,insertBeforeStyle){ if(node.querySelector("div.ds_owned_flag")) return; let thisappid = node.getAttribute('data-ds-appid') let thisurl = node.getAttribute('href') if(thisappid && (thisurl == null || thisurl.startsWith('https://store.steampowered.com/app/')) && saves.familyGameList.includes(Number(thisappid))){ if(url.startsWith('/app/')){ node.classList.add('ds_owned'); } node.classList.add('ds_flagged'); node.classList.remove('ds_wishlist') var flag = document.createElement('div'); flag.className = "ds_flag ds_owned_flag" flag.innerHTML = '在家庭库中 ' flag.style = "background:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAKCAYAAABi8KSDAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OUNDNzBFNTUyMUM0MTFFNDk1REVFODRBNUU5RjA2MUYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OUNDNzBFNTYyMUM0MTFFNDk1REVFODRBNUU5RjA2MUYiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo5Q0M3MEU1MzIxQzQxMUU0OTVERUU4NEE1RTlGMDYxRiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo5Q0M3MEU1NDIxQzQxMUU0OTVERUU4NEE1RTlGMDYxRiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pv3vUKAAAAAlSURBVHjaYvz//z8DsYARpFhISAivjnfv3jGSp3jUGeQ4AyDAADZHNe2nyOBrAAAAAElFTkSuQmCC') no-repeat 4px 4px #06cfbe" if(insertBeforeStyle){ node.insertBefore(flag, node.querySelector(`[style*="${insertBeforeStyle}"]`).nextSibling); }else{ node.appendChild(flag); } node.querySelectorAll("div.ds_flag.ds_wishlist_flag").forEach((wishlist_flag)=>{wishlist_flag.remove()}) } } function addBanner(block){ let appname = appHubAppName.innerText let owned = false if(block.querySelector('div.game_area_already_owned.page_content')){ owned = true } if(owned == false){ var headplug = document.createElement('div'); var targetElement = block.querySelector('div.queue_overflow_ctn'); headplug.style = "background:linear-gradient(to right, rgb(6 207 199 / 60%) 0%, rgb(33 105 106 / 60%) 100%);color:#06cfb5" headplug.className = "game_area_already_owned page_content" headplug.innerHTML =`