diff --git a/packages/core/src/files.android.ts b/packages/core/src/files.android.ts index ed87ab7..40f55b4 100644 --- a/packages/core/src/files.android.ts +++ b/packages/core/src/files.android.ts @@ -3,7 +3,10 @@ import { Config } from './config'; export { isReadable, readFile, loadText } from './files.browser'; -export async function getModDirectoriesIn(dir: string, config: Config): Promise { +export async function getModPathsIn( + dir: string, + config: Config, +): Promise<{ modDirectories: string[]; ccmods: string[] }> { if (dir === `${config.gameAssetsDir}mods/`) { try { let modsDirEntries = JSON.parse(CrossAndroidModListProvider.getModListAsJson()) as string[]; @@ -13,12 +16,12 @@ export async function getModDirectoriesIn(dir: string, config: Config): Promise< modSubdirs.push(`${dir}/${modDirName.slice(0, -1)}`); } } - return modSubdirs; + return { modDirectories: modSubdirs, ccmods: [] }; } catch (err) { console.error('Failed to get the list of mods from CrossAndroid:', err); } } - return filesBrowser.getModDirectoriesIn(dir, config); + return filesBrowser.getModPathsIn(dir, config); } export async function getInstalledExtensions(config: Config): Promise { diff --git a/packages/core/src/files.browser.ts b/packages/core/src/files.browser.ts index 71cc1be..371e594 100644 --- a/packages/core/src/files.browser.ts +++ b/packages/core/src/files.browser.ts @@ -32,7 +32,10 @@ export async function isReadable(path: string): Promise { } } -export async function getModDirectoriesIn(dir: string, _config: Config): Promise { +export async function getModPathsIn( + dir: string, + _config: Config, +): Promise<{ modDirectories: string[]; ccmods: string[] }> { if (dir.endsWith('/')) dir = dir.slice(0, -1); let indexPath = `${dir}/index.json`; @@ -48,7 +51,18 @@ export async function getModDirectoriesIn(dir: string, _config: Config): Promise throw err; } - return index.map((modDirPath) => paths.join(dir, paths.jailRelative(modDirPath))); + const modPaths = index.map((modDirPath) => paths.join(dir, paths.jailRelative(modDirPath))); + const modDirectories: string[] = []; + const ccmods: string[] = []; + for (const path of modPaths) { + if (path.endsWith('.ccmod')) { + ccmods.push(path); + } else { + modDirectories.push(path); + } + } + + return { modDirectories, ccmods }; } // Replicates the behavior of `ig.ExtensionList#loadExtensionsPHP`. diff --git a/packages/core/src/files.ccmod.ts b/packages/core/src/files.ccmod.ts index a7e7b98..f3d5973 100644 --- a/packages/core/src/files.ccmod.ts +++ b/packages/core/src/files.ccmod.ts @@ -54,13 +54,10 @@ export async function findRecursively(dir: string): Promise { return dirs; } -export async function loadCCMods( - allModsList: Array<{ parentDir: string; dir: string }>, -): Promise { - const ccmods: typeof allModsList = allModsList.filter((mod) => mod.dir.endsWith('.ccmod')); +export async function loadCCMods(ccmods: string[]): Promise { const ccmodArrayBuffers = await Promise.all( - ccmods.map(async (mod) => { - const url = `./${mod.dir}`; + ccmods.map(async (modDir) => { + const url = `./${modDir}`; return new Uint8Array(await files.readFile(url)); }), ); @@ -70,13 +67,10 @@ export async function loadCCMods( // console.timeEnd('uncompress'); for (let i = 0; i < ccmods.length; i++) { - const mod = ccmods[i]; + const modDir = ccmods[i]; const buf = uncompressed[i]; - fileMap.set(mod.dir, buf); + fileMap.set(modDir, buf); } - addFetchHandler( - ccmods.map((mod) => mod.dir), - readFile, - ); + addFetchHandler(ccmods, readFile); } diff --git a/packages/core/src/files.desktop.ts b/packages/core/src/files.desktop.ts index 5ff1e08..dea0c1a 100644 --- a/packages/core/src/files.desktop.ts +++ b/packages/core/src/files.desktop.ts @@ -54,7 +54,10 @@ async function findRecursivelyInternal( ); } -export async function getModDirectoriesIn(dir: string, _config: Config): Promise { +export async function getModPathsIn( + dir: string, + _config: Config, +): Promise<{ modDirectories: string[]; ccmods: string[] }> { if (dir.endsWith('/')) dir = dir.slice(0, -1); let allContents: string[]; @@ -68,18 +71,21 @@ export async function getModDirectoriesIn(dir: string, _config: Config): Promise throw err; } - let modDirectories: string[] = []; + const modDirectories: string[] = []; + const ccmods: string[] = []; await Promise.all( allContents.map(async (name) => { let fullPath = `${dir}/${name}`; // the `withFileTypes` option of `readdir` can't be used here because it // doesn't dereference symbolic links similarly to `stat` let stat = await fs.promises.stat(fullPath); - if (stat.isDirectory() || (stat.isFile() && name.endsWith('.ccmod'))) - modDirectories.push(fullPath); + if (stat.isDirectory()) modDirectories.push(fullPath); + else if (stat.isFile() && name.endsWith('.ccmod')) { + ccmods.push(fullPath); + } }), ); - return modDirectories; + return { modDirectories, ccmods }; } // Replicates the behavior of `ig.ExtensionList#loadExtensionsNWJS`. diff --git a/packages/core/src/files.ts b/packages/core/src/files.ts index 7642dbc..56d850e 100644 --- a/packages/core/src/files.ts +++ b/packages/core/src/files.ts @@ -11,7 +11,7 @@ const modules = { }; const currentModule = modules[utils.PLATFORM_TYPE]; -export const { getModDirectoriesIn, getInstalledExtensions } = currentModule; +export const { getModPathsIn, getInstalledExtensions } = currentModule; export async function isReadable(path: string): Promise { return (await filesCCMod.isReadable(path)) || currentModule.isReadable(path); diff --git a/packages/core/src/modloader.ts b/packages/core/src/modloader.ts index 58fc1b4..e5aa1b9 100644 --- a/packages/core/src/modloader.ts +++ b/packages/core/src/modloader.ts @@ -195,20 +195,24 @@ async function loadModloaderMetadata(): Promise<{ version: semver.SemVer }> { async function loadAllModMetadata(config: configM.Config, installedMods: ModsMap): Promise { let allModsList: Array<{ parentDir: string; dir: string }> = []; + let ccmodPaths: string[] = []; + for (let dir of config.modsDirs) { let subdirsList: string[]; + let ccmods: string[]; try { - subdirsList = await files.getModDirectoriesIn(dir, config); + ({ modDirectories: subdirsList, ccmods } = await files.getModPathsIn(dir, config)); } catch (err) { console.warn(`Failed to load the list of mods in '${dir}':`, err); continue; } - for (let subdir of subdirsList) { + for (let subdir of [...subdirsList, ...ccmods]) { allModsList.push({ parentDir: dir, dir: subdir }); } + ccmodPaths.push(...ccmods); } - await loadCCMods(allModsList); + await loadCCMods(ccmodPaths); let modsCountPerDir = new Map(); await Promise.all( diff --git a/packages/core/src/service-worker-bridge.ts b/packages/core/src/service-worker-bridge.ts index 29c5f13..7a9b477 100644 --- a/packages/core/src/service-worker-bridge.ts +++ b/packages/core/src/service-worker-bridge.ts @@ -46,7 +46,7 @@ export function addFetchHandler(pathPrefixes: string[], handler: FetchHandler): export interface ServiceWorkerPacket { path: string; - data: ArrayBufferLike | null; + data: BodyInit | null; } function setMessageHandling(): void {