您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Display playing stats for SteamGifts users
当前为
// ==UserScript== // @name Do You Even Play, Bro? // @namespace https://www.steamgifts.com/user/kelnage // @version 1.5.0 // @description Display playing stats for SteamGifts users // @author kelnage // @match https://www.steamgifts.com/user/*/giveaways/won* // @require https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js // @grant GM_xmlhttpRequest // @grant GM_getValue // @grant GM_setValue // @grant GM_deleteValue // @grant GM.xmlhttpRequest // @grant GM.getValue // @grant GM.setValue // @grant GM.deleteValue // @connect self // @connect api.steampowered.com // @connect store.steampowered.com // @require https://cdnjs.cloudflare.com/ajax/libs/jquery/1.10.0/jquery.min.js // @require https://cdnjs.cloudflare.com/ajax/libs/jquery-sparklines/2.1.2/jquery.sparkline.js // ==/UserScript== var CURRENT_VERSION = [1,5,0]; var username = $(".featured__heading__medium").text(); var userID64 = $('[data-tooltip="Visit Steam Profile"]').attr("href").match(/http:\/\/steamcommunity.com\/profiles\/([0-9]*)/)[1]; var WINS_URL = "https://www.steamgifts.com/user/" + username + "/giveaways/won/search"; var PLAYTIME_URL = "https://api.steampowered.com/IPlayerService/GetOwnedGames/v0001/"; // takes a steamid and API key var ACHIEVEMENTS_URL = "https://api.steampowered.com/ISteamUserStats/GetPlayerAchievements/v0001/"; // takes a steamid, appid and API key var STEAM_API_KEY = GM_getValue("DYEPB_API_KEY"); var API_KEY_REGEXP = /[0-9A-Z]{32}/; var WAIT_MILLIS = 500; var PLAYTIME_CACHE_KEY = "DYEPB_PLAYTIME_CACHE_" + encodeURIComponent(username), ACHIEVEMENT_CACHE_KEY = "DYEPB_ACHIEVEMENT_CACHE_" + encodeURIComponent(username), WINS_CACHE_KEY = "DYEPB_WINS_CACHE_" + encodeURIComponent(username), LAST_CACHE_KEY = "DYEPB_LAST_CACHED_" + encodeURIComponent(username), USER_CACHE_VERSION_KEY = "DYEPB_USER_CACHE_VERSION_" + encodeURIComponent(username), SUB_APPID_CACHE_KEY = "DYEPB_SUB_APPID_CACHE", SUB_APPID_CACHE_VERSION_KEY = "DYEPB_SUB_APPID_CACHE_VERSION", CHART_TEXT_PREFERENCE = "DYEPB_CHART_TEXT"; var $percentage = $('<div class="featured__table__row__right"></div>'), $average_total_playtime = $('<div class="featured__table__row__right"></div>'), $playtime_any_counts = $('<div class="featured__table__row__right" style="text-align: right"></div>'), $playtime_5_10_counts = $('<div class="featured__table__row__right" style="text-align: right"></div>'), $achievement_any_counts = $('<div class="featured__table__row__right" style="text-align: right"></div>'), $achievement_counts_chart = $('<div class="featured__table__row__right" style="text-align: right"></div>'), $achievement_25_100_counts = $('<div class="featured__table__row__right" style="text-align: right"></div>'), $last_updated = $('<span title="" style="color: rgba(255,255,255,0.4)"></span>'), $progress_text = $('<span style="margin-left: 0.3em"></span>'), $rm_key_link = $('<a style="margin-left: 0.5em;color: rgba(255,255,255,0.6)" href="#">Delete cached API key</a>'), $toolbar = $('<div id="sg_dyepb_toolbar" style="color: rgba(255,255,255,0.4)" class="nav__left-container"></div>'), $fetch_button = $('<a class="nav__button" href="#">' + (GM_getValue(LAST_CACHE_KEY) ? 'Update Playing Info' : 'Fetch Playing Info' ) + '</a>'), $key_button = $('<a class="nav__button" href="#">Provide API Key</a>'), $button_container = $('<div class="nav__button-container"></div>'), $progress_container = $('<div id="progress" style="margin: 0.5em 0"><img src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/0.16.1/images/loader-large.gif" height="10px" width="10px" /></div>'), $chart_text_switch = $('<a href="#" style="font-size: smaller">chart</a>'); var playtimeCache = {}, achievementCache = {}, winsCache = {}, subAppIdsCache = {}, activeRequests = 0, errorCount = 0, run_status = "STOPPED"; // can be STOPPED, PLAYTIME, WON_GAMES, ACHIEVEMENTS if(JSON.parse(GM_getValue(USER_CACHE_VERSION_KEY, "[0,0,0]")) > [1,3,2]) { // Ignore caches from versions older than 1.3.3 if(GM_getValue(PLAYTIME_CACHE_KEY)) { playtimeCache = JSON.parse(GM_getValue(PLAYTIME_CACHE_KEY)); } if(GM_getValue(ACHIEVEMENT_CACHE_KEY)) { achievementCache = JSON.parse(GM_getValue(ACHIEVEMENT_CACHE_KEY)); } if(GM_getValue(WINS_CACHE_KEY)) { var tempWinsCache = JSON.parse(GM_getValue(WINS_CACHE_KEY)); if(Array.isArray(tempWinsCache)) { // convert old array into an object for(var i = 0; i < tempWinsCache.length; i++) { winsCache['a'+tempWinsCache[i].appid] = tempWinsCache[i].appid; } } else { winsCache = tempWinsCache; } } } if(GM_getValue(SUB_APPID_CACHE_KEY)) { if(JSON.parse(GM_getValue(SUB_APPID_CACHE_VERSION_KEY, "[0,0,0]")) > [1,3,2]) { // Ignore caches from versions older than 1.3.3 subAppIdsCache = JSON.parse(GM_getValue(SUB_APPID_CACHE_KEY)); } } var errorFn = function(response) { activeRequests -= 1; errorCount += 1; console.log("Error details: ", response.status, response.responseText); }; var maxIndex = function(arr, val) { var i = arr.length - 1; while(i >= 0) { if(arr[i] == val) { return i; } i--; } return 0; }; var formatPercentage = function(x, per, precision) { if(isNaN(x / per)) { return "N/A"; } return Number(x / per * 100).toPrecision(precision) + "%"; }; var formatMinutes = function(mins) { if(isNaN(mins)) { return "N/A"; } if(mins < 60) { return mins.toPrecision(2) + " minutes"; } else { var hours = mins / 60; if(hours < 100) { return hours.toPrecision(2) + " hours"; } else if(hours < 1000) { return hours.toPrecision(3) + " hours"; } else if(hours < 10000) { return hours.toPrecision(4) + " hours"; } else { return hours.toPrecision(5) + " hours"; } } }; var enhanceRow = function($heading, minutesPlayed, achievementCounts, appid) { var $playtimeSpan = $heading.find(".dyegb_playtime"), $achievementSpan = $heading.find(".dyegb_achievement"); if(minutesPlayed) { if($playtimeSpan.length > 0) { $playtimeSpan.text(formatMinutes(minutesPlayed)); } else { $heading.append('<span class="dyegb_playtime giveaway__heading__thin">' + formatMinutes(minutesPlayed) + '</span>'); } } if(achievementCounts && achievementCounts.total > 0) { if($achievementSpan.length === 0) { $achievementSpan = $('<a href="https://steamcommunity.com/profiles/'+userID64+'/stats/'+appid+'/?tab=achievements" target="_new" class="dyegb_achievement giveaway__heading__thin">' + formatPercentage(achievementCounts.achieved, achievementCounts.total, 3) + '</a>'); $heading.append($achievementSpan); } if(achievementCounts.achieved === 0) { $achievementSpan.text("0%"); } else { $achievementSpan.attr('style', "font-weight: bold"); $achievementSpan.text(formatPercentage(achievementCounts.achieved, achievementCounts.total, 3)); $achievementSpan.attr('title', achievementCounts.achieved + '/' + achievementCounts.total + ' achievements'); if(achievementCounts.achieved == achievementCounts.total) { $achievementSpan.attr('style', "font-weight: bold; color: rgb(91, 192, 222)"); } else { $achievementSpan.addClass("giveaway__column--positive"); } } } }; var enhanceWonGames = function() { var $rows = $(".giveaway__row-inner-wrap"); $rows.each(function() { var $this = $(this), $heading = $this.find(".giveaway__heading"), $ga_icon = $this.find("a.giveaway__icon:has(i.fa-steam)"); if($ga_icon && $ga_icon.attr("href")) { var id = $ga_icon.attr("href").match(/http:\/\/store.steampowered.com\/([^\/]*)\/([0-9]*)\//); if(id[1] == "sub" || id[1] == "subs") { var totalMinutes = 0, totalAchievements = {achieved: 0, total: 0}, bestAppid = null, topCompletion = null; if(subAppIdsCache['s'+id[2]]) { var appids = subAppIdsCache['s'+id[2]]; for(var i = 0; i < appids.length; i++) { if(playtimeCache['a'+appids[i]]) { totalMinutes += playtimeCache['a'+appids[i]]; } if(achievementCache['a'+appids[i]]) { totalAchievements.achieved += achievementCache['a'+appids[i]].achieved; totalAchievements.total += achievementCache['a'+appids[i]].total; if(topCompletion === null || achievementCache['a'+appids[i]].achieved / achievementCache['a'+appids[i]].total > topCompletion) { topCompletion = achievementCache['a'+appids[i]].achieved / achievementCache['a'+appids[i]].total; bestAppid = appids[i]; } } } } enhanceRow($heading, totalMinutes, totalAchievements, bestAppid); } if(id[1] == "app" || id[1] == "apps") { enhanceRow($heading, playtimeCache['a'+id[2]], achievementCache['a'+id[2]], id[2]); } } }); }; var updateTableStats = function() { var achievement_percentage_sum = 0, achievement_game_count = 0, achieved_game_count = 0, achieved_game_count_25 = 0, achieved_game_count_100 = 0, achieved_game_cumulative = [], playtime_total = 0, playtime_game_count = 0, playtime_game_count_5h = 0, playtime_game_count_10h = 0, win_count = 0, achievement_playtime_total = 0, achievement_playtime_count = 0; var i = 0; while(i < 101) { achieved_game_cumulative[i] = 0; i++; } $.each(winsCache, function(aid, appid) { var achievement_counts = achievementCache[aid]; if(achievement_counts && achievement_counts.total > 0) { achievement_game_count += 1; if(achievement_counts.achieved > 0) { var ratio = achievement_counts.achieved / achievement_counts.total; achievement_percentage_sum += ratio; achieved_game_count += 1; if(achievement_counts.achieved >= (achievement_counts.total / 4)) { achieved_game_count_25 += 1; } if(achievement_counts.achieved === achievement_counts.total) { achieved_game_count_100 += 1; } } var j = 0, percentage = Math.round(achievement_counts.achieved / achievement_counts.total * 100); while(j <= percentage) { achieved_game_cumulative[j] += 1; j++; } } if(playtimeCache[aid] !== undefined) { win_count += 1; playtime_total += playtimeCache[aid]; if(playtimeCache[aid] > 0) { playtime_game_count += 1; } if(playtimeCache[aid] >= 300) { playtime_game_count_5h += 1; } if(playtimeCache[aid] >= 600) { playtime_game_count_10h += 1; } } if(achievement_counts && achievement_counts.total > 0 && playtimeCache[aid]) { achievement_playtime_total += playtimeCache[aid]; achievement_playtime_count += achievement_counts.achieved; } }); if(achieved_game_count > 0) { $percentage.text(formatPercentage(achievement_percentage_sum, achieved_game_count, 3)); } else { $percentage.text("N/A"); } if(playtime_game_count !== win_count) { $average_total_playtime.text(formatMinutes(playtime_total / win_count) + ' per win, ' + formatMinutes(playtime_total / playtime_game_count) + ' per played win, ' + formatMinutes(playtime_total) + ' total'); } else { $average_total_playtime.text(formatMinutes(playtime_total / win_count) + ' in all wins, ' + formatMinutes(playtime_total) + ' total'); } $playtime_any_counts.text(formatPercentage(playtime_game_count, win_count, 3) + ' (' + playtime_game_count + '/' + win_count + ')'); $playtime_5_10_counts.text('≥5 hours: ' + formatPercentage(playtime_game_count_5h, win_count, 3) + ' (' + playtime_game_count_5h + '/' + win_count + '), ≥10 hours: ' + formatPercentage(playtime_game_count_10h, win_count, 3) + ' (' + playtime_game_count_10h + '/' + win_count + ')'); $achievement_any_counts.text(formatPercentage(achieved_game_count, achievement_game_count, 3) + ' (' + achieved_game_count + '/' + achievement_game_count + ')'); $achievement_counts_chart.sparkline( achieved_game_cumulative, {'type': 'line', 'lineColor': 'rgba(255, 255, 255, 0.6)', 'fillColor': 'rgba(255, 255, 255, 0.4)', 'chartRangeMin': 0, 'height': 18, 'spotColor': 'rgb(153,204,102)', 'minSpotColor': 'rgb(153,204,102)', 'maxSpotColor': 'rgb(153,204,102)', 'tooltipOffsetX': -60, 'tooltipOffsetY': 25, 'tooltipFormatter': function(sparkline, options, fields) { return maxIndex(achieved_game_cumulative, fields.y) + '% complete: ' + formatPercentage(fields.y, achievement_game_count, 3) + ' (' + fields.y + '/' + achievement_game_count + ')'; }}); $achievement_counts_chart.css( 'background', 'linear-gradient(to right, transparent calc(25%), rgba(255,0,0,0.5) calc(25% + 2px), transparent calc(25% + 4px), transparent calc(50% - 2px), rgba(255,0,0,0.5) calc(50%), transparent calc(50% + 2px), transparent calc(75% - 3px), rgba(255,0,0,0.5) calc(75% - 1px), transparent calc(75% + 1px))'); $achievement_25_100_counts.text( '≥25% complete: ' + formatPercentage(achieved_game_count_25, achievement_game_count, 3) + ' (' + achieved_game_count_25 + '/' + achievement_game_count + '), completed: ' + formatPercentage(achieved_game_count_100, achievement_game_count, 3) + ' (' + achieved_game_count_100 + '/' + achievement_game_count + ')'); }; var updateDisplayedCacheDate = function(t) { if(t) { $last_updated.text('Last retrieved: ' + t.toLocaleDateString() + (errorCount > 0 ? ", with " + errorCount + " API query errors" : "")); $last_updated.attr('title', t.toLocaleString()); } }; var displayButtons = function() { if(!API_KEY_REGEXP.test(STEAM_API_KEY)) { $button_container.show(); $progress_container.hide(); $key_button.show(); $fetch_button.hide(); $last_updated.empty(); $last_updated.attr("title", ""); $last_updated.show(); $last_updated.append('<a style="color: rgba(255,255,255,0.6)" target="_blank" href="https://steamcommunity.com/dev/apikey">Click here to obtain a Steam API key</a>'); $rm_key_link.hide(); } else if(run_status == "STOPPED") { $button_container.show(); $progress_container.hide(); $fetch_button.show(); $key_button.hide(); $last_updated.empty(); // will be updated by updateDisplayedCacheDate $last_updated.show(); if(GM_getValue(LAST_CACHE_KEY)) { $fetch_button.text("Update Playing Info"); updateDisplayedCacheDate(new Date(GM_getValue(LAST_CACHE_KEY))); } else { $fetch_button.text("Fetch Playing Info"); } $rm_key_link.show(); } else { $button_container.hide(); $progress_container.show(); if(run_status == "PLAYTIMES") { $progress_text.text("Retrieving " + username + "'s logged playing times"); } else if(run_status == "WON_GAMES") { $progress_text.text("Retrieving " + username + "'s won games"); } else if(run_status == "ACHIEVEMENTS") { $progress_text.text("Retrieving " + username + "'s achievement progress (" + activeRequests + " games left to check)"); } $last_updated.hide(); $rm_key_link.hide(); } }; var updatePage = function(update_time) { enhanceWonGames(); updateTableStats(); displayButtons(); updateDisplayedCacheDate(update_time); }; var extractSubGames = function(sub, page) { subAppIdsCache['s'+sub] = []; $(".tab_item", page).each(function(i, e) { var $this = $(e), appId = $this.attr("data-ds-appid"), name = $this.find(".tab_item_name").text(), $link = $this.find(".tab_item_overlay"); if($link.attr("href") && !winsCache['a'+appId]) { var type = $link.attr("href").match(/http:\/\/store.steampowered.com\/([^\/]*)\/[0-9]*\//); winsCache['a'+appId] = appId; } subAppIdsCache['s'+sub].push(appId); }); }; var extractWon = function(page) { var extractCount = 0; $(".giveaway__row-inner-wrap", page) .filter(function(i) { return $(this).find("div.giveaway__column--positive").length == 1; }) .each(function(i, e) { var $ga_icon = $(e).find("a.giveaway__icon:has(i.fa-steam)"); if($ga_icon.length === 1 && $ga_icon.attr("href")) { var url = $ga_icon.attr("href"), id = url.match(/http:\/\/store.steampowered.com\/([^\/]*)\/([0-9]*)\//); if((id[1] == "sub" || id[1] == "subs") && !subAppIdsCache['s'+id[2]]) { // only fetch appids for uncached-subs - do subs ever change? Probably... activeRequests += 1; GM_xmlhttpRequest({ "method": "GET", "url": url, "onload": function(response) { if(response.finalUrl === url) { // if not, probably got redirected to Steam homepage extractSubGames(id[2], response.responseText); } else { console.log("Could not get details for sub " + id[2]); } activeRequests -= 1; }, "onabort": errorFn, "onerror": errorFn, "ontimeout": errorFn }); extractCount += 1; } else if((id[1] == "app" || id[1] == "apps") && !winsCache['a'+id[2]]) { winsCache['a'+id[2]] = id[2]; extractCount += 1; } } }); return extractCount; }; var fetchWon = function(page, callback) { activeRequests += 1; GM_xmlhttpRequest({ "method": "GET", "url": WINS_URL + "?page=" + page, "onload": function(response) { var count = extractWon(response.responseText); // stop fetching pages if no new wins found on current page if($("div.pagination__navigation > a > span:contains('Next')", response.responseText).length === 1 && count > 0) { setTimeout(function() { fetchWon(page + 1, callback); }, WAIT_MILLIS); } else { callback(); } activeRequests -= 1; }, "onabort": errorFn, "onerror": errorFn, "ontimeout": errorFn }); }; var fetchGamePlaytimes = function(steamID64, callback) { activeRequests += 1; GM_xmlhttpRequest({ "method": "GET", "url": PLAYTIME_URL + "?steamid=" + steamID64 + "&key=" + STEAM_API_KEY, "onload": function(response) { var data; try { data = JSON.parse(response.responseText); } catch(err) { errorFn({"status": response.status, "responseText": response.responseText}); } if(data) { var games = data.response.games; console.log(games); if(games) { for(var i = 0; i < games.length; i++) { playtimeCache["a"+games[i].appid] = games[i].playtime_forever; } } activeRequests -= 1; callback(); } }, "onabort": errorFn, "onerror": errorFn, "ontimeout": errorFn }); }; var fetchAchievementStatsFn = function(appid, steamID64) { return function() { GM_xmlhttpRequest({ "method": "GET", "url": ACHIEVEMENTS_URL + "?appid=" + appid + "&steamid=" + steamID64 + "&key=" + STEAM_API_KEY, "onload": function(response) { var data; try { data = JSON.parse(response.responseText); } catch(err) { errorFn({"status": response.status, "responseText": response.responseText}); } if(data) { achievements = data.playerstats.achievements; if(achievements) { var achieved = achievements.filter(function(achievement) { return achievement.achieved == 1; }).length; var total = achievements.length; achievementCache["a"+appid] = {"achieved": achieved, "total": total}; } else { achievementCache["a"+appid] = {"achieved": 0, "total": 0}; } activeRequests -= 1; } }, "onabort": errorFn, "onerror": errorFn, "ontimeout": errorFn }); }; }; var cacheJSONValue = function(key, value) { GM_setValue(key, JSON.stringify(value)); var updateTime = new Date(); GM_setValue(LAST_CACHE_KEY, updateTime.getTime()); updatePage(updateTime); }; (function() { 'use strict'; var $featured_table = $(".featured__table"), $featured_table_col1 = $featured_table.children(":first-child"), $featured_table_col2 = $featured_table.children(":last-child"); var $left_row_1 = $('<div class="featured__table__row"></div>'), $left_row_2 = $('<div class="featured__table__row"></div>'), $left_row_3 = $('<div class="featured__table__row"></div>'), $left_row_4 = $('<div class="featured__table__row"></div>'), $left_row_5 = $('<div class="featured__table__row"></div>'), $right_row_1 = $('<div class="featured__table__row"></div>'), $right_row_2 = $('<div class="featured__table__row"></div>'), $right_row_3 = $('<div class="featured__table__row"></div>'), $right_row_4 = $('<div class="featured__table__row"></div>'), $right_row_5 = $('<div class="featured__table__row"></div>'); $toolbar.append($button_container); $button_container.append($key_button); $button_container.append($fetch_button); $toolbar.append($progress_container); $progress_container.append($progress_text); $toolbar.append($last_updated); $toolbar.append($rm_key_link); $left_row_1.append('<div class="featured__table__row__left">Average and Total Playtime</div>'); $left_row_1.append($average_total_playtime); $left_row_2.append('<div class="featured__table__row__left">Games with any Playtime</div>'); $left_row_2.append($playtime_any_counts); $left_row_3.append('<div class="featured__table__row__left">Games with Playtime...</div>'); $left_row_3.append($playtime_5_10_counts); $right_row_1.append('<div class="featured__table__row__left">Avg. Achievement Percentage</div>'); $right_row_1.append($percentage); $right_row_2.append('<div class="featured__table__row__left">Games with ≥1 Achievement</div>'); $right_row_2.append($achievement_any_counts); var $achievement_games = $('<div class="featured__table__row__left">Achievement Rates </div>'); $achievement_games.append($chart_text_switch); $right_row_3.append($achievement_games); $right_row_3.append($achievement_25_100_counts); $right_row_3.append($achievement_counts_chart); if(GM_getValue(CHART_TEXT_PREFERENCE, "text") == "text") { $achievement_counts_chart.hide(); $chart_text_switch.text('chart'); } else { $achievement_25_100_counts.hide(); $chart_text_switch.text('text'); } $featured_table_col1.append($left_row_1).append($left_row_2).append($left_row_3); $featured_table_col2.append($right_row_1).append($right_row_2).append($right_row_3); $featured_table.after($toolbar); updatePage(GM_getValue(LAST_CACHE_KEY) ? new Date(GM_getValue(LAST_CACHE_KEY)) : null); $chart_text_switch.click(function(e) { e.preventDefault(); if(GM_getValue(CHART_TEXT_PREFERENCE, "text") == "text") { // switch to chart $achievement_counts_chart.show(); $achievement_25_100_counts.hide(); $.sparkline_display_visible(); GM_setValue(CHART_TEXT_PREFERENCE, "chart"); $chart_text_switch.text("text"); } else { // switch to text $achievement_counts_chart.hide(); $achievement_25_100_counts.show(); GM_setValue(CHART_TEXT_PREFERENCE, "text"); $chart_text_switch.text("chart"); } updateTableStats(); }); $key_button.click(function(e) { e.preventDefault(); STEAM_API_KEY = prompt('Please provide your Steam API key'); while(STEAM_API_KEY !== "" && STEAM_API_KEY !== null && !API_KEY_REGEXP.test(STEAM_API_KEY)) { STEAM_API_KEY = prompt('Please provide your valid Steam API key'); } if(API_KEY_REGEXP.test(STEAM_API_KEY)) { GM_setValue("DYEPB_API_KEY", STEAM_API_KEY); displayButtons(); } }); $rm_key_link.click(function(e) { e.preventDefault(); GM_deleteValue("DYEPB_API_KEY"); STEAM_API_KEY = ""; displayButtons(); }); $fetch_button.click(function(e) { e.preventDefault(); activeRequests = 0; errorCount = 0; run_status = "PLAYTIMES"; displayButtons(); fetchGamePlaytimes(userID64, function() { run_status = "WON_GAMES"; cacheJSONValue(PLAYTIME_CACHE_KEY, playtimeCache); fetchWon(1, function() { var intervalId = setInterval(function() { if(activeRequests === 0) { clearInterval(intervalId); run_status = "ACHIEVEMENTS"; cacheJSONValue(WINS_CACHE_KEY, winsCache); cacheJSONValue(SUB_APPID_CACHE_KEY, subAppIdsCache); GM_setValue(SUB_APPID_CACHE_VERSION_KEY, JSON.stringify(CURRENT_VERSION)); var i = 0; $.each(winsCache, function(id, appid) { activeRequests += 1; // increment delay to try to prevent overloading of Steam API setTimeout(fetchAchievementStatsFn(appid, userID64), i * 50); i += 1; }); intervalId = setInterval(function() { if(activeRequests === 0) { clearInterval(intervalId); run_status = "STOPPED"; cacheJSONValue(ACHIEVEMENT_CACHE_KEY, achievementCache); GM_setValue(USER_CACHE_VERSION_KEY, JSON.stringify(CURRENT_VERSION)); console.log("Errors during API queries:", errorCount); } else { displayButtons(); console.log("Active achievement requests:", activeRequests); } }, 500); } else { displayButtons(); console.log("Active game requests:", activeRequests); } }, 250); }); }); }); })();