Initial server commit

This commit is contained in:
Tyfon
2024-05-27 00:54:42 -07:00
parent 66ce87f5e7
commit 6f1b4179c0
656 changed files with 26523 additions and 0 deletions

33
server/types/loaders/BundleLoader.d.ts vendored Normal file
View File

@@ -0,0 +1,33 @@
import { HttpServerHelper } from "@spt-aki/helpers/HttpServerHelper";
import { BundleHashCacheService } from "@spt-aki/services/cache/BundleHashCacheService";
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
import { VFS } from "@spt-aki/utils/VFS";
export declare class BundleInfo {
modpath: string;
filename: string;
crc: number;
dependencies: string[];
constructor(modpath: string, bundle: BundleManifestEntry, bundleHash: number);
}
export declare class BundleLoader {
protected httpServerHelper: HttpServerHelper;
protected vfs: VFS;
protected jsonUtil: JsonUtil;
protected bundleHashCacheService: BundleHashCacheService;
protected bundles: Record<string, BundleInfo>;
constructor(httpServerHelper: HttpServerHelper, vfs: VFS, jsonUtil: JsonUtil, bundleHashCacheService: BundleHashCacheService);
/**
* Handle singleplayer/bundles
*/
getBundles(): BundleInfo[];
getBundle(key: string): BundleInfo;
addBundles(modpath: string): void;
addBundle(key: string, b: BundleInfo): void;
}
export interface BundleManifest {
manifest: BundleManifestEntry[];
}
export interface BundleManifestEntry {
key: string;
dependencyKeys: string[];
}

17
server/types/loaders/ModLoadOrder.d.ts vendored Normal file
View File

@@ -0,0 +1,17 @@
import { IPackageJsonData } from "@spt-aki/models/spt/mod/IPackageJsonData";
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
import { LocalisationService } from "@spt-aki/services/LocalisationService";
export declare class ModLoadOrder {
protected logger: ILogger;
protected localisationService: LocalisationService;
protected mods: Map<string, IPackageJsonData>;
protected modsAvailable: Map<string, IPackageJsonData>;
protected loadOrder: Set<string>;
constructor(logger: ILogger, localisationService: LocalisationService);
setModList(mods: Record<string, IPackageJsonData>): void;
getLoadOrder(): string[];
getModsOnLoadBefore(mod: string): Set<string>;
getModsOnLoadAfter(mod: string): Set<string>;
protected invertLoadBefore(mod: string): void;
protected getLoadOrderRecursive(mod: string, visited: Set<string>): void;
}

43
server/types/loaders/ModTypeCheck.d.ts vendored Normal file
View File

@@ -0,0 +1,43 @@
import { IPostAkiLoadMod } from "@spt-aki/models/external/IPostAkiLoadMod";
import { IPostAkiLoadModAsync } from "@spt-aki/models/external/IPostAkiLoadModAsync";
import { IPostDBLoadMod } from "@spt-aki/models/external/IPostDBLoadMod";
import { IPostDBLoadModAsync } from "@spt-aki/models/external/IPostDBLoadModAsync";
import { IPreAkiLoadMod } from "@spt-aki/models/external/IPreAkiLoadMod";
import { IPreAkiLoadModAsync } from "@spt-aki/models/external/IPreAkiLoadModAsync";
export declare class ModTypeCheck {
/**
* Use defined safe guard to check if the mod is a IPreAkiLoadMod
* @returns boolean
*/
isPreAkiLoad(mod: any): mod is IPreAkiLoadMod;
/**
* Use defined safe guard to check if the mod is a IPostAkiLoadMod
* @returns boolean
*/
isPostAkiLoad(mod: any): mod is IPostAkiLoadMod;
/**
* Use defined safe guard to check if the mod is a IPostDBLoadMod
* @returns boolean
*/
isPostDBAkiLoad(mod: any): mod is IPostDBLoadMod;
/**
* Use defined safe guard to check if the mod is a IPreAkiLoadModAsync
* @returns boolean
*/
isPreAkiLoadAsync(mod: any): mod is IPreAkiLoadModAsync;
/**
* Use defined safe guard to check if the mod is a IPostAkiLoadModAsync
* @returns boolean
*/
isPostAkiLoadAsync(mod: any): mod is IPostAkiLoadModAsync;
/**
* Use defined safe guard to check if the mod is a IPostDBLoadModAsync
* @returns boolean
*/
isPostDBAkiLoadAsync(mod: any): mod is IPostDBLoadModAsync;
/**
* Checks for mod to be compatible with 3.X+
* @returns boolean
*/
isPostV3Compatible(mod: any): boolean;
}

View File

@@ -0,0 +1,17 @@
import { DependencyContainer } from "tsyringe";
import { ModTypeCheck } from "@spt-aki/loaders/ModTypeCheck";
import { PreAkiModLoader } from "@spt-aki/loaders/PreAkiModLoader";
import { IModLoader } from "@spt-aki/models/spt/mod/IModLoader";
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
import { LocalisationService } from "@spt-aki/services/LocalisationService";
export declare class PostAkiModLoader implements IModLoader {
protected logger: ILogger;
protected preAkiModLoader: PreAkiModLoader;
protected localisationService: LocalisationService;
protected modTypeCheck: ModTypeCheck;
protected container: DependencyContainer;
constructor(logger: ILogger, preAkiModLoader: PreAkiModLoader, localisationService: LocalisationService, modTypeCheck: ModTypeCheck);
getModPath(mod: string): string;
load(): Promise<void>;
protected executeModsAsync(): Promise<void>;
}

