// ==UserScript== // @name Steam Group Filter Games // @version 1.0 // @namespace https://github.com/Davidj361/SteamGroupFilterGames // @description Filter Steam group members by what game they're playing // @include https://steamcommunity.com/groups/* // @include http://steamcommunity.com/groups/* // @run-at document-start // @grant unsafeWindow // @downloadURL https://raw.githubusercontent.com/Davidj361/SteamGroupFilterGames/master/steamgroupfiltergames.user.js // @updateURL https://raw.githubusercontent.com/Davidj361/SteamGroupFilterGames/master/steamgroupfiltergames.user.js // ==/UserScript== // Alot was put in to deal with the AJAX that Steam is doing and which this script relies on // And the hardest part was dealing with Greasemonkey's sandbox aspect // Everything outside the scope of this function won't be detected at runtime function steamGroupFilterGames_setupStartupFilter() { if (typeof jQuery === "function") { console.log("Steam Group Filter Games: Sucessfully found jQuery!"); } else { setTimeout(steamGroupFilterGames_setupStartupFilter, 100); return; } // Due to noConflict() var $ = jQuery; function steamGroupFilterGames_startupFilter($) { if (steamGroupFilterGames_found) return; var steamGroupFilterStarted = false; // Have to hook Steam's buggy AJAX which screws the script up if (typeof OnGroupContentLoadComplete === "function") { steamGroupFilterGames_found = true; var old = OnGroupContentLoadComplete; OnGroupContentLoadComplete = function(strTab, url, transport) { var ret = old(strTab, url, transport); steamGroupFilterStarted = false; steamGroupFilterGames_found = false; steamGroupFilterGames(); return ret; }; } else { setTimeout(steamGroupFilterGames_startupFilter, 100); return; } var main = function(jNode) { if (steamGroupFilterStarted) return; steamGroupFilterStarted = true; // Get the max page number var n = (function () { // We're already on the last page var $a = $('.pageLinks').contents().filter(function() { return this.nodeType === 3 && !$(this).parent('a').length && $(this).text().trim().length; })[1].data.trim(); // We're not on the last page var url = $(".pagelink").last().attr("href"); // Use some shitty regex to find the last page var reg = /\?p=([^"]+)/; // Filter for the page number var b = url.match(reg)[1]; // the number of pages for the group var result = 0; if ($a === undefined || isNaN($a)) result = b; else result = Math.max($a, b); return result; })(); // Global Script Variables var curr = 1; // Current page loaded var game = ""; var groupUrl = window.location.protocol + "//" + window.location.host + window.location.pathname; var nRetrieved = 0; // Number of users added and that passed the filter var stopped = false; // For the stop button var loadIconUrl = "https://raw.githubusercontent.com/Davidj361/SteamGroupFilterGames/master/loading.gif"; var startRetrieve = function() { $(".group_paging").first().empty(); // clear the old stuff // Show that we're retrieving var $loaderIcon = $("", { id: 'loaderIcon', src: loadIconUrl }); $(".group_paging").first().append($loaderIcon); $(".group_paging").first().append("
Filtering Page " + curr + "/" + n + "
"); // Add a button to stop filtering var $stopButton = $("
", { id: "stopFilterButton", style: "text-align: center;", class: "btn_green_white_innerfade btn_small_thin", click: function() { if (stopped) { $("#stopFilterButton").find("span").text("Stop"); stopped = false; $("#loaderIcon").show(); $("#steamgroupfiltergamesPageCount").show(); retrieveDataFromNextPage(); } else { $("#stopFilterButton").find("span").text("Continue"); stopped = true; $("#loaderIcon").hide(); $("#steamgroupfiltergamesPageCount").hide(); } } }); $(".group_paging").first().append($stopButton); $("#stopFilterButton").append("Stop"); retrieveDataFromNextPage(); }; // The function that is run when the filter is pressed var retrieveDataFromNextPage = function() { if (curr == n) return; var gets = []; // so we can have synchronousy // Hide the more button while we load the ajax $(".group_paging").last().hide(); // Hide the black bars // It will keep retrieving until it adds 51 users or reaches the end var pr = $.get(groupUrl + "/members/?p="+(curr++), {content_only: true}) .then(function (data) { // member block etc etc $(".member_block", data).each(function(index) { $(this).removeClass("last"); // CSS Fix if ($(this).html().toLowerCase().search(game) != -1) { var $elem = $(this); $(".member_block_content", $elem).attr("style", "display: inline-block;"); // CSS Fix var $loaderIcon = $("", { id: 'loaderIcon', src: loadIconUrl }); $elem.append($loaderIcon); $("#memberList").append($elem); nRetrieved++; // Check if there's a join game button on the person's profile var $profileUrl = $(".linkFriend", $(this)).attr("href"); $.get($profileUrl).then( function(d) { $button = $(".btn_green_white_innerfade", d).last(); if ( ($button.attr("href") != undefined) && ($button.attr("href").search("joinlobby") != -1) ) { $button.attr("style", "float: right;"); // CSS Fix $elem.append($button); } $("#loaderIcon", $elem).remove(); }); } }); }); gets.push(pr); // So we wait for all gets to be done with $.when.apply($, gets).then(function() { if(curr != n && nRetrieved < 51 && !stopped) { $("#steamgroupfiltergamesPageCount").text("Filtering Page " + curr + "/" + n); retrieveDataFromNextPage(); } else if (stopped) { // We pressed the stop button } else { $(".group_paging").first().empty(); $(".group_paging").last().show(); $("#memberList").append("
"); // Spacers due to horrible CSS if (curr == n) { $(".group_paging").empty(); $(".group_paging").last().append("
Reached End
"); } else if (nRetrieved >= 51) { nRetrieved = 0; // Reset the count // Create a more button that adds more players from each page when you click // It disappears after it reaches the max page var $moreButton = $("
", { id: "filterMoreButton", style: "text-align: center;", class: "btn_green_white_innerfade btn_small_thin", click: function() { startRetrieve(); if (curr == n) { $(".group_paging").empty(); $(".group_paging").last().text("Reached End"); } } }); $(".group_paging").first().append($moreButton); $("#filterMoreButton").append("\\|/ Get 51 Users More \\|/"); } } }); }; // Populate this page with all players from the steamgroup playing this game right now via AJAX // retrieve all the html for all pages in the group var filter = function() { game = $("#filterGameKey").val().toLowerCase(); curr = 1; stopped = false; // For the stop button nRetrieved = 0; // Clear up old data $("#memberList").empty(); $(".group_paging").empty(); $("#steamgroupfiltergamesSpacer").remove(); // $("#memberList").append("
"); // Spacers due to horrible CSS $(".group_paging").css("text-align", "center"); // CSS Fix $(".group_paging").css("height", "auto"); // CSS Fix startRetrieve(); }; // Create our html for the filterbar and submit button // Pretty much copy pasted the steam's for searching users var $filterbar = $('\
\
\ \
\ \
\
\
\
'); // Add a filter bar to filter the steam group for a game $(".search_controls").append($filterbar); // You need preventDefault so when you submit the page doesn't change and the form doesn't do a POST/GET $("#steamgroupfiltergames").bind('submit', function(evt) {evt.preventDefault(); filter(); }); } // // /*--- waitForKeyElements(): A utility function, for Greasemonkey scripts, // that detects and handles AJAXed content. // // Usage example: // // waitForKeyElements ( // "div.comments" // , commentCallbackFunction // ); // // //--- Page-specific function to do what we want when the node is found. // function commentCallbackFunction (jNode) { // jNode.text ("This comment changed by waitForKeyElements()."); // } // // IMPORTANT: This function requires your script to have loaded jQuery. // */ function waitForKeyElements ( selectorTxt, /* Required: The jQuery selector string that specifies the desired element(s). */ actionFunction, /* Required: The code to run when elements are found. It is passed a jNode to the matched element. */ bWaitOnce, /* Optional: If false, will continue to scan for new elements even after the first match is found. */ iframeSelector /* Optional: If set, identifies the iframe to search. */ ) { var targetNodes, btargetsFound; if (typeof iframeSelector == "undefined") targetNodes = $(selectorTxt); else targetNodes = $(iframeSelector).contents () .find (selectorTxt); if (targetNodes && targetNodes.length > 0) { btargetsFound = true; /*--- Found target node(s). Go through each and act if they are new. */ targetNodes.each ( function () { var jThis = $(this); var alreadyFound = jThis.data ('alreadyFound') || false; if (!alreadyFound) { //--- Call the payload function. var cancelFound = actionFunction (jThis); if (cancelFound) btargetsFound = false; else jThis.data ('alreadyFound', true); } } ); } else { btargetsFound = false; } //--- Get the timer-control variable for this selector. var controlObj = waitForKeyElements.controlObj || {}; var controlKey = selectorTxt.replace (/[^\w]/g, "_"); var timeControl = controlObj [controlKey]; //--- Now set or clear the timer as appropriate. if (btargetsFound && bWaitOnce && timeControl) { //--- The only condition where we need to clear the timer. clearInterval (timeControl); delete controlObj [controlKey] } else { //--- Set a timer, if needed. if ( ! timeControl) { timeControl = setInterval ( function () { waitForKeyElements ( selectorTxt, actionFunction, bWaitOnce, iframeSelector ); }, 300 ); controlObj [controlKey] = timeControl; } } waitForKeyElements.controlObj = controlObj; } waitForKeyElements(".pagelink", main, true); }; steamGroupFilterGames_startupFilter($); } unsafeWindow.steamGroupFilterGames_found = false; addJS_Node (null, null, steamGroupFilterGames_setupStartupFilter); function addJS_Node (text, s_URL, funcToRun, runOnLoad) { var D = document; var scriptNode = D.createElement ('script'); if (runOnLoad) { scriptNode.addEventListener ("load", runOnLoad, false); } scriptNode.type = "text/javascript"; if (text) scriptNode.textContent = text; if (s_URL) scriptNode.src = s_URL; if (funcToRun) scriptNode.textContent = '(' + funcToRun.toString() + ')()'; var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement; targ.appendChild (scriptNode); }