Skip to content

Instantly share code, notes, and snippets.

@burdiuz
Last active August 21, 2023 09:06
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save burdiuz/4b34bd1a40c88a4fbd0ccdb07fc6d096 to your computer and use it in GitHub Desktop.
Save burdiuz/4b34bd1a40c88a4fbd0ccdb07fc6d096 to your computer and use it in GitHub Desktop.
user-scripts for Steam Store

Steam Store user-scripts

For better Steam Store experience check SteamWebTools -- collection of useful user-scripts for Steam interface.

/*
Add apps to the cart. uses URL ids. To use overwrite X-Frame-Options to SAMEORIGIN.
*/
(() => {
const ids = ['ID', 'ID']; // list of ids
const frame = document.createElement('iframe');
/*
frame.width = 640;
frame.height = 480;
frame.style = 'position: absolute; z-index: 9999999; top: 0; left: 0';
//*/
document.body.appendChild(frame);
const next = () => {
console.log('load: ', ids[0]);
frame.src = `http://store.steampowered.com/app/${ids.shift()}/`;
};
frame.onload = () => {
const jQuery = frame.contentWindow.jQuery;
setTimeout(() => {
if(ids.length) {
setTimeout(next, 100);
}
const href = jQuery('div.btn_addtocart > a.btnv6_green_white_innerfade[href^="javascript:addToCart("]').attr('href');
const appId = href.match(/(\d+)\);$/)[1];
console.log(' - loaded, add to cart: ', appId);
frame.contentWindow.addToCart(appId);
}, 100);
jQuery('div.page_content_ctn div.block').remove()
jQuery('#app_reviews_hash').remove();
};
next();
})();
// Add to library all pending gifts. Should be executed on Pending Gifts page, use English locale.
(() => {
const timeout = (time) => new Promise((resolve) => setTimeout(resolve, time));
const getModalButtons = () => {
const modal = document.querySelector('.modal_box .modal_box_ctn');
modal.querySelectorAll('div.buttons').forEach((item) => (item.style.display==='none' ? item.remove() : null));
const buttons = modal.querySelectorAll('div.buttons');
return buttons[buttons.length-1];
};
const getModalAcceptButton = () => getModalButtons().querySelector('.btn_medium.btn_green_white_innerfade');
const getModalCloseButton = () => getModalButtons().querySelector('.btn_medium.btn_grey_white_innerfade.active');
const list = document.querySelectorAll('.pending_gift .gift_controls_buttons .btn_medium.btn_green_white_innerfade');
let index = 0;
const nextItem = () => {
console.log('Current Index:', index);
list[index++].click();
timeout(4000)
.then(() => getModalAcceptButton().click())
.then(() => timeout(1000))
.then(() => getModalCloseButton().click())
.then(() => timeout(1000))
.then(() => nextItem());
};
nextItem();
})();
/*
This script probably will not work, because your search results will reflect price bug,
so its better to use discount search with high values.
Go to page http://store.steampowered.com/search/?sort_by=Price_DESC&specials=1
Execute this script
*/
(() => {
let categories = '998,994,21,996,997'; // 998 - games
let currentPage = 0;
let lastPage = (() => {
let pages = jQuery('.search_pagination_right a');
return parseInt(jQuery(pages.get(pages.length - 2)).text());
})();
let list = null;
let currentRow = null;
let currentPrice = null;
window.ExecuteSearch = function(rgParameters) {
g_rgCurrentParameters = rgParameters;
g_ajaxInFlight = new Ajax.Updater('search_results', 'http://store.steampowered.com/search/results', {
parameters: rgParameters,
insertion: Insertion.Bottom,
method: 'get',
onComplete: function() {
jQuery('.search_pagination').remove();
loaded();
}
});
}
function loadNext() {
if (currentPage >= lastPage) return;
ExecuteSearch({
category1: categories,
specials: 1,
page: String(++currentPage),
sort_by: "Price_DESC"
});
}
function loaded() {
list = jQuery('a.search_result_row:not(.price_bug)');
if (list.length) {
list = list.splice(0, list.length);
parseListItem();
}
}
function parseListItem() {
currentRow = jQuery(list.shift());
try {
currentPrice = parseFloat(currentRow.find('.col.search_price.discounted.responsive_secondrow').text().match(/\$([\d\.]+)\s*$/)[1]);
verifyListItem();
} catch (error) {
console.log(currentItemTitle(), 'probably free');
nextListItem();
}
}
function verifyListItem() {
jQuery.get(currentRow.attr('href'), null, (html) => {
try {
let priceRaw = html.match(/class\s*=\s*"discount_final_price"\s*>\s*([^<]+)\s*/)[1];
let price = parseFloat(priceRaw.match(/[\d\.]+/)[0]);
if (currentPrice * 0.7 > price) {
currentRow.addClass('price_bug');
currentRow.find('.col.search_price.discounted.responsive_secondrow').text('$' + currentPrice + '/$' + price);
console.log(currentItemTitle(), currentPrice, price, ' - PRICE BUG - ');
} else {
console.log(currentItemTitle(), currentPrice, price, ' - skip - ');
currentRow.remove();
}
} catch (error) {
console.log(currentItemTitle(), ' - NO PRICE - ');
currentRow.remove();
}
nextListItem();
});
}
function nextListItem() {
if (list.length) {
parseListItem();
} else {
loadNext();
}
}
function currentItemTitle() {
return currentRow.find('.col.search_name').text().trim();
}
loaded();
})();
/* Filters items on Steam Store search page to display only fine discounted.
Steam Sale fine discounts
1. Open [Steam Search page](http://store.steampowered.com/search/?sort_by=Price_ASC&specials=1)
2. Check to be logged in, script will hide owned games
3. Open Browser console with Ctrl+Shift+I for Chrome(Console tab), Ctrl+Shift+K for Firefox, F12 for IE.
4. Paste code from [search-userscript.js](https://raw.githubusercontent.com/burdiuz/js-steam-fine-discounts/master/search-userscript.js) into console and press Enter
5. Wait for fine discounts to be found and displayed
*/
(function() {
var categories = '998,994,21,996,997'; // 998 - games
var currentPage = 0; // starting page number
var minDiscount = 80;
var skipOwned = true;
var lastPage = getLastPage() || 200; // how many pages to load and check
window.ExecuteSearch = function(rgParameters) {
g_rgCurrentParameters = rgParameters;
g_ajaxInFlight = new Ajax.Updater('search_results', 'http://store.steampowered.com/search/results', {
parameters: rgParameters,
insertion: Insertion.Bottom,
method: 'get',
onComplete: function() {
jQuery('.search_pagination').remove();
filterItems();
setTimeout(loadNext, 250);
}
});
}
function filterItems() {
jQuery('.search_result_row:not(.fine_discount)').each(function(index, node) {
row = jQuery(node);
var hide = false;
if (row.css('display') == 'none') hide = true;
else {
if (skipOwned && isOwned(row)) hide = true;
var item = row.find('.search_discount span');
var discount = parseFloat(String(item.text().match(/[\d\.]+/)));
if (!discount || discount < minDiscount) hide = true;
row.addClass('fine_discount');
}
if (hide) {
row.remove();
//row.css('display', 'none');
}
});
}
function loadNext() {
if (currentPage >= lastPage) return;
ExecuteSearch({
category1: categories,
specials: 1,
page: String(++currentPage),
sort_by: "PRICE_ASC"
});
}
function getLastPage() {
var pages = jQuery('.search_pagination_right a');
return parseInt(jQuery(pages.get(pages.length - 2)).text());
}
function isOwned(item) {
var bOwned = false;
var unPackageID = item.data('dsPackageid');
var strAppIDs = item.data('dsAppid');
if (unPackageID) {
if (GDynamicStore.s_rgOwnedPackages[unPackageID]) bOwned = true;
}
if (strAppIDs && typeof strAppIDs == 'string' && strAppIDs.indexOf(',') >= 0) {
var rgAppIDs = strAppIDs.split(',');
var bValid = false;
var bAllOwned = true;
for (var i = 0; i < rgAppIDs.length; i++) {
var unAppID = parseInt(rgAppIDs[i]);
if (!unAppID) continue;
bValid = true;
if (!GDynamicStore.s_rgOwnedApps[unAppID]) {
bAllOwned = false;
}
}
if (bValid && bAllOwned) {
bOwned = bAllOwned;
}
} else if (parseInt(strAppIDs)) {
// simple case of single appid
bOwned = Boolean(GDynamicStore.s_rgOwnedApps[parseInt(strAppIDs)]);
}
return bOwned;
}
loadNext();
})();
// Get SubId's for all items in cart. Should be executed on cart page, use English locale.
(() => {
const list = [];
const processed = [];
const ids = [];
jQuery('.cart_item').each((index, node) => {
const item = jQuery(node);
list.push({
link: item.find('.cart_item_img a').attr('href'),
title: item.find('.cart_item_desc a').text()
});
});
function next() {
let current = list.shift();
jQuery.get(current.link, null, (html) => {
//window.frameHtml = html;
let index = html.indexOf(current.title.trim() + '</h1>');
if (index<0) {
index = html.indexOf('In Cart</span>');
}
if (index>=0) {
html = html.substr(0, index);
const needle = '<form name="add_to_cart_';
index = html.lastIndexOf(needle);
if (index>=0) {
html = html.substr(index + needle.length);
const subId = html.match(/^\d+/);
if (subId) {
current.id = subId[0];
processed.push(current);
ids.push(current.id);
//console.log('Found:', current);
console.log(list.length, current.id, current.title);
} else {
console.log('NOF III:', current); // Not Found Error message
}
} else {
console.log('NOF II:', current); // Not Found Error message
}
} else {
console.log('NOF I:', current); // Not Found Error message
}
goTo();
})
.fail(() => {
console.log('NOF X:', current);
goTo();
});
}
function goTo() {
if (list.length) {
setTimeout(next, 0);
} else {
console.log('Items:', JSON.stringify(processed, null, 2));
console.log('IDs:', ids.join(', '));
}
}
console.log('Total items:', list.length);
goTo();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment