feat: refactor createWasmToken to improve stability and token capture mechanism

This commit is contained in:
MiraiSeori committed 2025-11-20 08:04:36 +08:00
1 parent 00d69fafbe
commit 6c240b2b98
2 files changed
+120 -197

No files matched your search

+60 -101
View File
@@ -11427,120 +11427,79 @@ localStorage.removeItem("lp");
//find module if pawtect_chunk is null
pawtect_chunk ??= await findTokenModule("pawtect_wasm_bg.wasm");
async function createWasmToken(regionX, regionY, payload) {
async function createWasmToken(regionX, regionY, payload) {
try {
// Load the Pawtect module and WASM
const mod = await import(new URL('/_app/immutable/chunks/' + pawtect_chunk, location.origin).href);
let wasm;
try {
wasm = await mod._();
console.log('✅ WASM initialized successfully');
} catch (wasmError) {
console.error('❌ WASM initialization failed:', wasmError);
// Load the Pawtect module
// Fallback to D1pWKeJi.js if pawtect_chunk is undefined, ensuring stability
const chunkName = (typeof pawtect_chunk !== 'undefined' && pawtect_chunk) ? pawtect_chunk : "D1pWKeJi.js";
const mod = await import(new URL('/_app/immutable/chunks/' + chunkName, location.origin).href);
// Check for API client (mod.a) instead of WASM init (mod._)
if (!mod.a) {
console.error('❌ API Client (mod.a) not found');
return null;
}
try {
try {
const me = await fetch(`https://backend.wplace.live/me`, { credentials: 'include' }).then(r => r.ok ? r.json() : null);
if (me?.id) {
mod.i(me.id);
console.log('✅ user ID set:', me.id);
}
} catch { }
} catch (userIdError) {
console.log('⚠️ Error setting user ID:', userIdError.message);
}
try {
const testUrl = `https://backend.wplace.live/s0/pixel/${regionX}/${regionY}`;
if (mod.r) {
mod.r(testUrl);
console.log('✅ Request URL set:', testUrl);
} else {
console.log('⚠️ request_url function (mod.r) not available');
}
} catch (urlError) {
console.log('⚠️ Error setting request URL:', urlError.message);
console.log('✅ Module loaded and API client found');
// Prepare data for paint() method
// We need to reconstruct the internal pixel object structure expected by mod.a.paint
console.log('📝 Reconstructing paint data from payload...');
const paintPixels = [];
for (let i = 0; i < payload.colors.length; i++) {
paintPixels.push({
tile: [regionX, regionY],
pixel: [payload.coords[i * 2], payload.coords[i * 2 + 1]],
season: mod.C, // Use exported season constant
colorIdx: payload.colors[i]
});
}
// Create test payload
// Hook request method to capture token
// This bypasses the need to manually handle WASM memory or obfuscated context functions
console.log('🚀 Hooking API client to capture token...');
const originalRequest = mod.a.request.bind(mod.a);
let capturedToken = null;
console.log('📝 payload:', payload);
// Encode payload
const enc = new TextEncoder();
const dec = new TextDecoder();
const bodyStr = JSON.stringify(payload);
const bytes = enc.encode(bodyStr);
console.log('📏 Payload size:', bytes.length, 'bytes');
console.log('📄 Payload string:', bodyStr);
// Allocate WASM memory with validation
let inPtr;
try {
if (!wasm.__wbindgen_malloc) {
console.error('❌ __wbindgen_malloc function not found');
return null;
mod.a.request = async function(url, options) {
// Intercept the token from headers
if (options && options.headers && options.headers['x-pawtect-token']) {
capturedToken = options.headers['x-pawtect-token'];
console.log('✅ Token captured via hook');
// Return fake success to satisfy paint() execution flow
return { status: 200, json: async () => ({}) };
}
// Pass through other requests (like /me)
return originalRequest(url, options);
};
inPtr = wasm.__wbindgen_malloc(bytes.length, 1);
console.log('✅ WASM memory allocated, pointer:', inPtr);
// Trigger the paint function
console.log('🚀 Calling mod.a.paint() to generate token...');
try {
// This handles UserID, URL, and WASM interaction internally
await mod.a.paint(paintPixels, payload.fp);
} catch (e) {
// Ignore errors caused by our fake request response
} finally {
// Restore original request method (Cleanup)
mod.a.request = originalRequest;
console.log('✅ Request hook restored');
}
// Copy data to WASM memory
const wasmBuffer = new Uint8Array(wasm.memory.buffer, inPtr, bytes.length);
wasmBuffer.set(bytes);
console.log('✅ Data copied to WASM memory');
} catch (memError) {
console.error('❌ Memory allocation error:', memError);
// Validate and return result
if (capturedToken) {
console.log('');
console.log('🎉 SUCCESS!');
console.log('🔑 Full token:');
console.log(capturedToken);
return capturedToken;
} else {
console.error('❌ Failed to capture token via hooking');
return null;
}
// Call the WASM function
console.log('🚀 Calling get_pawtected_endpoint_payload...');
let outPtr, outLen, token;
try {
const result = wasm.get_pawtected_endpoint_payload(inPtr, bytes.length);
console.log('✅ Function called, result type:', typeof result, result);
if (Array.isArray(result) && result.length === 2) {
[outPtr, outLen] = result;
console.log('✅ Got output pointer:', outPtr, 'length:', outLen);
// Decode the result
const outputBuffer = new Uint8Array(wasm.memory.buffer, outPtr, outLen);
token = dec.decode(outputBuffer);
console.log('✅ Token decoded successfully');
} else {
console.error('❌ Unexpected function result format:', result);
return null;
}
} catch (funcError) {
console.error('❌ Function call error:', funcError);
console.error('Stack trace:', funcError.stack);
return null;
}
// Cleanup memory
try {
if (wasm.__wbindgen_free && outPtr && outLen) {
wasm.__wbindgen_free(outPtr, outLen, 1);
console.log('✅ Output memory freed');
}
if (wasm.__wbindgen_free && inPtr) {
wasm.__wbindgen_free(inPtr, bytes.length, 1);
console.log('✅ Input memory freed');
}
} catch (cleanupError) {
console.log('⚠️ Cleanup warning:', cleanupError.message);
}
// Display results
console.log('');
console.log('🎉 SUCCESS!');
console.log('🔑 Full token:');
console.log(token);
return token;
} catch (error) {
console.error('❌ Failed to generate fp parameter:', error);
console.error('❌ Failed to generate token:', error);
return null;
}
}
+60 -96
View File
@@ -470,115 +470,79 @@
// Find module if pawtect_chunk is null
pawtect_chunk ??= await findTokenModule("pawtect_wasm_bg.wasm");
async function createWasmToken(regionX, regionY, payload) {
async function createWasmToken(regionX, regionY, payload) {
try {
// Load the Pawtect module and WASM
const mod = await import(new URL('/_app/immutable/chunks/'+pawtect_chunk, location.origin).href);
let wasm;
try {
wasm = await mod._();
console.log('✅ WASM initialized successfully');
} catch (wasmError) {
console.error('❌ WASM initialization failed:', wasmError);
// Load the Pawtect module
// Fallback to D1pWKeJi.js if pawtect_chunk is undefined, ensuring stability
const chunkName = (typeof pawtect_chunk !== 'undefined' && pawtect_chunk) ? pawtect_chunk : "D1pWKeJi.js";
const mod = await import(new URL('/_app/immutable/chunks/' + chunkName, location.origin).href);
// Check for API client (mod.a) instead of WASM init (mod._)
if (!mod.a) {
console.error('❌ API Client (mod.a) not found');
return null;
}
try {
try {
const me = await fetch(`https://backend.wplace.live/me`, { credentials: 'include' }).then(r => r.ok ? r.json() : null);
if (me?.id) {
mod.i(me.id);
console.log('✅ user ID set:', me.id);
}
} catch { }
} catch (userIdError) {
console.log('⚠️ Error setting user ID:', userIdError.message);
}
try {
const testUrl = `https://backend.wplace.live/s0/pixel/${regionX}/${regionY}`;
if (mod.r) {
mod.r(testUrl);
console.log('✅ Request URL set:', testUrl);
} else {
console.log('⚠️ request_url function (mod.r) not available');
}
} catch (urlError) {
console.log('⚠️ Error setting request URL:', urlError.message);
console.log('✅ Module loaded and API client found');
// Prepare data for paint() method
// We need to reconstruct the internal pixel object structure expected by mod.a.paint
console.log('📝 Reconstructing paint data from payload...');
const paintPixels = [];
for (let i = 0; i < payload.colors.length; i++) {
paintPixels.push({
tile: [regionX, regionY],
pixel: [payload.coords[i * 2], payload.coords[i * 2 + 1]],
season: mod.C, // Use exported season constant
colorIdx: payload.colors[i]
});
}
console.log('🔍 payload:', payload);
// Hook request method to capture token
// This bypasses the need to manually handle WASM memory or obfuscated context functions
console.log('🚀 Hooking API client to capture token...');
const originalRequest = mod.a.request.bind(mod.a);
let capturedToken = null;
// Encode payload
const enc = new TextEncoder();
const dec = new TextDecoder();
const bodyStr = JSON.stringify(payload);
const bytes = enc.encode(bodyStr);
console.log('🔍 Payload size:', bytes.length, 'bytes');
console.log('🔄 Payload string:', bodyStr);
// Allocate WASM memory with validation
let inPtr;
try {
if (!wasm.__wbindgen_malloc) {
console.error('❌ __wbindgen_malloc function not found');
return null;
mod.a.request = async function(url, options) {
// Intercept the token from headers
if (options && options.headers && options.headers['x-pawtect-token']) {
capturedToken = options.headers['x-pawtect-token'];
console.log('✅ Token captured via hook');
// Return fake success to satisfy paint() execution flow
return { status: 200, json: async () => ({}) };
}
// Pass through other requests (like /me)
return originalRequest(url, options);
};
inPtr = wasm.__wbindgen_malloc(bytes.length, 1);
console.log('✅ WASM memory allocated, pointer:', inPtr);
// Trigger the paint function
console.log('🚀 Calling mod.a.paint() to generate token...');
try {
// This handles UserID, URL, and WASM interaction internally
await mod.a.paint(paintPixels, payload.fp);
} catch (e) {
// Ignore errors caused by our fake request response
} finally {
// Restore original request method (Cleanup)
mod.a.request = originalRequest;
console.log('✅ Request hook restored');
}
// Copy data to WASM memory
const wasmBuffer = new Uint8Array(wasm.memory.buffer, inPtr, bytes.length);
wasmBuffer.set(bytes);
console.log('✅ Data copied to WASM memory');
} catch (memError) {
console.error('❌ Memory allocation error:', memError);
// Validate and return result
if (capturedToken) {
console.log('');
console.log('🎉 SUCCESS!');
console.log('🔑 Full token:');
console.log(capturedToken);
return capturedToken;
} else {
console.error('❌ Failed to capture token via hooking');
return null;
}
// Call the WASM function
console.log('🚀 Calling get_pawtected_endpoint_payload...');
let outPtr, outLen, token;
try {
const result = wasm.get_pawtected_endpoint_payload(inPtr, bytes.length);
console.log('✅ Function called, result type:', typeof result, result);
if (Array.isArray(result) && result.length === 2) {
[outPtr, outLen] = result;
console.log('✅ Got output pointer:', outPtr, 'length:', outLen);
// Decode the result
const outputBuffer = new Uint8Array(wasm.memory.buffer, outPtr, outLen);
token = dec.decode(outputBuffer);
console.log('✅ Token decoded successfully');
} else {
console.error('❌ Unexpected function result format:', result);
return null;
}
} catch (funcError) {
console.error('❌ Function call error:', funcError);
console.error('Stack trace:', funcError.stack);
return null;
}
// Cleanup memory
try {
if (wasm.__wbindgen_free && outPtr && outLen) {
wasm.__wbindgen_free(outPtr, outLen, 1);
console.log('✅ Output memory freed');
}
if (wasm.__wbindgen_free && inPtr) {
wasm.__wbindgen_free(inPtr, bytes.length, 1);
console.log('✅ Input memory freed');
}
} catch (cleanupError) {
console.log('⚠️ Cleanup warning:', cleanupError.message);
}
console.log('🎉 SUCCESS!');
console.log('🔑 Full token:', token);
return token;
} catch (error) {
console.error('❌ Failed to generate fp parameter:', error);
console.error('❌ Failed to generate token:', error);
return null;
}
}