init commit
This commit is contained in:
commit
03d75f84dc
133
index.ts
Normal file
133
index.ts
Normal file
@ -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<object> | 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<void> => {
|
||||
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<object>;
|
||||
const localValue = staticWorldStateBackup[name] as Array<object>;
|
||||
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<void> {
|
||||
logger.info(`[${this.name}] Plugin initialized successfully!`);
|
||||
await syncWorldState();
|
||||
}
|
||||
|
||||
async cleanup(): Promise<void> {
|
||||
logger.info(`[${this.name}] Plugin cleanup completed`);
|
||||
if (syncWorldStateTimer) {
|
||||
clearTimeout(syncWorldStateTimer);
|
||||
syncWorldStateTimer = null;
|
||||
}
|
||||
}
|
||||
}
|
15
plugin.json
Normal file
15
plugin.json
Normal file
@ -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"
|
||||
]
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user