// classDefinitions.js (This code runs in the page's main world) // IMPORTANT: This script will now directly read variables prepended by the content script. // These will be populated by the prepended script content from content.js // Make sure they are defined globally here, so they can be accessed. //let _wiiShopSoundUrls_ = window._wiiShopSoundUrls_ || []; //let _wiiShopBgmUrl_ = window._wiiShopBgmUrl_ || ''; //let _bgmInitiallyEnabled = window._bgmInitiallyEnabled || false; // Capture the BGM state let _bgmAlreadyPlaying = false; // This flag can be managed internally by wiiSound // Add a variable to track the current status (matching your original logic) let _currentstatus = ""; // Existing global variables exposed (these remain the same as your original) var ecsUrl = ""; var iasUrl = ""; var ccsUrl = ""; var ucsUrl = ""; var tid = ""; var tsz = ""; var ttmdsz = ""; var lv = ""; window.ecsUrl = ecsUrl; window.iasUrl = iasUrl; window.ccsUrl = ccsUrl; window.ucsUrl = ucsUrl; window.tid = tid; window.tsz = tsz; window.ttmdsz = ttmdsz; window.lv = lv; window._currentstatus = _currentstatus; // Expose _currentstatus to the global scope const _sendPageMessage = (action, payload = {}) => { window.postMessage({ type: 'WII_SHOP_EXTENSION_MESSAGE', // Custom type to identify our messages action: action, payload: payload }, '*'); // Use '*' for targetOrigin if unsure, but specify if possible for security. }; // Define the trace function const trace = function(...args) { if (typeof extensionStorage !== 'undefined' && typeof extensionStorage.slog === 'function') { extensionStorage.slog(args.map(a => String(a)).join(' ')); } console.log(...args); }; // --- extensionStorage (remains largely the same, but will include sendMessageToBackground) --- const storageCache = {}; const STORAGE_ENDPOINT = '/_extension_storage'; // This endpoint must be intercepted by background.js // --- extensionStorage (UPDATED to use postMessage bridge) --- const extensionStorage = { // Asynchronous set operation set: async (key, value) => { _sendPageMessage('extStorageSet', { key, value }); }, // Asynchronous get operation (requires awaiting a response via postMessage listener) get: async (key) => { return new Promise(resolve => { const listener = (event) => { // Ensure the message is from our extension, is a response, and matches our request if (event.source === window && event.data.type === 'WII_SHOP_EXTENSION_RESPONSE' && event.data.action === 'extStorageGet' && event.data.key === key) { // Match key for specific requests window.removeEventListener('message', listener); // Clean up listener if (event.data.error) { console.error("Error receiving extStorageGet response:", event.data.error); resolve(null); // Resolve with null on error } else { resolve(event.data.payload.value); } } }; window.addEventListener('message', listener); // Set up listener BEFORE sending message _sendPageMessage('extStorageGet', { key }); // Send the request }); }, slog: (message) => { _sendPageMessage('extStorageSet', { key: 'slogs', value: message }); }, getLogs: async () => { const result = await extensionStorage.get('logs'); return result || []; }, clearLogs: () => { _sendPageMessage('clearLogs'); }, spts: (points) => { _sendPageMessage('extStorageSet', { key: 'spts', value: points }); }, getpts: async () => { const points = await extensionStorage.get('pts'); return parseInt(points) || 0; }, clearpts: () => { _sendPageMessage('clearPoints'); }, // This method sends BGM control messages to content.js, which forwards to background.js sendMessageToBackground: async (message) => { _sendPageMessage(message.action, message); } }; window.extensionStorage = extensionStorage; // Initial logs/points check now needs to be asynchronous (async () => { console.log("Current points (from injected script - initial load):", await extensionStorage.getpts()); console.log("Trace loaded (from injected script - initial load):", await extensionStorage.getLogs()); })(); // Define the ECommerceInterface class class ECommerceInterface { constructor() { const unwantedPath = "/oss/serv/CheckRegistered.jsp"; if (window.location.pathname === unwantedPath) { console.log("Do nothing..."); } trace("ECommerceInterface initialized"); } getTicketInfos(titleId) { return { length: 1, get: function(index) { if (index === 0) { return { deviceId: 222222, limits: null }; } return null; } }; } getTitleInfo(titleid) { if (titleid === "0001000248414241") { return { titleId: titleid, isOnDevice: true, version: 21, isTmdPresent: true, occupiedUserBlocks: 0, occupiedUserInodes: 0, occupiedSysBlocks: 1599, occupiedSysInodes: 23 } } else { return { titleId: titleid, isOnDevice: false, version: 0, isTmdPresent: false, occupiedUserBlocks: 0, occupiedUserInodes: 0, occupiedSysBlocks: 0, occupiedSysInodes: 0 } } } async getLog() { return await extensionStorage.getLogs() || ""; } async getPoints() { return await extensionStorage.getpts() || 0; } setPoints(newPoints) { if (!Number.isInteger(newPoints)) { newPoints = parseInt(newPoints, 10); } if (isNaN(newPoints)) { console.error("Invalid points value provided:", newPoints); return; } extensionStorage.spts(newPoints); trace("Points updated to: " + extensionStorage.getpts()); } loadPoints() { console.log("nah i dont load points, they alr loaded"); } 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() { window._currentstatus = "getCachedBalance" const storedPoints = window.localStorage.getItem('points'); if (storedPoints) { return parseInt(storedPoints, 10); } else { return 0; } } refreshCachedBalance() { window._currentstatus = "refreshCachedBalance" return { status: 0, operation: "refreshCachedBalance", description: "", phase: 7, isCancelRequested: "false", downloadedSize: 0, totalSize: 0, errCode: 0, errInfo: null, }; } checkDeviceStatus() { window._currentstatus = "checkDeviceStatus"; return { status: 0, operation: "checkDeviceStatus", description: "", phase: 17, isCancelRequested: "false", downloadedSize: 0, totalSize: 0, errCode: 0, errInfo: null, }; } getDeviceInfo() { return { country: "US", region: "USA", isParentalControlEnabled: false, userAge: 20, language: "en", accountId: "659247864", deviceId: "4587571479", serial: "PC156494873", maxUserInodes: 200000, usedUserInodes: 100000, freeChannelAppCount: 41, blockSize: 536870912, totalBlocks: 65536, usedBlocks: 0, totalSysBlocks: 65536, usedSysBlocks: 0, titleId: "0001000248414241", accountCountry: "CA", deviceCode: "0302167078436756", accountDeviceCode: "0302167078436756", isKeyPairConfirmed: function() { return true; }, registrationStatus: "R", }; } async setSessionValue(key, value) { await extensionStorage.set(key, value); } async getSessionValue(key) { return await extensionStorage.get(key); } pubKeyEncrypt(nah) { console.log("behonest this is not required: " + nah); return nah; } async purchasePoints(pointsToBuy, itemId, price, payment, taxes, purchaseInfo, discount) { await this.setPoints(pointsToBuy); return 100; } getProgress() { var downsize = 0; if (window._currentstatus === "checkRegistration") { downsize = 727; } else if (window._currentstatus === "syncRegistration") { downsize = 913; } else if (window._currentstatus === "checkDeviceStatus") { downsize = 846; } else if (window._currentstatus === "refreshCachedBalance") { downsize = 731; } else { downsize = 0; } return { "status": 0, "operation": window._currentstatus, "description": "", "phase": 2, "isCancelRequested": false, "downloadedSize": downsize, "totalSize": 0, "errCode": 0, "errInfo": null }; } checkRegistration() { window._currentstatus = "checkRegistration"; return { "status": 0, "operation": "checkRegistration", "description": "", "phase": 11, "isCancelRequested": false, "downloadedSize": 0, "totalSize": 0, "errCode": 0, "errInfo": null }; } syncRegistration(value) { console.log("idk what to do with this: " + value); window._currentstatus = "syncRegistration"; return { "status": 0, "operation": "syncRegistration", "description": "", "phase": 18, "isCancelRequested": false, "downloadedSize": 0, "totalSize": 0, "errCode": 0, "errInfo": null }; } getWeakToken() { return "iamaweaktoken"; } getVersion() { return parseInt("21"); } request(value) { if (value === "checkRegistration") { return this.checkRegistration(); } else if (value === "checkDeviceStatus") { return this.checkDeviceStatus(); } else if (value === "refreshCachedBalance") { return this.refreshCachedBalance(); } else if (value === "getCachedBalance") { return this.getCachedBalance(); } } } class wiiShop { constructor() { trace("wiiShop initialized"); return "isok"; } connecting = null; retry() { window.location.pathname = "/oss/serv/W_01.jsp"; } endWaiting() { console.log("Currently does nothing endwaiting"); } enableHRP() { console.log("Does Jack shit homebuttonenabler"); } disableHRP() { console.log("Does jack shit home button disabler") } sleep(duration) { return new Promise(resolve => setTimeout(resolve, duration)); } async beginWaiting(seconds) { 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; } seconds = parsedValue; } if (!Number.isInteger(seconds)) { console.error("Invalid input: Please provide an integer value."); return; } let duration; duration = (seconds < 10) ? seconds * 1000 : seconds; await this.sleep(duration); console.log("Wait complete!"); } isCompatibleMode() { return true; } setWallpaper() { trace("Cant do setWallpaper yet, will later when i fully adapt this shi-") return null; } launchCode = 0; } class wiiSound { // These now directly reference the global variables prepended by the content script static audioUrls = _wiiShopSoundUrls_; static bgmUrl = _wiiShopBgmUrl_; // static currentBgmAudio = null; // No longer needed here, BGM managed in background constructor() { trace("wiiSound initialized"); } playSE(snd) { // This remains direct, as it plays a short-lived audio element in the page context. if (!wiiSound.audioUrls || wiiSound.audioUrls.length === 0) { console.warn("Audio URLs not yet loaded. Cannot play sound effect."); return; } const soundIndex = parseInt(snd, 10); if (isNaN(soundIndex) || soundIndex < 1 || soundIndex >= wiiSound.audioUrls.length) { console.warn("Invalid sound index for wiiSound.playSE:", snd); return; } const audioUrl = wiiSound.audioUrls[soundIndex]; if (!audioUrl) { console.warn("No audio URL found for sound index:", soundIndex); return; } const audio = new Audio(audioUrl); audio.style.display = 'none'; // Hide the audio element audio.play() .then(() => { console.log('Wii Shop Sound played:', soundIndex, audioUrl); }) .catch(error => { console.error('Error playing Wii Shop Sound:', soundIndex, audioUrl, error); }); } playBGM() { if (_bgmAlreadyPlaying === true) { return "nah mate, i aint playin for ya, im already playin"; } else { _bgmAlreadyPlaying = true; // Use extensionStorage.sendMessageToBackground (which uses postMessage) to control BGM in background extensionStorage.sendMessageToBackground({ action: "playBGM", bgmUrl: wiiSound.bgmUrl // Ensure BGM URL is available }).then(() => { trace('Request to play BGM sent via extensionStorage (postMessage bridge).'); }).catch(error => { console.error('Error sending playBGM message via extensionStorage:', error); _bgmAlreadyPlaying = false; // Reset on error }); } } stopBGM() { if (_bgmAlreadyPlaying === true) { _bgmAlreadyPlaying = false; // Reset the flag // Send a message via extensionStorage to background to stop BGM extensionStorage.sendMessageToBackground({ action: "stopBGM" }).then(() => { trace('Request to stop BGM sent via extensionStorage (postMessage bridge).'); }).catch(error => { console.error('Error sending stopBGM message via extensionStorage:', error); }); } else { return "wtf do you want me to stop eh?"; } } } 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; } fnm = parsedValue; } if (data == "name") { if (fnm == 0) { return "User1"; } else if (fnm == 1) { return "User2"; } else if (fnm == 2) { return "User3"; } else if (fnm == 3) { return "User4"; } else if (fnm == 4) { return "User5"; } } if (data == "userId") { if (fnm == 0) { return "3630753603591712"; } else if (fnm == 1) { return "3630753603591712"; } else if (fnm == 2) { return "3630753603591712"; } else if (fnm == 3) { return "3630753603591712"; } else if (fnm == 4) { return "3630753603591712"; } } if (data == "miiImage") { return "111" } } myUserId = "0302167078436756"; } class wiiDlTask { constructor() { trace("WiiDlTask init"); } addDownloadTask(url, interval){ trace("yes i got it dw i will download it :tro:"); } } class wiiMii { constructor() { trace("wiiMii init"); } } window.ECommerceInterface = ECommerceInterface; window.ECCreditCardEncryptedPayment = ECCreditCardEncryptedPayment; window.ECPrice = ECPrice; window.wiiKeyboard = wiiKeyboard; window.wiiShop = wiiShop; window.wiiSound = wiiSound; window.wiiMii = wiiMii; window.wiiDlTask = wiiDlTask; window.wiiNwc24 = wiiNwc24; window.wiiSDCard = wiiSDCard; // This block for initial BGM playback now needs to be async if (_bgmInitiallyEnabled) { document.addEventListener('DOMContentLoaded', async () => { // Give a slight delay to ensure wiiSound class is fully initialized await new Promise(resolve => setTimeout(resolve, 50)); if (window.wiiSound) { const soundInstance = new window.wiiSound(); soundInstance.playBGM(); // This will use the postMessage bridge } }); }