feat: initial i18n support for cheat information in remote web panel

This commit is contained in:
YifePlayte
2026-06-15 00:21:35 +08:00
parent 8756e41fb9
commit 37ce6b3f4a
4 changed files with 67 additions and 3 deletions
@@ -412,6 +412,7 @@ function normalizeSnapshot(rawSnapshot) {
const trainerMeta = { const trainerMeta = {
session: { session: {
instanceId: safeString(rawSnapshot.instanceId, 'wand-session'), instanceId: safeString(rawSnapshot.instanceId, 'wand-session'),
accessToken: safeString(rawSnapshot.accessToken),
}, },
trainer: { trainer: {
trainerId, trainerId,
@@ -78,7 +78,20 @@ function installIpcHandlers(electron, runtime, boundRenderers, pendingCommandRes
globalThis.__wandRemoteBridgeIpcInstalled = true; globalThis.__wandRemoteBridgeIpcInstalled = true;
electron.ipcMain.handle(IPC_CHANNEL.TRAINER_SNAPSHOT, (_event, snapshot) => { electron.ipcMain.handle(IPC_CHANNEL.TRAINER_SNAPSHOT, (_event, snapshot) => {
runtime.sync(snapshot); try {
const allWindows = electron.BrowserWindow.getAllWindows();
const win = allWindows[0];
win.webContents
.executeJavaScript(
`JSON.parse(localStorage.getItem("infinity:globalStore") || "{}")?.token?.accessToken`
)
.then((accessToken) => {
snapshot.accessToken = accessToken;
runtime.sync(snapshot);
});
} catch (e) {
runtime.sync(snapshot);
}
return true; return true;
}); });
electron.ipcMain.handle(REMOTE_INSTALLED_APPS_CHANNEL, (_event, snapshot) => { electron.ipcMain.handle(REMOTE_INSTALLED_APPS_CHANNEL, (_event, snapshot) => {
@@ -4,13 +4,14 @@ import type { PanelAction } from './state';
type Dispatch = (action: PanelAction) => void; type Dispatch = (action: PanelAction) => void;
export function handleProtocolMessage(dispatch: Dispatch, message: IncomingMessage, trainerMeta: TrainerMetaPayload | null): void { export async function handleProtocolMessage(dispatch: Dispatch, message: IncomingMessage, trainerMeta: TrainerMetaPayload | null): Promise<void> {
switch (message.type) { switch (message.type) {
case 'hello_ack': case 'hello_ack':
handleHelloAck(dispatch, message.payload.accepted, message.payload.remoteUrl); handleHelloAck(dispatch, message.payload.accepted, message.payload.remoteUrl);
return; return;
case 'trainer_meta': case 'trainer_meta':
dispatch({ type: 'trainerMeta', payload: message.payload }); const payloadWithI18n = await fetchI18nForTrainerMeta(message.payload);
dispatch({ type: 'trainerMeta', payload: payloadWithI18n });
return; return;
case 'game_status': case 'game_status':
dispatch({ type: 'gameStatus', payload: message.payload }); dispatch({ type: 'gameStatus', payload: message.payload });
@@ -59,3 +60,51 @@ function handleValueChanged(dispatch: Dispatch, message: Extract<IncomingMessage
const nextValue = cheat ? normalizeIncomingValue(cheat, message.payload.value) : message.payload.value; const nextValue = cheat ? normalizeIncomingValue(cheat, message.payload.value) : message.payload.value;
dispatch({ type: 'valueChanged', target: message.payload.target, value: nextValue }); dispatch({ type: 'valueChanged', target: message.payload.target, value: nextValue });
} }
async function fetchI18nForTrainerMeta(payload: TrainerMetaPayload): Promise<TrainerMetaPayload> {
try {
const accessToken = payload?.session?.accessToken;
const gameId = payload?.trainer?.gameId;
const gameVersion = payload?.trainer?.gameVersion;
const language = payload?.trainer?.language;
const params = new URLSearchParams();
if (gameVersion) params.append('gameVersions', gameVersion);
if (language) params.append('locale', language);
const url = `https://api.wemod.com/v3/games/${gameId}/trainer?${params.toString()}`;
const response = await fetch(url, {
method: 'GET',
headers: {
Authorization: `Bearer ${accessToken}`,
},
});
const trainer = await response.json();
payload.schema.cheats.forEach((item) => {
// name
const name = item.name;
if (name) {
const i18nString = trainer?.i18n?.strings?.[name];
if (i18nString) item.name = i18nString;
}
// description
const description = item.description;
if (description) {
const i18nString = trainer?.i18n?.strings?.[description];
if (i18nString) item.description = i18nString;
}
// instructions
const instructions = item.instructions;
if (instructions) {
const i18nString = trainer?.i18n?.strings?.[instructions];
if (i18nString) item.instructions = i18nString;
}
});
return payload;
} catch (e) {
return payload;
}
}
@@ -109,6 +109,7 @@ export interface TrainerSummary {
export interface TrainerMetaPayload { export interface TrainerMetaPayload {
session: { session: {
instanceId: string; instanceId: string;
accessToken: string;
}; };
trainer: TrainerSummary; trainer: TrainerSummary;
schema: { schema: {