commit 03d75f84dc4daf895e68b47d8b04acdd675be8e6 Author: ny <64143453+nyaoouo@users.noreply.github.com> Date: Tue Jul 1 00:32:48 2025 +0800 init commit diff --git a/index.ts b/index.ts new file mode 100644 index 0000000..7c7d672 --- /dev/null +++ b/index.ts @@ -0,0 +1,133 @@ +import { IPlugin } from "@/src/types/pluginTypes"; +import { logger } from "@/src/utils/logger"; + +import staticWorldState from "@/static/fixed_responses/worldState/worldState.json"; +import { config } from "@/src/services/configService"; + +/* Add this to your config.json worldState section to enable world state sync: +"sync":{ + "enabled": true, + "url": "https://content.warframe.com/dynamic/worldState.php", + "fields": { // adjust these fields to your needs + "Events": "merge", + "InGameMarket": "replace", + "SyndicateMissions": "replace", + "ActiveMissions": "replace", + "VoidTraders": "replace", + "PrimeVaultTraders": "replace", + "DailyDeals": "replace", + "Goals": "replace" + }, + "interval": 3000 +} +*/ + +type AnyObj = { [key: string]: object | Array | string | number | boolean }; +const staticWorldStateBackup: AnyObj = structuredClone(staticWorldState); +let syncWorldStateTimer: NodeJS.Timeout | null = null; + +interface myConfig { + worldState?: { + sync?: { + enabled: boolean; + url: string; + fields: { [key: string]: string }; + interval?: number; + }; + }; +} + +export const syncWorldState = async (): Promise => { + if (syncWorldStateTimer) { + clearTimeout(syncWorldStateTimer); + syncWorldStateTimer = null; + } + const config_ = config as myConfig; + if (!config_.worldState?.sync) { + logger.info("World state sync is disabled, skipping"); + return; + } + const { enabled, url, fields, interval } = config_.worldState.sync; + if (!enabled || !url || !fields) { + logger.info("World state sync is not enabled or misconfigured, skipping"); + return; + } + const res = await fetch(url, { method: "GET" }); + if (!res.ok) { + logger.error("Failed to fetch remote world state, will retry in 5 min", { + status: res.status, + statusText: res.statusText + }); + syncWorldStateTimer = setTimeout( + () => { + void syncWorldState(); + }, + 5 * 60 * 1000 + ); + return; + } + const data = await res.json(); + if (!data || typeof data !== "object") { + logger.error("Invalid world state sync response", { data }); + return; + } + const staticWorldState_ = staticWorldState as AnyObj; + const data_ = data as AnyObj; + + for (const [name, action_] of Object.entries(fields)) { + if (!(name in data)) { + logger.warn(`Field ${name} not found in world state sync response`, { data }); + continue; + } + const action = action_ as string; + if (action === "replace") { + staticWorldState_[name] = data_[name]; + continue; + } + if (action === "merge") { + switch (name) { + case "Events": + { + const remoteValue = data_[name] as Array; + const localValue = staticWorldStateBackup[name] as Array; + if (Array.isArray(remoteValue) && Array.isArray(localValue)) { + staticWorldState_[name] = localValue.concat(remoteValue); + } + } + break; + default: + logger.warn(`Not supported merge action for field ${name} in world state sync`); + } + continue; + } + logger.warn(`Unknown action ${action} for field ${name} in world state sync`); + continue; + } + if (interval && interval > 0) { + logger.info(`Next world state sync in ${interval} seconds`); + syncWorldStateTimer = setTimeout(() => { + void syncWorldState(); + }, interval * 1000); + } else { + logger.info("No next world state sync scheduled"); + } +}; + +export default class WorldStateSync implements IPlugin { + public name = "WorldStateSync"; + public version = "1.0.0"; + public description = "WorldStateSync plugin for Warframe Emulator"; + + async initialize(): Promise { + logger.info(`[${this.name}] Plugin initialized successfully!`); + await syncWorldState(); + } + + async cleanup(): Promise { + logger.info(`[${this.name}] Plugin cleanup completed`); + if (syncWorldStateTimer) { + clearTimeout(syncWorldStateTimer); + syncWorldStateTimer = null; + } + } +} diff --git a/plugin.json b/plugin.json new file mode 100644 index 0000000..df4c3d7 --- /dev/null +++ b/plugin.json @@ -0,0 +1,15 @@ +{ + "name": "WorldStateSync", + "version": "1.0.0", + "description": "WorldStateSync plugin for Warframe Emulator", + "main": "index.js", + "author": "Your Name", + "license": "GNU", + "config": { + "enabled": true + }, + "dependencies": {}, + "tags": [ + "custom" + ] +} \ No newline at end of file