diff --git a/project/assets/database/locales/server/de.json b/project/assets/database/locales/server/de.json index d5fda2ad..7addb45a 100644 --- a/project/assets/database/locales/server/de.json +++ b/project/assets/database/locales/server/de.json @@ -81,7 +81,6 @@ "modloader-outdated_dependency": "Mod {{mod}} benötigt {{modDependency}} {{requiredVersion}}. Vorhandene Version ist {{currentVersion}}", "modloader-user_mod_folder_missing": "ModLoader: User/Mod Ordner fehlt, wird erzeugt...", "modloader-visited": "kontrolliert", - "modloader-x_duplicates_found": "ModLoader: Ein oder mehrere Mods sind mehrfach vorhanden: %s, jeweils nur eine Version sollte geladen werden", "payment-not_enough_money_to_complete_transation": "Nicht genug Geld vorhanden um Transaktion abzuschließen, benötigt: {{amountToPay}}, vorhanden: {{amountAvailable}}", "payment-not_enough_money_to_complete_transation_short": "Nicht genug Geld vorhanden um Transaktion abzuschließen", "payment-zero_price_no_payment": "Preis ist 0, keine Bezahlung nötig", diff --git a/project/assets/database/locales/server/en.json b/project/assets/database/locales/server/en.json index 9e5a51d3..73adea15 100644 --- a/project/assets/database/locales/server/en.json +++ b/project/assets/database/locales/server/en.json @@ -136,7 +136,7 @@ "modloader-is_client_mod": "Mod (%s) is a client mod and should be placed in the following folder: /spt/bepinex/plugins", "modloader-installing_external_dependencies": "Installing dependencies for Mod: {{name}} by: {{author}}", "modloader-installing_external_dependencies_disabled": "Mod: {{name}} by: {{author}} requires external dependencies but the feature is currently disabled, go to \"{{configPath}}\", set \"{{configOption}}\" to true and restart the server.\nBy enabling this you accept all responsibility for what {{name}} downloads to your machine.", - "modloader-skipped_mod": "Skipping loading of Mod: {{name}} by: {{author}}", + "modloader-skipped_mod": "Skipping loading of Mod: {{mod}}", "modloader-loaded_mod": "Mod: {{name}} version: {{version}} by: {{author}} loaded", "modloader-loading_mods": "ModLoader: loading %s server mods...", "modloader-main_property_not_js": "Mod %s package.json main property must be a .js file", @@ -156,7 +156,7 @@ "modloader-mod_order_error": "ModLoader: Errors were found in order.json, GOING TO USE DEFAULT LOAD ORDER", "modloader-mod_order_missing_from_json": "ModLoader: Mod %s is missing from order.json, adding", "modloader-visited": "visited", - "modloader-x_duplicates_found": "One or more duplicate mods found: %s, Only one version of a mod should be loaded", + "modloader-x_duplicates_found": "You are trying to load more than one version of %s mod. Skipping all of them.", "openzone-unable_to_find_map": "Unable to add zones to location: %s as it doesn't exist", "payment-not_enough_money_to_complete_transation": "Profile did not have enough money to complete transaction: needed {{amountToPay}}, has {{amountAvailable}}", "payment-not_enough_money_to_complete_transation_short": "Not enough money to complete transaction", diff --git a/project/assets/database/locales/server/es.json b/project/assets/database/locales/server/es.json index dfef0ea1..bf165d5c 100644 --- a/project/assets/database/locales/server/es.json +++ b/project/assets/database/locales/server/es.json @@ -123,7 +123,6 @@ "modloader-mod_order_error": "ModLoader: Errores encontrados en order.json, volviendo a orden de carga por defecto.", "modloader-mod_order_missing_from_json": "ModLoader: Mod %s no está en order.json", "modloader-visited": "visitado", - "modloader-x_duplicates_found": "Una o más modificaciones duplicadas fueron encontradas: %s, Solo una versión de una modificación debería estar instalada", "openzone-unable_to_find_map": "No se pueden añadir zonas a la localización: %s ya que no existe.", "payment-not_enough_money_to_complete_transation": "El perfil no tenía suficiente dinero para completar la transacción: necesitado {{amountToPay}}, tiene {{amountAvailable}}", "payment-not_enough_money_to_complete_transation_short": "Insuficiente dinero para completar la transacción", diff --git a/project/assets/database/locales/server/fr.json b/project/assets/database/locales/server/fr.json index 25d68fd1..92b77c47 100644 --- a/project/assets/database/locales/server/fr.json +++ b/project/assets/database/locales/server/fr.json @@ -141,7 +141,6 @@ "modloader-mod_order_error": "ModLoader: des erreurs ont été trouvées dans order.json, REMISE A DEFAUT DE L'ORDRE DE CHARGEMENT", "modloader-mod_order_missing_from_json": "ModLoader: Mod %s is missing from order.json", "modloader-visited": "visité", - "modloader-x_duplicates_found": "un ou plusiers mod dupliqués ont été trouvés: %s, seulement une seule version de ce mod doit être installée", "openzone-unable_to_find_map": "Impossible d'ajouter des zones à la localisation: %s car elle n'existe pas", "payment-not_enough_money_to_complete_transation": "le profil n'a pas assez d'argent pour completer la transaction : somme requise {{amountToPay}}, possède uniquement {{amountAvailable}}", "payment-not_enough_money_to_complete_transation_short": "pas assez d'argent pour compléter la transaction", diff --git a/project/assets/database/locales/server/it.json b/project/assets/database/locales/server/it.json index 8717ae06..81f93855 100644 --- a/project/assets/database/locales/server/it.json +++ b/project/assets/database/locales/server/it.json @@ -114,7 +114,6 @@ "modloader-outdated_dependency": "Mod {{mod}} richiede {{modDependency}} versione {{requiredVersion}}. Attualmente è installata la versione {{currentVersion}}", "modloader-user_mod_folder_missing": "ModLoader: manca la cartella 'user/mod', creazione in corso...", "modloader-visited": "visitato", - "modloader-x_duplicates_found": "Trovate una o piu mod duplicate: %s, Solo una sola versione di una mod puo essere caricata", "openzone-unable_to_find_map": "Impossibile aggiungere zone al luogo: %s non esiste", "payment-not_enough_money_to_complete_transation": "Il profilo non ha abbastanza soldi per completare la transizione: servono {{amountToPay}}, ha {{amountAvailable}}", "payment-not_enough_money_to_complete_transation_short": "Soldi insufficienti per completare la transizione", diff --git a/project/assets/database/locales/server/jp.json b/project/assets/database/locales/server/jp.json index 246e0c4f..2e8b730d 100644 --- a/project/assets/database/locales/server/jp.json +++ b/project/assets/database/locales/server/jp.json @@ -81,7 +81,6 @@ "modloader-outdated_dependency": "モッド {{mod}} の前提条件である {{modDependency}} はバージョン {{requiredVersion}} を要求されています。現在インストールされているバージョンは {{currentVersion}}", "modloader-user_mod_folder_missing": "モッド読み込むツール: user/mod フォルダーが見つかりません、フォルダー作成中...", "modloader-visited": "ビジットをカウントした。", - "modloader-x_duplicates_found": "一点以上の重複モッドを発見しました: %s、 読み込まれるモッドは一バージョンのみです。", "payment-not_enough_money_to_complete_transation": "プロファイルに通貨が足りません: {{amountToPay}} が必要で、 {{amountAvailable}} が所持しています。", "payment-not_enough_money_to_complete_transation_short": "プロファイルに通貨が足りません。", "payment-zero_price_no_payment": "価額が0なので、支払いは要りません。", diff --git a/project/assets/database/locales/server/ko.json b/project/assets/database/locales/server/ko.json index 704b567f..244faa51 100644 --- a/project/assets/database/locales/server/ko.json +++ b/project/assets/database/locales/server/ko.json @@ -124,7 +124,6 @@ "modloader-mod_order_error": "ModLoader: order.json에서 오류가 발견되어 기본 로드 순서를 사용하려고 합니다.", "modloader-mod_order_missing_from_json": "ModLoader: Mod %s is missing from order.json", "modloader-visited": "방문 된 모드 (visited)", - "modloader-x_duplicates_found": "중복된 모드 발견: %s, 한 버전의 모드만 사용해야 합니다", "openzone-unable_to_find_map": "맵 개방 구역(openZone)에 지역(zone)을 추가 할 수 없음: %s 은(는) 존재하지 않는 지역입니다.", "payment-not_enough_money_to_complete_transation": "프로필에 충분한 소지금이 없음: 필요한 금액 {{amountToPay}}, 소지금 {{amountAvailable}}", "payment-not_enough_money_to_complete_transation_short": "거래하기 위한 충분한 소지금이 없습니다", diff --git a/project/assets/database/locales/server/nl.json b/project/assets/database/locales/server/nl.json index 748de430..dc6dbbc3 100644 --- a/project/assets/database/locales/server/nl.json +++ b/project/assets/database/locales/server/nl.json @@ -141,7 +141,6 @@ "modloader-mod_order_error": "ModLoader: Errors zijn gevonden in order.json, STANDAARD LAAD VOLGORDE WORDT GEBRUIKT", "modloader-mod_order_missing_from_json": "ModLoader: Mod %s mist in order.json", "modloader-visited": "bezocht", - "modloader-x_duplicates_found": "Een of meer identieke mods gevonden: %s, Er moet maar een versie van een mod geladen worden", "openzone-unable_to_find_map": "Kon geen zones toevoegen aan locatie: %s omdat deze niet bestaat", "payment-not_enough_money_to_complete_transation": "Profiel heeft niet genoeg geld om de transactie te voltooien: heeft {{amountToPay}} nodig, heeft {{amountAvailable}}", "payment-not_enough_money_to_complete_transation_short": "Niet genoeg geld om de transactie te voltooien", diff --git a/project/assets/database/locales/server/pl.json b/project/assets/database/locales/server/pl.json index bd2a75fc..ef04a880 100644 --- a/project/assets/database/locales/server/pl.json +++ b/project/assets/database/locales/server/pl.json @@ -141,7 +141,6 @@ "modloader-mod_order_error": "ModLoader: Wykryto błędy w order.json, UŻYCIE DOMYŚLNEJ KOLEJNOŚCI ŁADOWANIA", "modloader-mod_order_missing_from_json": "ModLoader: Mod %s brakuje w pliku order.json", "modloader-visited": "odwiedzony", - "modloader-x_duplicates_found": "Znaleziono jeden lub wiele zduplikowanych modów: %s, Została załadowana tylko jedna wersja modu", "openzone-unable_to_find_map": "Nie można dodać stref do lokalizacji: %s, ponieważ nie istnieje", "payment-not_enough_money_to_complete_transation": "Profil nie miał wystarczająco pieniędzy, aby sfinalizować transakcję: potrzebne {{amountToPay}}, posiada {{amountAvailable}}", "payment-not_enough_money_to_complete_transation_short": "Brak wystarczającej ilości pieniędzy, aby sfinalizować transakcję", diff --git a/project/assets/database/locales/server/ru.json b/project/assets/database/locales/server/ru.json index cbd59e1d..ae9b08d4 100644 --- a/project/assets/database/locales/server/ru.json +++ b/project/assets/database/locales/server/ru.json @@ -141,7 +141,6 @@ "modloader-mod_order_error": "Загрузчик модов: В файле order.json найдены ошибки, БУДЕТ ИСПОЛЬЗОВАТЬСЯ СТАНДАРТНЫЙ ПОРЯДОК ЗАГРУЗКИ", "modloader-mod_order_missing_from_json": "Загрузчик модов: Мод %s отсутствует в файле order.json", "modloader-visited": "посетил", - "modloader-x_duplicates_found": "Один или более дубликат(ов) мода обнаружено: %s, только одна версия мода должна быть загружена", "openzone-unable_to_find_map": "Невозможно добавить зоны в локацию: %s, так как она не существует", "payment-not_enough_money_to_complete_transation": "В профиле не хватает денег для завершения сделки: необходимо {{amountToPay}}, имеется {{amountAvailable}}", "payment-not_enough_money_to_complete_transation_short": "Не хватает денег для завершения сделки", diff --git a/project/assets/database/locales/server/sv.json b/project/assets/database/locales/server/sv.json index bfae73d9..efa92acc 100644 --- a/project/assets/database/locales/server/sv.json +++ b/project/assets/database/locales/server/sv.json @@ -115,7 +115,6 @@ "modloader-outdated_dependency": "Mod {{mod}} kräver {{modDependency}} version {{requiredVersion}}. Aktuell installerad version är {{currentVersion}}", "modloader-user_mod_folder_missing": "ModLoader: användare/mod-mapp saknas, skapar...", "modloader-visited": "besökta", - "modloader-x_duplicates_found": "En eller flera dubbletter av mods hittades: %s, Endast en version av en mod bör laddas", "openzone-unable_to_find_map": "Det går inte att lägga till zoner på plats: %s eftersom den inte finns", "payment-not_enough_money_to_complete_transation": "Profilen hade inte tillräckligt med pengar för att slutföra transaktionen: behövde {{amountToPay}}, har {{amountAvailable}}", "payment-not_enough_money_to_complete_transation_short": "Inte tillräckligt med pengar för att slutföra transaktionen", diff --git a/project/assets/database/locales/server/tr.json b/project/assets/database/locales/server/tr.json index 4756b20a..a68fa3f9 100644 --- a/project/assets/database/locales/server/tr.json +++ b/project/assets/database/locales/server/tr.json @@ -84,7 +84,6 @@ "modloader-mod_order_error": "ModLoader: order.json dosyasında hata bulundu, VARSAYILAN SIRALAMA ILE DEVAM EDILECEK", "modloader-mod_order_missing_from_json": "ModLoader: %s modu order.json dosyasında eksik", "modloader-visited": "ziyaret", - "modloader-x_duplicates_found": "Bir veya daha fazla yinelenen mod bulundu: %s, Bir modun yalnızca bir sürümü yüklenmelidir", "payment-not_enough_money_to_complete_transation": "Profilde işlemi tamamlamak için yeterli para yoktu: gerekli {{amountToPay}}, sahip olmak {{amountAvailable}}", "payment-not_enough_money_to_complete_transation_short": "İşlemi tamamlamak için yeterli para yok", "payment-zero_price_no_payment": "Fiyatı 0, ödemeye gerek yok", diff --git a/project/assets/database/locales/server/zh.json b/project/assets/database/locales/server/zh.json index 505190a0..1422a0b9 100644 --- a/project/assets/database/locales/server/zh.json +++ b/project/assets/database/locales/server/zh.json @@ -141,7 +141,6 @@ "modloader-mod_order_error": "模组加载器:order.json中发现错误,即 将 使 用 默 认 加 载 顺 序", "modloader-mod_order_missing_from_json": "模组加载器:order.json中缺少模组%s", "modloader-visited": "已访问", - "modloader-x_duplicates_found": "找到一个或者更多的重复模组:%s,一个模组只该加载一个版本", "openzone-unable_to_find_map": "无法为地点:%s添加空间,因为它不存在", "payment-not_enough_money_to_complete_transation": "存档没有足够金钱完成交易,需要{{amountToPay}},拥有{{amountAvailable}}", "payment-not_enough_money_to_complete_transation_short": "没有足够的钱来完成交易", diff --git a/project/src/loaders/PreAkiModLoader.ts b/project/src/loaders/PreAkiModLoader.ts index f0a37bb0..8db771d1 100644 --- a/project/src/loaders/PreAkiModLoader.ts +++ b/project/src/loaders/PreAkiModLoader.ts @@ -32,7 +32,7 @@ export class PreAkiModLoader implements IModLoader protected imported: Record = {}; protected akiConfig: ICoreConfig; protected serverDependencies: Record; - protected skippedMods: string[] = []; + protected skippedMods: Set; constructor( @inject("WinstonLogger") protected logger: ILogger, @@ -50,6 +50,7 @@ export class PreAkiModLoader implements IModLoader const packageJsonPath: string = path.join(__dirname, "../../package.json"); this.serverDependencies = JSON.parse(this.vfs.readFile(packageJsonPath)).dependencies; + this.skippedMods = new Set(); } public async load(container: DependencyContainer): Promise @@ -125,7 +126,10 @@ export class PreAkiModLoader implements IModLoader return; } - let mods: string[] = this.vfs.getDirs(this.basepath); + /** + * array of mod folder names + */ + const mods: string[] = this.vfs.getDirs(this.basepath); this.logger.info(this.localisationService.getText("modloader-loading_mods", mods.length)); @@ -153,18 +157,22 @@ export class PreAkiModLoader implements IModLoader } } + // Validate and remove broken mods from mod list + const validMods = this.getValidMods(mods); + + const modPackageData = this.getModsPackageData(validMods); + this.checkForDuplicateMods(modPackageData); + // Used to check all errors before stopping the load execution let errorsFound = false; - // Validate and remove broken mods from mod list - const brokenMods: string[] = this.getBrokenMods(mods); - mods = mods.filter( ( mod ) => !brokenMods.includes( mod ) ); - - const modPackageData = this.getModsPackageData(mods); - this.checkForDuplicateMods(modPackageData); - for (const modFolderName in modPackageData) + for (const [modFolderName, modToValidate] of modPackageData) { - const modToValidate = modPackageData[modFolderName]; + if (this.shouldSkipMod(modToValidate)) + { + // skip error checking and dependency install for mods already marked as skipped. + continue; + } // 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`)) @@ -199,15 +207,23 @@ export class PreAkiModLoader implements IModLoader // sort mod order const missingFromOrderJSON = {}; - const sortedMods = mods.sort((prev, next) => this.sortMods(prev, next, missingFromOrderJSON)); + validMods.sort((prev, next) => this.sortMods(prev, next, missingFromOrderJSON)); // log the missing mods from order.json Object.keys(missingFromOrderJSON).forEach((missingMod) => (this.logger.debug(this.localisationService.getText("modloader-mod_order_missing_from_json", missingMod)))); // add mods - for (const mod of sortedMods) + for (const mod of validMods) { - await this.addModAsync(mod); + const pkg = modPackageData.get(mod); + + if (this.shouldSkipMod(pkg)) + { + this.logger.warning(this.localisationService.getText("modloader-skipped_mod", { mod: mod })); + continue; + } + + await this.addModAsync(mod, pkg); } this.modLoadOrder.setModList(this.imported); @@ -237,63 +253,64 @@ export class PreAkiModLoader implements IModLoader /** * Check for duplicate mods loaded, show error if any - * @param modPackageData Dictionary of mod package.json data + * @param modPackageData map of mod package.json data */ - protected checkForDuplicateMods(modPackageData: Record): void + protected checkForDuplicateMods(modPackageData: Map): void { - const modNames = []; - for (const modKey in modPackageData) - { - const mod = modPackageData[modKey]; - modNames.push(`${mod.author}-${mod.name}`); - } - const dupes = this.getDuplicates(modNames); - if (dupes?.length > 0) - { - this.logger.error(this.localisationService.getText("modloader-x_duplicates_found", dupes.join(","))); - } - } + const grouppedMods: Map = new Map(); - /** - * Check for and return duplicate strings inside an array - * @param stringArray Array to check for duplicates - * @returns string array of duplicates, empty if none found - */ - protected getDuplicates(stringArray: string[]): string[] - { - return stringArray.filter((s => v => s.has(v) || !s.add(v))(new Set)); - } - - /** - * Get an array of mods with errors that prevent them from working with SPT - * @param mods mods to validate - * @returns Mod names as array - */ - protected getBrokenMods(mods: string[]): string[] - { - const brokenMods: string[] = []; - for (const mod of mods) + for (const mod of modPackageData.values()) { - if (!this.validMod(mod)) + const name = `${mod.author}-${mod.name}`; + grouppedMods.set(name, [...(grouppedMods.get(name) ?? []), mod]); + + // if there's more than one entry for a given mod it means there's at least 2 mods with the same author and name trying to load. + if (grouppedMods.get(name).length > 1 && !this.skippedMods.has(name)) { - brokenMods.push(mod); + this.skippedMods.add(name); } } - return brokenMods; + // at this point this.skippedMods only contains mods that are duplicated, so we can just go through every single entry and log it + for (const modName of this.skippedMods) + { + this.logger.error(this.localisationService.getText("modloader-x_duplicates_found", modName)); + } + } + + /** + * Returns an array of valid mods. + * + * @param mods mods to validate + * @returns array of mod folder names + */ + protected getValidMods(mods: string[]): string[] + { + const validMods: string[] = []; + + for (const mod of mods) + { + if (this.validMod(mod)) + { + validMods.push(mod); + } + } + + return validMods; } /** * Get packageJson data for mods * @param mods mods to get packageJson for - * @returns dictionary + * @returns map */ - protected getModsPackageData(mods: string[]): Record + protected getModsPackageData(mods: string[]): Map { - const loadedMods: Record = {}; + const loadedMods = new Map(); + for (const mod of mods) { - loadedMods[mod] = this.jsonUtil.deserialize(this.vfs.readFile(`${this.getModPath(mod)}/package.json`)); + loadedMods.set(mod, this.jsonUtil.deserialize(this.vfs.readFile(`${this.getModPath(mod)}/package.json`))); } return loadedMods; @@ -414,18 +431,11 @@ export class PreAkiModLoader implements IModLoader * Compile mod and add into class property "imported" * @param mod Name of mod to compile/add */ - protected async addModAsync(mod: string): Promise + protected async addModAsync(mod: string, pkg: IPackageJsonData): Promise { const modPath = this.getModPath(mod); - const packageData = this.jsonUtil.deserialize(this.vfs.readFile(`${modPath}/package.json`)); - if (this.skippedMods.includes(packageData.name)) - { - this.logger.warning(this.localisationService.getText("modloader-skipped_mod", {name: packageData.name, author: packageData.author})); - return; - } - - const isBundleMod = packageData.isBundleMod ?? false; + const isBundleMod = pkg.isBundleMod ?? false; if (isBundleMod) { @@ -444,16 +454,27 @@ 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 - packageData.main = (packageData.main).replace(".js", ".ts"); + pkg.main = (pkg.main).replace(".js", ".ts"); } } // Purge scripts data from package object - packageData.scripts = {}; + pkg.scripts = {}; // Add mod to imported list - this.imported[mod] = {...packageData, dependencies: packageData.modDependencies}; - this.logger.info(this.localisationService.getText("modloader-loaded_mod", {name: packageData.name, version: packageData.version, author: packageData.author})); + 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})); + } + + /** + * Checks if a given mod should be loaded or skipped. + * + * @param pkg mod package.json data + * @returns + */ + protected shouldSkipMod(pkg: IPackageJsonData): boolean + { + return this.skippedMods.has(`${pkg.author}-${pkg.name}`); } protected autoInstallDependencies(modPath: string, pkg: IPackageJsonData): void @@ -492,7 +513,7 @@ export class PreAkiModLoader implements IModLoader configOption: "autoInstallModDependencies" })); - this.skippedMods.push(pkg.name); + this.skippedMods.add(`${pkg.author}-${pkg.name}`); return; } @@ -512,7 +533,7 @@ export class PreAkiModLoader implements IModLoader this.vfs.rename(`${modPath}/package.json.bak`, `${modPath}/package.json`); } - protected areModDependenciesFulfilled(pkg: IPackageJsonData, loadedMods: Record): boolean + protected areModDependenciesFulfilled(pkg: IPackageJsonData, loadedMods: Map): boolean { if (!pkg.modDependencies) { @@ -524,15 +545,15 @@ export class PreAkiModLoader implements IModLoader for (const [modDependency, requiredVersion ] of Object.entries(pkg.modDependencies)) { // Raise dependency version incompatible if the dependency is not found in the mod list - if (!(modDependency in loadedMods)) + if (!loadedMods.has(modDependency)) { this.logger.error(this.localisationService.getText("modloader-missing_dependency", {mod: modName, modDependency: modDependency})); return false; } - if (!semver.satisfies(loadedMods[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[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; } } @@ -540,7 +561,7 @@ export class PreAkiModLoader implements IModLoader return true; } - protected isModCompatible(mod: IPackageJsonData, loadedMods: Record): boolean + protected isModCompatible(mod: IPackageJsonData, loadedMods: Map): boolean { const incompatbileModsList = mod.incompatibilities; if (!incompatbileModsList) @@ -551,7 +572,7 @@ export class PreAkiModLoader implements IModLoader for (const incompatibleModName of incompatbileModsList) { // Raise dependency version incompatible if any incompatible mod is found - if (incompatibleModName in loadedMods) + if (loadedMods.has(incompatibleModName)) { this.logger.error(this.localisationService.getText("modloader-incompatible_mod_found", {author: mod.author, modName: mod.name, incompatibleModName: incompatibleModName})); return false;