wiimart-extension/classDefinitions-tampermonkey.js
2025-07-06 13:00:30 -04:00

694 lines
24 KiB
JavaScript

// ==UserScript==
// @name Wii Shop Style Enhancer (Tampermonkey - With BGM)
// @namespace http://tampermonkey.net/
// @version 0.1
// @description Applies Wii Shop Channel aesthetics and functionality, including BGM.
// @author Thom
// @match *://*/* // Or more specific URLs where you want it to run
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_log
// @grant GM_getResourceURL
// @resource SND_SE01 https://wiilab.wiimart.org/wiimart/wiimart-extension/-/raw/main/audio/1.wav
// @resource SND_SE02 https://wiilab.wiimart.org/wiimart/wiimart-extension/-/raw/main/audio/2.wav
// @resource SND_SE03 https://wiilab.wiimart.org/wiimart/wiimart-extension/-/raw/main/audio/3.wav
// @resource SND_SE04 https://wiilab.wiimart.org/wiimart/wiimart-extension/-/raw/main/audio/4.wav
// @resource SND_SE05 https://wiilab.wiimart.org/wiimart/wiimart-extension/-/raw/main/audio/5.wav
// @resource SND_SE06 https://wiilab.wiimart.org/wiimart/wiimart-extension/-/raw/main/audio/6.wav
// @resource SND_SE07 https://wiilab.wiimart.org/wiimart/wiimart-extension/-/raw/main/audio/7.wav
// @resource SND_SE08 https://wiilab.wiimart.org/wiimart/wiimart-extension/-/raw/main/audio/8.wav
// @resource SND_SE09 https://wiilab.wiimart.org/wiimart/wiimart-extension/-/raw/main/audio/9.wav
// @resource SND_SE10 https://wiilab.wiimart.org/wiimart/wiimart-extension/-/raw/main/audio/10.wav
// @resource SND_SE11 https://wiilab.wiimart.org/wiimart/wiimart-extension/-/raw/main/audio/11.wav
// @resource SND_SE12 https://wiilab.wiimart.org/wiimart/wiimart-extension/-/raw/main/audio/12.wav
// @resource SND_SE13 https://wiilab.wiimart.org/wiimart/wiimart-extension/-/raw/main/audio/13.wav
// @resource SND_SE14 https://wiilab.wiimart.org/wiimart/wiimart-extension/-/raw/main/audio/14.wav
// @resource SND_SE15 https://wiilab.wiimart.org/wiimart/wiimart-extension/-/raw/main/audio/15.wav
// @resource SND_SE16 https://wiilab.wiimart.org/wiimart/wiimart-extension/-/raw/main/audio/16.wav
// @resource BGM_WII_SHOP https://wiilab.wiimart.org/wiimart/wiimart-extension/-/raw/main/audio/bgm.wav // Added BGM resource
// @resource WII_FONT https://wiilab.wiimart.org/wiimart/wiimart-extension/-/raw/main/fonts/fot_rodin_pro_m.ttf // Assuming you want to inject the font
// @run-at document-start
// ==/UserScript==
(function() {
'use strict';
// Global variables for sound URLs and status
const _wiiShopSoundUrls_ = [
null, // Index 0
GM_getResourceURL("SND_SE01"),
GM_getResourceURL("SND_SE02"),
GM_getResourceURL("SND_SE03"),
GM_getResourceURL("SND_SE04"),
GM_getResourceURL("SND_SE05"),
GM_getResourceURL("SND_SE06"),
GM_getResourceURL("SND_SE07"),
GM_getResourceURL("SND_SE08"),
GM_getResourceURL("SND_SE09"),
GM_getResourceURL("SND_SE10"),
GM_getResourceURL("SND_SE11"),
GM_getResourceURL("SND_SE12"),
GM_getResourceURL("SND_SE13"),
GM_getResourceURL("SND_SE14"),
GM_getResourceURL("SND_SE15"),
GM_getResourceURL("SND_SE16")
];
const _wiiShopBgmUrl_ = GM_getResourceURL("BGM_WII_SHOP"); // BGM URL!
let _bgmAlreadyPlaying = false; // Internal flag for BGM state
let _currentstatus = "";
// Existing global variables exposed (these remain the same)
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
// --- Tampermonkey-compliant trace function ---
const trace = function(...args) {
const logMessage = args.map(a => String(a)).join(' ');
GM_log("[WiiShop Trace]", logMessage); // Logs to Tampermonkey console
// Store logs in Tampermonkey storage if needed for `getLogs`
GM_getValue('slogs', '[]').then(currentLogsJson => {
let currentLogs = [];
try {
currentLogs = JSON.parse(currentLogsJson);
} catch (e) {
console.error("Error parsing stored logs:", e);
}
currentLogs.push(logMessage);
GM_setValue('slogs', JSON.stringify(currentLogs));
});
};
window.trace = trace; // Make it globally accessible
// --- Tampermonkey-compliant extensionStorage implementation ---
window.extensionStorage = {
async set(key, value) {
await GM_setValue(key, value);
console.log(`[TM Storage] Set ${key}:`, value);
},
async get(key) {
const value = await GM_getValue(key, undefined); // Default to undefined
console.log(`[TM Storage] Got ${key}:`, value);
return value;
},
async addLog(logMessage) {
trace(logMessage);
},
async getLogs() {
try {
const logsJson = await GM_getValue('slogs', '[]');
return JSON.parse(logsJson);
} catch (e) {
console.error("[TM Storage] Error getting logs:", e);
return [];
}
},
async clearLogs() {
await GM_setValue('slogs', '[]');
console.log("[TM Storage] Logs cleared.");
},
async spts(points) { // Set points
const pointsToAdd = parseInt(points) || 0;
if (pointsToAdd > 0) {
await GM_setValue('pts', pointsToAdd);
console.log(`[TM Storage] Points set to: ${pointsToAdd}`);
}
},
async getpts() { // Get points
const points = await GM_getValue('pts', 0);
return parseInt(points) || 0;
},
async clearpts() { // Clear points
await GM_setValue('pts', 0);
console.log("[TM Storage] Points cleared.");
},
// This method is now used for BGM control directly in the page context
async sendMessageToBackground(message) {
// This function is still here for compatibility if other parts of your script
// call it, but BGM handling is now direct within wiiSound.
GM_log("[WiiShop TM] Attempted to send message to 'background'. This feature is limited in Tampermonkey scripts:", message.action);
}
};
// Initial logs using the newly defined extensionStorage
console.log("Current points (from Tampermonkey script):", await window.extensionStorage.getpts());
console.log("Trace loaded (from Tampermonkey script):", await window.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() { // Made async because extensionStorage.getLogs is async
return (await window.extensionStorage.getLogs()) || "";
}
async getPoints() { // Made async
return (await window.extensionStorage.getpts()) || 0;
}
async setPoints(newPoints) { // Made async
if (!Number.isInteger(newPoints)) {
newPoints = parseInt(newPoints, 10);
}
if (isNaN(newPoints)) {
console.error("Invalid points value provided:", newPoints);
return;
}
await window.extensionStorage.spts(newPoints);
trace("Points updated to: " + await window.extensionStorage.getpts());
}
loadPoints() {
console.log("Points are already loaded, no action needed.");
}
cancelOperation() {
console.log("No operation to cancel.");
}
setWebSvcUrls(ecsuri, iasuri) {
window.ecsUrl = ecsuri;
window.iasUrl = iasuri;
}
setContentUrls(ccsuri, ucsuri) {
window.ccsUrl = ccsuri;
window.ucsUrl = ucsuri;
}
getCachedBalance() {
window._currentstatus = "getCachedBalance"
// Note: This uses localStorage, not extensionStorage. This might be a discrepancy
// with your original design or intentional for this specific function.
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: "fr",
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) { // Made async
await window.extensionStorage.set(key, value);
}
async getSessionValue(key) { // Made async
return await window.extensionStorage.get(key);
}
pubKeyEncrypt(nah) {
console.log("This pubKeyEncrypt method does not perform actual encryption in this context: " + nah);
return nah;
}
async purchasePoints(pointsToBuy, itemId, price, payment, taxes, purchaseInfo, discount) { // Made async
await this.setPoints(pointsToBuy);
window._currentstatus = "purchasePoints";
return {
"status": 0,
"operation": "purchasePoints",
"description": "",
"phase": 11,
"isCancelRequested": false,
"downloadedSize": 0,
"totalSize": 0,
"errCode": 0,
"errInfo": null
};
}
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("Synchronization value passed: " + 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();
}
}
}
// --- Define the wiiShop class ---
class wiiShop {
constructor() {
trace("wiiShop initialized");
return "isok";
}
connecting = null;
retry() {
window.location.pathname = "/oss/serv/W_01.jsp";
}
endWaiting() {
console.log("End waiting: No specific action defined.");
}
enableHRP() {
console.log("HRP (Home button functionality) enable: No specific action defined.");
}
disableHRP() {
console.log("HRP (Home button functionality) disable: No specific action defined.");
}
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 for beginWaiting.");
return;
}
seconds = parsedValue;
}
if (!Number.isInteger(seconds)) {
console.error("Invalid input: Please provide an integer value for beginWaiting.");
return;
}
let duration;
duration = (seconds < 10) ? seconds * 1000 : seconds;
await this.sleep(duration);
console.log("Wait complete!");
}
isCompatibleMode() {
return true;
}
launchCode = 0;
}
// --- Define the wiiSound class (with BGM) ---
class wiiSound {
static currentBgmAudio = null; // Stays static to manage a single BGM instance
constructor() {
trace("wiiSound initialized");
}
playSE(snd) {
if (!_wiiShopSoundUrls_ || _wiiShopSoundUrls_.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) {
console.warn("Invalid sound index for wiiSound.playSE:", snd);
return;
}
const audioUrl = _wiiShopSoundUrls_[soundIndex];
if (!audioUrl) {
console.warn("No audio URL found for sound index:", soundIndex);
return;
}
const audio = new Audio(audioUrl);
audio.style.display = 'none'; // Keep hidden
audio.volume = 0.5; // Default SE volume, adjust if desired
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) {
trace("playBGM called, but BGM is already playing.");
return "BGM already playing";
}
if (!_wiiShopBgmUrl_) {
console.warn("No BGM URL available.");
return "No BGM URL";
}
_bgmAlreadyPlaying = true;
if (wiiSound.currentBgmAudio && !wiiSound.currentBgmAudio.paused) {
wiiSound.currentBgmAudio.pause();
wiiSound.currentBgmAudio.src = ''; // Clear source
wiiSound.currentBgmAudio = null;
console.log('Stopped previous BGM instance before playing new one.');
}
try {
wiiSound.currentBgmAudio = new Audio(_wiiShopBgmUrl_);
wiiSound.currentBgmAudio.loop = true;
wiiSound.currentBgmAudio.volume = 0.4; // Adjust BGM volume here
wiiSound.currentBgmAudio.play()
.then(() => {
trace('BGM started playing directly in page context.');
})
.catch(e => {
_bgmAlreadyPlaying = false; // Reset if autoplay fails
console.error("Error playing BGM:", e);
trace("Error playing BGM:", e);
// Often due to browser autoplay policy. User interaction usually fixes this.
});
} catch (e) {
_bgmAlreadyPlaying = false; // Reset if Audio object creation fails
console.error("Failed to create Audio object for BGM:", e);
trace("Failed to create Audio object for BGM:", e);
}
}
stopBGM() {
if (wiiSound.currentBgmAudio && _bgmAlreadyPlaying) {
wiiSound.currentBgmAudio.pause();
wiiSound.currentBgmAudio.src = ''; // Clear source to free up memory
wiiSound.currentBgmAudio = null;
_bgmAlreadyPlaying = false;
trace('BGM stopped.');
} else {
trace("stopBGM called, but BGM was not playing or no audio object exists.");
}
}
}
// --- Define other classes ---
class wiiKeyboard {
constructor() {
trace("wiiKeyboard initialized");
}
}
class ECCreditCardEncryptedPayment {
constructor(smth) {
this.smth = smth;
}
}
class ECPrice {
constructor(uhh, ahh) {
return uhh; // This seems to just return the first argument
}
}
class wiiSDCard {
constructor() {
return; // Empty constructor
}
}
class wiiNwc24 {
constructor() {
return; // Empty constructor
}
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 for getFriendInfo.");
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") {
// Returning the same userId for all example users
if (fnm >= 0 && fnm < 5) { // Ensure index is within bounds
return "3630753603591712";
}
}
if (data == "miiImage") {
return "111" // Placeholder Mii image info
}
return null; // Return null if data type or index is not recognized
}
myUserId = "0302167078436756";
}
class wiiDlTask {
constructor() {
trace("WiiDlTask init");
}
addDownloadTask(url, interval){
trace("Download task received: I will download it for you.");
}
}
class wiiMii {
constructor() {
trace("wiiMii init");
}
}
// --- Expose classes to the global window object ---
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;
// --- Font Injection ---
const injectWiiFont = () => {
const style = document.createElement('style');
style.textContent = `
@font-face {
font-family: 'WiiShop';
src: url('${GM_getResourceURL('WII_FONT')}') format('truetype');
}
body, html, * {
font-family: 'WiiShop', sans-serif !important;
}
`;
(document.head || document.documentElement).appendChild(style);
console.log("Wii Shop font injected by Tampermonkey script.");
};
// --- Initial BGM Playback ---
const autoPlayBGM = () => {
if (window.wiiSound && !_bgmAlreadyPlaying) {
const soundInstance = new window.wiiSound();
soundInstance.playBGM();
}
};
// Inject font and try to play BGM on DOMContentLoaded
document.addEventListener('DOMContentLoaded', () => {
injectWiiFont();
autoPlayBGM();
});
})();