返回首頁 

Greasy Fork is available in English.

Steam历史最低价格查询

在steam商店页显示当前app历史最低价格及进包次数


安装此脚本?
// ==UserScript==// @name        Steam历史最低价格查询// @namespace   SteamHistoryLowestPrice// @description 在steam商店页显示当前app历史最低价格及进包次数// @include      https://store.steampowered.com/app/*// @include      https://store.steampowered.com/bundle/*// @include      https://store.steampowered.com/sub/*// @author      软妹币玩家、byzod// @license     GPL version 3 or any later version// @version     1.3// @grant       GM_xmlhttpRequest// @grant       GM_getValue// @grant       GM_setValue// @grant       GM_registerMenuCommand// @enable      true// jshint esversion:6// ==/UserScript==// 显示样式// 0 = 显示在购买按钮上面// 1 = 显示在购买信息框上面const INFO_STYLE = 1;// 货币区域覆盖,两个字母的国家代号,大小写均可// 空字符("")代表不覆盖,使用steam的cookie中steamCountry的值// 见 https://zh.wikipedia.org/wiki/ISO_3166-1 或 https://en.wikipedia.org/wiki/ISO_3166-1// 常用 美国USD:"us", ##CNY: "cn", 英国GBP: "uk", 日本JPY: "jp", 俄国RUS: "ru"const CC_OVERRIDE = GM_getValue('region') || "cn";// 货币符号const CURRENCY_SYMBOLS = {'AED': 'DH','AUD': 'A$','ARS': 'ARS$','BRL': 'R$','CAD': 'CDN$','CHF': 'CHF','CLP': 'CLP$','CNY': '¥',  // Chines Yuan'COP': 'COL$','CRC': '₡',    // Costa Rican Colón'EUR': '€',    // Euro'GBP': '£',    // British Pound Sterling'HKD': 'HK$','IDR': 'Rp','ILS': '₪',    // Israeli New Sheqel'INR': '₹',    // Indian Rupee'JPY': '¥',    // Japanese Yen'KRW': '₩',    // South Korean Won'MXN': 'Mex$','MYR': 'RM','NGN': '₦',    // Nigerian Naira'NOK': 'kr','NZD': 'NZ$','PEN': 'S/.','PHP': '₱',    // Philippine Peso'PLN': 'zł',   // Polish Zloty'PYG': '₲',    // Paraguayan Guarani'RUB': 'pуб','SAR': 'SR','SGD': 'S$','THB': '฿',    // Thai Baht'TRY': 'TL','TWD': 'NT$','UAH': '₴',    // Ukrainian Hryvnia'USD': '$',    // US Dollar'VND': '₫',    // Vietnamese Dong'ZAR': 'R ',};// 查询历史低价包括的商店const STORES = ["steam",// "amazonus",// "impulse",// "gamersgate",// "direct2drive",// "origin",// "uplay",// "indiegalastore",// "gamesplanet",// "indiegamestand",// "gog",// "nuuvem",// "dlgamer",// "humblestore",// "squenix",// "bundlestars",// "fireflower",// "humblewidgets",// "newegg",// "coinplay",// "wingamestore",// "macgamestore",// "gamebillet",// "silagames",// "itchio",// "gamejolt",// "paradox"];// 在app页和愿望单页显示史低价格let urlMatch = location.href.match(/(app|sub|bundle)\/(\d+)/);let appId = "";let type = "";let subIds = [];let bundleids = [];if (urlMatch && urlMatch.length == 3) {type = urlMatch[1]appId = urlMatch[2];}// console.log('[史低]: ' + type + ' : ' + appId + ', requesting data info...'); // DEBUG// 获取subsdocument.querySelectorAll("input[name=subid]").forEach(sub => subIds.push(sub.value));// 获取bundlesdocument.querySelectorAll("input[name=bundleid]").forEach(sub => bundleids.push(sub.value));let cc = "cn";if (CC_OVERRIDE.length > 0) {// 使用覆盖的货币区域cc = CC_OVERRIDE;} else {// 使用默认的的货币区域let ccMatch = document.cookie.match(/steamCountry=([a-z]{2})/i);if (ccMatch !== null && ccMatch.length == 2) {cc = ccMatch[1];}}AddLowestPriceTag(appId, type, subIds, bundleids, STORES.join(","), cc, location.protocol);// 在商店页添加史低信息async function AddLowestPriceTag(appId, type = "app", subIds = [], bundleids = [], stores = "steam", cc = "cn", protocol = "https") {// 史低信息容器们let lowestPriceNodes = {};// 统计subidlet findSubIds = [];if (type == "bundle") {// bundle就一个, 视作subidfindSubIds.push(appId);} else if (type == "app" || type == "sub") {// app/sub/bundle 可能有好多findSubIds = subIds.slice();if (bundleids.length > 0) {findSubIds.push.apply(findSubIds, bundleids);}}// 寻找每一个subid的购买按钮,生成史低信息容器们findSubIds.forEach(subId => {let gameWrapper = null;try {gameWrapper = document.querySelector('.game_area_purchase_game input[value="' + subId + '"]');switch (INFO_STYLE) {case 0:gameWrapper = gameWrapper.parentNode.parentNode.querySelector('.game_purchase_action');break;case 1:gameWrapper = gameWrapper.parentNode.parentNode;break;}} catch (ex) {gameWrapper = null;}if (gameWrapper) {let lowestInfo = document.createElement("div");lowestInfo.className = "game_lowest_price";lowestInfo.innerText = "正在读取历史最低价格...";switch (INFO_STYLE) {case 0:gameWrapper.prepend(lowestInfo);break;case 1:gameWrapper.append(lowestInfo);break;}lowestPriceNodes[subId] = lowestInfo;}});// 获取sub们的数据let data = null;try {data = await GettingSteamDBAppInfo(appId, type, subIds, stores, cc, protocol);if ((typeof data == 'string'))data = JSON.parse(data);if (data.r###lt == 'success') {data = data.data;} else {console.log('[史低]: ' + err);}} catch (err) {console.log('[史低]: ' + err);}// console.log('[史低]: app ' + appId + ' data : %o', data); // DEBUG// 解析datalet appInfos = [];let metaInfo = data ? data[".meta"] : null;// 如果是bundle, 除了.meta外只有一个bundle/xxx,否则是一大堆xxxif (type == "bundle") {data = data.data;appInfos.push({ Id: appId, Info: data["bundle/" + appId] });} else if (type == "app" || type == "sub") {data = data.data;for (let key in data) {let appid = key.replace(new RegExp('(app|sub|bundle)/'), "");if (!isNaN(appid)) {appInfos.push({ Id: appid, Info: data[key] });}}}// console.log('[史低]: app ' + appId + ' metaInfo: %o', metaInfo); // DEBUG// console.log('[史低]: app ' + appId + ' appInfos: %o', appInfos); // DEBUG// 如果查到info,塞到购买按钮上面去if (metaInfo && appInfos.length > 0) {// 获取整体信息let currencySymbol = metaInfo.currency in CURRENCY_SYMBOLS? CURRENCY_SYMBOLS[metaInfo.currency]: metaInfo.currency;// 为每一个sub或bundle添加史低appInfos.forEach(app => {let lowestInfo = lowestPriceNodes[app.Id];if (lowestInfo) {lowestInfo.innerHTML =// 历史最低'历史最低价是&nbsp;'+ '<span style="cursor:help;text-decoration:underline;" title="' + app.Info.lowest.recorded_formatted + '">'+ new Date(app.Info.lowest.recorded * 1e3).toLocaleDateString()+ '</span>&nbsp;时在&nbsp;'+ '<a target="_blank" href="' + app.Info.lowest.url + '"> '+ app.Info.lowest.store+ '</a>&nbsp;中的&nbsp;'+ '<span class="discount_pct">-' + app.Info.lowest.cut + '%</span>'+ '<a target="_blank" title="查看价格历史" href="' + app.Info.urls.history + '"> '+ currencySymbol + ' ' + app.Info.lowest.price+ '</a>'// 第二行+ '<br />'// 进包次数+ '进包&nbsp;<a target="_blank" title="查看进包信息"  href="' + app.Info.urls.bundles + '"'+ (app.Info.bundles && app.Info.bundles.live.length > 0? ' style="color:#0d0" title="' + app.Info.bundles.live.length + ' 个正在销售的慈善包"': '')+ '> '+ app.Info.bundles.count+ ' </a>&nbsp;次,'// 当前最低+ (app.Info.price.price <= app.Info.lowest.price? '<span class="game_purchase_discount_countdown">当前为历史最低价</span>,': '<span>当前最低价是</span>')+ '在&nbsp;'+ '<a target="_blank" href="' + app.Info.price.url + '"> '+ app.Info.price.store+ '</a>&nbsp;中的&nbsp;'+ '<span class="discount_pct">-' + app.Info.price.cut + '%</span>'+ '<a target="_blank" title="查看价格信息"  href="' + app.Info.urls.info + '"> '+ currencySymbol + ' ' + app.Info.price.price+ '</a>';}});} else {// metaInfo为空,或者appInfos无内容console.log('[史低]: get lowest price failed, data = %o', data);for (let id in lowestPriceNodes) {lowestPriceNodes[id].innerHTML = "";}}// 返回史低inforeturn Promise.resolve(lowestPriceNodes);}// 获取史低信息async function GettingSteamDBAppInfo(appId, type = "app", subIds = [], stores = "steam", cc = "cn", protocol = "https") {let requestPromise = null;let bundleId = "";if (type == "bundle") {bundleId = appId;} else if (type == "app" || type == "sub") {bundleId = bundleids.join(',');}if (!isNaN(appId) && parseInt(appId) > 0) {let requestUrl = protocol + "//esapi.isthereanydeal.com/v01/prices/?"+ "bundleids=" + bundleId+ "&subids=" + subIds.join(',')+ "&appids=" + appId+ "&stores=" + stores+ "&cc=" + cc+ "&coupon=true";// console.log('[史低]: requestUrl: ' + requestUrl); // DEBUGrequestPromise = new Promise((resolve, reject) => {GM_xmlhttpRequest({method: "GET",url: requestUrl,onload: function (response) {resolve(response.response);},onerror: function (error) {reject(error);}});});} else {requestPromise = Promise.reject("Invalid appid");}return requestPromise;}// 設定區域function setRegion() {const region = prompt('輸入地區代碼');if(!region) {return;}GM_setValue('region', region);}GM_registerMenuCommand('設定地區', setRegion);