Puts a game-specific IsThereAnyDeal link to the game pages on Epic Games Store
目前為
// ==UserScript==
// @name IsThereAnyDeal game-specific links on EpicGames Store
// @namespace 1N07
// @version 0.7.0
// @description Puts a game-specific IsThereAnyDeal link to the game pages on Epic Games Store
// @author 1N07
// @license unlicense
// @icon https://epicgames.com/favicon.ico
// @compatible firefox Tested on Firefox v122.0 and Tampermonkey 5.0.1
// @compatible firefox Likely to work on other userscript managers, but not tested
// @compatible chrome Latest version untested, but likely works with at least Tampermonkey
// @compatible opera Latest version untested, but likely works with at least Tampermonkey
// @compatible edge Latest version untested, but likely works with at least Tampermonkey
// @compatible safari Latest version untested, but likely works with at least Tampermonkey
// @match https://store.epicgames.com/*
// @grant GM_registerMenuCommand
// @grant GM_unregisterMenuCommand
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_xmlhttpRequest
// @connect isthereanydeal.com
// @noframes
// ==/UserScript==
(function() {
'use strict';
//var OpenSearchResultsInsteadHandle;
var OpenSearchResultsInstead = true; // = GM_getValue("OpenSearchResultsInstead", false);
//SetOpenSearchResultsInsteadHandle();
var lastUrl = null;
setInterval(() => {
if(window.location.href != lastUrl)
OnUrlChange();
}, 200);
var windowLoaded = false;
window.onload = () => {windowLoaded = true;};
function OnUrlChange()
{
lastUrl = window.location.href;
//Epic Game Store Page
if(window.location.href.match(/https:\/\/store\.epicgames\.com\/.+?\/(p|b)\/.+/g))
{
var insertInterval, place;
insertInterval = setInterval(function(){
place = document.querySelector('button[data-testid="purchase-cta-button"]');
if(place)
{
clearInterval(insertInterval);
addGlobalStyle(`
#ITADButt {
font-size: 11px;
letter-spacing: 0.5px;
font-weight: 500;
display: block;
position: relative;
border-radius: 4px;
text-transform: none;
text-align: center;
-moz-box-align: center;
align-items: center;
-moz-box-pack: center;
justify-content: center;
line-height: 15px;
padding: 5px 20px;
margin: 5px auto;
background-color: royalblue;
color: rgb(245, 245, 245);
height: 35px;
width: auto;
min-width: auto;
}
#ITADButt:hover, #ITADButt:focus, #ITADButt:active
{
filter: brightness(125%);
}
`);
InsertAndMakeSureButtonStays();
}
}, 200);
}
}
function InsertAndMakeSureButtonStays()
{
var ButtonStayInterval;
ButtonStayInterval = setInterval(() => {
if(!document.getElementById("ITADButt"))
{
let place = document.querySelector('button[data-testid="purchase-cta-button"]');
if(place)
{
let newElem = CreateHTMLFrag(`<button id="ITADButt" style="background-color: royalblue;height: 35px;padding: 5px 20px;margin: 5px auto;display: block;"><span class="css-hahhpe-PurchaseCTA__ctaText">IsThereAnyDeal</span></button>`);
place.parentNode.insertBefore(newElem, place);
document.getElementById("ITADButt").onclick = GoToITAD;
}
}
if(windowLoaded)
clearInterval(ButtonStayInterval);
}, 200);
}
function GoToITAD()
{
let name = null //Disabled this method for now, it doesn't seem that great afterall... document.getElementById("page-meta-keywords").getAttribute("content"); //this seems to be a fairly reliable way to get the title of the game without any affixes or what have you, like editions etc.
if(name === null || name.length == 0)
name = document.querySelector(`h1 > span[data-testid="pdp-title"]`).textContent;
if(name === null || name.length == 0)
alert("ITAD on EG: Could not find game title");
let link = "https://isthereanydeal.com/search/?q=" + encodeURIComponent(name);
if(OpenSearchResultsInstead)
window.open(link, "_blank");
else
{
let tab = window.open("", "_blank");
tab.document.write(`<style>body {background-color: #333; text-align: center; padding-top: 10%;}</style>
<h1 style="color: #BBB;">Loading IsThereAnyDeal page for:</h1>
<h1 style="color: #BBB;">`+name+`</h1>
<img src="https://i.imgur.com/zQZUBjE.gif" style="width: 100px;">`);
GM_xmlhttpRequest({
method: "GET",
url: link,
onload: (res) => {
let ITADPage = new DOMParser().parseFromString(res.responseText, "text/html").getElementById("pageContainer"); //need to parse from plain text because ITAD returns invalid XML
let gameLink = GetLinkToGamePage(ITADPage, name);
if(gameLink == null)
tab.alert("could not find game");
else
{
tab.open(gameLink, "_self");
}
},
onerror: () => {
tab.alert("GM_xmlhttpRequest error");
},
onabort: () => {
tab.alert("GM_xmlhttpRequest aborted");
},
ontimeout: () => {
tab.alert("GM_xmlhttpRequest timeout");
}
});
}
}
function GetLinkToGamePage(ITADPage, searchTerm)
{
let reDirLinks = ITADPage.querySelectorAll(".card__title");
if(reDirLinks !== null && reDirLinks.length > 0)
{
let searchTermRE = new RegExp(searchTerm,"g");
let leastExtraEl = null, leastExtraNum = 99999;
for(let i = 0; i < reDirLinks.length; i++)
{
let thisLen = reDirLinks[i].textContent.replace(searchTermRE, "").length;
if(thisLen < leastExtraNum)
{
leastExtraEl = reDirLinks[i];
leastExtraNum = thisLen;
}
}
if(leastExtraEl !== null)
{
//try {leastExtraEl.parentNode.parentNode.parentNode.parentNode.style.border = "5px dotted greenyellow";} catch(err){}
return ("https://isthereanydeal.com" + leastExtraEl.href).replace("https://store.epicgames.com", ""); //.href apparently REALLY wants to put the Epic domain in there for some reason, so removing that...
}
return null;
}
return null;
}
function CreateHTMLFrag(htmlStr) {
var el = document.createElement("div");
el.innerHTML = htmlStr;
return el;
var frag = document.createDocumentFragment(),
temp = document.createElement('div');
temp.innerHTML = htmlStr;
while (temp.firstChild) {
frag.appendChild(temp.firstChild);
}
return frag;
}
function addGlobalStyle(css)
{
var head, style;
head = document.getElementsByTagName('head')[0];
if (!head) { return; }
style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = css;
head.appendChild(style);
}
function SetOpenSearchResultsInsteadHandle() {
GM_unregisterMenuCommand(OpenSearchResultsInsteadHandle);
OpenSearchResultsInsteadHandle = GM_registerMenuCommand("Open search results instead (" + (OpenSearchResultsInstead ? "On" : "Off") + ") -click to change-", function(){
OpenSearchResultsInstead = !OpenSearchResultsInstead;
GM_setValue("OpenSearchResultsInstead", OpenSearchResultsInstead);
SetOpenSearchResultsInsteadHandle();
if(confirm('Press "OK" to refresh the page to apply new settings'))
location.reload();
});
}
})();