From 027519fe9f5560e1122665f7114100f9a05c8d12 Mon Sep 17 00:00:00 2001 From: xiaoxiao921 Date: Sat, 4 May 2024 11:09:17 +0200 Subject: [PATCH 1/3] Add Risk of Rain Returns support via ReturnOfModding --- src/assets/data/games.json | 52 ++++++++++++++++++ .../game_selection/RiskofRainReturns.jpg | Bin 0 -> 37313 bytes src/installers/ReturnOfModdingInstaller.ts | 42 ++++++++++++++ src/installers/registry.ts | 2 + src/model/game/GameManager.ts | 6 ++ src/model/installing/PackageLoader.ts | 2 + src/pages/Manager.vue | 3 + .../PlatformInterceptorImpl.ts | 1 + src/r2mm/data/LogOutput.ts | 4 ++ .../InstallationRuleApplicator.ts | 2 + .../InstallRules_ReturnOfModding.ts | 32 +++++++++++ .../ModLoaderVariantRecord.ts | 2 + .../instructions/GameInstructions.ts | 2 + .../loader/ReturnOfModdingGameInstructions.ts | 15 +++++ src/r2mm/manager/SettingsDexieStore.ts | 2 +- 15 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 src/assets/images/game_selection/RiskofRainReturns.jpg create mode 100644 src/installers/ReturnOfModdingInstaller.ts create mode 100644 src/r2mm/installing/default_installation_rules/game_rules/InstallRules_ReturnOfModding.ts create mode 100644 src/r2mm/launching/instructions/instructions/loader/ReturnOfModdingGameInstructions.ts diff --git a/src/assets/data/games.json b/src/assets/data/games.json index 91c4ec2d0..1861cad34 100644 --- a/src/assets/data/games.json +++ b/src/assets/data/games.json @@ -2340,6 +2340,58 @@ "relativeFileExclusions": [] } }, + "risk-of-rain-returns": { + "label": "risk-of-rain-returns", + "meta": { + "displayName": "Risk of Rain Returns", + "iconUrl": "RiskofRainReturns.jpg" + }, + "distributions": [ + { + "platform": "steam", + "identifier": "1337520" + } + ], + "r2modman": { + "internalFolderName": "RiskofRainReturns", + "dataFolderName": "", + "settingsIdentifier": "RiskofRainReturns", + "packageIndex": "https://thunderstore.io/c/risk-of-rain-returns/api/v1/package/", + "exclusionsUrl": "https://raw.githubusercontent.com/ebkr/r2modmanPlus/master/modExclusions.md", + "steamFolderName": "Risk of Rain Returns", + "exeNames": [ + "Risk of Rain Returns.exe" + ], + "gameInstancetype": "game", + "gameSelectionDisplayMode": "visible", + "modLoaderPackages": [ + { + "packageId": "ReturnOfModding-ReturnOfModding", + "rootFolder": "ReturnOfModdingPack", + "loader": "returnofmodding" + } + ], + "installRules": [ + { + "route": "ReturnOfModding/plugins", + "trackingMethod": "subdir", + "defaultFileExtensions": [ + ".lua" + ], + "isDefaultLocation": true + }, + { + "route": "ReturnOfModding/plugins_data", + "trackingMethod": "subdir" + }, + { + "route": "ReturnOfModding/config", + "trackingMethod": "subdir" + } + ], + "relativeFileExclusions": [] + } + }, "rogue-genesia": { "uuid": "02371030-eb56-4d5d-bed5-fa68446ff6ac", "label": "rogue-genesia", diff --git a/src/assets/images/game_selection/RiskofRainReturns.jpg b/src/assets/images/game_selection/RiskofRainReturns.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f5a309dbed2da5bdf1c58ca4c0d2cd79dde2a501 GIT binary patch literal 37313 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 literal 0 HcmV?d00001 diff --git a/src/installers/ReturnOfModdingInstaller.ts b/src/installers/ReturnOfModdingInstaller.ts new file mode 100644 index 000000000..5d29cd5c5 --- /dev/null +++ b/src/installers/ReturnOfModdingInstaller.ts @@ -0,0 +1,42 @@ +import { InstallArgs, PackageInstaller } from "./PackageInstaller"; +import path from "path"; +import FsProvider from "../providers/generic/file/FsProvider"; +import { MODLOADER_PACKAGES } from "../r2mm/installing/profile_installers/ModLoaderVariantRecord"; +import { PackageLoader } from "../model/installing/PackageLoader"; + +const basePackageFiles = ["manifest.json", "readme.md", "icon.png"]; + +export class ReturnOfModdingInstaller extends PackageInstaller { + /** + * Handles installation of BepInEx + */ + async install(args: InstallArgs) { + const { + mod, + packagePath, + profile, + } = args; + + const mapping = MODLOADER_PACKAGES.find((entry) => + entry.packageName.toLowerCase() == mod.getName().toLowerCase() && + entry.loaderType == PackageLoader.RETURN_OF_MODDING, + ); + const mappingRoot = mapping ? mapping.rootFolder : ""; + + let root: string; + if (mappingRoot.trim().length > 0) { + root = path.join(packagePath, mappingRoot); + } else { + root = path.join(packagePath); + } + for (const item of (await FsProvider.instance.readdir(root))) { + if (!basePackageFiles.includes(item.toLowerCase())) { + if ((await FsProvider.instance.stat(path.join(root, item))).isFile()) { + await FsProvider.instance.copyFile(path.join(root, item), path.join(profile.getPathOfProfile(), item)); + } else { + await FsProvider.instance.copyFolder(path.join(root, item), path.join(profile.getPathOfProfile(), item)); + } + } + } + } +} diff --git a/src/installers/registry.ts b/src/installers/registry.ts index b8cf5dd53..e68d5d3e6 100644 --- a/src/installers/registry.ts +++ b/src/installers/registry.ts @@ -5,6 +5,7 @@ import { PackageInstaller } from "./PackageInstaller"; import { InstallRuleInstaller } from "./InstallRuleInstaller"; import { ShimloaderInstaller, ShimloaderPluginInstaller } from "./ShimloaderInstaller"; import { LovelyInstaller, LovelyPluginInstaller } from "./LovelyInstaller"; +import { ReturnOfModdingInstaller } from "./ReturnOfModdingInstaller"; const _PackageInstallers = { @@ -16,6 +17,7 @@ const _PackageInstallers = { "shimloader-plugin": new ShimloaderPluginInstaller(), "lovely": new LovelyInstaller(), "lovely-plugin": new LovelyPluginInstaller(), + "returnofmodding": new ReturnOfModdingInstaller(), } export type PackageInstallerId = keyof typeof _PackageInstallers; diff --git a/src/model/game/GameManager.ts b/src/model/game/GameManager.ts index ce1464a1a..e0c49e9c1 100644 --- a/src/model/game/GameManager.ts +++ b/src/model/game/GameManager.ts @@ -632,6 +632,12 @@ export default class GameManager { "https://thunderstore.io/c/castle-story/api/v1/package/", EXCLUSIONS, [new StorePlatformMetadata(StorePlatform.STEAM_DIRECT, "227860")], "CastleStory.png", GameSelectionDisplayMode.VISIBLE, GameInstanceType.GAME, PackageLoader.BEPINEX, []), + + new Game("Risk of Rain Returns", "RiskofRainReturns", "RiskofRainReturns", + "Risk of Rain Returns", ["Risk of Rain Returns.exe"], "", + "https://thunderstore.io/c/risk-of-rain-returns/api/v1/package/", EXCLUSIONS, + [new StorePlatformMetadata(StorePlatform.STEAM_DIRECT, "1337520")], "RiskofRainReturns.jpg", + GameSelectionDisplayMode.VISIBLE, GameInstanceType.GAME, PackageLoader.RETURN_OF_MODDING, ["rorr"]), ]; static get activeGame(): Game { diff --git a/src/model/installing/PackageLoader.ts b/src/model/installing/PackageLoader.ts index 338036e74..1cea9309c 100644 --- a/src/model/installing/PackageLoader.ts +++ b/src/model/installing/PackageLoader.ts @@ -9,6 +9,7 @@ export enum PackageLoader { ANCIENT_DUNGEON_VR, SHIMLOADER, LOVELY, + RETURN_OF_MODDING, } export function GetInstallerIdForLoader(loader: PackageLoader): PackageInstallerId | null { @@ -21,6 +22,7 @@ export function GetInstallerIdForLoader(loader: PackageLoader): PackageInstaller case PackageLoader.NORTHSTAR: return "bepinex"; case PackageLoader.SHIMLOADER: return "shimloader"; case PackageLoader.LOVELY: return "lovely"; + case PackageLoader.RETURN_OF_MODDING: return "returnofmodding"; case PackageLoader.ANCIENT_DUNGEON_VR: return null; } } diff --git a/src/pages/Manager.vue b/src/pages/Manager.vue index 04d31e0ee..9ea58328e 100644 --- a/src/pages/Manager.vue +++ b/src/pages/Manager.vue @@ -491,6 +491,9 @@ import CategoryFilterModal from '../components/modals/CategoryFilterModal.vue'; break; case PackageLoader.MELON_LOADER: logOutputPath = path.join(this.profile.getPathOfProfile(), "MelonLoader", "Latest.log"); + break; + case PackageLoader.RETURN_OF_MODDING: + logOutputPath = path.join(this.profile.getPathOfProfile(), "ReturnOfModding", "LogOutput.log"); break; } const text = (await fs.readFile(logOutputPath)).toString(); diff --git a/src/providers/generic/game/platform_interceptor/PlatformInterceptorImpl.ts b/src/providers/generic/game/platform_interceptor/PlatformInterceptorImpl.ts index c965633a5..f85900f39 100644 --- a/src/providers/generic/game/platform_interceptor/PlatformInterceptorImpl.ts +++ b/src/providers/generic/game/platform_interceptor/PlatformInterceptorImpl.ts @@ -65,6 +65,7 @@ function buildRunners(runners: PlatformRunnersType): LoaderRunnersType { [PackageLoader.GODOT_ML]: runners, [PackageLoader.SHIMLOADER]: runners, [PackageLoader.LOVELY]: runners, + [PackageLoader.RETURN_OF_MODDING]: runners, } } diff --git a/src/r2mm/data/LogOutput.ts b/src/r2mm/data/LogOutput.ts index a130c38db..7d580f597 100644 --- a/src/r2mm/data/LogOutput.ts +++ b/src/r2mm/data/LogOutput.ts @@ -38,6 +38,10 @@ export default class LogOutput { fs.exists(path.join(Profile.getActiveProfile().getPathOfProfile(), 'BepInEx', 'LogOutput.log')) .then(value => this._exists = value); break; + case PackageLoader.RETURN_OF_MODDING: + fs.exists(path.join(Profile.getActiveProfile().getPathOfProfile(), 'ReturnOfModding', 'LogOutput.log')) + .then(value => this._exists = value); + break; case PackageLoader.MELON_LOADER: case PackageLoader.NORTHSTAR: fs.exists(path.join(Profile.getActiveProfile().getPathOfProfile(), 'MelonLoader', 'Latest.log')) diff --git a/src/r2mm/installing/default_installation_rules/InstallationRuleApplicator.ts b/src/r2mm/installing/default_installation_rules/InstallationRuleApplicator.ts index 2e4c0fab2..7c7fb1e21 100644 --- a/src/r2mm/installing/default_installation_rules/InstallationRuleApplicator.ts +++ b/src/r2mm/installing/default_installation_rules/InstallationRuleApplicator.ts @@ -19,6 +19,7 @@ import { import { buildMelonLoaderRules } from "../default_installation_rules/game_rules/InstallRules_MelonLoader"; +import { buildReturnOfModdingRules } from './game_rules/InstallRules_ReturnOfModding'; export default class InstallationRuleApplicator { @@ -126,6 +127,7 @@ export default class InstallationRuleApplicator { buildBepInExRules("AgainstTheStorm"), buildBepInExRules("Lycans"), buildBepInExRules("CastleStory"), + buildReturnOfModdingRules("RiskofRainReturns"), ] } } diff --git a/src/r2mm/installing/default_installation_rules/game_rules/InstallRules_ReturnOfModding.ts b/src/r2mm/installing/default_installation_rules/game_rules/InstallRules_ReturnOfModding.ts new file mode 100644 index 000000000..6f015a639 --- /dev/null +++ b/src/r2mm/installing/default_installation_rules/game_rules/InstallRules_ReturnOfModding.ts @@ -0,0 +1,32 @@ +import type { CoreRuleType } from '../../InstallationRules'; +import * as path from 'path'; +import { GAME_NAME } from '../../profile_installers/ModLoaderVariantRecord'; +import { RuleSubtype } from "../../InstallationRules"; + +export function buildReturnOfModdingRules(gameName: GAME_NAME, extraRules?: RuleSubtype[]): CoreRuleType { + return { + gameName: gameName, + rules: [ + { + route: path.join("ReturnOfModding", "plugins"), + isDefaultLocation: true, + defaultFileExtensions: [".lua"], + trackingMethod: "SUBDIR", + subRoutes: [] + }, + { + route: path.join("ReturnOfModding", "plugins_data"), + defaultFileExtensions: [], + trackingMethod: "SUBDIR", + subRoutes: [] + }, + { + route: path.join("ReturnOfModding", "config"), + defaultFileExtensions: [], + trackingMethod: "SUBDIR", + subRoutes: [] + }, + ...(extraRules ? extraRules : []), + ], + } +} diff --git a/src/r2mm/installing/profile_installers/ModLoaderVariantRecord.ts b/src/r2mm/installing/profile_installers/ModLoaderVariantRecord.ts index e635c2aec..3b47e9d3a 100644 --- a/src/r2mm/installing/profile_installers/ModLoaderVariantRecord.ts +++ b/src/r2mm/installing/profile_installers/ModLoaderVariantRecord.ts @@ -68,6 +68,7 @@ export const MODLOADER_PACKAGES = [ new ModLoaderPackageMapping("0xFFF7-votv_shimloader", "", PackageLoader.SHIMLOADER), new ModLoaderPackageMapping("Thunderstore-unreal_shimloader", "", PackageLoader.SHIMLOADER), new ModLoaderPackageMapping("Thunderstore-lovely", "", PackageLoader.LOVELY), + new ModLoaderPackageMapping("ReturnOfModding-ReturnOfModding", "ReturnOfModdingPack", PackageLoader.RETURN_OF_MODDING), ]; @@ -172,6 +173,7 @@ const VARIANTS = { AgainstTheStorm: MODLOADER_PACKAGES, Lycans: MODLOADER_PACKAGES, CastleStory: MODLOADER_PACKAGES, + RiskofRainReturns: MODLOADER_PACKAGES, }; // Exported separately from the definition in order to preserve the key names in the type definition. // Otherwise this would become [key: string] and we couldn't use the game names for type hinting elsewhere. diff --git a/src/r2mm/launching/instructions/GameInstructions.ts b/src/r2mm/launching/instructions/GameInstructions.ts index 37368db03..43b7ae233 100644 --- a/src/r2mm/launching/instructions/GameInstructions.ts +++ b/src/r2mm/launching/instructions/GameInstructions.ts @@ -9,6 +9,7 @@ import { GodotMLGameInstructions } from "../../launching/instructions/instructio import { AncientVRGameInstructions } from "../../launching/instructions/instructions/loader/AncientVRGameInstructions"; import ShimloaderGameInstructions from './instructions/loader/ShimloaderGameInstructions'; import LovelyGameInstructions from './instructions/loader/LovelyGameInstructions'; +import ReturnOfModdingGameInstructions from './instructions/loader/ReturnOfModdingGameInstructions'; export interface GameInstruction { moddedParameters: string, @@ -26,6 +27,7 @@ export default class GameInstructions { [PackageLoader.ANCIENT_DUNGEON_VR, new AncientVRGameInstructions()], [PackageLoader.SHIMLOADER, new ShimloaderGameInstructions()], [PackageLoader.LOVELY, new LovelyGameInstructions()], + [PackageLoader.RETURN_OF_MODDING, new ReturnOfModdingGameInstructions()], ]); public static async getInstructionsForGame(game: Game, profile: Profile): Promise { diff --git a/src/r2mm/launching/instructions/instructions/loader/ReturnOfModdingGameInstructions.ts b/src/r2mm/launching/instructions/instructions/loader/ReturnOfModdingGameInstructions.ts new file mode 100644 index 000000000..49f82f44f --- /dev/null +++ b/src/r2mm/launching/instructions/instructions/loader/ReturnOfModdingGameInstructions.ts @@ -0,0 +1,15 @@ +import GameInstructionGenerator from '../GameInstructionGenerator'; +import { GameInstruction } from '../../GameInstructions'; +import Game from '../../../../../model/game/Game'; +import Profile from '../../../../../model/Profile'; +import * as path from 'path'; + +export default class ReturnOfModdingGameInstructions extends GameInstructionGenerator { + + public async generate(game: Game, profile: Profile): Promise { + return { + moddedParameters: `--rom_modding_root_folder "${profile.getPathOfProfile()}"`, + vanillaParameters: "--rom_enabled false" + }; + } +} diff --git a/src/r2mm/manager/SettingsDexieStore.ts b/src/r2mm/manager/SettingsDexieStore.ts index 819c36216..20f75af81 100644 --- a/src/r2mm/manager/SettingsDexieStore.ts +++ b/src/r2mm/manager/SettingsDexieStore.ts @@ -34,7 +34,7 @@ export default class SettingsDexieStore extends Dexie { // Add all games to store. Borked v2-3 locally // Increment per game or change to settings. - this.version(71).stores(store); + this.version(72).stores(store); this.activeGame = game; this.global = this.table("value"); From e9cc464b87ad754834dc21c4c69a54509dce94c7 Mon Sep 17 00:00:00 2001 From: xiaoxiao921 <837334+xiaoxiao921@users.noreply.github.com> Date: Wed, 15 May 2024 22:12:21 +0200 Subject: [PATCH 2/3] . --- src/model/game/GameManager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/model/game/GameManager.ts b/src/model/game/GameManager.ts index e0c49e9c1..25274c31c 100644 --- a/src/model/game/GameManager.ts +++ b/src/model/game/GameManager.ts @@ -636,7 +636,7 @@ export default class GameManager { new Game("Risk of Rain Returns", "RiskofRainReturns", "RiskofRainReturns", "Risk of Rain Returns", ["Risk of Rain Returns.exe"], "", "https://thunderstore.io/c/risk-of-rain-returns/api/v1/package/", EXCLUSIONS, - [new StorePlatformMetadata(StorePlatform.STEAM_DIRECT, "1337520")], "RiskofRainReturns.jpg", + [new StorePlatformMetadata(StorePlatform.STEAM, "1337520")], "RiskofRainReturns.jpg", GameSelectionDisplayMode.VISIBLE, GameInstanceType.GAME, PackageLoader.RETURN_OF_MODDING, ["rorr"]), ]; From 379152d26c25f27ac628bbe093952d948411d147 Mon Sep 17 00:00:00 2001 From: xiaoxiao921 <837334+xiaoxiao921@users.noreply.github.com> Date: Thu, 16 May 2024 09:48:40 +0200 Subject: [PATCH 3/3] fix returnofmodding copied to game folder/not properly ignored --- src/r2mm/manager/ModLinker.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/r2mm/manager/ModLinker.ts b/src/r2mm/manager/ModLinker.ts index bb3584a5e..a70a31856 100644 --- a/src/r2mm/manager/ModLinker.ts +++ b/src/r2mm/manager/ModLinker.ts @@ -127,7 +127,8 @@ export default class ModLinker { const exclusionsList = [ "bepinex", "bepinex_server", "mods", "melonloader", "plugins", "userdata", - "_state", "userlibs", "qmods", "shimloader" + "_state", "userlibs", "qmods", "shimloader", + "returnofmodding" ]; if (!exclusionsList.includes(file.toLowerCase())) {