View File

@@ -0,0 +1,21 @@
import { DependencyContainer } from "tsyringe";
import { OnLoad } from "@spt-aki/di/OnLoad";
import { BundleLoader } from "@spt-aki/loaders/BundleLoader";
import { ModTypeCheck } from "@spt-aki/loaders/ModTypeCheck";
import { PreAkiModLoader } from "@spt-aki/loaders/PreAkiModLoader";
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
import { LocalisationService } from "@spt-aki/services/LocalisationService";
export declare class PostDBModLoader implements OnLoad {
protected logger: ILogger;
protected bundleLoader: BundleLoader;
protected preAkiModLoader: PreAkiModLoader;
protected localisationService: LocalisationService;
protected modTypeCheck: ModTypeCheck;
protected container: DependencyContainer;
constructor(logger: ILogger, bundleLoader: BundleLoader, preAkiModLoader: PreAkiModLoader, localisationService: LocalisationService, modTypeCheck: ModTypeCheck);
onLoad(): Promise<void>;
getRoute(): string;
getModPath(mod: string): string;
protected executeModsAsync(): Promise<void>;
protected addBundles(): void;
}

View File

@@ -0,0 +1,99 @@
import { DependencyContainer } from "tsyringe";
import { ModLoadOrder } from "@spt-aki/loaders/ModLoadOrder";
import { ModTypeCheck } from "@spt-aki/loaders/ModTypeCheck";
import { ModDetails } from "@spt-aki/models/eft/profile/IAkiProfile";
import { ICoreConfig } from "@spt-aki/models/spt/config/ICoreConfig";
import { IModLoader } from "@spt-aki/models/spt/mod/IModLoader";
import { IPackageJsonData } from "@spt-aki/models/spt/mod/IPackageJsonData";
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
import { ConfigServer } from "@spt-aki/servers/ConfigServer";
import { LocalisationService } from "@spt-aki/services/LocalisationService";
import { ModCompilerService } from "@spt-aki/services/ModCompilerService";
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
import { VFS } from "@spt-aki/utils/VFS";
export declare class PreAkiModLoader implements IModLoader {
protected logger: ILogger;
protected vfs: VFS;
protected jsonUtil: JsonUtil;
protected modCompilerService: ModCompilerService;
protected localisationService: LocalisationService;
protected configServer: ConfigServer;
protected modLoadOrder: ModLoadOrder;
protected modTypeCheck: ModTypeCheck;
protected container: DependencyContainer;
protected readonly basepath = "user/mods/";
protected readonly modOrderPath = "user/mods/order.json";
protected order: Record<string, number>;
protected imported: Record<string, IPackageJsonData>;
protected akiConfig: ICoreConfig;
protected serverDependencies: Record<string, string>;
protected skippedMods: Set<string>;
constructor(logger: ILogger, vfs: VFS, jsonUtil: JsonUtil, modCompilerService: ModCompilerService, localisationService: LocalisationService, configServer: ConfigServer, modLoadOrder: ModLoadOrder, modTypeCheck: ModTypeCheck);
load(container: DependencyContainer): Promise<void>;
/**
* Returns a list of mods with preserved load order
* @returns Array of mod names in load order
*/
getImportedModsNames(): string[];
getImportedModDetails(): Record<string, IPackageJsonData>;
getProfileModsGroupedByModName(profileMods: ModDetails[]): ModDetails[];
getModPath(mod: string): string;
protected importModsAsync(): Promise<void>;
protected sortMods(prev: string, next: string, missingFromOrderJSON: Record<string, boolean>): number;
/**
* Check for duplicate mods loaded, show error if any
* @param modPackageData map of mod package.json data
*/
protected checkForDuplicateMods(modPackageData: Map<string, IPackageJsonData>): void;
/**
* Returns an array of valid mods.
*
* @param mods mods to validate
* @returns array of mod folder names
*/
protected getValidMods(mods: string[]): string[];
/**
* Get packageJson data for mods
* @param mods mods to get packageJson for
* @returns map <modFolderName - package.json>
*/
protected getModsPackageData(mods: string[]): Map<string, IPackageJsonData>;
/**
* Is the passed in mod compatible with the running server version
* @param mod Mod to check compatibiltiy with AKI
* @returns True if compatible
*/
protected isModCombatibleWithAki(mod: IPackageJsonData): boolean;
/**
* Execute each mod found in this.imported
* @returns void promise
*/
protected executeModsAsync(): Promise<void>;
/**
* Read loadorder.json (create if doesnt exist) and return sorted list of mods
* @returns string array of sorted mod names
*/
sortModsLoadOrder(): string[];
/**
* Compile mod and add into class property "imported"
* @param mod Name of mod to compile/add
*/
protected addModAsync(mod: string, pkg: IPackageJsonData): Promise<void>;
/**
* Checks if a given mod should be loaded or skipped.
*
* @param pkg mod package.json data
* @returns
*/
protected shouldSkipMod(pkg: IPackageJsonData): boolean;
protected autoInstallDependencies(modPath: string, pkg: IPackageJsonData): void;
protected areModDependenciesFulfilled(pkg: IPackageJsonData, loadedMods: Map<string, IPackageJsonData>): boolean;
protected isModCompatible(mod: IPackageJsonData, loadedMods: Map<string, IPackageJsonData>): boolean;
/**
* Validate a mod passes a number of checks
* @param modName name of mod in /mods/ to validate
* @returns true if valid
*/
protected validMod(modName: string): boolean;
getContainer(): DependencyContainer;
}