wiimart-extension/background.js
2025-07-06 17:36:11 -04:00

227 lines
8.9 KiB
JavaScript

// background.js
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();
// --- Web Request Listeners ---
// 1. Block specific requests (title_manager.js)
runtimeAPI.webRequest.onBeforeRequest.addListener(
function(details) {
if (details.url.includes("title_manager.js")) {
console.log("Background: Blocking request for:", details.url);
return { cancel: true };
}
return {};
},
{ urls: ["<all_urls>"] },
["blocking"]
);
// 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 {};
},
{ 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;
}
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;
}
});