Skip to content

Commit

Permalink
Implement initial code for configuration file hot-reloading
Browse files Browse the repository at this point in the history
  • Loading branch information
ArchangelWTF committed Feb 18, 2025
1 parent 0a60b92 commit d77027a
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 0 deletions.
50 changes: 50 additions & 0 deletions src/Fika.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@ import { ImageRouter } from "@spt/routers/ImageRouter";
import { DatabaseServer } from "@spt/servers/DatabaseServer";
import { ImporterUtil } from "@spt/utils/ImporterUtil";

import { watch } from "node:fs";
import { ConfigTypes } from "@spt/models/enums/ConfigTypes";
import { ICoreConfig } from "@spt/models/spt/config/ICoreConfig";
import type { ILogger } from "@spt/models/spt/utils/ILogger";
import { ConfigServer } from "@spt/servers/ConfigServer";
import { FileSystem } from "@spt/utils/FileSystem";
import { JsonUtil } from "@spt/utils/JsonUtil";
import { IFikaConfig } from "./models/fika/config/IFikaConfig";
import { IFikaConfigBackground } from "./models/fika/config/IFikaConfigBackground";
import { IFikaConfigHeadless } from "./models/fika/config/IFikaConfigHeadless";
import { IFikaConfigNatPunchServer } from "./models/fika/config/IFikaConfigNatPunchServer";
Expand All @@ -27,6 +32,7 @@ export class Fika {
protected backgroundConfig: IFikaConfigBackground;

constructor(
@inject("WinstonLogger") protected logger: ILogger,
@inject("DatabaseServer") protected databaseServer: DatabaseServer,
@inject("ConfigServer") protected configServer: ConfigServer,
@inject("Overrider") protected overrider: Overrider,
Expand All @@ -36,6 +42,8 @@ export class Fika {
@inject("FikaHeadlessProfileService") protected fikaHeadlessProfileService: FikaHeadlessProfileService,
@inject("ImageRouter") protected imageRouter: ImageRouter,
@inject("ImporterUtil") protected importerUtil: ImporterUtil,
@inject("JsonUtil") protected jsonUtil: JsonUtil,
@inject("FileSystem") protected fileSystem: FileSystem,
@inject("FikaPlayerRelationsCacheService") protected fikaPlayerRelationCacheServce: FikaPlayerRelationsCacheService,
) {
this.modPath = fikaConfig.getModPath();
Expand Down Expand Up @@ -69,6 +77,8 @@ export class Fika {
const image = this.backgroundConfig.easteregg ? "assets/images/launcher/bg-senko.png" : "assets/images/launcher/bg.png";
this.imageRouter.addRoute("/files/launcher/bg", path.join(this.modPath, image));
}

this.watchFikaConfig();
}

private async addFikaClientLocales() {
Expand Down Expand Up @@ -101,4 +111,44 @@ export class Fika {
}
}
}

private watchFikaConfig(): void {
const configPath = path.join(this.modPath, "assets/configs/fika.jsonc");
let fileChangeTimeout = null;

// At the moment this doesn't reload:
// Nat punch server (Requires additional setup)
// SPT Http configuration (Can't be changed once initialized)
// Any client options if a client is already in-game, client will have to restart his game.
watch(configPath, async (eventType, _filename) => {
if (eventType === "change") {
if (fileChangeTimeout) {
clearTimeout(fileChangeTimeout);
}

fileChangeTimeout = setTimeout(async () => {
let config = this.jsonUtil.deserializeJsonC<IFikaConfig>(await this.fileSystem.read(configPath));

if (!config) {
this.logger.warning("[Fika Server] could not hot-reload config, is the syntax correct?");
return;
}

const oldHeadlessAmount = this.fikaConfig.getConfig().headless.profiles.amount;

if (this.fikaConfig.updateFikaConfig(config)) {
// Re-initialize new headless profiles if the number changed.
if (this.fikaConfig.getConfig().headless.profiles.amount > oldHeadlessAmount) {
await this.fikaHeadlessProfileService.init();
}

// Re-initialize required & optional mods
await this.fikaClientService.preInit();

this.logger.info("[Fika Server] Config hot-reloaded successfully");
}
}, 500);
}
});
}
}
23 changes: 23 additions & 0 deletions src/utils/FikaConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,29 @@ export class FikaConfig {
httpConfig.backendPort = config.http.backendPort;
}

public updateFikaConfig(config: IFikaConfig): boolean {
if (config != this.fikaConfig) {
this.fikaConfig = config;

const coreConfig = this.configServer.getConfig(ConfigTypes.CORE) as ICoreConfig;
const commando = coreConfig.features.chatbotFeatures.ids.commando;
const sptFriend = coreConfig.features.chatbotFeatures.ids.spt;

// Re-handle chatbot settings
if (config.server.SPT.disableSPTChatBots) {
coreConfig.features.chatbotFeatures.enabledBots[commando] = false;
coreConfig.features.chatbotFeatures.enabledBots[sptFriend] = false;
} else {
coreConfig.features.chatbotFeatures.enabledBots[commando] = true;
coreConfig.features.chatbotFeatures.enabledBots[sptFriend] = true;
}

return true;
}

return false;
}

public getConfig(): IFikaConfig {
return this.fikaConfig;
}
Expand Down

0 comments on commit d77027a

Please sign in to comment.