Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Risk of Rain Returns support via ReturnOfModding #1318

Merged
merged 5 commits into from
Jun 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions src/assets/data/games.json
Original file line number Diff line number Diff line change
Expand Up @@ -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://github.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",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 42 additions & 0 deletions src/installers/ReturnOfModdingInstaller.ts
Original file line number Diff line number Diff line change
@@ -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));
}
}
}
}
}
2 changes: 2 additions & 0 deletions src/installers/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { PackageInstaller } from './PackageInstaller';
import { ShimloaderInstaller, ShimloaderPluginInstaller } from './ShimloaderInstaller';
import { LovelyInstaller, LovelyPluginInstaller } from './LovelyInstaller';
import { NorthstarInstaller } from './NorthstarInstaller';
import { ReturnOfModdingInstaller } from './ReturnOfModdingInstaller';


const _PackageInstallers = {
Expand All @@ -17,6 +18,7 @@ const _PackageInstallers = {
"shimloader-plugin": new ShimloaderPluginInstaller(),
"lovely": new LovelyInstaller(),
"lovely-plugin": new LovelyPluginInstaller(),
"returnofmodding": new ReturnOfModdingInstaller(),
}

export type PackageInstallerId = keyof typeof _PackageInstallers;
Expand Down
8 changes: 7 additions & 1 deletion src/model/game/GameManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -632,13 +632,19 @@ 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, ["cs"]),

new Game(
"Panicore", "Panicore", "Panicore",
"Panicore", ["Panicore.exe"], "Panicore",
"https://thunderstore.io/c/panicore/api/v1/package/", EXCLUSIONS,
[new StorePlatformMetadata(StorePlatform.STEAM, "2695940")], "Panicore.png",
GameSelectionDisplayMode.VISIBLE, GameInstanceType.GAME, PackageLoader.SHIMLOADER, ["panicore"]),

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, "1337520")], "RiskofRainReturns.jpg",
GameSelectionDisplayMode.VISIBLE, GameInstanceType.GAME, PackageLoader.RETURN_OF_MODDING, ["rorr"]),
];

static get activeGame(): Game {
Expand Down
2 changes: 2 additions & 0 deletions src/model/installing/PackageLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export enum PackageLoader {
ANCIENT_DUNGEON_VR,
SHIMLOADER,
LOVELY,
RETURN_OF_MODDING,
}

export function GetInstallerIdForLoader(loader: PackageLoader): PackageInstallerId | null {
Expand All @@ -20,6 +21,7 @@ export function GetInstallerIdForLoader(loader: PackageLoader): PackageInstaller
case PackageLoader.NORTHSTAR: return "northstar";
case PackageLoader.SHIMLOADER: return "shimloader";
case PackageLoader.LOVELY: return "lovely";
case PackageLoader.RETURN_OF_MODDING: return "returnofmodding";
case PackageLoader.ANCIENT_DUNGEON_VR: return null;
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/pages/Manager.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ function buildRunners(runners: PlatformRunnersType): LoaderRunnersType {
[PackageLoader.GODOT_ML]: runners,
[PackageLoader.SHIMLOADER]: runners,
[PackageLoader.LOVELY]: runners,
[PackageLoader.RETURN_OF_MODDING]: runners,
}
}

Expand Down
4 changes: 4 additions & 0 deletions src/r2mm/data/LogOutput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand Down Expand Up @@ -126,6 +127,7 @@ export default class InstallationRuleApplicator {
buildBepInExRules("AgainstTheStorm"),
buildBepInExRules("Lycans"),
buildBepInExRules("CastleStory"),
buildReturnOfModdingRules("RiskofRainReturns"),
]
}
}
Original file line number Diff line number Diff line change
@@ -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 : []),
],
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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),
];


Expand Down Expand Up @@ -173,6 +174,7 @@ const VARIANTS = {
Lycans: MODLOADER_PACKAGES,
CastleStory: MODLOADER_PACKAGES,
Panicore: 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.
Expand Down
2 changes: 2 additions & 0 deletions src/r2mm/launching/instructions/GameInstructions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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<GameInstruction> {
Expand Down
Original file line number Diff line number Diff line change
@@ -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<GameInstruction> {
return {
moddedParameters: `--rom_modding_root_folder "${profile.getPathOfProfile()}"`,
vanillaParameters: "--rom_enabled false"
};
}
}
3 changes: 2 additions & 1 deletion src/r2mm/manager/ModLinker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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())) {
Expand Down