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

Bugfix 1.13 beta.4 #16601

Merged
merged 7 commits into from
Oct 22, 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
3 changes: 1 addition & 2 deletions src/app/Application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ class Application {
this.mArgs = args;

ipcMain.on('show-window', () => this.showMainWindow(args?.startMinimized));

process.env['UV_THREADPOOL_SIZE'] = (os.cpus().length * 1.5).toString();
app.commandLine.appendSwitch('js-flags', `--max-old-space-size=${args.maxMemory || 4096}`);

Expand Down Expand Up @@ -1079,7 +1078,7 @@ class Application {
message: 'Your Vortex installation has been corrupted. '
+ 'This could be the result of a virus or manual manipulation. '
+ 'Vortex might still appear to work (partially) but we suggest '
+ 'you reinstall it.',
+ 'you reinstall it. For more information please refer to Vortex\'s log files.',
noLink: true,
buttons: ['Quit', 'Ignore'],
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ async function setDownloadGames(
// game may be undefined if the download is recognized but it's for a
// game Vortex doesn't support
api.sendNotification({
id: 'download-moved' + (game?.name ?? gameIds[0]),
type: 'success',
title: 'Download moved to game {{gameName}}',
message: download.localPath,
Expand Down
4 changes: 3 additions & 1 deletion src/extensions/ini_prep/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable */
import {IExtensionApi, IExtensionContext} from '../../types/IExtensionContext';
import { IProfile, IState } from '../../types/IState';
import { ITestResult } from '../../types/ITestResult';
Expand Down Expand Up @@ -175,8 +176,9 @@ function bakeSettings(t: TFunction,
setdefault(enabledTweaks, getBaseFile(file), [])
.push(path.join(tweaksPath, file));
});
return Promise.resolve();
})
.catch(err => undefined);
.catch(err => Promise.resolve(undefined));
}).then(() => Promise.mapSeries(baseFiles, iniFileName => {
// starting with the .base file for each ini, re-bake the file by applying
// the ini tweaks
Expand Down
6 changes: 5 additions & 1 deletion src/extensions/mod_management/util/testModReference.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export function safeCoerce(input: string): string {
}

export function coerceToSemver(version: string): string {
version = version?.trim?.();
if (!version) {
return undefined;
}
Expand All @@ -86,7 +87,10 @@ export function coerceToSemver(version: string): string {
}
} else {
if (coerceableRE.test(version)) {
const coerced = semver.coerce(version);
// Remove leading 0's from the version segments as that's
// an illegal semantic versioning format/pattern
const sanitizedVersion = version.replace(/\b0+(\d)/g, '$1');
const coerced = semver.coerce(sanitizedVersion);
if (coerced) {
return coerced.version
}
Expand Down
8 changes: 7 additions & 1 deletion src/extensions/mod_management/views/ModList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1076,7 +1076,13 @@ class ModList extends ComponentEx<IProps, IComponentState> {
}

private updateModGrouping(modsWithState) {
const modList = Object.keys(modsWithState).map(key => modsWithState[key]);
const modList = Object.keys(modsWithState).reduce((accum, key) => {
const mod = modsWithState[key];
if (mod) {
accum.push(mod);
}
return accum;
}, []);
const grouped = groupMods(modList, { groupBy: 'file', multipleEnabled: false });

const groupedMods = grouped.reduce((prev: { [id: string]: IModWithState[] }, value) => {
Expand Down
12 changes: 10 additions & 2 deletions src/extensions/nexus_integration/util/convertGameId.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,25 @@ export function convertGameIdReverse(knownGames: IGameStored[], input: string):
return undefined;
}

const game = knownGames.find(iter =>
const validGames = knownGames.filter(iter => iter.id === input.toLowerCase() ||
(iter.details !== undefined) && (iter.details.nexusPageId === input));

// We obviously prefer the exact match first.
const game = validGames.find(iter => iter.id === input.toLowerCase());
if (game !== undefined) {
return game.id;
}

// Alternatively - there may be a nexus page id match.
if (validGames.length > 0) {
return validGames[0].id;
}

return {
skyrimspecialedition: 'skyrimse',
newvegas: 'falloutnv',
elderscrollsonline: 'teso',
}[input.toLowerCase()] || input;
}[input.toLowerCase()] || input.toLowerCase();
}

/**
Expand Down
49 changes: 30 additions & 19 deletions src/extensions/symlink_activator_elevate/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/* eslint-disable */
import { clearUIBlocker, setUIBlocker } from '../../actions';
import {IExtensionApi, IExtensionContext} from '../../types/IExtensionContext';
import { IGame } from '../../types/IGame';
import { IState } from '../../types/IState';
import {ProcessCanceled, TemporaryError, UserCanceled} from '../../util/CustomErrors';
import {ProcessCanceled, UserCanceled} from '../../util/CustomErrors';
import * as fs from '../../util/fs';
import { Normalize } from '../../util/getNormalizeFunc';
import getVortexPath from '../../util/getVortexPath';
Expand Down Expand Up @@ -101,7 +102,7 @@ class DeploymentMethod extends LinkingDeployment {
private mOpenRequests: { [num: number]: { resolve: () => void, reject: (err: Error) => void } };
private mIPCServer: net.Server;
private mDone: () => void;
private mWaitForUser: () => Promise<void>;
// private mWaitForUser: () => Promise<void>;
private mOnReport: (report: string) => void;
private mTmpFilePath: string;

Expand All @@ -114,18 +115,18 @@ class DeploymentMethod extends LinkingDeployment {
api);
this.mElevatedClient = null;

this.mWaitForUser = () => new Promise<void>((resolve, reject) => api.sendNotification({
type: 'info',
message: 'Deployment requires elevation',
noDismiss: true,
actions: [{
title: 'Elevate',
action: dismiss => { dismiss(); resolve(); },
}, {
title: 'Cancel',
action: dismiss => { dismiss(); reject(new UserCanceled()); },
}],
}));
// this.mWaitForUser = () => new Promise<void>((resolve, reject) => api.sendNotification({
// type: 'info',
// message: 'Deployment requires elevation',
// noDismiss: true,
// actions: [{
// title: 'Elevate',
// action: dismiss => { dismiss(); resolve(); },
// }, {
// title: 'Cancel',
// action: dismiss => { dismiss(); reject(new UserCanceled()); },
// }],
// }));

let lastReport: string;
this.mOnReport = (report: string) => {
Expand Down Expand Up @@ -173,11 +174,21 @@ class DeploymentMethod extends LinkingDeployment {
}

public userGate(): Promise<void> {
const state: IState = this.api.store.getState();

return state.settings.workarounds.userSymlinks
? Promise.resolve()
: this.mWaitForUser();
// In the past, we used to block the user from deploying/purging his mods
// until he would give us consent to elevate permissions to do so.
// That is a redundant anti-pattern as the elevation UI itself will already inform the user
// of this requirement and give him the opportunity to cancel or proceed with the deployment!
//
// Additionally - blocking the deployment behind a collapsible notification is extremely bad UX
// as it is not necessarily obvious to the user that we require him to click on the notification.
// Finally, this will block the user from switching to other games while Vortex awaits for elevation
// causing the "Are you stuck?" overlay to appear and remain there, waiting for the user to click on an
// invisible notification button.
//
// I could add a Promise.race([this.waitForUser(), this.waitForElevation()]) to replace the mWaitForUser
// functor - but what's the point - if the user clicked deploy, he surely wants to elevate his instance
// as well. (And if not, he can always cancel the Windows API dialog!)
return Promise.resolve();
}

public prepare(dataPath: string, clean: boolean, lastActivation: IDeployedFile[],
Expand Down