// ==UserScript==
// @name SteamHistoryLowestPrice
// @namespace [email protected]
// @description 显示游戏在各种商店中当前和历史最低价格及进包次数
// @include /^https?:\/\/store\.steampowered\.com\/app\/\d+/
// @version 2017-6-24
// @grant GM_xmlhttpRequest
// jshint esversion:6
// ==/UserScript==
// 货币符号
const CURRENCY_SYMBOLS = {
'AED': 'DH',
'AUD': 'A$',
'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 appId = location.href.match(/app\/(\d+)/)[1];
// console.log('[史低]: appid = ' + appId + ', requesting data info...'); // DEBUG
let cc = "cn";
let ccMatch = document.cookie.match(/steamCountry=([a-z]{2})/i);
if (ccMatch !== null && ccMatch.length == 2) {
cc = ccMatch[1];
}
// console.log('[史低]: request ' + appId + ' (' + cc + ') stores : %o', STORES); // DEBUG
AddLowestPriceTag(appId, STORES.join(","), cc, location.protocol);
// 在商店页添加史低信息
async function AddLowestPriceTag(appId, stores = "steam", cc = "cn", protocol = "https"){
let data = null;
let buyBtn = document.querySelector(".game_purchase_action");
let lowestInfo = document.createElement("div");
// 读取中……
lowestInfo.className = "game_lowest_price";
lowestInfo.innerText = "正在读取历史最低价格...";
// 插到购买按钮上面
if(buyBtn){
buyBtn.prepend(lowestInfo);
}
try {
data = JSON.parse( await GettingSteamDBAppInfo(appId, stores, cc, protocol) );
} catch (err) {
console.log('[史低]: ' + err);
}
// console.log('[史低]: app data ' + appId + ' : %o', data); // DEBUG
let appInfo = data["app/" + appId];
let metaInfo = data[".meta"];
// 如果查到info,并且有价格,塞到第一个购买按钮上面去
if(buyBtn && metaInfo && appInfo && appInfo.price && appInfo.lowest){
let currencySymbol = metaInfo.currency in CURRENCY_SYMBOLS
? CURRENCY_SYMBOLS[metaInfo.currency]
: metaInfo.currency;
lowestInfo.innerHTML =
// 历史最低
'历史最低价是 '
+ '<span style="cursor:help;text-decoration:underline;" title="' + appInfo.lowest.recorded_formatted + '">'
+ new Date(appInfo.lowest.recorded * 1e3).toLocaleDateString()
+ '</span> 时在 '
+ '<a target="_blank" href="' + appInfo.lowest.url + '"> '
+ appInfo.lowest.store
+ '</a> 中的 '
+ '<span class="discount_pct">-' + appInfo.lowest.cut + '%</span>'
+ '<a target="_blank" title="查看价格历史" href="' + appInfo.urls.history + '"> '
+ currencySymbol + ' ' + appInfo.lowest.price
+ '</a>'
// 第二行
+ '<br />'
// 进包次数
+ '进包 <a target="_blank" title="查看进包信息" href="' + appInfo.urls.bundles + '"'
+ (appInfo.bundles && appInfo.bundles.live.length > 0
? ' style="color:#0d0" title="' + appInfo.bundles.live.length + ' 个正在销售的慈善包"'
: '')
+'> '
+ appInfo.bundles.count
+ ' </a> 次,'
// 当前最低
+ (appInfo.price.price <= appInfo.lowest.price
? '<span class="game_purchase_discount_countdown">当前为历史最低价</span>,'
: '<span>当前最低价是</span>' )
+ '在 '
+ '<a target="_blank" href="' + appInfo.price.url + '"> '
+ appInfo.price.store
+ '</a> 中的 '
+ '<span class="discount_pct">-' + appInfo.price.cut + '%</span>'
+ '<a target="_blank" title="查看价格信息" href="' + appInfo.urls.info + '"> '
+ currencySymbol + ' ' + appInfo.price.price
+ '</a>';
}
// 返回史低info
return Promise.resolve(lowestInfo);
}
// 获取史低信息
async function GettingSteamDBAppInfo(appId, stores = "steam", cc = "cn", protocol = "https"){
let requestPromise = null;
if(!isNaN(appId) && parseInt(appId) > 0){
requestPromise = new Promise( (resolve, reject) => {
GM_xmlhttpRequest({
method: "GET",
url: protocol + "//api.enhancedsteam.com/pricev3/?appid=" + appId + "&stores=" + stores + "&cc=" + cc,
onload: function (response) {
resolve(response.response);
},
onerror: function (error) {
reject(error);
}
});
});
} else {
requestPromise = Promise.reject("Invalid appid");
}
return requestPromise;
}