mirror of
https://wiilab.wiimart.org/wiimart/wiimart-extension
synced 2025-09-02 19:41:00 +02:00
smol updates
This commit is contained in:
parent
555031d406
commit
7b7a9fac8a
307
background.js
307
background.js
@ -1,27 +1,37 @@
|
||||
// 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
|
||||
const runtimeAPI = typeof browser !== 'undefined' ? browser : chrome;
|
||||
const storageAPI = runtimeAPI.storage.local;
|
||||
|
||||
let currentBgmAudio = null;
|
||||
let bgmEnabledState = false;
|
||||
let logs = []; // In-memory log cache
|
||||
let currentPoints = 0; // In-memory points cache
|
||||
|
||||
const DEBUG_REDIRECT_SERIAL = "PC156494873"; // Centralized constant
|
||||
|
||||
// --- Initialization on startup ---
|
||||
async function initializeBackground() {
|
||||
try {
|
||||
const result = await storageAPI.get(['bgmEnabled', 'logs', 'pts']);
|
||||
bgmEnabledState = result.bgmEnabled === true;
|
||||
logs = result.logs || [];
|
||||
currentPoints = result.pts || 0;
|
||||
console.log("Background: Initial states loaded. BGM:", bgmEnabledState, "Logs count:", logs.length, "Points:", currentPoints);
|
||||
} catch (error) {
|
||||
console.error("Background: Error during initialization:", error);
|
||||
}
|
||||
}
|
||||
initializeBackground();
|
||||
|
||||
// Check if the browser is Firefox or Chrome
|
||||
const isFirefox = typeof browser !== "undefined";
|
||||
// background.js
|
||||
// --- Web Request Listeners ---
|
||||
|
||||
// Handle all miip:// requests
|
||||
chrome.webRequest.onBeforeRequest.addListener(
|
||||
// 1. Block specific requests (title_manager.js)
|
||||
runtimeAPI.webRequest.onBeforeRequest.addListener(
|
||||
function(details) {
|
||||
console.log("[DEBUG] Intercepted URL:", details.url);
|
||||
|
||||
if (details.url.startsWith('miip://')) {
|
||||
const redirectUrl = chrome.runtime.getURL("images/mii.bmp");
|
||||
console.log("[DEBUG] Redirecting to:", redirectUrl);
|
||||
return { redirectUrl: redirectUrl };
|
||||
if (details.url.includes("title_manager.js")) {
|
||||
console.log("Background: Blocking request for:", details.url);
|
||||
return { cancel: true };
|
||||
}
|
||||
return {};
|
||||
},
|
||||
@ -29,84 +39,189 @@ chrome.webRequest.onBeforeRequest.addListener(
|
||||
["blocking"]
|
||||
);
|
||||
|
||||
let logs = [];
|
||||
|
||||
chrome.webRequest.onBeforeRequest.addListener(
|
||||
(details) => {
|
||||
const url = new URL(details.url);
|
||||
|
||||
if (url.pathname === '/_extension_storage') {
|
||||
const params = new URLSearchParams(url.search);
|
||||
|
||||
// GET Requests
|
||||
if (params.has('get')) {
|
||||
const key = params.get('get');
|
||||
console.log("Get key: " + key)
|
||||
return new Promise(resolve => {
|
||||
chrome.storage.local.get(key, result => {
|
||||
if (key === 'logs') {
|
||||
resolve({
|
||||
redirectUrl: `data:application/json,${JSON.stringify({
|
||||
value: logs
|
||||
})}`
|
||||
});
|
||||
} else {
|
||||
resolve({
|
||||
redirectUrl: `data:application/json,${JSON.stringify({
|
||||
value: result[key]
|
||||
})}`
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// SET Requests
|
||||
if (params.has('set_key')) {
|
||||
const key = params.get('set_key');
|
||||
const value = params.get('set_value');
|
||||
console.log("Set key: " + key + " with value: " + value)
|
||||
if (key === 'slogs') {
|
||||
console.log("Set key: logs with value: " + value)
|
||||
logs.push(`[SET] ${new Date().toISOString()}: ${value}`);
|
||||
chrome.storage.local.set({ logs });
|
||||
} else {
|
||||
chrome.storage.local.set({ [key]: value });
|
||||
// 2. Handle all miip:// requests
|
||||
runtimeAPI.webRequest.onBeforeRequest.addListener(
|
||||
function(details) {
|
||||
console.log("Background: Intercepted URL:", details.url);
|
||||
if (details.url.startsWith('miip://')) {
|
||||
const redirectUrl = runtimeAPI.runtime.getURL("images/mii.bmp");
|
||||
console.log("Background: Redirecting miip:// to:", redirectUrl);
|
||||
return { redirectUrl: redirectUrl };
|
||||
}
|
||||
return { cancel: true };
|
||||
}
|
||||
|
||||
// CLEAR Logs
|
||||
if (params.has('clogs')) {
|
||||
console.log("Clear Logs")
|
||||
logs = [];
|
||||
chrome.storage.local.set({ logs: [] });
|
||||
return { cancel: true };
|
||||
}
|
||||
if (params.has('set_key') && params.get('set_key') === 'spts') {
|
||||
const pointsToAdd = parseInt(params.get('set_value')) || 0;
|
||||
|
||||
chrome.storage.local.get(['pts'], (result) => {
|
||||
const currentPoints = parseInt(result.pts) || 0;
|
||||
const newTotal = currentPoints + pointsToAdd;
|
||||
|
||||
// Update both in-memory and storage
|
||||
logs.push(`[POINTS] Added ${pointsToAdd} points (Total: ${newTotal})`);
|
||||
chrome.storage.local.set({
|
||||
pts: newTotal,
|
||||
logs
|
||||
});
|
||||
});
|
||||
|
||||
return { cancel: true };
|
||||
}
|
||||
if (params.has('cpts')) {
|
||||
console.log("Clear Points")
|
||||
chrome.storage.local.set({ pts: 0 });
|
||||
return { cancel: true };
|
||||
}
|
||||
return {};
|
||||
},
|
||||
{ urls: ["<all_urls>"] }, // Listen for all URLs to catch miip:// scheme
|
||||
["blocking"]
|
||||
);
|
||||
|
||||
// 3. Redirect debug.jsp if Serial parameter is missing
|
||||
runtimeAPI.webRequest.onBeforeRequest.addListener(
|
||||
function(details) {
|
||||
const url = new URL(details.url);
|
||||
if (url.pathname.includes('/oss/serv/debug.jsp')) {
|
||||
const serialParam = url.searchParams.get('Serial');
|
||||
if (!serialParam) {
|
||||
console.warn("Background: Intercepted debug.jsp without Serial. Adding static Serial and redirecting.");
|
||||
url.searchParams.set('Serial', DEBUG_REDIRECT_SERIAL);
|
||||
const redirectUrl = url.toString();
|
||||
console.log("Background: Redirecting to:", redirectUrl);
|
||||
return { redirectUrl: redirectUrl };
|
||||
}
|
||||
}
|
||||
return {};
|
||||
},
|
||||
{ urls: ["*://oss-auth.thecheese.io/oss/serv/debug.jsp*"], types: ["main_frame"] },
|
||||
["blocking"]
|
||||
);
|
||||
|
||||
// --- BGM Playback Functions (managed within background script) ---
|
||||
function playBGM(url) {
|
||||
if (currentBgmAudio) {
|
||||
currentBgmAudio.pause();
|
||||
currentBgmAudio.currentTime = 0;
|
||||
currentBgmAudio = null;
|
||||
}
|
||||
},
|
||||
{ urls: ["*://*/_extension_storage*"] },
|
||||
["blocking"]
|
||||
);
|
||||
|
||||
currentBgmAudio = new Audio(url);
|
||||
currentBgmAudio.loop = true;
|
||||
currentBgmAudio.volume = 0.5; // Default volume
|
||||
|
||||
currentBgmAudio.play()
|
||||
.then(() => console.log("Background: BGM started playing:", url))
|
||||
.catch(e => console.error("Background: Error playing BGM:", e));
|
||||
}
|
||||
|
||||
function stopBGM() {
|
||||
if (currentBgmAudio) {
|
||||
currentBgmAudio.pause();
|
||||
currentBgmAudio.currentTime = 0;
|
||||
currentBgmAudio = null;
|
||||
console.log("Background: BGM stopped.");
|
||||
}
|
||||
}
|
||||
|
||||
async function setBGMEnabled(enabled) {
|
||||
bgmEnabledState = enabled;
|
||||
try {
|
||||
await storageAPI.set({ bgmEnabled: enabled });
|
||||
console.log("Background: BGM enabled state saved to storage:", enabled);
|
||||
if (!enabled) {
|
||||
stopBGM();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Background: Error saving BGM enabled state:", error);
|
||||
}
|
||||
}
|
||||
|
||||
async function setFontDisabled(disabled) {
|
||||
try {
|
||||
await storageAPI.set({ fontDisabled: disabled });
|
||||
console.log("Background: Font disabled state saved to storage:", disabled);
|
||||
} catch (error) {
|
||||
console.error("Background: Error saving font disabled state:", error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --- Main Message Listener (handles communication from popup and content script) ---
|
||||
runtimeAPI.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
||||
// Return true for asynchronous sendResponse or Promise to keep the message channel open.
|
||||
console.log("Background: Received message:", request.action, "from sender:", sender.tab ? "Content Script (Tab ID: " + sender.tab.id + ")" : "Popup/Extension");
|
||||
|
||||
switch (request.action) {
|
||||
// --- BGM Control ---
|
||||
case "playBGM":
|
||||
// Only play if BGM is enabled by user preference
|
||||
if (bgmEnabledState) {
|
||||
playBGM(request.url); // Use request.url from the content script
|
||||
} else {
|
||||
console.log("Background: BGM disabled by user preference, not playing.");
|
||||
}
|
||||
sendResponse({ success: true });
|
||||
return false; // Synchronous acknowledgment
|
||||
|
||||
case "stopBGM":
|
||||
stopBGM();
|
||||
sendResponse({ success: true });
|
||||
return false;
|
||||
|
||||
case "setBGMEnabled": // This handles toggle state and playback logic
|
||||
setBGMEnabled(request.enabled);
|
||||
sendResponse({ success: true });
|
||||
return false;
|
||||
|
||||
case "getBGMEnabled":
|
||||
sendResponse({ enabled: bgmEnabledState }); // Return the current in-memory state
|
||||
return false;
|
||||
|
||||
case "setBGMVolume":
|
||||
if (currentBgmAudio) {
|
||||
currentBgmAudio.volume = request.volume;
|
||||
console.log("Background: BGM volume set to:", request.volume);
|
||||
}
|
||||
sendResponse({ success: true });
|
||||
return false;
|
||||
|
||||
// --- Storage Actions ---
|
||||
case "getStorage":
|
||||
// Handles requests to get data from storage, including 'logs'
|
||||
return (async () => {
|
||||
const result = await storageAPI.get(request.key);
|
||||
let valueToReturn;
|
||||
if (request.key === 'logs') {
|
||||
valueToReturn = logs; // Return in-memory logs
|
||||
} else if (request.key === 'pts') {
|
||||
valueToReturn = currentPoints; // Return in-memory points
|
||||
} else {
|
||||
valueToReturn = result[request.key];
|
||||
}
|
||||
console.log(`Background: getStorage for ${request.key}, returning:`, valueToReturn);
|
||||
return { value: valueToReturn }; // Send back the result (as a Promise)
|
||||
})();
|
||||
|
||||
case "setStorage":
|
||||
// Handles requests to set data in storage, including 'slog' for logs
|
||||
return (async () => {
|
||||
console.log(`Background: setStorage for ${request.key}, value:`, request.value);
|
||||
if (request.key === 'slog') { // Special handling for logs (append)
|
||||
logs.push(`[${new Date().toISOString()}] ${request.value}`);
|
||||
// Optional: Limit log size if necessary (e.g., to last 100 entries)
|
||||
if (logs.length > 100) logs = logs.slice(logs.length - 100); // Keep last 100
|
||||
await storageAPI.set({ logs: logs }); // Persist logs to local storage
|
||||
} else if (request.key === 'spts') { // Special handling for points (add to existing)
|
||||
const pointsToAdd = parseInt(request.value) || 0;
|
||||
currentPoints += pointsToAdd;
|
||||
await storageAPI.set({ pts: currentPoints });
|
||||
console.log("Background: Points updated to:", currentPoints);
|
||||
} else { // Generic set for other keys
|
||||
await storageAPI.set({ [request.key]: request.value });
|
||||
}
|
||||
return { success: true }; // Acknowledge completion
|
||||
})();
|
||||
|
||||
case "clearLogs":
|
||||
return (async () => {
|
||||
console.log("Background: Clearing logs.");
|
||||
logs = []; // Clear in-memory logs
|
||||
await storageAPI.set({ logs: [] }); // Clear stored logs
|
||||
return { success: true };
|
||||
})();
|
||||
|
||||
case "clearPoints":
|
||||
return (async () => {
|
||||
console.log("Background: Clearing points.");
|
||||
currentPoints = 0; // Clear in-memory points
|
||||
await storageAPI.set({ pts: 0 });
|
||||
return { success: true };
|
||||
})();
|
||||
|
||||
// --- Font Control ---
|
||||
case "setFontDisabled": /* ... */ return false;
|
||||
case "getFontDisabled": /* ... */ return false;
|
||||
|
||||
default:
|
||||
console.warn("Background: Unrecognized message action:", request.action);
|
||||
sendResponse({ success: false, error: "Unrecognized action" });
|
||||
return false;
|
||||
}
|
||||
});
|
@ -1,31 +1,18 @@
|
||||
// classDefinitions.js (This code runs in the page's main world)
|
||||
|
||||
// IMPORTANT: This script will now receive URLs via window.postMessage from the content script.
|
||||
// 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
|
||||
|
||||
// These will be populated by the message listener
|
||||
let _wiiShopSoundUrls_ = [];
|
||||
let _wiiShopBgmUrl_ = '';
|
||||
let _bgmInitiallyEnabled = false; // This flag will also be passed via postMessage if needed, or handled by content.js
|
||||
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 = "";
|
||||
|
||||
// --- Listener for messages from the content script ---
|
||||
window.addEventListener('message', (event) => {
|
||||
// Ensure the message is from our extension and the correct type
|
||||
if (event.source === window && event.data && event.data.type === "WII_SHOP_EXTENSION_INIT") {
|
||||
_wiiShopSoundUrls_ = event.data.soundUrls;
|
||||
_wiiShopBgmUrl_ = event.data.bgmUrl;
|
||||
_bgmInitiallyEnabled = event.data.bgmInitiallyEnabled; // Capture this if needed in classDefinitions.js
|
||||
console.log("classDefinitions.js received URLs and initial BGM state from content script.");
|
||||
|
||||
// If you need to trigger BGM playback from *within* classDefinitions.js based on initial state, do it here
|
||||
// However, your content.js already handles this by sending a message to the background, which is better.
|
||||
// The _bgmInitiallyEnabled flag is now more for reference within this script if needed by other logic.
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Existing global variables exposed (these remain the same as your original)
|
||||
var ecsUrl = "";
|
||||
@ -48,6 +35,14 @@ 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') {
|
||||
@ -60,84 +55,77 @@ const trace = function(...args) {
|
||||
const storageCache = {};
|
||||
const STORAGE_ENDPOINT = '/_extension_storage'; // This endpoint must be intercepted by background.js
|
||||
|
||||
// --- extensionStorage (UPDATED to use postMessage bridge) ---
|
||||
const extensionStorage = {
|
||||
set: (key, value) => {
|
||||
storageCache[key] = value;
|
||||
fetch(`${STORAGE_ENDPOINT}?set_key=${encodeURIComponent(key)}&set_value=${encodeURIComponent(value)}`)
|
||||
.catch(e => console.error("[Page] Error sending storage_set:", e));
|
||||
// Asynchronous set operation
|
||||
set: async (key, value) => {
|
||||
_sendPageMessage('extStorageSet', { key, value });
|
||||
},
|
||||
|
||||
get: (key) => {
|
||||
if (key in storageCache) return storageCache[key];
|
||||
// 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
|
||||
|
||||
const request = new XMLHttpRequest();
|
||||
// Use synchronous XHR for get, which is fine in page context
|
||||
request.open('GET', `${STORAGE_ENDPOINT}?get=${encodeURIComponent(key)}`, false);
|
||||
try {
|
||||
request.send(null);
|
||||
if (request.status === 200 || request.status === 0) { // status 0 for local file access in some contexts
|
||||
const data = JSON.parse(request.responseText);
|
||||
storageCache[key] = data.value;
|
||||
return data.value;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("[Page] Error getting storage via XMLHttpRequest:", e);
|
||||
}
|
||||
return null;
|
||||
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) => {
|
||||
fetch(`${STORAGE_ENDPOINT}?set_key=slogs&set_value=${encodeURIComponent(message)}`)
|
||||
.catch(e => console.error("[Page] Error sending slog:", e));
|
||||
_sendPageMessage('extStorageSet', { key: 'slogs', value: message });
|
||||
},
|
||||
|
||||
getLogs: () => {
|
||||
return extensionStorage.get('logs') || [];
|
||||
getLogs: async () => {
|
||||
const result = await extensionStorage.get('logs');
|
||||
return result || [];
|
||||
},
|
||||
|
||||
clearLogs: () => {
|
||||
fetch(`${STORAGE_ENDPOINT}?clogs=true`)
|
||||
.catch(e => console.error("[Page] Error sending clearLogs:", e));
|
||||
storageCache.logs = [];
|
||||
_sendPageMessage('clearLogs');
|
||||
},
|
||||
|
||||
spts: (points) => {
|
||||
const pointsToAdd = parseInt(points) || 0;
|
||||
if (pointsToAdd > 0) {
|
||||
fetch(`${STORAGE_ENDPOINT}?set_key=spts&set_value=${pointsToAdd}`)
|
||||
.catch(e => console.error("[Page] Error sending spts:", e));
|
||||
}
|
||||
_sendPageMessage('extStorageSet', { key: 'spts', value: points });
|
||||
},
|
||||
|
||||
getpts: () => {
|
||||
const points = extensionStorage.get('pts');
|
||||
getpts: async () => {
|
||||
const points = await extensionStorage.get('pts');
|
||||
return parseInt(points) || 0;
|
||||
},
|
||||
|
||||
clearpts: () => {
|
||||
fetch(`${STORAGE_ENDPOINT}?cpts=true`)
|
||||
.catch(e => console.error("[Page] Error sending clearpts:", e));
|
||||
storageCache.pts = 0;
|
||||
_sendPageMessage('clearPoints');
|
||||
},
|
||||
|
||||
// New method to send messages to the background script for BGM control
|
||||
// This method sends BGM control messages to content.js, which forwards to background.js
|
||||
sendMessageToBackground: async (message) => {
|
||||
let url = `${STORAGE_ENDPOINT}?action=${encodeURIComponent(message.action)}`;
|
||||
if (message.bgmUrl) {
|
||||
url += `&bgmUrl=${encodeURIComponent(message.bgmUrl)}`;
|
||||
}
|
||||
try {
|
||||
await fetch(url);
|
||||
} catch (e) {
|
||||
console.error(`[Page] Error sending BGM command '${message.action}':`, e);
|
||||
}
|
||||
_sendPageMessage(message.action, message);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
window.extensionStorage = extensionStorage;
|
||||
|
||||
console.log("Current points (from injected script):", extensionStorage.getpts());
|
||||
console.log("Trace loaded (from injected script):", extensionStorage.getLogs());
|
||||
// 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
|
||||
@ -189,12 +177,12 @@ class ECommerceInterface {
|
||||
}
|
||||
}
|
||||
}
|
||||
getLog() {
|
||||
return extensionStorage.getLogs() || "";
|
||||
async getLog() {
|
||||
return await extensionStorage.getLogs() || "";
|
||||
}
|
||||
|
||||
getPoints() {
|
||||
return extensionStorage.getpts() || 0;
|
||||
async getPoints() {
|
||||
return await extensionStorage.getpts() || 0;
|
||||
}
|
||||
|
||||
setPoints(newPoints) {
|
||||
@ -211,6 +199,7 @@ class ECommerceInterface {
|
||||
trace("Points updated to: " + extensionStorage.getpts());
|
||||
}
|
||||
|
||||
|
||||
loadPoints() {
|
||||
console.log("nah i dont load points, they alr loaded");
|
||||
}
|
||||
@ -275,7 +264,7 @@ class ECommerceInterface {
|
||||
region: "USA",
|
||||
isParentalControlEnabled: false,
|
||||
userAge: 20,
|
||||
language: "fr",
|
||||
language: "en",
|
||||
accountId: "659247864",
|
||||
deviceId: "4587571479",
|
||||
serial: "PC156494873",
|
||||
@ -295,18 +284,18 @@ class ECommerceInterface {
|
||||
registrationStatus: "R",
|
||||
};
|
||||
}
|
||||
setSessionValue(key, value) {
|
||||
extensionStorage.set(key, value);
|
||||
async setSessionValue(key, value) {
|
||||
await extensionStorage.set(key, value);
|
||||
}
|
||||
getSessionValue(key) {
|
||||
return extensionStorage.get(key);
|
||||
async getSessionValue(key) {
|
||||
return await extensionStorage.get(key);
|
||||
}
|
||||
pubKeyEncrypt(nah) {
|
||||
console.log("behonest this is not required: " + nah);
|
||||
return nah;
|
||||
}
|
||||
purchasePoints(pointsToBuy, itemId, price, payment, taxes, purchaseInfo, discount) {
|
||||
this.setPoints(pointsToBuy);
|
||||
async purchasePoints(pointsToBuy, itemId, price, payment, taxes, purchaseInfo, discount) {
|
||||
await this.setPoints(pointsToBuy);
|
||||
return 100;
|
||||
}
|
||||
getProgress() {
|
||||
@ -337,30 +326,30 @@ class ECommerceInterface {
|
||||
checkRegistration() {
|
||||
window._currentstatus = "checkRegistration";
|
||||
return {
|
||||
"status": 0,
|
||||
"operation": "checkRegistration",
|
||||
"description": "",
|
||||
"phase": 11,
|
||||
"isCancelRequested": false,
|
||||
"downloadedSize": 0,
|
||||
"totalSize": 0,
|
||||
"errCode": 0,
|
||||
"errInfo": null
|
||||
"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
|
||||
"status": 0,
|
||||
"operation": "syncRegistration",
|
||||
"description": "",
|
||||
"phase": 18,
|
||||
"isCancelRequested": false,
|
||||
"downloadedSize": 0,
|
||||
"totalSize": 0,
|
||||
"errCode": 0,
|
||||
"errInfo": null
|
||||
};
|
||||
}
|
||||
getWeakToken() {
|
||||
@ -431,41 +420,44 @@ class wiiShop {
|
||||
isCompatibleMode() {
|
||||
return true;
|
||||
}
|
||||
setWallpaper() {
|
||||
trace("Cant do setWallpaper yet, will later when i fully adapt this shi-")
|
||||
return null;
|
||||
}
|
||||
launchCode = 0;
|
||||
}
|
||||
|
||||
class wiiSound {
|
||||
// These will now be populated by the message listener
|
||||
static audioUrls = [];
|
||||
static bgmUrl = '';
|
||||
static currentBgmAudio = null; // Stays static to manage a single BGM instance
|
||||
// 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");
|
||||
// No need to copy _injected variables here, as they'll be populated by the message listener
|
||||
}
|
||||
|
||||
playSE(snd) {
|
||||
// Ensure URLs are available before attempting to play
|
||||
if (!_wiiShopSoundUrls_ || _wiiShopSoundUrls_.length === 0) {
|
||||
// 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 >= _wiiShopSoundUrls_.length) {
|
||||
if (isNaN(soundIndex) || soundIndex < 1 || soundIndex >= wiiSound.audioUrls.length) {
|
||||
console.warn("Invalid sound index for wiiSound.playSE:", snd);
|
||||
return;
|
||||
}
|
||||
|
||||
const audioUrl = _wiiShopSoundUrls_[soundIndex];
|
||||
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';
|
||||
audio.style.display = 'none'; // Hide the audio element
|
||||
audio.play()
|
||||
.then(() => {
|
||||
console.log('Wii Shop Sound played:', soundIndex, audioUrl);
|
||||
@ -476,55 +468,34 @@ class wiiSound {
|
||||
}
|
||||
|
||||
playBGM() {
|
||||
// Use an internal flag for _bgmAlreadyPlaying
|
||||
if (_bgmAlreadyPlaying === true) {
|
||||
return "nah mate, i aint playin for ya, im already playin";
|
||||
} else {
|
||||
_bgmAlreadyPlaying = true;
|
||||
if (wiiSound.currentBgmAudio && !wiiSound.currentBgmAudio.paused) {
|
||||
wiiSound.currentBgmAudio.pause();
|
||||
wiiSound.currentBgmAudio.currentTime = 0;
|
||||
console.log('Stopped previous BGM.');
|
||||
}
|
||||
|
||||
// Ensure BGM URL is available to send via extensionStorage
|
||||
if (!_wiiShopBgmUrl_) {
|
||||
console.warn("No BGM URL available to send to background script.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Use extensionStorage.sendMessageToBackground to control BGM in background
|
||||
if (typeof window.extensionStorage !== 'undefined' && typeof window.extensionStorage.sendMessageToBackground === 'function') {
|
||||
window.extensionStorage.sendMessageToBackground({
|
||||
action: "playBGM",
|
||||
bgmUrl: _wiiShopBgmUrl_
|
||||
}).then(() => {
|
||||
trace('Request to play BGM sent to background script via extensionStorage.');
|
||||
}).catch(error => {
|
||||
console.error('Error sending playBGM message to background via extensionStorage:', error);
|
||||
});
|
||||
} else {
|
||||
console.warn("window.extensionStorage.sendMessageToBackground not available for playBGM.");
|
||||
}
|
||||
// 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() {
|
||||
// Use an internal flag for _bgmAlreadyPlaying
|
||||
if (_bgmAlreadyPlaying === true) {
|
||||
_bgmAlreadyPlaying = false; // Reset the flag
|
||||
// Send a message to background via extensionStorage to stop BGM
|
||||
if (typeof window.extensionStorage !== 'undefined' && typeof window.extensionStorage.sendMessageToBackground === 'function') {
|
||||
window.extensionStorage.sendMessageToBackground({
|
||||
action: "stopBGM"
|
||||
}).then(() => {
|
||||
trace('Request to stop BGM sent to background script via extensionStorage.');
|
||||
}).catch(error => {
|
||||
console.error('Error sending stopBGM message to background via extensionStorage:', error);
|
||||
});
|
||||
} else {
|
||||
console.warn("window.extensionStorage.sendMessageToBackground not available for stopBGM.");
|
||||
}
|
||||
// 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?";
|
||||
}
|
||||
@ -636,13 +607,14 @@ window.wiiDlTask = wiiDlTask;
|
||||
window.wiiNwc24 = wiiNwc24;
|
||||
window.wiiSDCard = wiiSDCard;
|
||||
|
||||
// This block for initial BGM playback now needs to be async
|
||||
if (_bgmInitiallyEnabled) {
|
||||
// Use a short delay or an event listener to ensure all page elements are ready
|
||||
// and to potentially work around immediate autoplay blocks (though not guaranteed).
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
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();
|
||||
soundInstance.playBGM(); // This will use the postMessage bridge
|
||||
}
|
||||
});
|
||||
}
|
459
content.js
459
content.js
@ -1,17 +1,22 @@
|
||||
// content.js
|
||||
|
||||
// Log that the content script is running
|
||||
console.log("Content script is running.");
|
||||
console.log("Wii Shop Extension Content Script: Running at document_start.");
|
||||
|
||||
// --- Feature Detection for Cross-Browser Compatibility ---
|
||||
const runtimeAPI = typeof browser !== 'undefined' ? browser : chrome;
|
||||
const storageAPI = runtimeAPI.storage; // This will be browser.storage or chrome.storage
|
||||
|
||||
// --- Original Font Loading Logic ---
|
||||
let fontLoaded = false;
|
||||
// Define storageAPI more robustly
|
||||
let storageAPI;
|
||||
try {
|
||||
storageAPI = runtimeAPI.storage.local;
|
||||
} catch (e) {
|
||||
console.error("Content script: Could not access storage API!", e);
|
||||
// Fallback if storage API is unavailable (e.g., in a non-extension context)
|
||||
storageAPI = { get: async () => ({}), set: async () => {} };
|
||||
}
|
||||
|
||||
// --- Font Loading Logic ---
|
||||
function loadFont() {
|
||||
return "disabled";
|
||||
console.log("Wii Shop Extension: Attempting to load custom font.");
|
||||
const fontUrl = runtimeAPI.runtime.getURL("fonts/fot_rodin_pro_m.ttf");
|
||||
const style = document.createElement('style');
|
||||
style.textContent = `
|
||||
@ -19,213 +24,285 @@ function loadFont() {
|
||||
font-family: 'Wii NTLG PGothic JPN Regular';
|
||||
src: url('${fontUrl}') format('truetype');
|
||||
}
|
||||
body {
|
||||
font-family: 'Wii NTLG PGothic JPN Regular', sans-serif !important;
|
||||
}
|
||||
* {
|
||||
body, #text03-01, #text05-01, #text06-01, .buttonTextBlackM {
|
||||
font-family: 'Wii NTLG PGothic JPN Regular', sans-serif !important;
|
||||
}
|
||||
#text03-01, #text05-01, #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 */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
}
|
||||
.buttonTextBlackM {
|
||||
font-size: 24px; /* Adjust font size as needed */
|
||||
color: black; /* Set text color */
|
||||
text-align: center; /* Center text within the div */
|
||||
font-size: 24px;
|
||||
color: black;
|
||||
text-align: center;
|
||||
}
|
||||
`;
|
||||
|
||||
const head = document.head || document.getElementsByTagName('head')[0];
|
||||
if (head) {
|
||||
head.appendChild(style);
|
||||
console.log("Font loaded into <head>.");
|
||||
return "Font loaded into <head>";
|
||||
}
|
||||
|
||||
const observer = new MutationObserver(() => {
|
||||
const head = document.head || document.getElementsByTagName('head')[0];
|
||||
if (head) {
|
||||
head.appendChild(style);
|
||||
observer.disconnect();
|
||||
console.log("Font loaded into <head> via MutationObserver.");
|
||||
return "Font loaded into <head> via MutationObserver";
|
||||
}
|
||||
});
|
||||
observer.observe(document, { childList: true, subtree: true });
|
||||
|
||||
const fallbackTimeout = setTimeout(() => {
|
||||
if (!document.head || !document.head.contains(style)) {
|
||||
document.body.appendChild(style);
|
||||
console.log("Font loaded into <body> as a fallback.");
|
||||
observer.disconnect();
|
||||
return "Font loaded into <body> as a fallback";
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
setTimeout(() => {
|
||||
if (!document.head || !document.body.contains(style)) {
|
||||
console.error("Failed to load font: <head> and <body> are not available.");
|
||||
return "Failed to load font: <head> and <body> are not available.";
|
||||
}
|
||||
observer.disconnect();
|
||||
clearTimeout(fallbackTimeout);
|
||||
}, 2000);
|
||||
|
||||
return "Font loading initiated";
|
||||
}
|
||||
|
||||
// Check the font state on page load
|
||||
function checkFontState() {
|
||||
storageAPI.local.get(['fontDisabled']).then(function(result) {
|
||||
if (!result.fontDisabled) {
|
||||
//loadFont();
|
||||
} else {
|
||||
console.log("Font loading disabled by preference.");
|
||||
}
|
||||
}).catch(error => console.error("Error checking font state:", error));
|
||||
}
|
||||
|
||||
|
||||
const soundFilePaths = [
|
||||
'', // Index 0 (unused)
|
||||
'audio/1.wav',
|
||||
'audio/2.wav',
|
||||
'audio/3.wav',
|
||||
'audio/4.wav',
|
||||
'audio/5.wav',
|
||||
'audio/6.wav',
|
||||
'audio/7.wav',
|
||||
'audio/8.wav',
|
||||
'audio/9.wav',
|
||||
'audio/10.wav',
|
||||
'audio/11.wav',
|
||||
'audio/12.wav',
|
||||
'audio/13.wav',
|
||||
'audio/14.wav',
|
||||
'audio/15.wav',
|
||||
'audio/16.wav'
|
||||
|
||||
];
|
||||
const bgmFilePath = 'audio/bgm.wav'; // Define BGM file path
|
||||
|
||||
// Generate the full, web-accessible URLs
|
||||
const generatedSoundUrls = [];
|
||||
for (let i = 0; i < soundFilePaths.length; i++) {
|
||||
if (soundFilePaths[i]) {
|
||||
generatedSoundUrls[i] = runtimeAPI.runtime.getURL(soundFilePaths[i]);
|
||||
console.log("Wii Shop Extension: Font loaded into <head>.");
|
||||
} else {
|
||||
generatedSoundUrls[i] = '';
|
||||
}
|
||||
}
|
||||
const generatedBgmUrl = runtimeAPI.runtime.getURL(bgmFilePath); // Generate BGM URL
|
||||
|
||||
|
||||
// Function to load class definitions and inject globals
|
||||
const loadClassDefinitions = () => {
|
||||
const injectScript = () => {
|
||||
if (document.documentElement.querySelector('script[data-injected-id="wii-shop-cdjs"]')) {
|
||||
// Already injected, prevent double injection
|
||||
return;
|
||||
}
|
||||
|
||||
const script = document.createElement('script');
|
||||
script.setAttribute('type', 'text/javascript');
|
||||
script.setAttribute('src', runtimeAPI.runtime.getURL('classDefinitions.js')); // Set src to the external file
|
||||
script.setAttribute('data-injected-id', 'wii-shop-cdjs'); // Add an ID to prevent duplicates
|
||||
|
||||
// Inject into the document.documentElement (<html> tag) as the very first child
|
||||
if (document.documentElement) {
|
||||
document.documentElement.insertBefore(script, document.documentElement.firstChild);
|
||||
console.log("classDefinitions.js injected into page context via script element (early).");
|
||||
|
||||
// --- Post message to the injected script AFTER it's loaded ---
|
||||
// This ensures classDefinitions.js has a chance to set up its message listener.
|
||||
script.onload = () => {
|
||||
window.postMessage({
|
||||
type: "WII_SHOP_EXTENSION_INIT",
|
||||
soundUrls: generatedSoundUrls,
|
||||
bgmUrl: generatedBgmUrl
|
||||
}, window.location.origin); // Specify origin for security
|
||||
console.log("WII_SHOP_EXTENSION_INIT message sent to page context.");
|
||||
};
|
||||
script.onerror = (e) => {
|
||||
console.error("Error loading classDefinitions.js:", e);
|
||||
};
|
||||
|
||||
} else {
|
||||
console.error("Failed to inject script: document.documentElement not found.");
|
||||
}
|
||||
};
|
||||
|
||||
// Check if document.documentElement is already available
|
||||
if (document.documentElement) {
|
||||
injectScript();
|
||||
} else {
|
||||
// If not, use a MutationObserver to wait for the <html> element to be available
|
||||
// Fallback for when head is not yet available at document_start
|
||||
const observer = new MutationObserver((mutations, obs) => {
|
||||
if (document.documentElement) {
|
||||
injectScript();
|
||||
obs.disconnect(); // Stop observing once injected
|
||||
const currentHead = document.head || document.getElementsByTagName('head')[0];
|
||||
if (currentHead) {
|
||||
currentHead.appendChild(style);
|
||||
obs.disconnect();
|
||||
console.log("Wii Shop Extension: Font loaded into <head> via MutationObserver fallback.");
|
||||
}
|
||||
});
|
||||
// Observe the document for changes in its child nodes (to catch <html> being added)
|
||||
observer.observe(document, { childList: true, subtree: true });
|
||||
observer.observe(document.documentElement || document, { childList: true, subtree: true });
|
||||
}
|
||||
}
|
||||
|
||||
// Check the font state and load if not disabled
|
||||
async function checkFontState() {
|
||||
try {
|
||||
const result = await storageAPI.get(['fontDisabled']);
|
||||
if (!result.fontDisabled) {
|
||||
//loadFont(); disabled
|
||||
} else {
|
||||
console.log("Wii Shop Extension: Font loading disabled by user preference.");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Wii Shop Extension: Error checking font state:", error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --- Sound and BGM File Paths (Ensure these are correctly mapped to web-accessible resources) ---
|
||||
const soundFilePaths = [
|
||||
'', // Index 0 (unused)
|
||||
'audio/1.wav', 'audio/2.wav', 'audio/3.wav', 'audio/4.wav',
|
||||
'audio/5.wav', 'audio/6.wav', 'audio/7.wav', 'audio/8.wav',
|
||||
'audio/9.wav', 'audio/10.wav', 'audio/11.wav', 'audio/12.wav',
|
||||
'audio/13.wav', 'audio/14.wav', 'audio/15.wav', 'audio/16.wav'
|
||||
];
|
||||
const bgmFilePath = 'audio/bgm.wav';
|
||||
|
||||
// Generate the full, web-accessible URLs. These MUST be defined at the top level.
|
||||
const generatedSoundUrls = soundFilePaths.map(path => path ? runtimeAPI.runtime.getURL(path) : '');
|
||||
const generatedBgmUrl = runtimeAPI.runtime.getURL(bgmFilePath);
|
||||
|
||||
|
||||
// --- Function to load class definitions and inject globals ---
|
||||
const loadClassDefinitions = async () => {
|
||||
const classDefinitionsUrl = runtimeAPI.runtime.getURL('classDefinitions.js');
|
||||
console.log("Wii Shop Extension: Attempting to fetch classDefinitions.js from:", classDefinitionsUrl);
|
||||
|
||||
try {
|
||||
const response = await fetch(classDefinitionsUrl);
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status} fetching ${classDefinitionsUrl}`);
|
||||
}
|
||||
const classDefinitionsText = await response.text();
|
||||
console.log("Wii Shop Extension: classDefinitions.js fetched successfully. Length:", classDefinitionsText.length);
|
||||
|
||||
// Get initial BGM and Font state from storage for globals
|
||||
const storageResult = await storageAPI.get(['bgmEnabled', 'fontDisabled']);
|
||||
const bgmInitiallyEnabled = storageResult.bgmEnabled === true;
|
||||
const fontInitiallyDisabled = storageResult.fontDisabled === true;
|
||||
|
||||
// Construct the script content to prepend to classDefinitions.js
|
||||
const prependedGlobals = `
|
||||
(function() {
|
||||
// Ensure these are globally available within the page context
|
||||
window._wiiShopSoundUrls_ = ${JSON.stringify(generatedSoundUrls)};
|
||||
window._wiiShopBgmUrl_ = ${JSON.stringify(generatedBgmUrl)};
|
||||
window._bgmInitiallyEnabled = ${JSON.stringify(bgmInitiallyEnabled)};
|
||||
window._fontInitiallyDisabled = ${JSON.stringify(fontInitiallyDisabled)};
|
||||
|
||||
// Define the bridge function for the page context to communicate with content script
|
||||
const _sendMessageToContentScript = (action, payload = {}) => {
|
||||
window.postMessage({
|
||||
type: 'WiiShopExtension_MessageFromPage', // Unique type for messages from page to content script
|
||||
action: action, // The specific action like 'getStorage', 'playBGM', etc.
|
||||
payload: payload
|
||||
}, window.location.origin);
|
||||
};
|
||||
window.WiiShopExtension_sendMessage = _sendMessageToContentScript; // Expose globally for page's use
|
||||
|
||||
// Redefine/Expose extensionStorage if it's used by original page code or other injected scripts
|
||||
// This makes sure get/set calls from page go through our background script
|
||||
window.extensionStorage = {
|
||||
get: async function(key) {
|
||||
const response = await new Promise(resolve => {
|
||||
_sendMessageToContentScript('getStorage', { key: key });
|
||||
// Listen for the response back from the content script
|
||||
const listener = (event) => {
|
||||
if (event.source === window && event.data && event.data.type === 'WiiShopExtension_ResponseToPage' && event.data.action === 'getStorage' && event.data.key === key) {
|
||||
window.removeEventListener('message', listener);
|
||||
resolve(event.data.payload.value); // Extract the value
|
||||
}
|
||||
};
|
||||
window.addEventListener('message', listener);
|
||||
});
|
||||
return response;
|
||||
},
|
||||
set: async function(key, value) {
|
||||
await _sendMessageToContentScript('setStorage', { key: key, value: value });
|
||||
},
|
||||
slog: async function(message) {
|
||||
await _sendMessageToContentScript('setStorage', { key: 'slog', value: message });
|
||||
},
|
||||
spts: async function(points) {
|
||||
await _sendMessageToContentScript('setStorage', { key: 'spts', value: points });
|
||||
},
|
||||
clearLogs: async function() {
|
||||
await _sendMessageToContentScript('clearLogs');
|
||||
},
|
||||
clearPoints: async function() {
|
||||
await _sendMessageToContentScript('clearPoints');
|
||||
},
|
||||
playBGM: async function(url) {
|
||||
await _sendMessageToContentScript('playBGM', { url: url });
|
||||
},
|
||||
stopBGM: async function() {
|
||||
await _sendMessageToContentScript('stopBGM');
|
||||
}
|
||||
};
|
||||
})();
|
||||
`;
|
||||
|
||||
const scriptToInject = document.createElement('script');
|
||||
scriptToInject.setAttribute('type', 'text/javascript');
|
||||
scriptToInject.setAttribute('data-injected-id', 'wii-shop-cdjs');
|
||||
scriptToInject.textContent = prependedGlobals + classDefinitionsText;
|
||||
|
||||
let targetElement = document.head || document.documentElement;
|
||||
if (targetElement && !document.querySelector('[data-injected-id="wii-shop-cdjs"]')) {
|
||||
targetElement.insertBefore(scriptToInject, targetElement.firstChild);
|
||||
console.log("Wii Shop Extension: classDefinitions.js injected into page context.");
|
||||
|
||||
setTimeout(() => {
|
||||
if (scriptToInject.parentNode) {
|
||||
scriptToInject.parentNode.removeChild(scriptToInject);
|
||||
console.log("Wii Shop Extension: Injected classDefinitions.js script removed from DOM.");
|
||||
}
|
||||
}, 100);
|
||||
} else {
|
||||
console.warn("Wii Shop Extension: classDefinitions.js already injected or target element (head/html) not found.");
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error("Wii Shop Extension: Failed to load class definitions:", error);
|
||||
}
|
||||
};
|
||||
|
||||
// Load the class definitions
|
||||
loadClassDefinitions();
|
||||
checkFontState();
|
||||
|
||||
|
||||
// --- Initial BGM Playback on DOMContentLoaded ---
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
// Give a slight delay to ensure classDefinitions.js and window.extensionStorage are fully ready
|
||||
await new Promise(resolve => setTimeout(resolve, 50));
|
||||
|
||||
// Request the initial BGM enabled state from the background script via extensionStorage
|
||||
if (typeof window.extensionStorage !== 'undefined' && typeof window.extensionStorage.get === 'function') {
|
||||
try {
|
||||
const bgmEnabled = await window.extensionStorage.get('bgmEnabled');
|
||||
console.log("Initial BGM enabled state from storage:", bgmEnabled);
|
||||
|
||||
if (bgmEnabled === true) {
|
||||
console.log("Attempting to play initial BGM from content script.");
|
||||
window.extensionStorage.sendMessageToBackground({
|
||||
action: "playBGM",
|
||||
bgmUrl: generatedBgmUrl
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error retrieving initial BGM state or sending play request:", error);
|
||||
}
|
||||
} else {
|
||||
console.warn("window.extensionStorage not available for initial BGM check.");
|
||||
// --- Message Listener (from injected page script to content script) ---
|
||||
window.addEventListener('message', async (event) => {
|
||||
if (event.source !== window || !event.data || event.data.type !== 'WiiShopExtension_MessageFromPage') {
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
// Listener for messages from the popup (if any, specifically for BGM toggle)
|
||||
const { action, payload } = event.data;
|
||||
console.log("Content script received message from page:", action, payload);
|
||||
|
||||
try {
|
||||
let responsePayload;
|
||||
|
||||
switch (action) {
|
||||
case 'getStorage':
|
||||
responsePayload = await runtimeAPI.runtime.sendMessage({ action: 'getStorage', key: payload.key });
|
||||
window.postMessage({
|
||||
type: 'WiiShopExtension_ResponseToPage',
|
||||
action: 'getStorage',
|
||||
key: payload.key,
|
||||
payload: responsePayload
|
||||
}, event.origin);
|
||||
break;
|
||||
|
||||
case 'setStorage':
|
||||
await runtimeAPI.runtime.sendMessage({ action: 'setStorage', key: payload.key, value: payload.value });
|
||||
break;
|
||||
|
||||
case 'clearLogs':
|
||||
await runtimeAPI.runtime.sendMessage({ action: 'clearLogs' });
|
||||
break;
|
||||
|
||||
case 'clearPoints':
|
||||
await runtimeAPI.runtime.sendMessage({ action: 'clearPoints' });
|
||||
break;
|
||||
|
||||
case 'playBGM':
|
||||
await runtimeAPI.runtime.sendMessage({ action: 'playBGM', url: payload.url });
|
||||
break;
|
||||
|
||||
case 'stopBGM':
|
||||
await runtimeAPI.runtime.sendMessage({ action: 'stopBGM' });
|
||||
break;
|
||||
|
||||
case 'setBGMEnabled':
|
||||
await runtimeAPI.runtime.sendMessage({ action: 'setBGMEnabled', enabled: payload.enabled });
|
||||
break;
|
||||
|
||||
case 'getBGMEnabled':
|
||||
responsePayload = await runtimeAPI.runtime.sendMessage({ action: 'getBGMEnabled' });
|
||||
window.postMessage({
|
||||
type: 'WiiShopExtension_ResponseToPage',
|
||||
action: 'getBGMEnabled',
|
||||
payload: responsePayload
|
||||
}, event.origin);
|
||||
break;
|
||||
|
||||
case 'setFontDisabled':
|
||||
await runtimeAPI.runtime.sendMessage({ action: 'setFontDisabled', disabled: payload.disabled });
|
||||
break;
|
||||
|
||||
case 'getFontDisabled':
|
||||
responsePayload = await runtimeAPI.runtime.sendMessage({ action: 'getFontDisabled' });
|
||||
window.postMessage({
|
||||
type: 'WiiShopExtension_ResponseToPage',
|
||||
action: 'getFontDisabled',
|
||||
payload: responsePayload
|
||||
}, event.origin);
|
||||
break;
|
||||
|
||||
// Removed: case 'injectedScriptReady' as content.js no longer waits for it explicitly.
|
||||
|
||||
default:
|
||||
console.warn("Content script: Unhandled message from page:", action, payload);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Content script error handling action "${action}":`, error);
|
||||
if (action === 'getStorage' || action === 'getBGMEnabled' || action === 'getFontDisabled') {
|
||||
window.postMessage({
|
||||
type: 'WiiShopExtension_ResponseToPage',
|
||||
action: action,
|
||||
key: payload ? payload.key : undefined,
|
||||
error: error.message
|
||||
}, event.origin);
|
||||
}
|
||||
}
|
||||
}, false);
|
||||
|
||||
// --- Main Initialization ---
|
||||
// Load the class definitions immediately at document_start.
|
||||
loadClassDefinitions();
|
||||
checkFontState(); // Check and load font if enabled.
|
||||
|
||||
// Removed: The specific window.onload listener for debug.jsp
|
||||
// The debug.jsp page will now execute its original onload attribute.
|
||||
|
||||
|
||||
// --- Listener for messages from the popup (if any) ---
|
||||
runtimeAPI.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
||||
if (request.action === "toggleBGMImmediate") {
|
||||
if (request.enabled) {
|
||||
console.log("Received toggleBGMImmediate from popup: Play BGM.");
|
||||
if (typeof window.extensionStorage !== 'undefined' && typeof window.extensionStorage.sendMessageToBackground === 'function') {
|
||||
window.extensionStorage.sendMessageToBackground({
|
||||
action: "playBGM",
|
||||
bgmUrl: generatedBgmUrl
|
||||
});
|
||||
}
|
||||
console.log("Content: Received toggleBGMImmediate from popup: Play BGM.");
|
||||
runtimeAPI.runtime.sendMessage({
|
||||
action: "playBGM",
|
||||
url: generatedBgmUrl
|
||||
}).catch(error => console.error("Content: Error sending playBGM (immediate) to background:", error));
|
||||
} else {
|
||||
console.log("Received toggleBGMImmediate from popup: Stop BGM.");
|
||||
if (typeof window.extensionStorage !== 'undefined' && typeof window.extensionStorage.sendMessageToBackground === 'function') {
|
||||
window.extensionStorage.sendMessageToBackground({
|
||||
action: "stopBGM"
|
||||
});
|
||||
}
|
||||
console.log("Content: Received toggleBGMImmediate from popup: Stop BGM.");
|
||||
runtimeAPI.runtime.sendMessage({
|
||||
action: "stopBGM"
|
||||
}).catch(error => console.error("Content: Error sending stopBGM (immediate) to background:", error));
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -11,6 +11,7 @@
|
||||
"webRequestBlocking"
|
||||
],
|
||||
"host_permissions": [
|
||||
"*://oss-auth.thecheese.io/oss/serv/debug.jsp*",
|
||||
"<all_urls>"
|
||||
],
|
||||
"action": {
|
||||
|
113
popup.js
113
popup.js
@ -1,49 +1,94 @@
|
||||
// popup.js
|
||||
const STORAGE_ENDPOINT = '/_extension_storage'; // Your existing storage endpoint
|
||||
|
||||
document.getElementById('clearTrace').addEventListener('click', function() {
|
||||
fetch(`${STORAGE_ENDPOINT}?clogs=true`)
|
||||
.catch(() => {});
|
||||
document.getElementById('cleared').textContent = 'Cleared: trace';
|
||||
// Use runtimeAPI for cross-browser compatibility
|
||||
const runtimeAPI = typeof browser !== 'undefined' ? browser : chrome;
|
||||
const storageAPI = runtimeAPI.storage.local; // Using local storage API
|
||||
|
||||
// Cache DOM elements for better performance
|
||||
const clearTraceButton = document.getElementById('clearTrace');
|
||||
const clearPointsButton = document.getElementById('clearPoints');
|
||||
const clearedMessage = document.getElementById('cleared');
|
||||
const toggleFontCheckbox = document.getElementById('toggleFont');
|
||||
const toggleBGMCheckbox = document.getElementById('toggleBGM');
|
||||
|
||||
// --- Helper Functions ---
|
||||
|
||||
// Displays a temporary message in the 'cleared' div
|
||||
function showClearedMessage(message) {
|
||||
clearedMessage.textContent = `Cleared: ${message}`;
|
||||
setTimeout(() => {
|
||||
clearedMessage.textContent = ''; // Clear message after 2 seconds
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
// Sends a message to the background script
|
||||
async function sendMessageToBackground(action, payload = {}) {
|
||||
try {
|
||||
const response = await runtimeAPI.runtime.sendMessage({ action, ...payload });
|
||||
console.log(`Popup: Message "${action}" sent to background, response:`, response);
|
||||
return response;
|
||||
} catch (error) {
|
||||
console.error(`Popup: Error sending message "${action}" to background:`, error);
|
||||
return { success: false, error: error.message };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --- Event Listeners ---
|
||||
|
||||
clearTraceButton.addEventListener('click', function() {
|
||||
sendMessageToBackground('clearLogs'); // Action handled by background.js
|
||||
showClearedMessage('trace');
|
||||
});
|
||||
|
||||
document.getElementById('clearPoints').addEventListener('click', function() {
|
||||
fetch(`${STORAGE_ENDPOINT}?cpts=true`)
|
||||
.catch(() => {});
|
||||
document.getElementById('cleared').textContent = 'Cleared: points';
|
||||
clearPointsButton.addEventListener('click', function() {
|
||||
sendMessageToBackground('clearPoints'); // Action handled by background.js
|
||||
showClearedMessage('points');
|
||||
});
|
||||
|
||||
// Handle the checkbox for enabling/disabling the font
|
||||
document.getElementById('toggleFont').addEventListener('change', function() {
|
||||
toggleFontCheckbox.addEventListener('change', function() {
|
||||
const isChecked = this.checked;
|
||||
// Set the font state in the extension's storage
|
||||
// Using chrome.storage.local for consistency with browser extension APIs
|
||||
chrome.storage.local.set({ fontEnabled: isChecked }); // Renamed key to 'fontEnabled' for clarity
|
||||
// Store 'fontDisabled' state (true if checkbox is UNCHECKED, false if CHECKED)
|
||||
storageAPI.set({ fontDisabled: !isChecked })
|
||||
.then(() => {
|
||||
console.log("Font state saved:", isChecked ? "Enabled" : "Disabled");
|
||||
// No direct message to content script for font, as it typically requires a page reload
|
||||
// for the font to correctly apply across all elements.
|
||||
})
|
||||
.catch(error => console.error("Error saving font state:", error));
|
||||
});
|
||||
|
||||
// Check the current font state when the popup is opened
|
||||
chrome.storage.local.get(['fontEnabled'], function(result) {
|
||||
// Default to true if not set (font enabled by default)
|
||||
document.getElementById('toggleFont').checked = (result.fontEnabled !== false);
|
||||
});
|
||||
|
||||
|
||||
// --- NEW BGM TOGGLE LOGIC ---
|
||||
document.getElementById('toggleBGM').addEventListener('change', function() {
|
||||
toggleBGMCheckbox.addEventListener('change', function() {
|
||||
const isChecked = this.checked;
|
||||
chrome.storage.local.set({ bgmEnabled: isChecked }, function() {
|
||||
// Optionally, send a message to content scripts to update immediately
|
||||
chrome.tabs.query({ active: true, currentWindow: true }, function(tabs) {
|
||||
chrome.tabs.sendMessage(tabs[0].id, {
|
||||
action: "toggleBGM",
|
||||
// Send a message to the background script to toggle BGM state and playback
|
||||
sendMessageToBackground('toggleBGM', { enabled: isChecked });
|
||||
|
||||
// Additionally, if the page is active, tell content script to update immediately
|
||||
// (though background script will handle persistence)
|
||||
runtimeAPI.tabs.query({ active: true, currentWindow: true }, function(tabs) {
|
||||
if (tabs[0]) {
|
||||
runtimeAPI.tabs.sendMessage(tabs[0].id, {
|
||||
action: "toggleBGMImmediate",
|
||||
enabled: isChecked
|
||||
});
|
||||
});
|
||||
}).catch(error => console.warn("Popup: Could not send immediate BGM toggle to content script:", error));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Check the current BGM state when the popup is opened
|
||||
chrome.storage.local.get(['bgmEnabled'], function(result) {
|
||||
// Default to false if not set (BGM disabled by default on startup)
|
||||
document.getElementById('toggleBGM').checked = (result.bgmEnabled === true);
|
||||
|
||||
// --- Initial State Loading ---
|
||||
|
||||
// Load all states when the popup is opened
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
storageAPI.get(['fontDisabled', 'bgmEnabled'])
|
||||
.then(result => {
|
||||
// Font: checked means font IS enabled, so `fontDisabled` should be false
|
||||
toggleFontCheckbox.checked = !(result.fontDisabled === true);
|
||||
console.log("Popup: Initial font state loaded:", toggleFontCheckbox.checked);
|
||||
|
||||
// BGM: checked means BGM IS enabled
|
||||
toggleBGMCheckbox.checked = (result.bgmEnabled === true);
|
||||
console.log("Popup: Initial BGM state loaded:", toggleBGMCheckbox.checked);
|
||||
})
|
||||
.catch(error => console.error("Popup: Error loading initial states:", error));
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user