commit 9bc0b022aa00e532afc750b4b66ce43187fb1f87 Author: thom2305 Date: Tue May 6 20:49:00 2025 -0400 first commit diff --git a/background.js b/background.js new file mode 100644 index 0000000..6112dc8 --- /dev/null +++ b/background.js @@ -0,0 +1,61 @@ +// background.js + +// Function to block specific requests +function blockRequest(details) { + // Check if the request URL matches the file you want to block + if (details.url.includes("title_manager.js")) { + console.log("Blocking request for:", details.url); + return { cancel: true }; // Cancel the request + } +} + +// Check if the browser is Firefox or Chrome +const isFirefox = typeof browser !== "undefined"; + +if (isFirefox) { + // Use the browser API for Firefox + browser.webRequest.onBeforeRequest.addListener( + blockRequest, + { urls: [ + "https://oss-auth.blinklab.com/*", + "https://oss-auth.thecheese.io/*", + "https://oss-auth.shop.wii.com/*" + ]}, // Adjust this to match the URLs where you want to block files + ["allowed"] // Enable blocking + ); +} else { + // Use the chrome API for Chrome + chrome.webRequest.onBeforeRequest.addListener( + blockRequest, + { urls: [ + "https://oss-auth.blinklab.com/*", + "https://oss-auth.thecheese.io/*", + "https://oss-auth.shop.wii.com/*", + "http://wiimart:8080/oss/serv/*", + "https://wiimart:8080/oss/serv/*" + ]}, // Adjust this to match the URLs where you want to block files + ["allowed"] // Enable blocking + ); +} + +// background.js + +// Listen for web requests +chrome.webRequest.onBeforeRequest.addListener( + function(details) { + // Check if the URL matches the pattern + const urlPattern = /^miip:\/\/CID\/.*\.bmp\?width=48&height=48&bgR=\d{1,3}&bgG=\d{1,3}&bgB=\d{1,3}$/; + if (urlPattern.test(details.url)) { + // Redirect to the image stored in the extension + return { redirectUrl: chrome.runtime.getURL("images/mii.bmp") }; + } + }, + { urls: [ + "https://oss-auth.blinklab.com/*", + "https://oss-auth.thecheese.io/*", + "https://oss-auth.shop.wii.com/*", + "http://wiimart:8080/oss/serv/*", + "https://wiimart:8080/oss/serv/*" + ]}, // You can restrict this to specific URLs if needed + ["blocking"] +); \ No newline at end of file diff --git a/classDefinitions.js b/classDefinitions.js new file mode 100644 index 0000000..75a2c81 --- /dev/null +++ b/classDefinitions.js @@ -0,0 +1,378 @@ +var ecsUrl = ""; +var iasUrl = ""; +var ccsUrl = ""; +var ucsUrl = ""; +var tid = ""; +var tsz = ""; +var ttmdsz = ""; +var lv = ""; + +// Expose the URLs to the global scope +window.ecsUrl = ecsUrl; +window.iasUrl = iasUrl; +window.ccsUrl = ccsUrl; +window.ucsUrl = ucsUrl; +window.tid = tid; +window.tsz = tsz; +window.ttmdsz = ttmdsz; +window.lv = lv; + +var thetrace = ""; +var points = 0; // Initialize points + +// Load the existing trace and points from localStorage +const loadData = () => { + const storedTrace = window.localStorage.getItem('thetrace'); + if (storedTrace) { + thetrace = storedTrace; // Set thetrace to the stored value + } + window.thetrace = thetrace; // Make it available globally + + const storedPoints = window.localStorage.getItem('points'); + if (storedPoints) { + points = parseInt(storedPoints, 10); // Set points to the stored value + } +}; + +// Define the trace function +const trace = function(...args) { + // Join the arguments into a single string + const message = args.join(" "); // You can customize the separator if needed + // Append the message to the thetrace variable with a newline + thetrace += message + "\n"; + + // Update the global window.thetrace variable + window.thetrace = thetrace; + + // Save the updated trace to localStorage + window.localStorage.setItem('thetrace', window.thetrace); + console.log(...args); + console.trace(...args); +}; + +loadData(); +console.log("Trace loaded:", window.thetrace); +console.log("Current points:", points); + + +// Define the ECommerceInterface class +class ECommerceInterface { + constructor() { + const unwantedPath = "/oss/serv/CheckRegistered.jsp"; + if (window.location.pathname === unwantedPath) { + //window.location.pathname = "/oss/serv/W_01.jsp"; + console.log("Do nothing..."); + } + this._titlesMap = new Map([ + ["0001000248414241", { + name: 'Wii Shop Channel', + version: '21', + isTmdPresent: true, + }], + ['0001000248414242', { + name: 'idk', + version: '1', + isTmdPresent: true, + }], + ]); + trace("ECommerceInterface initialized"); // Use the trace function + this.loadPoints(); // Load data when the class is instantiated + } + + getTicketInfos(titleId) { + // Return a mock object that simulates an unlimited license + return { + length: 1, // Simulate the length property + get: function(index) { + if (index === 0) { + return { + deviceId: 222222, // Simulate a personalized ticket + limits: null // No limits, indicating an unlimited license + }; + } + return null; // Return null for any other index + } + }; + } + + getTitleInfo(shopAppTitleId) { + const title = this._titlesMap.get(shopAppTitleId); + if (!title || typeof title !== 'object' || !title.isTmdPresent || title.version == null) { + return null; + } + } + getTitleInfo(titleid) { + return { + isOnDevice: false, + version: 0, + isTmdPresent: false, + } + } + getLog() { + return window.localStorage.getItem('thetrace') || ""; // Return the stored trace or an empty string + } + + getPoints() { + return points; // Return the current points + } + + setPoints(newPoints) { + if (!Number.isInteger(newPoints)) { + newPoints = parseInt(newPoints, 10); // Convert to integer if not + } + + if (isNaN(newPoints)) { + console.error("Invalid points value provided:", newPoints); + return; + } + + const currentPoints = parseInt(window.localStorage.getItem('points'), 10) || 0; + points = currentPoints + newPoints; + window.localStorage.setItem('points', points); + trace("Points updated to: " + points); + } + + loadPoints() { + const storedPoints = window.localStorage.getItem('points'); + if (storedPoints) { + points = parseInt(storedPoints, 10); // Set points to the stored value + } + } + + cancelOperation() { + console.log("bro what do you want me to cancel"); + } + + setWebSvcUrls(ecsuri, iasuri) { + window.ecsUrl = ecsuri; + window.iasUrl = iasuri; + } + + setContentUrls(ccsuri, ucsuri) { + window.ccsUrl = ccsuri; + window.ucsUrl = ucsuri; + } + + getCachedBalance() { + const storedPoints = window.localStorage.getItem('points'); + if (storedPoints) { + return parseInt(storedPoints, 10); + } + else { + return 0; + } + } + + refreshCachedBalance() { + const storedPoints = window.localStorage.getItem('points'); + if (storedPoints) { + return parseInt(storedPoints, 10); + } + else { + return 0; + } + } + + checkDeviceStatus() { + return 1; + } + + getDeviceInfo() { + return { + country: "CA", // Example value + region: "USA", // Example value + isParentalControlEnabled: false, // Example value + userAge: 20, // Example value + language: "fr", // Example value + accountId: "659247", // Example value + deviceId: "458757", // Example value + serial: "PC156494873", // Example value + maxUserInodes: 200000, + usedUserInodes: 100000, + freeChannelAppCount: 41, + freeChannelAppCount: 41, + blockSize: 536870912, + totalBlocks: 65536, + usedBlocks: 0, + totalSysBlocks: 65536, + usedSysBlocks: 0, + titleId: "0001000248414241", + }; + } + setSessionValue(idk, idk2) { + + console.log("tbh idk ill just log: " + idk + " log2: " + idk2); + } + getSessionValue(avalue) { + if (avalue == "nTitlesDownloaded"){ + return 0; + } else { + console.log("thy omighty value: " + avalue); + return; + } + } + pubKeyEncrypt(nah) { + console.log("behonest this is not required: " + nah) + return nah; + } + purchasePoints(pointsToBuy, itemId, price, payment, taxes, purchaseInfo, discount) { + this.setPoints(pointsToBuy); + return 100; + } + getProgress() { + console.log("idk what to return its a progress?"); + return 100; + } + checkRegistration() { + return true; + } + getWeakToken() { + return "iamaweaktoken"; + } +} + +class wiiShop { + constructor() { + trace("wiiShop initialized"); // Use the trace function + } + retry() { + window.location.pathname = "/oss/serv/W_01.jsp"; + } + endWaiting() { + console.log("Currently does nothing endwaiting"); + } + enableHRP() { + console.log("Does Jack shit homebuttonenabler"); + } + sleep(duration) { + return new Promise(resolve => setTimeout(resolve, duration)); // duration is in milliseconds + } + async beginWaiting(seconds) { + // Check if the input is a string and convert to integer if so + if (seconds == null) { + seconds = 3; + } + if (typeof seconds === 'string') { + const parsedValue = parseInt(seconds, 10); + if (isNaN(parsedValue) || parsedValue.toString() !== seconds) { + console.error("Invalid input: Please provide a valid integer value."); + return; // Exit the function if the string is not a valid integer + } + seconds = parsedValue; // Convert string to integer + } + + // Check if the input is a valid integer + if (!Number.isInteger(seconds)) { + console.error("Invalid input: Please provide an integer value."); + return; // Exit the function if the input is not an integer + } + + let duration; + + // Convert single-digit seconds to milliseconds + duration = (seconds < 10) ? seconds * 1000 : seconds; // Convert to ms if single digit + + await this.sleep(duration); + console.log("Wait complete!"); + } + isCompatibleMode() { + return true; + } +} + +class wiiSound { + constructor() { + trace("wiiSound initialized"); // Use the trace function + } + playSE(snd) { + console.log("i play this sound hehehehe (it dont exist lol): " + snd); + } +} + +class wiiKeyboard { + constructor() { + trace("wiiKeyboard initialized"); + } +} + +class ECCreditCardEncryptedPayment { + constructor(smth) { + this.smth = smth; + } +} + +class ECPrice { + constructor(uhh, ahh) { + return uhh; + } +} + +class wiiSDCard { + constructor() { + return; + } +} + +class wiiNwc24 { + constructor() { + return; + } + sendable() { + return true; + } + mailErrNo() { + return null; + } + errMsg() { + return null; + } + getFriendNum() { + return 5; + } + getFriendInfo(fnm, data) { + if (typeof fnm === 'string') { + const parsedValue = parseInt(fnm, 10); + if (isNaN(parsedValue) || parsedValue.toString() !== fnm) { + console.error("Invalid input: Please provide a valid integer value."); + return; // Exit the function if the string is not a valid integer + } + fnm = parsedValue; // Convert string to integer + } + if (data == "name") { + if (fnm == 1) { + return "User1"; + } else if (fnm == 2) { + return "User2"; + } else if (fnm == 3) { + return "User3"; + } else if (fnm == 4) { + return "User4"; + } else if (fnm == 5) { + return "User5"; + } + } + if (data == "userId") { + if (fnm == 1) { + return "3630753603591712"; + } else if (fnm == 2) { + return "3630753603591712"; + } else if (fnm == 3) { + return "3630753603591712"; + } else if (fnm == 4) { + return "3630753603591712"; + } else if (fnm == 5) { + return "3630753603591712"; + } + } + if (data == "miiImage") { + return "111" + } + } +} + +window.ECommerceInterface = ECommerceInterface; +window.ECCreditCardEncryptedPayment = ECCreditCardEncryptedPayment; +window.ECPrice = ECPrice; +window.wiiKeyboard = wiiKeyboard; +window.wiiShop = wiiShop; +window.wiiSound = wiiSound; diff --git a/content.js b/content.js new file mode 100644 index 0000000..710e0cf --- /dev/null +++ b/content.js @@ -0,0 +1,148 @@ +// content.js + +// Log that the content script is running +console.log("Content script is running."); + + +let fontLoaded = false; + +function loadFont() { + const fontUrl = chrome.runtime.getURL("fonts/fot_rodin_pro_m.ttf"); + const style = document.createElement('style'); + style.textContent = ` + @font-face { + font-family: 'Wii NTLG PGothic JPN Regular'; + src: url('${fontUrl}') format('truetype'); + } + body { + font-family: 'Wii NTLG PGothic JPN Regular', sans-serif !important; + } + * { + font-family: 'Wii NTLG PGothic JPN Regular', sans-serif !important; + } + #text03-01 { + display: flex; /* Enable flexbox */ + justify-content: center; /* Center horizontally */ + align-items: center; /* Center vertically */ + height: 100vh; /* Full height of the viewport */ + width: 100%; /* Full width */ + } + + #text05-01 { + display: flex; /* Enable flexbox */ + justify-content: center; /* Center horizontally */ + align-items: center; /* Center vertically */ + height: 100vh; /* Full height of the viewport */ + width: 100%; /* Full width */ + } + + #text06-01 { + display: flex; /* Enable flexbox */ + justify-content: center; /* Center horizontally */ + align-items: center; /* Center vertically */ + height: 100vh; /* Full height of the viewport */ + width: 100%; /* Full width */ + } + + .buttonTextBlackM { + font-size: 24px; /* Adjust font size as needed */ + color: black; /* Set text color */ + text-align: center; /* Center text within the div */ + } + `; + + // Try to append to the head first + const head = document.head || document.getElementsByTagName('head')[0]; + if (head) { + head.appendChild(style); + console.log("Font loaded into ."); + return "Font loaded into "; // Return success message + } + + // If head is not available, use MutationObserver to wait for it + const observer = new MutationObserver(() => { + const head = document.head || document.getElementsByTagName('head')[0]; + if (head) { + head.appendChild(style); + observer.disconnect(); // Stop observing once the style is added + console.log("Font loaded into via MutationObserver."); + return "Font loaded into via MutationObserver"; // Return success message + } + }); + + // Start observing the document for changes + observer.observe(document, { childList: true, subtree: true }); + + // Fallback: If the head is still not available, append to the body + const fallbackTimeout = setTimeout(() => { + if (!document.head || !document.head.contains(style)) { + document.body.appendChild(style); + console.log("Font loaded into as a fallback."); + observer.disconnect(); // Stop observing if we fall back + return "Font loaded into as a fallback"; // Return success message + } + }, 1000); // Wait for 1 second before falling back + + // Check if the observer is still active after 2 seconds + setTimeout(() => { + // If the font is still not loaded, log an error + if (!document.head || !document.body.contains(style)) { + console.error("Failed to load font: and are not available."); + return "Failed to load font: and are not available."; // Return error message + } + observer.disconnect(); // Clear the observer + clearTimeout(fallbackTimeout); // Clear the timeout + }, 2000); // Check again after 2 seconds + + return "Font loading initiated"; // Return initial status +} + +// Check the font state on page load + +function checkFontState() { + chrome.storage.local.get(['fontDisabled'], function(result) { + if (!result.fontDisabled) { + return loadFont(); + } else { + return "disabled"; + } + }); +} + +// Function to load class definitions based on the browser +const loadClassDefinitions = async () => { + let classDefinitionsUrl; + // Check the user agent to determine the browser + const userAgent = navigator.userAgent.toLowerCase(); + if (userAgent.includes("chrome")) { + // Load the class definitions for Chrome + classDefinitionsUrl = chrome.runtime.getURL('classDefinitions.js'); // Adjust the path as necessary + } else if (userAgent.includes("firefox")) { + // Load the class definitions for Firefox + classDefinitionsUrl = browser.runtime.getURL('classDefinitions.js'); // Adjust the path as necessary + } else { + console.warn("Unsupported browser. Class definitions will not be loaded."); + return; // Exit if the browser is not supported + } + // Fetch the class definitions file + try { + const response = await fetch(classDefinitionsUrl); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + const classDefinitions = await response.text(); + // Create a script element and set its content + const script = document.createElement('script'); + script.textContent = classDefinitions; + // Insert the script at the start of the element + document.documentElement.insertBefore(script, document.documentElement.firstChild); + } catch (error) { + console.error("Failed to load class definitions:", error); + } +}; + +// Load the class definitions +loadClassDefinitions(); +// Load the existing trace and points from localStorage +const result = checkFontState(); +console.log(result); \ No newline at end of file diff --git a/fonts/fot_rodin_pro_m.ttf b/fonts/fot_rodin_pro_m.ttf new file mode 100644 index 0000000..e731839 Binary files /dev/null and b/fonts/fot_rodin_pro_m.ttf differ diff --git a/images/loading.png b/images/loading.png new file mode 100644 index 0000000..c03adc8 Binary files /dev/null and b/images/loading.png differ diff --git a/images/static-assets-upload9069998132264556450.bmp b/images/static-assets-upload9069998132264556450.bmp new file mode 100644 index 0000000..99bb1a3 Binary files /dev/null and b/images/static-assets-upload9069998132264556450.bmp differ diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..9bcf8ad --- /dev/null +++ b/manifest.json @@ -0,0 +1,47 @@ +{ + "manifest_version": 3, + "name": "WiiShop but on browsers", + "version": "1.0", + "permissions": [ + "scripting", + "activeTab", + "storage", + "webRequest", + "webRequestBlocking", + "tabs" + ], + "action": { + "default_popup": "popup.html" + }, + "background": { + "scripts": ["background.js"] + }, + "content_scripts": [ + { + "matches": [ + "https://oss-auth.blinklab.com/*", + "https://oss-auth.thecheese.io/*", + "https://oss-auth.shop.wii.com/*", + "http://wiimart:8080/oss/serv/*", + "https://wiimart:8080/oss/serv/*" + ], + "js": ["content.js"], + "run_at": "document_start" + } + ], + "web_accessible_resources": [ + { + "resources": [ + "fonts/*", + "classDefinitions.js" + ], + "matches": [ + "https://oss-auth.blinklab.com/*", + "https://oss-auth.thecheese.io/*", + "https://oss-auth.shop.wii.com/*", + "http://wiimart:8080/oss/serv/*", + "https://wiimart:8080/oss/serv/*" + ] + } + ] +} \ No newline at end of file diff --git a/popup.html b/popup.html new file mode 100644 index 0000000..bed3d64 --- /dev/null +++ b/popup.html @@ -0,0 +1,33 @@ + + + + + + + My Extension + + + +

My Extension

+ + +
+ + + + \ No newline at end of file diff --git a/popup.js b/popup.js new file mode 100644 index 0000000..cec2cc4 --- /dev/null +++ b/popup.js @@ -0,0 +1,22 @@ +// popup.js +document.getElementById('clearTrace').addEventListener('click', function() { + window.localStorage.setItem('thetrace', ''); // Clear the 'thetrace' variable + document.getElementById('cleared').textContent = 'Cleared: trace'; +}); + +document.getElementById('clearPoints').addEventListener('click', function() { + window.localStorage.setItem('points', ''); // Clear the 'points' variable + document.getElementById('cleared').textContent = 'Cleared: points'; +}); + +// Handle the checkbox for enabling/disabling the font +document.getElementById('toggleFont').addEventListener('change', function() { + const isChecked = this.checked; + // Set the font state in the extension's storage + chrome.storage.local.set({ fontDisabled: !isChecked }); +}); + +// Check the current font state when the popup is opened +chrome.storage.local.get(['fontDisabled'], function(result) { + document.getElementById('toggleFont').checked = !result.fontDisabled; // Set checkbox based on stored value +}); \ No newline at end of file