// ==UserScript==
// @name Currency Converter
// @namespace http://tampermonkey.net/
// @version 1.0.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/*
// @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 css
GM_addStyle(GM_getResourceText('SweetAlert2CSS'));
// setup swal
swal.setDefaults({
timer: 3000,
useRejections: false,
});
// load config
const config = JSON.parse(GM_getValue('Bisko_CC', '{}'));
const interval = 3 * 60 * 60 * 1000; // update exchange rate every 3 hours
// constructing functions
const has = Object.prototype.hasOwnProperty;
const preferredCurrency = () => {
const preferred = config.preferredCurrency;
if (has.call(config.exchangeRate.rates, preferred)) return preferred;
return 'CNY';
};
const updateCurrency = (currency = null) => {
const targetCurrency = currency || preferredCurrency();
const symbols = {
AUD: 'AU$',
CAD: 'CA$',
CNY: 'CN¥',
EUR: '€',
GBP: '£',
HKD: 'HK$',
JPY: 'JP¥',
KRW: '₩',
MYR: 'RM',
NTD: 'NT$',
NZD: 'NZ$',
RUB: 'руб',
USD: 'US$',
};
// converting price
$('.currency_price').each((index, element) => {
const $ele = $(element);
const data = $ele.attr('data-price').split(' ');
const originalCurrency = data[0];
const originalPrice = parseFloat(data[1]);
let convertedPrice = originalPrice;
if (originalCurrency !== targetCurrency && targetCurrency !== 'ORI') {
const toBase = originalPrice / config.exchangeRate.rates[originalCurrency];
const toTarget = toBase * config.exchangeRate.rates[targetCurrency];
convertedPrice = toTarget.toFixed(2);
}
$ele.text(convertedPrice);
});
// replacing currency symbol
const originalCurrency = $('.currency_name').attr('data-currency');
const symbol = targetCurrency === 'ORI' ? symbols[originalCurrency] : symbols[targetCurrency];
$('.currency_name').text(symbol);
};
const constructMenu = () => {
const $li = $('
');
const $ul = $('').appendTo($li);
const currencies = {
ORI: '恢復',
AUD: '澳幣',
CAD: '加幣',
CNY: '人民幣',
EUR: '歐元',
GBP: '英鎊',
HKD: '港幣',
JPY: '日圓',
KRW: '韓圓',
MYR: '令吉',
NTD: '台幣',
NZD: '紐幣',
RUB: '盧布',
USD: '美元',
};
const preferred = preferredCurrency();
GM_addStyle(`
.Bisko_CC_Menu ul {
display: none;
position: absolute;
padding: 0;
background-color: #272727;
z-index: 9999;
}
.Bisko_CC_Menu:hover ul {
display: block;
}
.Bisko_CC_Menu li {
padding: 2px 10px;
list-style-type: none;
cursor: pointer;
}
.Bisko_CC_Menu li:hover, .preferred {
background-color: SandyBrown;
}
`);
Object.keys(currencies).forEach((currency) => {
const itemName = `${currency} ${currencies[currency]}`;
$ul.append(
$(`${itemName}`)
.addClass(() => (preferred === currency ? 'preferred' : ''))
.click(() => {
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;
};
const handler = () => {
switch (location.host) {
case 'yuplay.ru':
GM_addStyle(`
.games-pricedown span.currency_price {
font-size: 18px;
}
.good-title span.currency_price {
margin-right: 3px;
font-size: 22px;
}
`);
$('.header-right').append(constructMenu());
$('.price')
.each((index, element) => {
$(element).contents().each((i, node) => {
const $node = $(node);
if (node.tagName === 'S') { // retail price node
$node
.addClass('currency_price')
.attr('data-price', `RUB ${$node.text().trim()}`);
} else if (node.nodeType === 3) { // sales price node
const price = node.textContent.trim();
if ($.isNumeric(price)) $node.replaceWith(`${price}`);
} else if (node.tagName === 'SPAN') { // currency node
$node
.addClass('currency_name')
.attr('data-currency', 'RUB');
}
});
})
.prev('.sale').find('s')
.each((i, node) => {
const $node = $(node);
$node
.addClass('currency_price')
.attr('data-price', `RUB ${$node.text().trim()}`);
});
break;
// case 'www.gamersgate.com':
case 'ru.gamersgate.com':
case 'cn.gamersgate.com': {
let originalCurrency = '';
if (location.host.startsWith('ru')) originalCurrency = 'RUB';
if (location.host.startsWith('cn')) originalCurrency = 'CNY';
GM_addStyle(`
.Bisko_CC_Menu {
width: 49px;
text-align: center;
}
.Bisko_CC_Menu svg {
width: 36px;
height: 36px;
background-color: #093745;
border: 1px solid #2c7c92;
}
.Bisko_CC_Menu, .Bisko_CC_Menu li {
background-image: none !important;
color: white;
}
.Bisko_CC_Menu li {
height: initial !important;
float: none !important;
padding: 5px 10px !important;
}
.Bisko_CC_Menu li:hover, .preferred {
background-color: SandyBrown !important;
}
`);
$('.btn_menuseparator').replaceWith(constructMenu());
$('.Bisko_CC_Menu a').replaceWith(`
`);
const prices = $('.price_price, .prtag, li > .f_right:nth-child(2)');
prices.each((index, element) => {
$(element)
.css('padding-right', '5px')
.find('span').each((i, node) => {
const $node = $(node);
const price = parseFloat($node.text().replace(/[^.0-9]/g, ''));
$node
.addClass('currency_price')
.attr('data-price', `${originalCurrency} ${price}`)
.after(``);
});
});
prices.prev().prev()
.find('.bold.white')
.each((index, element) => {
const $ele = $(element);
const price = parseFloat($ele.text().replace(/[^.0-9]/g, ''));
$ele
.addClass('currency_price')
.attr('data-price', `${originalCurrency} ${price}`);
});
prices.closest('.descr_cont').next().find('.grid-old-price').each((index, element) => {
const $ele = $(element);
const price = parseFloat($ele.text().replace(/[^.0-9]/g, ''));
$ele.html(`
`);
});
break;
}
case 'www.greenmangaming.com': {
GM_addStyle(`
.Bisko_CC_Menu > a {
margin: 0 !important;
padding: 6px 15px !important;
font-size: 14px;
}
.Bisko_CC_Menu > a:hover, .Bisko_CC_Menu li:hover, .preferred {
background-color: #494a4f !important;
}
`);
$('.megamenu').append(constructMenu());
let homepage = false;
let originalCurrency = $('.currency-code').eq(0).text();
const GMGHandler = (index, element) => {
const $ele = $(element);
let price = parseFloat($ele.text().replace(/[^.0-9]/g, ''));
if (homepage && ['RUB'].includes(originalCurrency)) price /= 100;
$ele.html(`
`);
};
// home page
if (originalCurrency.length === 0) {
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
mutation.addedNodes.forEach((addedNode) => {
if (addedNode.src && addedNode.src.includes('bam.nr-data.net')) {
const src = decodeURI(addedNode.src);
originalCurrency = src.split('currency_code":"').pop().slice(0, 3) || 'USD';
homepage = true;
$('.prices > span').each(GMGHandler);
updateCurrency();
observer.disconnect();
}
});
});
});
observer.observe(document.head, {
childList: true,
});
} else $('price > span').each(GMGHandler); // product page
break;
}
default:
}
updateCurrency();
};
const getExchangeRate = () => {
GM_xmlhttpRequest({
method: 'GET',
url: 'http://api.fixer.io/latest',
onload: (res) => {
if (res.status === 200) {
try {
const 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',
);
}
},
});
};
$(() => {
if (Object.keys(config).length === 0) getExchangeRate(); // first installed
else if (Date.now() - interval > config.lastUpdate) getExchangeRate(); // update exchange rate
else handler();
});