您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Replace cards from jinteki.net by external source to make possible to have cards in another language
// ==UserScript== // @name Jinteki.net cards in french 1.9.6 // @namespace http://tampermonkey.net/ // @version 1.9.6 // @description Replace cards from jinteki.net by external source to make possible to have cards in another language // @author Michael Muguet, Sylvain Charlot // @match https://*.jinteki.net/* // @grant none // @run-at document-end // ==/UserScript== console.log('Jinteki.net cards in french 1.9.6 script is running.'); const validUrlCache = new Map(); const mouseOverCache = new Map(); // Fonction pour vérifier l'existence des images function imageExists(url, callback) { if (validUrlCache.has(url)) { callback(validUrlCache.get(url)); return; } const img = new Image(); img.onload = () => { validUrlCache.set(url, true); callback(true); }; img.onerror = () => { validUrlCache.set(url, false); callback(false); }; img.src = url; } // Fonction pour construire la nouvelle source d'image function buildNewSrc(src) { const fileName = src.split('/').pop().replace(/\.(png|jpg)$/, ''); if (src.includes("jinteki.net/img/cards/en/default/stock/")) { return `https://nsg.muguet.online/jinteki/default/${fileName}.jpg`; } else if (src.includes("jinteki.net/img/cards/en/high/stock/")) { return `https://nsg.muguet.online/jinteki/high/${fileName}.png`; } else if (src.includes("jinteki.net/img/cards/overrides/")) { const regex = /overrides\/([^/]+)\/en\/([^/]+)\/stock\//; const match = src.match(regex); if (match) { return `https://nsg.muguet.online/jinteki/${match[2]}/${fileName}.${match[2] === 'default' ? 'jpg' : 'png'}`; } } console.log(`Image source does not match known sources: ${src}`); return null; } // Fonction pour remplacer les sources des images function replaceImageWithNewElement(img) { const newSrc = buildNewSrc(img.src); if (!newSrc) return; imageExists(newSrc, exists => { if (exists) { console.log(`Replacing image element: ${img.src}`); const newImg = document.createElement('img'); newImg.src = newSrc; newImg.className = img.className; newImg.alt = img.alt; newImg.dataset.replaced = "true"; img.parentNode.replaceChild(newImg, img); console.log(`New image element: ${newImg.src}`); } else { console.log(`Replacement image not found for: ${img.src}`); } }); } // Fonction pour observer les changements dans le DOM function observeDOM() { const observer = new MutationObserver(mutations => { mutations.forEach(mutation => { mutation.addedNodes.forEach(node => { if (node.tagName === 'IMG' && node.src.includes("jinteki.net/img/cards/")) { console.log(`Found new image in mutation observer: ${node.src}`); replaceImageWithNewElement(node); } // Vérifier également les images à l'intérieur des nouveaux nœuds ajoutés if (node.querySelectorAll) { const imgs = node.querySelectorAll('img'); imgs.forEach(img => { if (img.src.includes("jinteki.net/img/cards/")) { console.log(`Found nested image in mutation observer: ${img.src}`); replaceImageWithNewElement(img); } }); } }); }); }); // Configurer l'observation sur le corps du document observer.observe(document.body, { childList: true, subtree: true }); } // Fonction pour intercepter les requêtes d'images function interceptImageRequests() { const originalImage = Object.getOwnPropertyDescriptor(HTMLImageElement.prototype, 'src'); Object.defineProperty(HTMLImageElement.prototype, 'src', { set: function(value) { if (!this.dataset.replaced) { // Vérifier si l'image a déjà été remplacée const newSrc = buildNewSrc(value); if (!newSrc) { originalImage.set.call(this, value); return; } imageExists(newSrc, exists => { if (exists) { console.log(`Intercepted and replacing image source: ${value}`); originalImage.set.call(this, newSrc); } else { console.log(`Replacement image not found for: ${value}`); originalImage.set.call(this, value); } }); } else { originalImage.set.call(this, value); } } }); } // Fonction pour gérer les événements de survol function handleHoverEvent() { const cards = document.querySelectorAll('.card-element-class'); // Remplacez par la classe appropriée cards.forEach(card => { card.addEventListener('mouseenter', () => { const img = card.querySelector('img'); // Sélectionnez l'image agrandie if (img && img.src.includes("jinteki.net/img/cards/")) { console.log(`Hover detected - Found image: ${img.src}`); replaceImageWithNewElement(img); } }); }); } // Fonction principale pour lancer le traitement function traitement() { console.log('Jinteki.net cards in french script is loading.'); interceptImageRequests(); // Intercepter les requêtes d'images dès le chargement const images = document.querySelectorAll('img'); console.log(`Initial run - Found ${images.length} images.`); images.forEach(img => { if (img.src.includes("jinteki.net/img/cards/")) { console.log(`Initial run - Found image: ${img.src}`); replaceImageWithNewElement(img); } }); // Observer les changements dans le DOM observeDOM(); // Gérer les événements de survol handleHoverEvent(); console.log('End load Jinteki.net cards in french script.'); } // Attendre que le contenu de la page soit chargé traitement();