diff --git a/src/r2mm/installing/LocalModInstaller.ts b/src/r2mm/installing/LocalModInstaller.ts index ad3f09d08..8805cf6ac 100644 --- a/src/r2mm/installing/LocalModInstaller.ts +++ b/src/r2mm/installing/LocalModInstaller.ts @@ -28,7 +28,7 @@ export default class LocalModInstaller extends LocalModInstallerProvider { * be used in troubleshooting, telling us that the version of the mod isn't * necessarily the same that's available via Thunderstore API. */ - private async writeManifestToCache(cacheDirectory: string, manifest: ManifestV2) { + private async writeCustomManifestToCache(cacheDirectory: string, manifest: ManifestV2) { const manifestPath: string = path.join(cacheDirectory, 'mm_v2_manifest.json'); if (await FsProvider.instance.exists(manifestPath)) { @@ -42,10 +42,33 @@ export default class LocalModInstaller extends LocalModInstallerProvider { await FsProvider.instance.writeFile(manifestPath, JSON.stringify(manifest)); } + /** + * Write Thunderstore compatible manifest.json to cache if one wasn't provided + * with the upload. This is done to have consistency between all installed + * mods, regardless of how they were installed. Having the manifest present + * allows e.g. other mods to sniff out what other mods are installed. + */ + private async writeManifestToCache(cacheDirectory: string, manifest: ManifestV2) { + const manifestPath: string = path.join(cacheDirectory, 'manifest.json'); + + if (!(await FsProvider.instance.exists(manifestPath))) { + const content = { + 'name': manifest.getDisplayName(), // getName() returns "author-modname" here + 'description': manifest.getDescription(), + 'version_number': manifest.getVersionNumber().toString(), + 'dependencies': manifest.getDependencies(), + 'website_url': '' + }; + + await FsProvider.instance.writeFile(manifestPath, JSON.stringify(content, null, 4)); + } + } + public async extractToCacheWithManifestData(profile: ImmutableProfile, zipFile: string, manifest: ManifestV2) { const cacheDirectory: string = await this.initialiseCacheDirectory(manifest); await ZipExtract.extractOnly(zipFile, cacheDirectory); await this.writeManifestToCache(cacheDirectory, manifest); + await this.writeCustomManifestToCache(cacheDirectory, manifest); await ProfileInstallerProvider.instance.uninstallMod(manifest, profile); throwForR2Error(await ProfileInstallerProvider.instance.installMod(manifest, profile)); throwForR2Error(await ProfileModList.addMod(manifest, profile)); @@ -57,6 +80,7 @@ export default class LocalModInstaller extends LocalModInstallerProvider { const fileSafe = file.split("\\").join("/"); await FsProvider.instance.copyFile(fileSafe, path.join(cacheDirectory, path.basename(fileSafe))); await this.writeManifestToCache(cacheDirectory, manifest); + await this.writeCustomManifestToCache(cacheDirectory, manifest); } catch (e) { throw R2Error.fromThrownValue(e, "Error moving file to cache"); }