style: run format:apply
This commit is contained in:
+102
-40
@@ -1,56 +1,118 @@
|
||||
import { create } from 'zustand';
|
||||
import { useInventoryStore } from './useInventoryStore';
|
||||
import { mapStoreToSpooferConfig, mapSpooferConfigToStore } from './wsProtocol';
|
||||
|
||||
interface WebsocketState {
|
||||
socket: WebSocket | null;
|
||||
isConnected: boolean;
|
||||
connect: () => void;
|
||||
socket: WebSocket | null;
|
||||
isConnected: boolean;
|
||||
connect: () => void;
|
||||
}
|
||||
|
||||
let lastTogglesJson = '';
|
||||
let lastInventoryJson = '';
|
||||
|
||||
export const useWebsocketStore = create<WebsocketState>((set, get) => ({
|
||||
socket: null,
|
||||
isConnected: false,
|
||||
socket: null,
|
||||
isConnected: false,
|
||||
|
||||
connect: () => {
|
||||
if (get().socket) return;
|
||||
connect: () => {
|
||||
if (get().socket) return;
|
||||
|
||||
const ws = new WebSocket('ws://localhost:4444');
|
||||
const ws = new WebSocket('ws://localhost:4444');
|
||||
|
||||
ws.onopen = () => {
|
||||
console.log('Connected to Spoofer Engine');
|
||||
set({ socket: ws, isConnected: true });
|
||||
};
|
||||
ws.onopen = () => {
|
||||
console.log('Connected to Spoofer Engine');
|
||||
set({ socket: ws, isConnected: true });
|
||||
};
|
||||
|
||||
ws.onclose = () => {
|
||||
console.log('Disconnected. Retrying in 2s...');
|
||||
set({ socket: null, isConnected: false });
|
||||
setTimeout(() => get().connect(), 2000);
|
||||
};
|
||||
ws.onclose = () => {
|
||||
console.log('Disconnected. Retrying in 2s...');
|
||||
set({ socket: null, isConnected: false });
|
||||
setTimeout(() => get().connect(), 2000);
|
||||
};
|
||||
|
||||
ws.onerror = (err) => {
|
||||
console.error('WS Error:', err);
|
||||
ws.close();
|
||||
};
|
||||
ws.onerror = (err) => {
|
||||
console.error('WS Error:', err);
|
||||
ws.close();
|
||||
};
|
||||
|
||||
ws.onmessage = (msg) => {
|
||||
try {
|
||||
const payload = JSON.parse(msg.data);
|
||||
if (payload.action === 'init_config')
|
||||
useInventoryStore.getState().importProfile(payload.data);
|
||||
} catch (e) {
|
||||
console.error("Failed to parse WS message", e);
|
||||
}
|
||||
};
|
||||
}
|
||||
ws.onmessage = async (msg) => {
|
||||
try {
|
||||
const payload = JSON.parse(msg.data);
|
||||
|
||||
// C++ sends action=0 (INIT_CONFIG) on WebSocket open
|
||||
if (payload.action === 0) {
|
||||
const mapped = await mapSpooferConfigToStore(payload.profile);
|
||||
|
||||
// Snapshot current state strings to prevent echo
|
||||
lastInventoryJson = JSON.stringify({
|
||||
unlockedCharacters: mapped.unlockedCharacters,
|
||||
unlockedCustomizations: mapped.unlockedCustomizations,
|
||||
unlockedDLCs: mapped.unlockedDLCs,
|
||||
unlockedPerks: mapped.unlockedPerks,
|
||||
items: mapped.items,
|
||||
offerings: mapped.offerings,
|
||||
addons: mapped.addons
|
||||
});
|
||||
lastTogglesJson = JSON.stringify({
|
||||
spoofItems: payload.toggles?.spoofItems ?? false,
|
||||
spoofPerks: payload.toggles?.spoofPerks ?? false,
|
||||
spoofCatalog: payload.toggles?.spoofCatalog ?? false,
|
||||
spoofDLCs: payload.toggles?.spoofDLCs ?? false
|
||||
});
|
||||
|
||||
useInventoryStore.getState().importProfile(mapped);
|
||||
useInventoryStore.getState().importToggles(payload.toggles);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Failed to parse WS message', e);
|
||||
}
|
||||
};
|
||||
}
|
||||
}));
|
||||
|
||||
useInventoryStore.subscribe((newState) => {
|
||||
const { socket, isConnected } = useWebsocketStore.getState();
|
||||
// Subscribe to store changes and sync to C++ client
|
||||
useInventoryStore.subscribe((state) => {
|
||||
const { socket, isConnected } = useWebsocketStore.getState();
|
||||
if (!isConnected || !socket || socket.readyState !== WebSocket.OPEN) return;
|
||||
|
||||
if (isConnected && socket) {
|
||||
socket.send(JSON.stringify({
|
||||
action: "sync_inventory",
|
||||
data: newState
|
||||
}));
|
||||
}
|
||||
});
|
||||
// --- Check toggles ---
|
||||
const toggles = {
|
||||
spoofItems: state.spoofItems,
|
||||
spoofPerks: state.spoofPerks,
|
||||
spoofCatalog: state.spoofCatalog,
|
||||
spoofDLCs: state.spoofDLCs
|
||||
};
|
||||
const togglesJson = JSON.stringify(toggles);
|
||||
if (togglesJson !== lastTogglesJson) {
|
||||
lastTogglesJson = togglesJson;
|
||||
socket.send(JSON.stringify({ action: 2, toggles }));
|
||||
}
|
||||
|
||||
// --- Check inventory ---
|
||||
const inventory = {
|
||||
unlockedCharacters: state.unlockedCharacters,
|
||||
unlockedCustomizations: state.unlockedCustomizations,
|
||||
unlockedDLCs: state.unlockedDLCs,
|
||||
unlockedPerks: state.unlockedPerks,
|
||||
items: state.items,
|
||||
offerings: state.offerings,
|
||||
addons: state.addons
|
||||
};
|
||||
const inventoryJson = JSON.stringify(inventory);
|
||||
if (inventoryJson !== lastInventoryJson) {
|
||||
lastInventoryJson = inventoryJson;
|
||||
|
||||
mapStoreToSpooferConfig(state).then((profile) => {
|
||||
// Re-check connection in case it dropped during async mapping
|
||||
const ws = useWebsocketStore.getState();
|
||||
if (
|
||||
ws.isConnected &&
|
||||
ws.socket &&
|
||||
ws.socket.readyState === WebSocket.OPEN
|
||||
) {
|
||||
ws.socket.send(JSON.stringify({ action: 1, profile }));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user