feat: Implemented romm saves for dolphin and xenia

feat: Implemented save backups for emulatorjs
fix: Added support for rar archives
fix: Moved to individual ini adjustments for pcsx2 and ppsspp to allow for user editing of configs
This commit is contained in:
Simeon Radivoev 2026-04-09 17:15:37 +03:00
parent 54dd9256e3
commit 7948bd24fa
Signed by: simeonradivoev
GPG key ID: 7611A451D2A5D37A
36 changed files with 1103 additions and 243 deletions

View file

@ -1,4 +1,11 @@
// ES-DE to emulator JS mapping
import Elysia, { status } from "elysia";
import z from "zod";
import path from 'node:path';
import { config, events, plugins } from "../app";
import { getLocalGame, updateLocalLastPlayed } from "../games/services/statusService";
// TODO: use the retroarch cores based on ES-DE
export const cores: Record<string, string> = {
"atari5200": "atari5200",
@ -43,4 +50,57 @@ export const cores: Record<string, string> = {
"plus4": "plus4",
"vic20": "vic20",
"dos": "dos"
};
};
export default new Elysia({ prefix: '/emulatorjs' })
.put('/save', async ({ body: { save, screenshot } }) =>
{
await Bun.write(path.join(config.get('downloadPath'), 'saves', "EMULATORJS", save.name), save);
}, {
body: z.object({
save: z.file(),
screenshot: z.file().optional()
})
}).get('/load', async ({ query: { filePath } }) =>
{
return Bun.file(path.join(config.get('downloadPath'), 'saves', "EMULATORJS", filePath));
}, { query: z.object({ filePath: z.string() }) })
.post('/post_play/:source/:id', async ({ params: { source, id }, body: { save } }) =>
{
const localGame = await getLocalGame(source, id);
if (!localGame) return status("Not Found");
const changedSaveFiles: SaveFileChange[] = [];
if (save)
{
const savesPath = path.join(config.get('downloadPath'), 'saves', "EMULATORJS");
const saveFile = path.join(savesPath, save.name);
await Bun.write(saveFile, save);
changedSaveFiles.push({ subPath: save.name, cwd: savesPath });
events.emit('notification', { message: "Save Backed Up", type: "success", icon: "save" });
}
await updateLocalLastPlayed(localGame.id);
await plugins.hooks.games.postPlay.promise({
source,
id,
saveFolderPath: path.join(config.get('downloadPath'), "saves", "EMULATORJS"),
gameInfo: { platformSlug: localGame?.platform.slug },
changedSaveFiles: changedSaveFiles,
validChangedSaveFiles: changedSaveFiles,
command: {
id: "EMULATORJS",
command: "",
emulator: "EMULATORJS",
valid: true,
metadata: {
romPath: localGame?.path_fs ?? undefined,
emulatorBin: undefined,
emulatorDir: undefined
}
}
});
}, {
body: z.object({
save: z.file().optional()
})
});