From 92b8d02ce361b0daf1f740de69ca96d501d8e0ad Mon Sep 17 00:00:00 2001 From: Cade Ayres Date: Tue, 20 Jan 2026 21:39:15 +0000 Subject: [PATCH 1/5] Fixed ManagerUpdateBanner version check --- src/components/banner/ManagerUpdateBanner.vue | 26 +++++-------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/src/components/banner/ManagerUpdateBanner.vue b/src/components/banner/ManagerUpdateBanner.vue index 6848fb2c7..93775ab23 100644 --- a/src/components/banner/ManagerUpdateBanner.vue +++ b/src/components/banner/ManagerUpdateBanner.vue @@ -15,27 +15,13 @@ async function isManagerUpdateAvailable() { return fetch('https://api.github.com/repos/ebkr/r2modmanPlus/releases') .then(response => response.json()) .then((parsed: any) => { - parsed.sort((a: any, b: any) => { - if (b !== null) { - const versionA = new VersionNumber(a.name); - const versionB = new VersionNumber(b.name); - return versionA.isNewerThan(versionB); + portableUpdateAvailable.value = parsed.find((release: any) => { + if (release.draft) { + return false; } - return 1; - }); - let foundMatch = false; - parsed.forEach((release: any) => { - if (!foundMatch && !release.draft) { - const releaseVersion = new VersionNumber(release.name); - if (releaseVersion.isNewerThan(ManagerInformation.VERSION)) { - portableUpdateAvailable.value = true; - updateTagName.value = release.tag_name; - foundMatch = true; - return; - } - } - }); - portableUpdateAvailable.value = true; + const releaseVersion = new VersionNumber(release.name); + return releaseVersion.isNewerThan(ManagerInformation.VERSION); + }) !== undefined; }).catch(err => { // Do nothing, potentially offline. Try next launch. }); From f4f8d0ecbb4188351ee2e5f71c54a85e20e25ff8 Mon Sep 17 00:00:00 2001 From: Cade Ayres Date: Wed, 21 Jan 2026 08:12:58 +0000 Subject: [PATCH 2/5] Re-added WINEDLLOVERRIDES automated application --- .../runners/linux/SteamGameRunner_Linux.ts | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/src/r2mm/launching/runners/linux/SteamGameRunner_Linux.ts b/src/r2mm/launching/runners/linux/SteamGameRunner_Linux.ts index eae851fb8..08ad22abf 100644 --- a/src/r2mm/launching/runners/linux/SteamGameRunner_Linux.ts +++ b/src/r2mm/launching/runners/linux/SteamGameRunner_Linux.ts @@ -1,5 +1,6 @@ import FsProvider from '../../../../providers/generic/file/FsProvider'; import path from '../../../../providers/node/path/path'; +import LinuxGameDirectoryResolver from '../../../manager/linux/GameDirectoryResolver'; import GameRunnerProvider from '../../../../providers/generic/game/GameRunnerProvider'; import Game from '../../../../model/game/Game'; import R2Error from '../../../../model/errors/R2Error'; @@ -33,6 +34,10 @@ export default class SteamGameRunner_Linux extends GameRunnerProvider { if (isProton) { // BepInEx uses winhttp, GDWeave uses winmm. More can be added later. const proxyDll = game.packageLoader == PackageLoader.GDWEAVE ? "winmm" : "winhttp"; + const promise = await this.ensureWineWillLoadDllOverride(game, proxyDll); + if (promise instanceof R2Error) { + return promise; + } proxyArgs['WINEDLLOVERRIDES'] = `"${proxyDll}=n,b"` } else { // If sh files aren't executable then the wrapper will fail. @@ -132,6 +137,67 @@ export default class SteamGameRunner_Linux extends GameRunnerProvider { LoggerProvider.instance.Log(LogSeverity.ERROR, (err as Error).message); throw new R2Error('Error starting Steam', (err as Error).message, 'Ensure that the Steam folder has been set correctly in the settings'); } + } + + private async ensureWineWillLoadDllOverride(game: Game, proxyDll: string): Promise{ + const fs = FsProvider.instance; + const compatDataDir = await (GameDirectoryResolverProvider.instance as LinuxGameDirectoryResolver).getCompatDataDirectory(game); + if(compatDataDir instanceof R2Error) + return compatDataDir; + const userReg = path.join(compatDataDir, 'pfx', 'user.reg'); + const userRegData = (await fs.readFile(userReg)).toString(); + const ensuredUserRegData = this.regAddInSection( + userRegData, + "[Software\\\\Wine\\\\DllOverrides]", + proxyDll, + "native,builtin" + ); + + if(userRegData !== ensuredUserRegData){ + await fs.copyFile(userReg, path.join(path.dirname(userReg), 'user.reg.bak')); + await fs.writeFile(userReg, ensuredUserRegData); + } + } + + private regAddInSection(reg: string, section: string, key: string, value: string): string { + /* + Example section + [header] // our section variable + #time=... // timestamp + "key"="value" + + It's ended with two newlines (/n/n) + */ + let split = reg.split("\n"); + + let begin = 0; + // Get section begin + for (let index = 0; index < split.length; index++) { + if (split[index]!.startsWith(section)) { + begin = index + 2; // We need to skip the timestamp line + break; + } + } + + // Get end + let end = 0; + for (let index = begin; index < split.length; index++) { + if (split[index]!.length == 0) { + end = index; + break; + } + } + + // Check for key and fix it eventually, then return + for (let index = begin; index < end; index++) { + if (split[index]!.startsWith(`"${key}"`)) { + split[index] = `"${key}"="${value}"`; + return split.join("\n"); + } + } + // Append key and return + split.splice(end, 0, `"${key}"="${value}"`); + return split.join("\n"); } } From 6cbb6241de1dd3af9192d1daee1338d80ab06f0a Mon Sep 17 00:00:00 2001 From: Alex Neargarder Date: Wed, 21 Jan 2026 05:40:33 -0500 Subject: [PATCH 3/5] Fix help menu giving comma separated args --- src/pages/Help.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Help.vue b/src/pages/Help.vue index 905ddca46..572a39eb2 100644 --- a/src/pages/Help.vue +++ b/src/pages/Help.vue @@ -159,7 +159,7 @@ onMounted(() => { doorstopTarget.value = ""; return; } else { - doorstopTarget.value = target; + doorstopTarget.value = target.map(value => `"${value}"`).join(' '); } }); }); From 43736bcab3ed49e93dacb82980f4562c8d3a2c1d Mon Sep 17 00:00:00 2001 From: Cade Ayres Date: Wed, 21 Jan 2026 17:21:21 +0000 Subject: [PATCH 4/5] Updated CHANGELOG and versions --- CHANGELOG.md | 22 ++++++++++++++-------- package.json | 2 +- src/_managerinf/ManagerInformation.ts | 2 +- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e5889a8c..1474b54a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +### 3.2.13 +#### Fixes +- Linux behaviour used to automatically set WINEDLLOVERRIDES. This has been restored for now. +- Launch argument display fixed in the Help section (Thanks to @alexneargarder). + ### 3.2.12 #### Games added - KeyWe @@ -16,21 +21,22 @@ - RV There Yet - Crab Game - Cloverpit - - Xbox Game Pass PC support + - Xbox Game Pass PC support #### Performance - Mods.yml file size has been reduced by 99.35% - - This results in huge improvements to the performance of profiles - - You'll need to perform a changing action on the profile for it to take effect. This can be: - - Mod re-ordering - - Install/Uninstall/Enable/Disable + - This results in huge improvements to the performance of profiles + - You'll need to perform a changing action on the profile for it to take effect. This can be: + - Mod re-ordering + - Install/Uninstall/Enable/Disable + - Once done, accessing the profiles screen should be near instant - Local mod list is loaded asynchronously and is visible far quicker than before - - Significantly reduces time spent hanging waiting for the mod list to load + - Significantly reduces time spent hanging waiting for the mod list to load #### Design changes - Mod card buttons have been made consistent and no longer take up the entire space - - Easier to visually scan - - Less mouse movement required + - Easier to visually scan + - Less mouse movement required - The online preview panel now has a different background colour - Scrollbars are now app-styled rather than native - Other tweaks to improve the user experience diff --git a/package.json b/package.json index f21277f15..7f700c21e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "r2modman", - "version": "3.2.12", + "version": "3.2.13", "description": "A simple and easy to use mod manager for many games using Thunderstore.", "productName": "r2modman", "author": "ebkr", diff --git a/src/_managerinf/ManagerInformation.ts b/src/_managerinf/ManagerInformation.ts index d3a96af07..b87fe722d 100644 --- a/src/_managerinf/ManagerInformation.ts +++ b/src/_managerinf/ManagerInformation.ts @@ -1,7 +1,7 @@ import VersionNumber from '../model/VersionNumber'; export default class ManagerInformation { - public static VERSION: VersionNumber = new VersionNumber('3.2.12'); + public static VERSION: VersionNumber = new VersionNumber('3.2.13'); public static IS_PORTABLE: boolean = false; public static APP_NAME: string = "r2modman"; } From 42bb4be8905d6cd88eed05e1ff11395c9c2852ed Mon Sep 17 00:00:00 2001 From: Cade Ayres Date: Wed, 21 Jan 2026 17:24:41 +0000 Subject: [PATCH 5/5] Switched return error to a console.error --- src/r2mm/launching/runners/linux/SteamGameRunner_Linux.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/r2mm/launching/runners/linux/SteamGameRunner_Linux.ts b/src/r2mm/launching/runners/linux/SteamGameRunner_Linux.ts index 08ad22abf..996b4a851 100644 --- a/src/r2mm/launching/runners/linux/SteamGameRunner_Linux.ts +++ b/src/r2mm/launching/runners/linux/SteamGameRunner_Linux.ts @@ -36,7 +36,9 @@ export default class SteamGameRunner_Linux extends GameRunnerProvider { const proxyDll = game.packageLoader == PackageLoader.GDWEAVE ? "winmm" : "winhttp"; const promise = await this.ensureWineWillLoadDllOverride(game, proxyDll); if (promise instanceof R2Error) { - return promise; + // We no longer want to display an error as launch args should be set correctly. + // A console error still allows it to be discoverable. + console.error(promise); } proxyArgs['WINEDLLOVERRIDES'] = `"${proxyDll}=n,b"` } else {