Skip to content
Closed
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
31 changes: 31 additions & 0 deletions src/main/core/paths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,37 @@ export function windowsStorageRoots(
};
}

export interface LinuxStorageHomes {
readonly config: string;
readonly data: string;
readonly cache: string;
readonly state: string;
}

/** Resolve the Flatpak layout beneath the sandbox-provided XDG homes. */
export function linuxStorageRoots(
homes: LinuxStorageHomes,
): ApplicationStorageRoots {
for (const [name, root] of Object.entries(homes)) {
if (!path.posix.isAbsolute(root)) {
throw new Error(`Linux ${name} home must be absolute`);
}
}

const config = path.posix.join(homes.config, "gwonmac");
const data = path.posix.join(homes.data, "gwonmac");
const cache = path.posix.join(homes.cache, "gwonmac");
const state = path.posix.join(homes.state, "gwonmac");
return {
config,
data,
cache,
state,
logs: path.posix.join(state, "logs"),
sessions: path.posix.join(data, "sessions"),
};
}

export function gamePaths(storage: ApplicationStorageRoots): GamePaths {
const game = path.join(storage.cache, "game");
const artifacts = path.join(game, "artifacts");
Expand Down
14 changes: 13 additions & 1 deletion src/main/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ import { sweepOrphanDirectories } from "./core/atomic-file.js";
import {
colocatedStorageRoots,
documentDirectories,
linuxStorageRoots,
windowsStorageRoots,
} from "./core/paths.js";
import { gamePaths } from "./paths.js";
Expand Down Expand Up @@ -200,12 +201,23 @@ const explicitUserData = app.commandLine.hasSwitch("user-data-dir");
if (!explicitUserData && process.platform === "darwin") {
app.setPath("userData", path.join(app.getPath("appData"), "Guild Wars"));
}
const linuxFlatpak = process.platform === "linux"
&& process.env.FLATPAK_ID === DISTRIBUTION_CHANNEL_CONFIG.release.bundleId;
const applicationStorageRoots = explicitUserData
? colocatedStorageRoots(app.getPath("userData"))
: windowsNativeHost
? windowsStorageRoots(windowsNativeHost.localAppData())
: linuxFlatpak
? linuxStorageRoots({
config: process.env.XDG_CONFIG_HOME ?? app.getPath("appData"),
data: process.env.XDG_DATA_HOME ?? app.getPath("appData"),
cache:
process.env.XDG_CACHE_HOME ?? path.join(app.getPath("home"), ".cache"),
state: process.env.XDG_STATE_HOME
?? path.join(process.env.XDG_DATA_HOME ?? app.getPath("appData"), "state"),
})
: colocatedStorageRoots(app.getPath("userData"));
if (!explicitUserData && process.platform === "win32") {
if (!explicitUserData && (process.platform === "win32" || linuxFlatpak)) {
app.setPath("userData", applicationStorageRoots.sessions);
app.setPath("sessionData", applicationStorageRoots.sessions);
}
Expand Down
26 changes: 26 additions & 0 deletions tests/unit/paths.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
diagnosticFramesPath,
documentDirectories,
gamePaths,
linuxStorageRoots,
multiProfilePaths,
nativeExecutableName,
unpackedPath,
Expand Down Expand Up @@ -223,4 +224,29 @@ describe("resolved profile paths", () => {
"C:\\Users\\Player\\AppData\\Local\\Guild Wars Reforged\\data\\sessions",
});
});

it("pins the Flatpak layout beneath sandbox-provided XDG homes", () => {
assert.deepEqual(linuxStorageRoots({
config: "/var/config",
data: "/var/data",
cache: "/var/cache",
state: "/var/state",
}), {
config: "/var/config/gwonmac",
data: "/var/data/gwonmac",
cache: "/var/cache/gwonmac",
state: "/var/state/gwonmac",
logs: "/var/state/gwonmac/logs",
sessions: "/var/data/gwonmac/sessions",
});
});

it("refuses relative Linux XDG homes", () => {
assert.throws(() => linuxStorageRoots({
config: "config",
data: "/var/data",
cache: "/var/cache",
state: "/var/state",
}), /Linux config home must be absolute/);
});
});
Loading