From 25099c03baf809557b0c88a507e850a7f4df178a Mon Sep 17 00:00:00 2001 From: Danielv123 Date: Sun, 13 Apr 2025 18:00:52 +0200 Subject: [PATCH] Use config instead of constants, other review commetns --- packages/controller/src/ControlConnection.ts | 11 ++---- packages/controller/src/Controller.ts | 4 -- packages/lib/src/ModStore.ts | 41 ++++++++------------ packages/lib/src/config/definitions.ts | 14 +++++++ 4 files changed, 35 insertions(+), 35 deletions(-) diff --git a/packages/controller/src/ControlConnection.ts b/packages/controller/src/ControlConnection.ts index 86653a76..a921e3af 100644 --- a/packages/controller/src/ControlConnection.ts +++ b/packages/controller/src/ControlConnection.ts @@ -524,7 +524,8 @@ export default class ControlConnection extends BaseConnection { const cacheKey = `${request.factorioVersion}-${request.hide_deprecated}`; const cachedData = this._controller.modPortalCache.get(cacheKey); - if (cachedData && Date.now() - cachedData.timestamp < Controller.MOD_PORTAL_CACHE_DURATION) { + const cacheDuration = this._controller.config.get("controller.mod_portal_cache_duration_minutes") * 60 * 1000; + if (cachedData && Date.now() - cachedData.timestamp < cacheDuration) { return new lib.ModPortalGetAllRequest.Response(cachedData.data); } @@ -532,6 +533,7 @@ export default class ControlConnection extends BaseConnection { logger.info(`Fetching mod portal data for ${cacheKey}`); const mods = await lib.ModStore.fetchAllModsFromPortal( request.factorioVersion, + this._controller.config.get("controller.mod_portal_page_size"), request.hide_deprecated ); this._controller.modPortalCache.set(cacheKey, { timestamp: Date.now(), data: mods }); @@ -555,7 +557,6 @@ export default class ControlConnection extends BaseConnection { // Check if mod already exists if (this._controller.modStore.files.has(filename)) { logger.verbose(`Mod ${filename} already exists, skipping download.`); - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion return this._controller.modStore.files.get(filename)!; } @@ -564,11 +565,7 @@ export default class ControlConnection extends BaseConnection { const token = this._controller.config.get("controller.factorio_token"); if (!username || !token) { - // Attempt download without credentials - might fail for some mods - logger.warn(`Factorio username or token not configured. Attempting anonymous download for ${filename}.`); - // Note: The Factorio Mod Portal API might reject downloads without credentials. - // Consider throwing an error here if credentials are required by your setup. - // throw new lib.RequestError("Factorio credentials (username, token) not configured on the controller."); + throw new lib.RequestError("Factorio credentials (username, token) not configured on the controller."); } try { diff --git a/packages/controller/src/Controller.ts b/packages/controller/src/Controller.ts index 08d2e6d8..18a38751 100644 --- a/packages/controller/src/Controller.ts +++ b/packages/controller/src/Controller.ts @@ -97,12 +97,8 @@ export default class Controller { clusterLogBuildInterval: ReturnType | null = null; // Cache for mod portal requests - static MOD_PORTAL_CACHE_DURATION = 30 * 60 * 1000; // 30 minutes modPortalCache = new Map(); - /** @type {?module:lib.ProcessConnector} */ - process = null; - static async bootstrap(config: lib.ControllerConfig) { let databaseDirectory = config.get("controller.database_directory"); await fs.ensureDir(databaseDirectory); diff --git a/packages/lib/src/ModStore.ts b/packages/lib/src/ModStore.ts index ddf6a0a2..7b97e609 100644 --- a/packages/lib/src/ModStore.ts +++ b/packages/lib/src/ModStore.ts @@ -64,9 +64,6 @@ interface ModPortalResponse { results: ModDetails[]; } -const MOD_PORTAL_API_URL = "https://mods.factorio.com/api/mods"; -const MOD_PORTAL_MAX_PAGE_SIZE = 1000; // Or largest allowed by API - export default class ModStore extends TypedEventEmitter { constructor( public modsDirectory: string, @@ -188,35 +185,33 @@ export default class ModStore extends TypedEventEmitter, version: string, username: string, token: string ) { - if (releases.length === 0) { return; } + const selectedRelease = releases.find(release => release.version === version); - const latestRelease = releases.find(release => release.version === version); - - if (latestRelease === undefined) { + if (selectedRelease === undefined) { logger.warn(`Mod release matching version ${version} not found.`); return; } try { - const url = new URL(`https://mods.factorio.com/${latestRelease.download_url}`); + const url = new URL(`https://mods.factorio.com/${selectedRelease.download_url}`); url.searchParams.set("username", username); url.searchParams.set("token", token); - const tempFileName = `${this.modsDirectory}/${latestRelease.file_name}.tmp`; - const finalFileName = `${this.modsDirectory}/${latestRelease.file_name}`; + const tempFileName = `${this.modsDirectory}/${selectedRelease.file_name}.tmp`; + const finalFileName = `${this.modsDirectory}/${selectedRelease.file_name}`; await ModStore.downloadFile(url, tempFileName); await fs.rename(tempFileName, finalFileName); - await this.loadFile(latestRelease.file_name); + await this.loadFile(selectedRelease.file_name); } catch (err: any) { - logger.error(`Failed to download or load mod ${latestRelease.file_name} (${version}): ${err.message}`); + logger.error(`Failed to download or load mod ${selectedRelease.file_name} (${version}): ${err.message}`); // Attempt to clean up temp file if it exists try { - const tempFileName = `${this.modsDirectory}/${latestRelease.file_name}.tmp`; + const tempFileName = `${this.modsDirectory}/${selectedRelease.file_name}.tmp`; await fs.unlink(tempFileName); } catch (unlinkErr: any) { if (unlinkErr.code !== "ENOENT") { // Ignore if file doesn't exist - logger.warn(`Failed to clean up temp file ${latestRelease.file_name}.tmp: ${unlinkErr.message}`); + logger.warn(`Failed to clean up temp file ${selectedRelease.file_name}.tmp: ${unlinkErr.message}`); } } } @@ -322,11 +317,13 @@ export default class ModStore extends TypedEventEmitter { logger.info(`Fetching all mods for Factorio version ${factorioVersion}...`); @@ -335,8 +332,8 @@ export default class ModStore extends TypedEventEmitter { optional: true, initialValue: 1, }, + "controller.mod_portal_cache_duration_minutes": { + title: "Mod Portal Cache Duration", + description: "Duration in minutes to cache mod portal API responses.", + type: "number", + initialValue: 30, + }, + "controller.mod_portal_page_size": { + title: "Mod Portal Page Size", + description: "Maximum number of results per page when querying the Factorio mod portal API.", + type: "number", + initialValue: 1000, + }, }; }