Formatting for loader classes.
This commit is contained in:
parent
8586447d21
commit
3f2d36a2fc
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
import { inject, injectable } from "tsyringe";
|
import { inject, injectable } from "tsyringe";
|
||||||
|
|
||||||
import { HttpServerHelper } from "@spt-aki/helpers/HttpServerHelper";
|
import { HttpServerHelper } from "@spt-aki/helpers/HttpServerHelper";
|
||||||
@ -31,9 +30,9 @@ export class BundleLoader
|
|||||||
constructor(
|
constructor(
|
||||||
@inject("HttpServerHelper") protected httpServerHelper: HttpServerHelper,
|
@inject("HttpServerHelper") protected httpServerHelper: HttpServerHelper,
|
||||||
@inject("VFS") protected vfs: VFS,
|
@inject("VFS") protected vfs: VFS,
|
||||||
@inject("JsonUtil") protected jsonUtil: JsonUtil
|
@inject("JsonUtil") protected jsonUtil: JsonUtil,
|
||||||
)
|
)
|
||||||
{ }
|
{}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle singleplayer/bundles
|
* Handle singleplayer/bundles
|
||||||
@ -65,7 +64,8 @@ export class BundleLoader
|
|||||||
|
|
||||||
public addBundles(modpath: string): void
|
public addBundles(modpath: string): void
|
||||||
{
|
{
|
||||||
const manifest = this.jsonUtil.deserialize<BundleManifest>(this.vfs.readFile(`${modpath}bundles.json`)).manifest;
|
const manifest =
|
||||||
|
this.jsonUtil.deserialize<BundleManifest>(this.vfs.readFile(`${modpath}bundles.json`)).manifest;
|
||||||
|
|
||||||
for (const bundle of 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;
|
this.bundles[key] = b;
|
||||||
}
|
}
|
||||||
@ -83,11 +83,11 @@ export class BundleLoader
|
|||||||
|
|
||||||
export interface BundleManifest
|
export interface BundleManifest
|
||||||
{
|
{
|
||||||
manifest: Array<BundleManifestEntry>
|
manifest: Array<BundleManifestEntry>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BundleManifestEntry
|
export interface BundleManifestEntry
|
||||||
{
|
{
|
||||||
key: string
|
key: string;
|
||||||
path: string
|
path: string;
|
||||||
}
|
}
|
||||||
|
@ -13,9 +13,9 @@ export class ModLoadOrder
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@inject("WinstonLogger") protected logger: ILogger,
|
@inject("WinstonLogger") protected logger: ILogger,
|
||||||
@inject("LocalisationService") protected localisationService: LocalisationService
|
@inject("LocalisationService") protected localisationService: LocalisationService,
|
||||||
)
|
)
|
||||||
{ }
|
{}
|
||||||
|
|
||||||
public setModList(mods: Record<string, IPackageJsonData>): void
|
public setModList(mods: Record<string, IPackageJsonData>): void
|
||||||
{
|
{
|
||||||
@ -25,8 +25,8 @@ export class ModLoadOrder
|
|||||||
|
|
||||||
const visited = new Set<string>();
|
const visited = new Set<string>();
|
||||||
|
|
||||||
//invert loadBefore into loadAfter on specified mods
|
// invert loadBefore into loadAfter on specified mods
|
||||||
for (const [ modName, modConfig ] of this.modsAvailable)
|
for (const [modName, modConfig] of this.modsAvailable)
|
||||||
{
|
{
|
||||||
if ((modConfig.loadBefore ?? []).length > 0)
|
if ((modConfig.loadBefore ?? []).length > 0)
|
||||||
{
|
{
|
||||||
@ -143,7 +143,12 @@ export class ModLoadOrder
|
|||||||
{
|
{
|
||||||
if (this.modsAvailable.get(modAfter)?.loadAfter?.includes(mod))
|
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);
|
dependencies.add(modAfter);
|
||||||
|
@ -10,7 +10,6 @@ import { IPreAkiLoadModAsync } from "@spt-aki/models/external/IPreAkiLoadModAsyn
|
|||||||
@injectable()
|
@injectable()
|
||||||
export class ModTypeCheck
|
export class ModTypeCheck
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use defined safe guard to check if the mod is a IPreAkiLoadMod
|
* Use defined safe guard to check if the mod is a IPreAkiLoadMod
|
||||||
* @returns boolean
|
* @returns boolean
|
||||||
@ -19,7 +18,7 @@ export class ModTypeCheck
|
|||||||
{
|
{
|
||||||
return mod?.preAkiLoad;
|
return mod?.preAkiLoad;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use defined safe guard to check if the mod is a IPostAkiLoadMod
|
* Use defined safe guard to check if the mod is a IPostAkiLoadMod
|
||||||
* @returns boolean
|
* @returns boolean
|
||||||
@ -28,7 +27,7 @@ export class ModTypeCheck
|
|||||||
{
|
{
|
||||||
return mod?.postAkiLoad;
|
return mod?.postAkiLoad;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use defined safe guard to check if the mod is a IPostDBLoadMod
|
* Use defined safe guard to check if the mod is a IPostDBLoadMod
|
||||||
* @returns boolean
|
* @returns boolean
|
||||||
@ -46,7 +45,7 @@ export class ModTypeCheck
|
|||||||
{
|
{
|
||||||
return mod?.preAkiLoadAsync;
|
return mod?.preAkiLoadAsync;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use defined safe guard to check if the mod is a IPostAkiLoadModAsync
|
* Use defined safe guard to check if the mod is a IPostAkiLoadModAsync
|
||||||
* @returns boolean
|
* @returns boolean
|
||||||
@ -55,7 +54,7 @@ export class ModTypeCheck
|
|||||||
{
|
{
|
||||||
return mod?.postAkiLoadAsync;
|
return mod?.postAkiLoadAsync;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use defined safe guard to check if the mod is a IPostDBLoadModAsync
|
* Use defined safe guard to check if the mod is a IPostDBLoadModAsync
|
||||||
* @returns boolean
|
* @returns boolean
|
||||||
@ -71,12 +70,11 @@ export class ModTypeCheck
|
|||||||
*/
|
*/
|
||||||
public isPostV3Compatible(mod: any): boolean
|
public isPostV3Compatible(mod: any): boolean
|
||||||
{
|
{
|
||||||
return this.isPreAkiLoad(mod) ||
|
return this.isPreAkiLoad(mod) ||
|
||||||
this.isPostAkiLoad(mod) ||
|
this.isPostAkiLoad(mod) ||
|
||||||
this.isPostDBAkiLoad(mod) ||
|
this.isPostDBAkiLoad(mod) ||
|
||||||
this.isPreAkiLoadAsync(mod) ||
|
this.isPreAkiLoadAsync(mod) ||
|
||||||
this.isPostAkiLoadAsync(mod) ||
|
this.isPostAkiLoadAsync(mod) ||
|
||||||
this.isPostDBAkiLoadAsync(mod);
|
this.isPostDBAkiLoadAsync(mod);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,9 +19,9 @@ export class PostAkiModLoader implements IModLoader
|
|||||||
@inject("VFS") protected vfs: VFS,
|
@inject("VFS") protected vfs: VFS,
|
||||||
@inject("PreAkiModLoader") protected preAkiModLoader: PreAkiModLoader,
|
@inject("PreAkiModLoader") protected preAkiModLoader: PreAkiModLoader,
|
||||||
@inject("LocalisationService") protected localisationService: LocalisationService,
|
@inject("LocalisationService") protected localisationService: LocalisationService,
|
||||||
@inject("ModTypeCheck") protected modTypeCheck: ModTypeCheck
|
@inject("ModTypeCheck") protected modTypeCheck: ModTypeCheck,
|
||||||
)
|
)
|
||||||
{ }
|
{}
|
||||||
|
|
||||||
public getModPath(mod: string): string
|
public getModPath(mod: string): string
|
||||||
{
|
{
|
||||||
@ -43,20 +43,27 @@ export class PostAkiModLoader implements IModLoader
|
|||||||
for (const modName of mods)
|
for (const modName of mods)
|
||||||
{
|
{
|
||||||
// // import class
|
// // 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}`;
|
const modpath = `${process.cwd()}/${filepath}`;
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
const mod = require(modpath);
|
const mod = require(modpath);
|
||||||
|
|
||||||
if (this.modTypeCheck.isPostAkiLoadAsync(mod.mod))
|
if (this.modTypeCheck.isPostAkiLoadAsync(mod.mod))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await (mod.mod as IPostAkiLoadModAsync).postAkiLoadAsync(container);
|
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
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,10 +15,10 @@ export class PostDBModLoader implements OnLoad
|
|||||||
@inject("WinstonLogger") protected logger: ILogger,
|
@inject("WinstonLogger") protected logger: ILogger,
|
||||||
@inject("PreAkiModLoader") protected preAkiModLoader: PreAkiModLoader,
|
@inject("PreAkiModLoader") protected preAkiModLoader: PreAkiModLoader,
|
||||||
@inject("LocalisationService") protected localisationService: LocalisationService,
|
@inject("LocalisationService") protected localisationService: LocalisationService,
|
||||||
@inject("ModTypeCheck") protected modTypeCheck: ModTypeCheck
|
@inject("ModTypeCheck") protected modTypeCheck: ModTypeCheck,
|
||||||
)
|
)
|
||||||
{ }
|
{}
|
||||||
|
|
||||||
public async onLoad(): Promise<void>
|
public async onLoad(): Promise<void>
|
||||||
{
|
{
|
||||||
if (globalThis.G_MODS_ENABLED)
|
if (globalThis.G_MODS_ENABLED)
|
||||||
@ -26,13 +26,12 @@ export class PostDBModLoader implements OnLoad
|
|||||||
await this.executeMods(this.preAkiModLoader.getContainer());
|
await this.executeMods(this.preAkiModLoader.getContainer());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public getRoute(): string
|
public getRoute(): string
|
||||||
{
|
{
|
||||||
return "aki-mods";
|
return "aki-mods";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public getModPath(mod: string): string
|
public getModPath(mod: string): string
|
||||||
{
|
{
|
||||||
return this.preAkiModLoader.getModPath(mod);
|
return this.preAkiModLoader.getModPath(mod);
|
||||||
@ -43,21 +42,28 @@ export class PostDBModLoader implements OnLoad
|
|||||||
const mods = this.preAkiModLoader.sortModsLoadOrder();
|
const mods = this.preAkiModLoader.sortModsLoadOrder();
|
||||||
for (const modName of mods)
|
for (const modName of mods)
|
||||||
{
|
{
|
||||||
// // import class
|
// 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}`;
|
const modpath = `${process.cwd()}/${filepath}`;
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
const mod = require(modpath);
|
const mod = require(modpath);
|
||||||
|
|
||||||
if (this.modTypeCheck.isPostDBAkiLoadAsync(mod.mod))
|
if (this.modTypeCheck.isPostDBAkiLoadAsync(mod.mod))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await (mod.mod as IPostDBLoadModAsync).postDBLoadAsync(container);
|
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
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ export class PreAkiModLoader implements IModLoader
|
|||||||
@inject("LocalisationService") protected localisationService: LocalisationService,
|
@inject("LocalisationService") protected localisationService: LocalisationService,
|
||||||
@inject("ConfigServer") protected configServer: ConfigServer,
|
@inject("ConfigServer") protected configServer: ConfigServer,
|
||||||
@inject("ModLoadOrder") protected modLoadOrder: ModLoadOrder,
|
@inject("ModLoadOrder") protected modLoadOrder: ModLoadOrder,
|
||||||
@inject("ModTypeCheck") protected modTypeCheck: ModTypeCheck
|
@inject("ModTypeCheck") protected modTypeCheck: ModTypeCheck,
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
this.akiConfig = this.configServer.getConfig<ICoreConfig>(ConfigTypes.CORE);
|
this.akiConfig = this.configServer.getConfig<ICoreConfig>(ConfigTypes.CORE);
|
||||||
@ -96,10 +96,10 @@ export class PreAkiModLoader implements IModLoader
|
|||||||
for (const modName in modsGroupedByName)
|
for (const modName in modsGroupedByName)
|
||||||
{
|
{
|
||||||
const modDatas = modsGroupedByName[modName];
|
const modDatas = modsGroupedByName[modName];
|
||||||
const modVersions = modDatas.map(x => x.version);
|
const modVersions = modDatas.map((x) => x.version);
|
||||||
const highestVersion = semver.maxSatisfying(modVersions, "*");
|
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)
|
if (!chosenVersion)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
@ -130,28 +130,28 @@ export class PreAkiModLoader implements IModLoader
|
|||||||
* array of mod folder names
|
* array of mod folder names
|
||||||
*/
|
*/
|
||||||
const mods: string[] = this.vfs.getDirs(this.basepath);
|
const mods: string[] = this.vfs.getDirs(this.basepath);
|
||||||
|
|
||||||
this.logger.info(this.localisationService.getText("modloader-loading_mods", mods.length));
|
this.logger.info(this.localisationService.getText("modloader-loading_mods", mods.length));
|
||||||
|
|
||||||
// Mod order
|
// Mod order
|
||||||
if (!this.vfs.exists(this.modOrderPath))
|
if (!this.vfs.exists(this.modOrderPath))
|
||||||
{
|
{
|
||||||
this.logger.info(this.localisationService.getText("modloader-mod_order_missing"));
|
this.logger.info(this.localisationService.getText("modloader-mod_order_missing"));
|
||||||
|
|
||||||
// Write file with empty order array to disk
|
// Write file with empty order array to disk
|
||||||
this.vfs.writeFile(this.modOrderPath, this.jsonUtil.serializeAdvanced({order: []}, null, 4));
|
this.vfs.writeFile(this.modOrderPath, this.jsonUtil.serializeAdvanced({order: []}, null, 4));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const modOrder = this.vfs.readFile(this.modOrderPath, { encoding: "utf8" });
|
const modOrder = this.vfs.readFile(this.modOrderPath, {encoding: "utf8"});
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
for (const [index, mod] of (this.jsonUtil.deserialize<any>(modOrder).order as string[]).entries())
|
for (const [index, mod] of (this.jsonUtil.deserialize<any>(modOrder).order as string[]).entries())
|
||||||
{
|
{
|
||||||
this.order[mod] = index;
|
this.order[mod] = index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (error)
|
catch (error)
|
||||||
{
|
{
|
||||||
this.logger.error(this.localisationService.getText("modloader-mod_order_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 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);
|
this.autoInstallDependencies(`${this.basepath}${modFolderName}`, modToValidate);
|
||||||
}
|
}
|
||||||
@ -222,7 +225,7 @@ export class PreAkiModLoader implements IModLoader
|
|||||||
|
|
||||||
if (this.shouldSkipMod(pkg))
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,15 +239,15 @@ export class PreAkiModLoader implements IModLoader
|
|||||||
{
|
{
|
||||||
const previndex = this.order[prev];
|
const previndex = this.order[prev];
|
||||||
const nextindex = this.order[next];
|
const nextindex = this.order[next];
|
||||||
|
|
||||||
// mod is not on the list, move the mod to last
|
// mod is not on the list, move the mod to last
|
||||||
if (previndex === undefined)
|
if (previndex === undefined)
|
||||||
{
|
{
|
||||||
missingFromOrderJSON[prev] = true;
|
missingFromOrderJSON[prev] = true;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if (nextindex === undefined)
|
else if (nextindex === undefined)
|
||||||
{
|
{
|
||||||
missingFromOrderJSON[next] = true;
|
missingFromOrderJSON[next] = true;
|
||||||
|
|
||||||
@ -283,7 +286,7 @@ export class PreAkiModLoader implements IModLoader
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of valid mods.
|
* Returns an array of valid mods.
|
||||||
*
|
*
|
||||||
* @param mods mods to validate
|
* @param mods mods to validate
|
||||||
* @returns array of mod folder names
|
* @returns array of mod folder names
|
||||||
*/
|
*/
|
||||||
@ -391,14 +394,19 @@ export class PreAkiModLoader implements IModLoader
|
|||||||
// Perform async load of mod
|
// Perform async load of mod
|
||||||
if (this.modTypeCheck.isPreAkiLoadAsync(requiredMod.mod))
|
if (this.modTypeCheck.isPreAkiLoadAsync(requiredMod.mod))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await (requiredMod.mod as IPreAkiLoadModAsync).preAkiLoadAsync(container);
|
await (requiredMod.mod as IPreAkiLoadModAsync).preAkiLoadAsync(container);
|
||||||
globalThis[mod] = requiredMod;
|
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;
|
continue;
|
||||||
@ -457,7 +465,7 @@ export class PreAkiModLoader implements IModLoader
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// rename the mod entry point to .ts if it's set to .js because G_MODS_TRANSPILE_TS is set to false
|
// 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
|
// Add mod to imported list
|
||||||
this.imported[mod] = {...pkg, dependencies: pkg.modDependencies};
|
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.
|
* Checks if a given mod should be loaded or skipped.
|
||||||
*
|
*
|
||||||
* @param pkg mod package.json data
|
* @param pkg mod package.json data
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
protected shouldSkipMod(pkg: IPackageJsonData): boolean
|
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 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)
|
if (!this.akiConfig.features.autoInstallModDependencies)
|
||||||
{
|
{
|
||||||
this.logger.warning(this.localisationService.getText("modloader-installing_external_dependencies_disabled", {
|
this.logger.warning(
|
||||||
name: pkg.name,
|
this.localisationService.getText("modloader-installing_external_dependencies_disabled", {
|
||||||
author: pkg.author,
|
name: pkg.name,
|
||||||
configPath: path.join(globalThis.G_RELEASE_CONFIGURATION ? "Aki_Data/Server/configs" : "assets/configs", "core.json"),
|
author: pkg.author,
|
||||||
configOption: "autoInstallModDependencies"
|
configPath: path.join(
|
||||||
}));
|
globalThis.G_RELEASE_CONFIGURATION ? "Aki_Data/Server/configs" : "assets/configs",
|
||||||
|
"core.json",
|
||||||
|
),
|
||||||
|
configOption: "autoInstallModDependencies",
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
this.skippedMods.add(`${pkg.author}-${pkg.name}`);
|
this.skippedMods.add(`${pkg.author}-${pkg.name}`);
|
||||||
return;
|
return;
|
||||||
@ -524,12 +543,21 @@ export class PreAkiModLoader implements IModLoader
|
|||||||
this.vfs.rename(`${modPath}/package.json`, `${modPath}/package.json.bak`);
|
this.vfs.rename(`${modPath}/package.json`, `${modPath}/package.json.bak`);
|
||||||
this.vfs.writeFile(`${modPath}/package.json`, "{}");
|
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 `;
|
let command = `${pnpmPath} install `;
|
||||||
command += dependenciesToInstall.map(([depName, depVersion]) => `${depName}@${depVersion}`).join(" ");
|
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
|
// Delete the new blank package.json then rename the backup back to the original name
|
||||||
this.vfs.removeFile(`${modPath}/package.json`);
|
this.vfs.removeFile(`${modPath}/package.json`);
|
||||||
@ -545,18 +573,30 @@ export class PreAkiModLoader implements IModLoader
|
|||||||
|
|
||||||
const modName = `${pkg.author}-${pkg.name}`;
|
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
|
// Raise dependency version incompatible if the dependency is not found in the mod list
|
||||||
if (!loadedMods.has(modDependency))
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!semver.satisfies(loadedMods.get(modDependency).version, requiredVersion))
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -577,7 +617,13 @@ export class PreAkiModLoader implements IModLoader
|
|||||||
// Raise dependency version incompatible if any incompatible mod is found
|
// Raise dependency version incompatible if any incompatible mod is found
|
||||||
if (loadedMods.has(incompatibleModName))
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -599,7 +645,7 @@ export class PreAkiModLoader implements IModLoader
|
|||||||
const modIsCalledSrc = modName.toLowerCase() === "src";
|
const modIsCalledSrc = modName.toLowerCase() === "src";
|
||||||
const modIsCalledDb = modName.toLowerCase() === "db";
|
const modIsCalledDb = modName.toLowerCase() === "db";
|
||||||
const hasBepinExFolderStructure = this.vfs.exists(`${modPath}/plugins`);
|
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)
|
if (modIsCalledSrc || modIsCalledDb || modIsCalledUser)
|
||||||
{
|
{
|
||||||
@ -629,7 +675,12 @@ export class PreAkiModLoader implements IModLoader
|
|||||||
{
|
{
|
||||||
if (!(check in config))
|
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;
|
issue = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -642,23 +693,23 @@ export class PreAkiModLoader implements IModLoader
|
|||||||
|
|
||||||
if ("main" in config)
|
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));
|
this.logger.error(this.localisationService.getText("modloader-main_property_not_js", modName));
|
||||||
issue = true;
|
issue = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!this.vfs.exists(`${modPath}/${config.main}`))
|
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
|
// 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 tsFileName = config.main.replace(".js", ".ts");
|
||||||
const tsFileExists = this.vfs.exists(`${modPath}/${tsFileName}`);
|
const tsFileExists = this.vfs.exists(`${modPath}/${tsFileName}`);
|
||||||
|
|
||||||
if (!tsFileExists)
|
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;
|
issue = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -666,7 +717,9 @@ export class PreAkiModLoader implements IModLoader
|
|||||||
|
|
||||||
if (config.incompatibilities && !Array.isArray(config.incompatibilities))
|
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;
|
issue = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user