// ==UserScript==
// @name Currency Converter
// @namespace http://tampermonkey.net/
// @version 2.2.0
// @description try to take over the world!
// @icon http://store.steampowered.com/favicon.ico
// @author Bisumaruko
// @include http*://yuplay.ru/*
// @include http*://*.gamersgate.com/*
// @include http*://www.greenmangaming.com/*
// @include http*://gama-gama.ru/*
// @include http*://*.gamesplanet.com/*
// @include http*://www.cdkeys.com/*
// @include http*://directg.net/*
// @include http*://www.humblebundle.com/*
// @include http*://www.indiegala.com/*
// @include http*://www.bundlestars.com/*
// @include http*://www.opiumpulses.com/*
// @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.slim.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/limonte-sweetalert2/6.6.6/sweetalert2.min.js
// @resource SweetAlert2CSS https://cdnjs.cloudflare.com/ajax/libs/limonte-sweetalert2/6.6.6/sweetalert2.min.css
// @grant GM_xmlhttpRequest
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_addStyle
// @grant GM_getResourceText
// @run-at document-start
// @connect api.fixer.io
// @downloadURL none
// ==/UserScript==
/*
global GM_xmlhttpRequest, GM_setValue, GM_getValue, GM_addStyle, GM_getResourceText,
$, swal,
document, location, MutationObserver
*/
// inject swal css
GM_addStyle(GM_getResourceText('SweetAlert2CSS'));
// setup swal
swal.setDefaults({
timer: 3000,
useRejections: false
});
// load config
var config = JSON.parse(GM_getValue('Bisko_CC', '{}'));
var interval = 3 * 60 * 60 * 1000; // update exchange rate every 3 hours
var currencies = {
ORI: {
nameEN: '',
nameZH: '恢復',
symbol: ''
},
AUD: {
nameEN: 'Australian Dollar',
nameZH: '澳幣',
symbol: 'AU$'
},
CAD: {
nameEN: 'Canadian Dollar',
nameZH: '加幣',
symbol: 'CA$'
},
CNY: {
nameEN: 'Chinese Yuan',
nameZH: '人民幣',
symbol: 'CN¥'
},
EUR: {
nameEN: 'Euro',
nameZH: '歐元',
symbol: '€'
},
GBP: {
nameEN: 'Great Britain Pound',
nameZH: '英鎊',
symbol: '£'
},
HKD: {
nameEN: 'Hong Kong Dollar',
nameZH: '港幣',
symbol: 'HK$'
},
JPY: {
nameEN: 'Japanese Yen',
nameZH: '日圓',
symbol: 'JP¥'
},
KRW: {
nameEN: 'South Korean Won',
nameZH: '韓圓',
symbol: '₩'
},
MYR: {
nameEN: 'Malaysian Ringgit',
nameZH: '令吉',
symbol: 'RM'
},
NTD: {
nameEN: 'New Taiwan Dollar',
nameZH: '台幣',
symbol: 'NT$'
},
NZD: {
nameEN: 'New Zealand Dollar',
nameZH: '紐幣',
symbol: 'NZ$'
},
RUB: {
nameEN: 'Russian Ruble',
nameZH: '盧布',
symbol: 'руб'
},
USD: {
nameEN: 'United States Dollar',
nameZH: '美元',
symbol: 'US$'
}
};
var originalCurrency = 'USD';
// jQuery extension
$.fn.price = function price() {
return this.eq(0).text().replace(/[^.0-9]/g, '');
};
$.fn.bindPriceData = function bindPriceData() {
return this.each(function (index, element) {
var $ele = $(element);
$ele.addClass('CCPrice').attr('data-CCPrice', JSON.stringify({
currency: originalCurrency,
price: $ele.text().replace(/[^.0-9]/g, '')
}));
});
};
// constructing functions
var has = Object.prototype.hasOwnProperty;
var preferredCurrency = function preferredCurrency() {
return has.call(config.exchangeRate.rates, config.preferredCurrency) ? config.preferredCurrency : 'CNY';
}; // default to CNY
var updateCurrency = function updateCurrency() {
var currency = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
var targetCurrency = currency || preferredCurrency();
$('.CCPrice').each(function (index, element) {
var $ele = $(element);
var data = JSON.parse($ele.attr('data-CCPrice'));
var convertedPrice = 0;
if (targetCurrency === 'ORI') {
targetCurrency = data.currency;
convertedPrice = data.price;
} else {
var rates = config.exchangeRate.rates;
convertedPrice = data.price * (rates[targetCurrency] / rates[data.currency]);
}
$ele.text(convertedPrice.toLocaleString('en', {
style: 'currency',
currency: targetCurrency,
maximumFractionDigits: 2
}).replace('MYR', currencies.MYR.symbol).replace('NTD', currencies.NTD.symbol));
});
};
var constructMenu = function constructMenu() {
var $li = $('
');
var $ul = $('').appendTo($li);
var preferred = preferredCurrency();
GM_addStyle('\n .Bisko_CC_Menu ul {\n display: none;\n position: absolute;\n padding: 0;\n background-color: #272727;\n z-index: 9999;\n }\n .Bisko_CC_Menu:hover ul {\n display: block;\n }\n .Bisko_CC_Menu li {\n padding: 2px 10px;\n list-style-type: none;\n cursor: pointer;\n }\n .Bisko_CC_Menu li:hover, .preferred {\n background-color: SandyBrown;\n }\n ');
Object.keys(currencies).forEach(function (currency) {
var itemName = currency + ' ' + currencies[currency].nameZH;
$ul.append($('' + itemName + '').addClass(function () {
return preferred === currency ? 'preferred' : '';
}).click(function () {
config.preferredCurrency = currency;
GM_setValue('Bisko_CC', JSON.stringify(config));
updateCurrency(currency);
$('.Bisko_CC_Menu .preferred').removeClass('preferred');
$('.Bisko_CC_Menu .' + currency).addClass('preferred');
}));
});
return $li;
};
var handler = function handler() {
switch (location.host) {
case 'yuplay.ru':
originalCurrency = 'RUB';
GM_addStyle('\n .games-pricedown span.CCPrice {\n font-size: 18px;\n }\n .good-title span.CCPrice {\n margin-right: 3px;\n font-size: 22px;\n }\n ');
$('.header-right').append(constructMenu());
// homepage games-pricedown
$('.games-pricedown .sale > s, .games-pricedown .price').bindPriceData();
// homepage game box & product page
$('.games-box .price, .good-title .price').contents().each(function (index, node) {
var $node = $(node);
var text = $node.text().trim();
if (node.tagName === 'S') $node.bindPriceData(); // retail price
if (node.tagName === 'SPAN') $node.remove(); // currency
else if (node.nodeType === 3 && text.length > 0) {
// sales price
$node.replaceWith($('' + text + '').bindPriceData());
}
});
break;
case 'gama-gama.ru':
originalCurrency = 'RUB';
GM_addStyle('\n .Bisko_CC_Menu > a, .Bisko_CC_Menu li {\n color: white;\n }\n .Bisko_CC_Menu ul {\n margin: 0;\n }\n ');
$('#top_back').append(constructMenu().wrapInner('').children().unwrap());
// homepage
$('.price_1, .old_price, .promo_price').bindPriceData();
// product page
$('.card-info-oldprice > span, .card-info-price > span').bindPriceData();
$('.card-info-oldprice, .card-info-price').contents().filter(function (i, node) {
return node.nodeType !== 1;
}).remove();
break;
// case 'www.gamersgate.com':
case 'ru.gamersgate.com':
case 'cn.gamersgate.com':
if (location.host.startsWith('ru')) originalCurrency = 'RUB';
if (location.host.startsWith('cn')) originalCurrency = 'CNY';
GM_addStyle('\n .Bisko_CC_Menu {\n width: 49px;\n text-align: center;\n }\n .Bisko_CC_Menu svg {\n width: 36px;\n height: 36px;\n background-color: #093745;\n border: 1px solid #2c7c92;\n }\n .Bisko_CC_Menu, .Bisko_CC_Menu li {\n background-image: none !important;\n color: white;\n }\n .Bisko_CC_Menu li {\n height: initial !important;\n float: none !important;\n padding: 5px 10px !important;\n }\n .Bisko_CC_Menu li:hover, .preferred {\n background-color: SandyBrown !important;\n }\n ');
$('.btn_menuseparator').replaceWith(constructMenu());
$('.Bisko_CC_Menu a').replaceWith('\n \n ');
// homepage & product page
$('\n .prtag > span,\n .grid-old-price,\n .price_price > span,\n div > span > .bold.white,\n li > .f_right:nth-child(2) > span\n ').bindPriceData();
break;
case 'www.greenmangaming.com':
originalCurrency = $('.currency-code').eq(0).text();
GM_addStyle('\n .Bisko_CC_Menu > a {\n margin: 0 !important;\n padding: 6px 15px !important;\n font-size: 14px;\n }\n .Bisko_CC_Menu > a:hover, .Bisko_CC_Menu li:hover, .preferred {\n background-color: #494a4f !important;\n }\n ');
$('.megamenu').append(constructMenu());
// home page
new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
mutation.addedNodes.forEach(function (addedNode) {
if (addedNode.src && addedNode.src.includes('bam.nr-data.net')) {
var $prices = $('.prices > span');
var src = decodeURI(addedNode.src);
originalCurrency = src.split('currency_code":"').pop().slice(0, 3) || 'USD';
// offset decimal place in Europe (. ,)
if (['EUR', 'RUB'].includes(originalCurrency)) {
$prices.text(function (i, text) {
return text.replace(',', '.');
});
}
$prices.bindPriceData();
updateCurrency();
}
});
});
}).observe(document.head, {
childList: true
});
// product page
$('price > span').bindPriceData();
break;
case 'uk.gamesplanet.com':
case 'de.gamesplanet.com':
case 'fr.gamesplanet.com':
{
originalCurrency = !location.host.startsWith('uk') ? 'EUR' : 'GBP';
var GPHandler = function GPHandler() {
var $prices = $('.price_base > strike, .price_current');
$('.container > ul').append(constructMenu());
// offset decimal place in Europe (. ,)
if (!location.host.startsWith('uk')) {
$prices.text(function (i, text) {
return text.replace(',', '.');
});
}
$prices.bindPriceData();
updateCurrency();
};
GPHandler(true);
new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
mutation.removedNodes.forEach(function (removedNode) {
if (removedNode.id === 'nprogress') GPHandler();
});
});
}).observe(document, {
childList: true,
subtree: true
});
break;
}
case 'www.cdkeys.com':
{
originalCurrency = $('.currency-switcher:first-child .value').text();
var currenciesDefault = ['AUD', 'CAD', 'EUR', 'GBP', 'JPY', 'NZD', 'USD'];
var currenciesAppend = ['CNY', 'HKD', 'KRW', 'MYR', 'NTD', 'RUB'];
// bind event to default currency switcher to save preferrred currency
$('.currency-switcher:first-child ul span').each(function (index, element) {
var $ele = $(element);
var currency = $ele.text().slice(0, 3);
if (currenciesDefault.includes(currency)) {
$ele.parent().click(function () {
config.preferredCurrency = currency;
GM_setValue('Bisko_CC', JSON.stringify(config));
});
}
});
// append currencies not in the default currency switcher
currenciesAppend.forEach(function (currency) {
$('.currency-switcher:first-child ul').append($('' + currency + ' - ' + currencies[currency].nameEN + '').click(function () {
config.preferredCurrency = currency;
GM_setValue('Bisko_CC', JSON.stringify(config));
updateCurrency(currency);
}));
});
$('.price').bindPriceData();
break;
}
case 'directg.net':
originalCurrency = 'KRW';
GM_addStyle('\n .Bisko_CC_Menu ul {\n width: 180px;\n border-top: 3px solid #67c1f5;\n background-color: #1b2838 !important;\n opacity: 0.95;\n color: rgba(255,255,255,0.5) !important;\n }\n .Bisko_CC_Menu ul li {\n padding: 10px 30px;\n font-weight: bold;\n }\n .Bisko_CC_Menu ul li:hover, .preferred {\n background-color: initial !important;\n color: white;\n }\n ');
$('.nav').append(constructMenu());
$('span.PricebasePrice, span.PricesalesPrice').bindPriceData().next('span[itemprop="priceCurrency"]').remove();
break; /*
case 'www.origin.com': {
const region = location.pathname.split('/')[1];
const currencyRegion = {
twn: 'NTD',
jpn: 'JPY',
rus: 'RUB',
usa: 'USD',
nzl: 'NZD',
irl: 'EUR',
kor: 'KRW',
};
}*/
case 'www.humblebundle.com':
originalCurrency = 'USD';
GM_addStyle('\n .Bisko_CC_Menu {\n float: left;\n }\n .Bisko_CC_Menu > a {\n display: block;\n padding: 15px 20px;\n }\n .Bisko_CC_Menu ul {\n background-color: #494f5c !important;\n color: rgba(255, 255, 255, 0.6);\n }\n .Bisko_CC_Menu ul li {\n padding: 5px 10px;\n }\n .Bisko_CC_Menu ul li:hover, .preferred {\n background-color: initial !important;\n color: white;\n }\n ');
$('.nav:first-child').append(constructMenu());
new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
mutation.removedNodes.forEach(function (removedNode) {
if (removedNode.data === 'The Humble Store: Loading') {
$('.price, .store-price, .full-price, .current-price').bindPriceData();
updateCurrency();
}
});
});
}).observe(document.head, {
childList: true,
subtree: true
});
break;
case 'www.indiegala.com':
originalCurrency = 'USD';
GM_addStyle('\n .Bisko_CC_Menu ul {\n transform: translateY(-100%);\n background-color: #474747 !important;\n border: 1px solid #272727;\n }\n .Bisko_CC_Menu ul li {\n padding: 8px 15px;\n color: #dad6ca;\n }\n .Bisko_CC_Menu ul li:hover, .preferred {\n background-color: #2E2E2E !important;\n color: white;\n }\n ');
$('#libdContainer > ul:not(:first-child)').append(constructMenu());
$('.Bisko_CC_Menu > a').addClass('libd-group-item libd-bounce');
// homepage & product page
$('.inner-info, .inner, .price-container').contents().each(function (index, node) {
var $node = $(node);
var text = $node.text().trim();
$node.parent().parent().css('overflow', 'hidden');
if (node.nodeType === 1 && node.tagName !== 'BR') $node.bindPriceData();else if (node.nodeType === 3 && text.length) {
$node.replaceWith($('' + text + '').bindPriceData());
}
});
// search result
$('.price-cont').bindPriceData();
break;
case 'www.bundlestars.com':
originalCurrency = 'USD';
GM_addStyle('\n .Bisko_CC_Menu ul {\n background-color: #212121 !important;\n }\n .Bisko_CC_Menu ul li {\n padding: 8px 15px;\n }\n .Bisko_CC_Menu ul li:hover, .preferred {\n background-color: #1A1A1A !important;\n }\n ');
$('.nav').eq(0).append(constructMenu());
new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
mutation.removedNodes.forEach(function (removedNode) {
if (removedNode.id === 'loading-bar-spinner') {
$('.bs-price, .bs-currency-discount > span, .bs-currency-price').bindPriceData();
$('.bs-card-meta > .bs-pricing, .bs-card-meta > .bs-currency-discount').css({
position: 'absolute',
right: '19px'
});
updateCurrency();
}
});
});
}).observe(document.body, {
childList: true
});
break;
case 'www.opiumpulses.com':
originalCurrency = 'USD';
GM_addStyle('\n .Bisko_CC_Menu {\n float: right;\n margin-top: 5px;\n padding: 1px 5px;\n vertical-align: middle;\n background-image: linear-gradient(#4E4E4E, #101112 40%, #191b1d);\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n }\n .Bisko_CC_Menu > a {\n color: #f89406;\n }\n ');
$('.top-bar > .container > form').after(constructMenu().wrapInner('').children().unwrap());
// homepage
$('.album__container p > span:first-of-type').bindPriceData();
// store page
$('.product-box s, .product-box .text-danger').bindPriceData();
new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
mutation.addedNodes.forEach(function (addedNode) {
if (addedNode.id === 'productlistview') {
$(addedNode).find('.product-box s, .product-box .text-danger').bindPriceData();
updateCurrency();
}
});
});
}).observe(document.body, {
childList: true,
subtree: true
});
break;
default:
}
// only update prices when appended currencies are selected
if (originalCurrency !== preferredCurrency()) updateCurrency();
};
var getExchangeRate = function getExchangeRate() {
GM_xmlhttpRequest({
method: 'GET',
url: 'http://api.fixer.io/latest',
onload: function onload(res) {
if (res.status === 200) {
try {
var exchangeRate = JSON.parse(res.response);
config.exchangeRate = exchangeRate;
config.lastUpdate = Date.now();
// add EUR, NTD
config.exchangeRate.rates.EUR = 1;
config.exchangeRate.rates.NTD = config.exchangeRate.rates.HKD * 3.9;
GM_setValue('Bisko_CC', JSON.stringify(config));
handler();
} catch (e) {
swal('Parsing Failed', 'An error occured when parsing exchange rate data, please reload to try again', 'error');
}
} else {
swal('Loading Failed', 'Unable to fetch exchange rate data, please reload to try again', 'error');
}
}
});
};
$(function () {
if (Object.keys(config).length === 0) getExchangeRate(); // first installed
else if (Date.now() - interval > config.lastUpdate) getExchangeRate(); // update exchange rate
else handler();
});