From 3f2d36a2fc11ac38c76a208559f17b0656b28110 Mon Sep 17 00:00:00 2001 From: Refringe Date: Mon, 13 Nov 2023 11:10:44 -0500 Subject: [PATCH] Formatting for loader classes. --- project/src/loaders/BundleLoader.ts | 18 +-- project/src/loaders/ModLoadOrder.ts | 15 ++- project/src/loaders/ModTypeCheck.ts | 16 ++- project/src/loaders/PostAkiModLoader.ts | 21 ++-- project/src/loaders/PostDBModLoader.ts | 28 +++-- project/src/loaders/PreAkiModLoader.ts | 139 ++++++++++++++++-------- 6 files changed, 153 insertions(+), 84 deletions(-) diff --git a/project/src/loaders/BundleLoader.ts b/project/src/loaders/BundleLoader.ts index b14e5b9b..b2e40f6f 100644 --- a/project/src/loaders/BundleLoader.ts +++ b/project/src/loaders/BundleLoader.ts @@ -1,4 +1,3 @@ - import { inject, injectable } from "tsyringe"; import { HttpServerHelper } from "@spt-aki/helpers/HttpServerHelper"; @@ -31,9 +30,9 @@ export class BundleLoader constructor( @inject("HttpServerHelper") protected httpServerHelper: HttpServerHelper, @inject("VFS") protected vfs: VFS, - @inject("JsonUtil") protected jsonUtil: JsonUtil + @inject("JsonUtil") protected jsonUtil: JsonUtil, ) - { } + {} /** * Handle singleplayer/bundles @@ -65,7 +64,8 @@ export class BundleLoader public addBundles(modpath: string): void { - const manifest = this.jsonUtil.deserialize(this.vfs.readFile(`${modpath}bundles.json`)).manifest; + const manifest = + this.jsonUtil.deserialize(this.vfs.readFile(`${modpath}bundles.json`)).manifest; for (const bundle of manifest) { @@ -75,7 +75,7 @@ export class BundleLoader } } - public addBundle(key: string, b: BundleInfo): void + public addBundle(key: string, b: BundleInfo): void { this.bundles[key] = b; } @@ -83,11 +83,11 @@ export class BundleLoader export interface BundleManifest { - manifest: Array + manifest: Array; } export interface BundleManifestEntry { - key: string - path: string -} \ No newline at end of file + key: string; + path: string; +} diff --git a/project/src/loaders/ModLoadOrder.ts b/project/src/loaders/ModLoadOrder.ts index 469c0454..c874ac01 100644 --- a/project/src/loaders/ModLoadOrder.ts +++ b/project/src/loaders/ModLoadOrder.ts @@ -13,9 +13,9 @@ export class ModLoadOrder constructor( @inject("WinstonLogger") protected logger: ILogger, - @inject("LocalisationService") protected localisationService: LocalisationService + @inject("LocalisationService") protected localisationService: LocalisationService, ) - { } + {} public setModList(mods: Record): void { @@ -25,8 +25,8 @@ export class ModLoadOrder const visited = new Set(); - //invert loadBefore into loadAfter on specified mods - for (const [ modName, modConfig ] of this.modsAvailable) + // invert loadBefore into loadAfter on specified mods + for (const [modName, modConfig] of this.modsAvailable) { if ((modConfig.loadBefore ?? []).length > 0) { @@ -143,7 +143,12 @@ export class ModLoadOrder { if (this.modsAvailable.get(modAfter)?.loadAfter?.includes(mod)) { - throw new Error(this.localisationService.getText("modloader-load_order_conflict", {modOneName: mod, modTwoName: modAfter})); + throw new Error( + this.localisationService.getText("modloader-load_order_conflict", { + modOneName: mod, + modTwoName: modAfter, + }), + ); } dependencies.add(modAfter); diff --git a/project/src/loaders/ModTypeCheck.ts b/project/src/loaders/ModTypeCheck.ts index 2edc06de..12f302b5 100644 --- a/project/src/loaders/ModTypeCheck.ts +++ b/project/src/loaders/ModTypeCheck.ts @@ -10,7 +10,6 @@ import { IPreAkiLoadModAsync } from "@spt-aki/models/external/IPreAkiLoadModAsyn @injectable() export class ModTypeCheck { - /** * Use defined safe guard to check if the mod is a IPreAkiLoadMod * @returns boolean @@ -19,7 +18,7 @@ export class ModTypeCheck { return mod?.preAkiLoad; } - + /** * Use defined safe guard to check if the mod is a IPostAkiLoadMod * @returns boolean @@ -28,7 +27,7 @@ export class ModTypeCheck { return mod?.postAkiLoad; } - + /** * Use defined safe guard to check if the mod is a IPostDBLoadMod * @returns boolean @@ -46,7 +45,7 @@ export class ModTypeCheck { return mod?.preAkiLoadAsync; } - + /** * Use defined safe guard to check if the mod is a IPostAkiLoadModAsync * @returns boolean @@ -55,7 +54,7 @@ export class ModTypeCheck { return mod?.postAkiLoadAsync; } - + /** * Use defined safe guard to check if the mod is a IPostDBLoadModAsync * @returns boolean @@ -71,12 +70,11 @@ export class ModTypeCheck */ public isPostV3Compatible(mod: any): boolean { - return this.isPreAkiLoad(mod) || - this.isPostAkiLoad(mod) || + return this.isPreAkiLoad(mod) || + this.isPostAkiLoad(mod) || this.isPostDBAkiLoad(mod) || this.isPreAkiLoadAsync(mod) || this.isPostAkiLoadAsync(mod) || this.isPostDBAkiLoadAsync(mod); - } -} \ No newline at end of file +} diff --git a/project/src/loaders/PostAkiModLoader.ts b/project/src/loaders/PostAkiModLoader.ts index deb30055..a04b4c2c 100644 --- a/project/src/loaders/PostAkiModLoader.ts +++ b/project/src/loaders/PostAkiModLoader.ts @@ -19,9 +19,9 @@ export class PostAkiModLoader implements IModLoader @inject("VFS") protected vfs: VFS, @inject("PreAkiModLoader") protected preAkiModLoader: PreAkiModLoader, @inject("LocalisationService") protected localisationService: LocalisationService, - @inject("ModTypeCheck") protected modTypeCheck: ModTypeCheck + @inject("ModTypeCheck") protected modTypeCheck: ModTypeCheck, ) - { } + {} public getModPath(mod: string): string { @@ -43,20 +43,27 @@ export class PostAkiModLoader implements IModLoader for (const modName of mods) { // // import class - const filepath = `${this.preAkiModLoader.getModPath(modName)}${this.preAkiModLoader.getImportedModDetails()[modName].main}`; + const filepath = `${this.preAkiModLoader.getModPath(modName)}${ + this.preAkiModLoader.getImportedModDetails()[modName].main + }`; const modpath = `${process.cwd()}/${filepath}`; // eslint-disable-next-line @typescript-eslint/no-var-requires const mod = require(modpath); if (this.modTypeCheck.isPostAkiLoadAsync(mod.mod)) { - try + try { await (mod.mod as IPostAkiLoadModAsync).postAkiLoadAsync(container); } - catch (err) + catch (err) { - this.logger.error(this.localisationService.getText("modloader-async_mod_error", `${err?.message ?? ""}\n${err.stack ?? ""}`)); + this.logger.error( + this.localisationService.getText( + "modloader-async_mod_error", + `${err?.message ?? ""}\n${err.stack ?? ""}`, + ), + ); } } @@ -80,4 +87,4 @@ export class PostAkiModLoader implements IModLoader } } } -} \ No newline at end of file +} diff --git a/project/src/loaders/PostDBModLoader.ts b/project/src/loaders/PostDBModLoader.ts index 8b324792..86e80e0c 100644 --- a/project/src/loaders/PostDBModLoader.ts +++ b/project/src/loaders/PostDBModLoader.ts @@ -15,10 +15,10 @@ export class PostDBModLoader implements OnLoad @inject("WinstonLogger") protected logger: ILogger, @inject("PreAkiModLoader") protected preAkiModLoader: PreAkiModLoader, @inject("LocalisationService") protected localisationService: LocalisationService, - @inject("ModTypeCheck") protected modTypeCheck: ModTypeCheck + @inject("ModTypeCheck") protected modTypeCheck: ModTypeCheck, ) - { } - + {} + public async onLoad(): Promise { if (globalThis.G_MODS_ENABLED) @@ -26,13 +26,12 @@ export class PostDBModLoader implements OnLoad await this.executeMods(this.preAkiModLoader.getContainer()); } } - + public getRoute(): string { return "aki-mods"; } - public getModPath(mod: string): string { return this.preAkiModLoader.getModPath(mod); @@ -43,21 +42,28 @@ export class PostDBModLoader implements OnLoad const mods = this.preAkiModLoader.sortModsLoadOrder(); for (const modName of mods) { - // // import class - const filepath = `${this.preAkiModLoader.getModPath(modName)}${this.preAkiModLoader.getImportedModDetails()[modName].main}`; + // import class + const filepath = `${this.preAkiModLoader.getModPath(modName)}${ + this.preAkiModLoader.getImportedModDetails()[modName].main + }`; const modpath = `${process.cwd()}/${filepath}`; // eslint-disable-next-line @typescript-eslint/no-var-requires const mod = require(modpath); if (this.modTypeCheck.isPostDBAkiLoadAsync(mod.mod)) { - try + try { await (mod.mod as IPostDBLoadModAsync).postDBLoadAsync(container); } - catch (err) + catch (err) { - this.logger.error(this.localisationService.getText("modloader-async_mod_error", `${err?.message ?? ""}\n${err.stack ?? ""}`)); + this.logger.error( + this.localisationService.getText( + "modloader-async_mod_error", + `${err?.message ?? ""}\n${err.stack ?? ""}`, + ), + ); } } @@ -67,4 +73,4 @@ export class PostDBModLoader implements OnLoad } } } -} \ No newline at end of file +} diff --git a/project/src/loaders/PreAkiModLoader.ts b/project/src/loaders/PreAkiModLoader.ts index 630305c4..3568eb83 100644 --- a/project/src/loaders/PreAkiModLoader.ts +++ b/project/src/loaders/PreAkiModLoader.ts @@ -43,7 +43,7 @@ export class PreAkiModLoader implements IModLoader @inject("LocalisationService") protected localisationService: LocalisationService, @inject("ConfigServer") protected configServer: ConfigServer, @inject("ModLoadOrder") protected modLoadOrder: ModLoadOrder, - @inject("ModTypeCheck") protected modTypeCheck: ModTypeCheck + @inject("ModTypeCheck") protected modTypeCheck: ModTypeCheck, ) { this.akiConfig = this.configServer.getConfig(ConfigTypes.CORE); @@ -96,10 +96,10 @@ export class PreAkiModLoader implements IModLoader for (const modName in modsGroupedByName) { const modDatas = modsGroupedByName[modName]; - const modVersions = modDatas.map(x => x.version); + const modVersions = modDatas.map((x) => x.version); const highestVersion = semver.maxSatisfying(modVersions, "*"); - const chosenVersion = modDatas.find(x => x.name === modName && x.version === highestVersion); + const chosenVersion = modDatas.find((x) => x.name === modName && x.version === highestVersion); if (!chosenVersion) { continue; @@ -130,28 +130,28 @@ export class PreAkiModLoader implements IModLoader * array of mod folder names */ const mods: string[] = this.vfs.getDirs(this.basepath); - + this.logger.info(this.localisationService.getText("modloader-loading_mods", mods.length)); // Mod order - if (!this.vfs.exists(this.modOrderPath)) + if (!this.vfs.exists(this.modOrderPath)) { this.logger.info(this.localisationService.getText("modloader-mod_order_missing")); // Write file with empty order array to disk this.vfs.writeFile(this.modOrderPath, this.jsonUtil.serializeAdvanced({order: []}, null, 4)); } - else + else { - const modOrder = this.vfs.readFile(this.modOrderPath, { encoding: "utf8" }); - try + const modOrder = this.vfs.readFile(this.modOrderPath, {encoding: "utf8"}); + try { for (const [index, mod] of (this.jsonUtil.deserialize(modOrder).order as string[]).entries()) { this.order[mod] = index; } } - catch (error) + catch (error) { this.logger.error(this.localisationService.getText("modloader-mod_order_error")); } @@ -175,7 +175,10 @@ export class PreAkiModLoader implements IModLoader } // if the mod has library dependencies check if these dependencies are bundled in the server, if not install them - if (modToValidate.dependencies && Object.keys(modToValidate.dependencies).length > 0 && !this.vfs.exists(`${this.basepath}${modFolderName}/node_modules`)) + if ( + modToValidate.dependencies && Object.keys(modToValidate.dependencies).length > 0 && + !this.vfs.exists(`${this.basepath}${modFolderName}/node_modules`) + ) { this.autoInstallDependencies(`${this.basepath}${modFolderName}`, modToValidate); } @@ -222,7 +225,7 @@ export class PreAkiModLoader implements IModLoader if (this.shouldSkipMod(pkg)) { - this.logger.warning(this.localisationService.getText("modloader-skipped_mod", { mod: mod })); + this.logger.warning(this.localisationService.getText("modloader-skipped_mod", {mod: mod})); continue; } @@ -236,15 +239,15 @@ export class PreAkiModLoader implements IModLoader { const previndex = this.order[prev]; const nextindex = this.order[next]; - + // mod is not on the list, move the mod to last - if (previndex === undefined) + if (previndex === undefined) { missingFromOrderJSON[prev] = true; return 1; } - else if (nextindex === undefined) + else if (nextindex === undefined) { missingFromOrderJSON[next] = true; @@ -283,7 +286,7 @@ export class PreAkiModLoader implements IModLoader /** * Returns an array of valid mods. - * + * * @param mods mods to validate * @returns array of mod folder names */ @@ -391,14 +394,19 @@ export class PreAkiModLoader implements IModLoader // Perform async load of mod if (this.modTypeCheck.isPreAkiLoadAsync(requiredMod.mod)) { - try + try { await (requiredMod.mod as IPreAkiLoadModAsync).preAkiLoadAsync(container); globalThis[mod] = requiredMod; } - catch (err) + catch (err) { - this.logger.error(this.localisationService.getText("modloader-async_mod_error", `${err?.message ?? ""}\n${err.stack ?? ""}`)); + this.logger.error( + this.localisationService.getText( + "modloader-async_mod_error", + `${err?.message ?? ""}\n${err.stack ?? ""}`, + ), + ); } continue; @@ -457,7 +465,7 @@ export class PreAkiModLoader implements IModLoader else { // rename the mod entry point to .ts if it's set to .js because G_MODS_TRANSPILE_TS is set to false - pkg.main = (pkg.main).replace(".js", ".ts"); + pkg.main = pkg.main.replace(".js", ".ts"); } } @@ -466,14 +474,20 @@ export class PreAkiModLoader implements IModLoader // Add mod to imported list this.imported[mod] = {...pkg, dependencies: pkg.modDependencies}; - this.logger.info(this.localisationService.getText("modloader-loaded_mod", {name: pkg.name, version: pkg.version, author: pkg.author})); + this.logger.info( + this.localisationService.getText("modloader-loaded_mod", { + name: pkg.name, + version: pkg.version, + author: pkg.author, + }), + ); } /** * Checks if a given mod should be loaded or skipped. - * + * * @param pkg mod package.json data - * @returns + * @returns */ protected shouldSkipMod(pkg: IPackageJsonData): boolean { @@ -509,12 +523,17 @@ export class PreAkiModLoader implements IModLoader // If this feature flag is set to false, we warn the user he has a mod that requires extra dependencies and might not work, point them in the right direction on how to enable this feature. if (!this.akiConfig.features.autoInstallModDependencies) { - this.logger.warning(this.localisationService.getText("modloader-installing_external_dependencies_disabled", { - name: pkg.name, - author: pkg.author, - configPath: path.join(globalThis.G_RELEASE_CONFIGURATION ? "Aki_Data/Server/configs" : "assets/configs", "core.json"), - configOption: "autoInstallModDependencies" - })); + this.logger.warning( + this.localisationService.getText("modloader-installing_external_dependencies_disabled", { + name: pkg.name, + author: pkg.author, + configPath: path.join( + globalThis.G_RELEASE_CONFIGURATION ? "Aki_Data/Server/configs" : "assets/configs", + "core.json", + ), + configOption: "autoInstallModDependencies", + }), + ); this.skippedMods.add(`${pkg.author}-${pkg.name}`); return; @@ -524,12 +543,21 @@ export class PreAkiModLoader implements IModLoader this.vfs.rename(`${modPath}/package.json`, `${modPath}/package.json.bak`); this.vfs.writeFile(`${modPath}/package.json`, "{}"); - this.logger.info(this.localisationService.getText("modloader-installing_external_dependencies", {name: pkg.name, author: pkg.author})); + this.logger.info( + this.localisationService.getText("modloader-installing_external_dependencies", { + name: pkg.name, + author: pkg.author, + }), + ); - const pnpmPath = path.join(process.cwd(), (globalThis.G_RELEASE_CONFIGURATION ? "Aki_Data/Server/@pnpm/exe" : "node_modules/@pnpm/exe"), (os.platform() === "win32" ? "pnpm.exe" : "pnpm")); + const pnpmPath = path.join( + process.cwd(), + globalThis.G_RELEASE_CONFIGURATION ? "Aki_Data/Server/@pnpm/exe" : "node_modules/@pnpm/exe", + os.platform() === "win32" ? "pnpm.exe" : "pnpm", + ); let command = `${pnpmPath} install `; command += dependenciesToInstall.map(([depName, depVersion]) => `${depName}@${depVersion}`).join(" "); - execSync(command, { cwd: modPath }); + execSync(command, {cwd: modPath}); // Delete the new blank package.json then rename the backup back to the original name this.vfs.removeFile(`${modPath}/package.json`); @@ -545,18 +573,30 @@ export class PreAkiModLoader implements IModLoader const modName = `${pkg.author}-${pkg.name}`; - for (const [modDependency, requiredVersion ] of Object.entries(pkg.modDependencies)) + for (const [modDependency, requiredVersion] of Object.entries(pkg.modDependencies)) { // Raise dependency version incompatible if the dependency is not found in the mod list if (!loadedMods.has(modDependency)) { - this.logger.error(this.localisationService.getText("modloader-missing_dependency", {mod: modName, modDependency: modDependency})); + this.logger.error( + this.localisationService.getText("modloader-missing_dependency", { + mod: modName, + modDependency: modDependency, + }), + ); return false; } if (!semver.satisfies(loadedMods.get(modDependency).version, requiredVersion)) { - this.logger.error(this.localisationService.getText("modloader-outdated_dependency", {mod: modName, modDependency: modDependency, currentVersion: loadedMods.get(modDependency).version, requiredVersion: requiredVersion})); + this.logger.error( + this.localisationService.getText("modloader-outdated_dependency", { + mod: modName, + modDependency: modDependency, + currentVersion: loadedMods.get(modDependency).version, + requiredVersion: requiredVersion, + }), + ); return false; } } @@ -577,7 +617,13 @@ export class PreAkiModLoader implements IModLoader // Raise dependency version incompatible if any incompatible mod is found if (loadedMods.has(incompatibleModName)) { - this.logger.error(this.localisationService.getText("modloader-incompatible_mod_found", {author: mod.author, modName: mod.name, incompatibleModName: incompatibleModName})); + this.logger.error( + this.localisationService.getText("modloader-incompatible_mod_found", { + author: mod.author, + modName: mod.name, + incompatibleModName: incompatibleModName, + }), + ); return false; } } @@ -599,7 +645,7 @@ export class PreAkiModLoader implements IModLoader const modIsCalledSrc = modName.toLowerCase() === "src"; const modIsCalledDb = modName.toLowerCase() === "db"; const hasBepinExFolderStructure = this.vfs.exists(`${modPath}/plugins`); - const containsDll = this.vfs.getFiles(`${modPath}`).find(x => x.includes(".dll")); + const containsDll = this.vfs.getFiles(`${modPath}`).find((x) => x.includes(".dll")); if (modIsCalledSrc || modIsCalledDb || modIsCalledUser) { @@ -629,7 +675,12 @@ export class PreAkiModLoader implements IModLoader { if (!(check in config)) { - this.logger.error(this.localisationService.getText("modloader-missing_package_json_property", {modName: modName, prop: check})); + this.logger.error( + this.localisationService.getText("modloader-missing_package_json_property", { + modName: modName, + prop: check, + }), + ); issue = true; } } @@ -642,23 +693,23 @@ export class PreAkiModLoader implements IModLoader if ("main" in config) { - if (config.main.split(".").pop() !== "js") // expects js file as entry - { + if (config.main.split(".").pop() !== "js") + { // expects js file as entry this.logger.error(this.localisationService.getText("modloader-main_property_not_js", modName)); issue = true; } - if (!this.vfs.exists(`${modPath}/${config.main}`)) { - // If TS file exists with same name, dont perform check as we'll generate JS from TS file const tsFileName = config.main.replace(".js", ".ts"); const tsFileExists = this.vfs.exists(`${modPath}/${tsFileName}`); if (!tsFileExists) { - this.logger.error(this.localisationService.getText("modloader-main_property_points_to_nothing", modName)); + this.logger.error( + this.localisationService.getText("modloader-main_property_points_to_nothing", modName), + ); issue = true; } } @@ -666,7 +717,9 @@ export class PreAkiModLoader implements IModLoader if (config.incompatibilities && !Array.isArray(config.incompatibilities)) { - this.logger.error(this.localisationService.getText("modloader-incompatibilities_not_string_array", modName)); + this.logger.error( + this.localisationService.getText("modloader-incompatibilities_not_string_array", modName), + ); issue = true; }