fix: Issues with launching and installation on the steam deck

This commit is contained in:
Simeon Radivoev 2026-03-30 20:00:08 +03:00
parent dc0f2d150a
commit ccc5a05ed7
Signed by: simeonradivoev
GPG key ID: C16C2132A7660C8E
19 changed files with 247 additions and 80 deletions

View file

@ -9,7 +9,7 @@ import { getOrCachedGithubRelease } from "../cache";
import Seven from 'node-7z';
import fs from "node:fs/promises";
import { Downloader } from "@/bun/utils/downloader";
import { move } from "fs-extra";
import { ensureDir, move } from "fs-extra";
import { simulateProgress } from "@/bun/utils";
type EmulatorDownloadStates = "download" | "extract";
@ -82,7 +82,7 @@ export class EmulatorDownloadJob implements IJob<z.infer<typeof EmulatorDownload
{
if (isArchive)
{
if (await downloader.start() && destinationPaths[0])
if (destinationPaths[0])
{
let destinationPath = destinationPaths[0];
await new Promise((resolve, reject) =>
@ -108,6 +108,13 @@ export class EmulatorDownloadJob implements IJob<z.infer<typeof EmulatorDownload
}
}
}
} else
{
await ensureDir(emulatorsFolder);
for (const destPath of destinationPaths)
{
await fs.rename(destPath, path.join(emulatorsFolder, path.basename(destPath)));
}
}
}
}

View file

@ -31,7 +31,8 @@ export class InstallJob implements IJob<never, InstallJobStates>
public gameId: string;
public source: string;
public config?: JobConfig;
// The local game ID of newly created entry, if successful
public localGameId?: number;
public group = InstallJob.id;
constructor(id: string, source: string, config?: JobConfig)
@ -252,6 +253,7 @@ export class InstallJob implements IJob<never, InstallJobStates>
})));
}
this.localGameId = id;
});
} else
{

View file

@ -5,7 +5,6 @@ import { db, events, plugins } from "../app";
import * as appSchema from "@schema/app";
import { eq, sql } from "drizzle-orm";
import { ChildProcessWithoutNullStreams, spawn } from 'node:child_process';
import { killBrowser } from "@/bun/utils/browser-spawner";
export class LaunchGameJob implements IJob<z.infer<typeof LaunchGameJob.dataSchema>, "playing">
{
@ -43,34 +42,44 @@ export class LaunchGameJob implements IJob<z.infer<typeof LaunchGameJob.dataSche
await new Promise((resolve, reject) =>
{
let game: Bun.Subprocess;
let game: any;
if (!commandArgs)
{
game = Bun.spawn(this.validCommand.command.split(' '), {
// ES-DE commands require shell execution. Some emulators fail otherwise.
const spawnGame = spawn(this.validCommand.command, {
shell: true,
cwd: this.validCommand.startDir,
windowsVerbatimArguments: true,
signal: context.abortSignal
});
game.exited.then(resolve).catch(e =>
spawnGame.stdout.on('data', data => console.log(data));
spawnGame.on('close', (code) =>
{
resolve(code);
});
spawnGame.on('error', e =>
{
console.error(e);
reject(e);
});
game = spawnGame;
}
else if (this.validCommand.metadata.emulatorBin)
{
game = Bun.spawn([this.validCommand.metadata.emulatorBin, ...commandArgs], {
// We have full control over launching integrated emulators better to use bun spawn
const bunGame = Bun.spawn([this.validCommand.metadata.emulatorBin, ...commandArgs], {
cwd: this.validCommand.startDir,
windowsVerbatimArguments: true,
signal: context.abortSignal
});
game.exited.then(resolve).catch(e =>
bunGame.exited.then(resolve).catch(e =>
{
console.error(e);
reject(e);
});
game = bunGame;
} else
{
reject(new Error("No Emulator Bin"));