Add script.user.js
This commit is contained in:
239
script.user.js
Normal file
239
script.user.js
Normal file
@@ -0,0 +1,239 @@
|
||||
// ==UserScript==
|
||||
// @name RuneScape Wiki Ely Prices
|
||||
// @namespace https://ely.gg/
|
||||
// @version 1.0.0
|
||||
// @description Show Ely prices on RuneScape Wiki pages
|
||||
// @match https://runescape.wiki/w/*
|
||||
// @grant GM_xmlhttpRequest
|
||||
// @connect www.ely.gg
|
||||
// @connect gist.yorgei.dev
|
||||
// ==/UserScript==
|
||||
|
||||
(async function () {
|
||||
const dataUrl = 'https://git.yorgei.dev/yorgei/rs-wiki-ely/raw/branch/main/new_data.json';
|
||||
|
||||
function gmFetchJson(url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
GM_xmlhttpRequest({
|
||||
method: 'GET',
|
||||
url,
|
||||
onload: res => {
|
||||
try {
|
||||
const json = JSON.parse(res.responseText);
|
||||
resolve(json);
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
},
|
||||
onerror: err => reject(err)
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function fetchPriceData(itemId) {
|
||||
const url = `https://www.ely.gg/chart/${itemId}/prices`;
|
||||
const data = await gmFetchJson(url);
|
||||
return data;
|
||||
}
|
||||
|
||||
try {
|
||||
const pageTitleElement = document.querySelector('.mw-page-title-main');
|
||||
if (!pageTitleElement) return;
|
||||
|
||||
const originalCursor = pageTitleElement.style.cursor;
|
||||
|
||||
const dataResponse = await fetch(dataUrl);
|
||||
const itemData = await dataResponse.json();
|
||||
|
||||
const pageTitle = pageTitleElement.textContent.trim();
|
||||
const urlPath = window.location.pathname;
|
||||
const urlTitle = urlPath.replace('/w/', '').replace(/_/g, ' ');
|
||||
|
||||
let itemId = null;
|
||||
|
||||
if (itemData[pageTitle]) {
|
||||
itemId = itemData[pageTitle];
|
||||
} else if (itemData[urlTitle]) {
|
||||
itemId = itemData[urlTitle];
|
||||
} else {
|
||||
for (const [itemName, id] of Object.entries(itemData)) {
|
||||
const itemNameBase = itemName.split('(')[0].trim();
|
||||
const lowerItem = itemName.toLowerCase();
|
||||
const lowerBase = itemNameBase.toLowerCase();
|
||||
const lowerTitle = pageTitle.toLowerCase();
|
||||
const lowerUrlTitle = urlTitle.toLowerCase();
|
||||
if (
|
||||
lowerItem === lowerTitle ||
|
||||
lowerItem === lowerUrlTitle ||
|
||||
lowerBase === lowerTitle ||
|
||||
lowerBase === lowerUrlTitle
|
||||
) {
|
||||
itemId = id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!itemId) return;
|
||||
|
||||
try {
|
||||
const priceData = await fetchPriceData(itemId);
|
||||
if (!priceData.items || !priceData.items.length) return;
|
||||
|
||||
const lastItem = priceData.items[priceData.items.length - 1];
|
||||
const price = Number(lastItem.price).toLocaleString();
|
||||
const date = new Date(lastItem.date).toLocaleDateString();
|
||||
const saleType = String(lastItem.purchase || '').toLowerCase();
|
||||
let saleTypeShort = saleType;
|
||||
if (saleType === 'sold') {
|
||||
saleTypeShort = 'inb';
|
||||
} else if (saleType === 'bought') {
|
||||
saleTypeShort = 'ins';
|
||||
}
|
||||
|
||||
const priceDisplay = document.createElement('span');
|
||||
priceDisplay.textContent = ` (${price} gp - ${saleTypeShort} - ${date})`;
|
||||
priceDisplay.style.color = '#5a8c5a';
|
||||
priceDisplay.style.fontWeight = 'bold';
|
||||
priceDisplay.style.fontSize = '0.9em';
|
||||
|
||||
pageTitleElement.appendChild(priceDisplay);
|
||||
|
||||
pageTitleElement.style.cursor = 'pointer';
|
||||
pageTitleElement.addEventListener('click', async () => {
|
||||
try {
|
||||
const latestPriceData = await fetchPriceData(itemId);
|
||||
if (latestPriceData.items && latestPriceData.items.length > 0) {
|
||||
showSalesPopup(latestPriceData.items, itemId, pageTitleElement, originalCursor);
|
||||
} else {
|
||||
window.open(`https://www.ely.gg/view_item/${itemId}`, '_blank');
|
||||
}
|
||||
} catch (e) {
|
||||
window.open(`https://www.ely.gg/view_item/${itemId}`, '_blank');
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
const idDisplay = document.createElement('span');
|
||||
idDisplay.textContent = ` (ID: ${itemId}) | Failed to get price.`;
|
||||
idDisplay.style.color = '#5a8c5a';
|
||||
idDisplay.style.fontWeight = 'bold';
|
||||
idDisplay.style.fontSize = '0.9em';
|
||||
pageTitleElement.appendChild(idDisplay);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error loading Ely userscript data:', e);
|
||||
}
|
||||
|
||||
function showSalesPopup(items, itemId, pageTitleElement, originalCursor) {
|
||||
const existingPopup = document.getElementById('ely-sales-popup');
|
||||
if (existingPopup) {
|
||||
existingPopup.remove();
|
||||
}
|
||||
|
||||
const popup = document.createElement('div');
|
||||
popup.id = 'ely-sales-popup';
|
||||
popup.style.position = 'fixed';
|
||||
popup.style.top = '50%';
|
||||
popup.style.left = '50%';
|
||||
popup.style.transform = 'translate(-50%, -50%)';
|
||||
popup.style.backgroundColor = '#fff';
|
||||
popup.style.border = '1px solid #ccc';
|
||||
popup.style.borderRadius = '8px';
|
||||
popup.style.boxShadow = '0 4px 8px rgba(0,0,0,0.1)';
|
||||
popup.style.padding = '20px';
|
||||
popup.style.zIndex = '10000';
|
||||
popup.style.maxWidth = '500px';
|
||||
popup.style.width = '90%';
|
||||
popup.style.maxHeight = '70vh';
|
||||
popup.style.overflowY = 'auto';
|
||||
|
||||
const header = document.createElement('h3');
|
||||
header.textContent = 'Recent Sales';
|
||||
header.style.marginTop = '0';
|
||||
header.style.marginBottom = '15px';
|
||||
header.style.color = '#333';
|
||||
popup.appendChild(header);
|
||||
|
||||
const salesList = document.createElement('div');
|
||||
salesList.style.marginBottom = '20px';
|
||||
|
||||
const recentSales = items.slice(-10).reverse();
|
||||
|
||||
recentSales.forEach(sale => {
|
||||
const saleItem = document.createElement('div');
|
||||
saleItem.style.display = 'flex';
|
||||
saleItem.style.justifyContent = 'space-between';
|
||||
saleItem.style.padding = '8px 0';
|
||||
saleItem.style.borderBottom = '1px solid #eee';
|
||||
|
||||
const price = document.createElement('span');
|
||||
price.textContent = `${parseInt(sale.price, 10).toLocaleString()} gp`;
|
||||
price.style.fontWeight = 'bold';
|
||||
|
||||
const type = document.createElement('span');
|
||||
const purchaseLower = String(sale.purchase || '').toLowerCase();
|
||||
type.textContent = purchaseLower === 'sold' ? 'inb' : 'ins';
|
||||
type.style.color = purchaseLower === 'sold' ? '#d9534f' : '#5cb85c';
|
||||
type.style.fontWeight = 'bold';
|
||||
|
||||
const date = document.createElement('span');
|
||||
date.textContent = new Date(sale.date).toLocaleDateString();
|
||||
date.style.color = '#666';
|
||||
|
||||
saleItem.appendChild(price);
|
||||
saleItem.appendChild(type);
|
||||
saleItem.appendChild(date);
|
||||
salesList.appendChild(saleItem);
|
||||
});
|
||||
|
||||
popup.appendChild(salesList);
|
||||
|
||||
const buttonContainer = document.createElement('div');
|
||||
buttonContainer.style.display = 'flex';
|
||||
buttonContainer.style.justifyContent = 'space-between';
|
||||
buttonContainer.style.marginTop = '10px';
|
||||
|
||||
const elyButton = document.createElement('button');
|
||||
elyButton.textContent = 'Go to Ely';
|
||||
elyButton.style.backgroundColor = '#5a8c5a';
|
||||
elyButton.style.color = 'white';
|
||||
elyButton.style.border = 'none';
|
||||
elyButton.style.padding = '8px 16px';
|
||||
elyButton.style.borderRadius = '4px';
|
||||
elyButton.style.cursor = 'pointer';
|
||||
elyButton.addEventListener('click', () => {
|
||||
window.open(`https://www.ely.gg/view_item/${itemId}`, '_blank');
|
||||
popup.remove();
|
||||
pageTitleElement.style.cursor = originalCursor;
|
||||
});
|
||||
|
||||
const closeButton = document.createElement('button');
|
||||
closeButton.textContent = 'Close';
|
||||
closeButton.style.backgroundColor = '#6c757d';
|
||||
closeButton.style.color = 'white';
|
||||
closeButton.style.border = 'none';
|
||||
closeButton.style.padding = '8px 16px';
|
||||
closeButton.style.borderRadius = '4px';
|
||||
closeButton.style.cursor = 'pointer';
|
||||
closeButton.addEventListener('click', () => {
|
||||
popup.remove();
|
||||
pageTitleElement.style.cursor = originalCursor;
|
||||
});
|
||||
|
||||
buttonContainer.appendChild(elyButton);
|
||||
buttonContainer.appendChild(closeButton);
|
||||
popup.appendChild(buttonContainer);
|
||||
|
||||
document.body.appendChild(popup);
|
||||
|
||||
function closePopupOnOutsideClick(e) {
|
||||
if (!popup.contains(e.target) && e.target !== pageTitleElement) {
|
||||
popup.remove();
|
||||
document.removeEventListener('click', closePopupOnOutsideClick);
|
||||
pageTitleElement.style.cursor = originalCursor;
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('click', closePopupOnOutsideClick);
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user