From c889fbbd967e87e2bfc3540762fabdd0dcfff6c4 Mon Sep 17 00:00:00 2001 From: Georges-Antoine Assi Date: Sun, 21 Jan 2024 20:18:48 -0500 Subject: [PATCH] actually fix asset saving and loading --- backend/endpoints/saves.py | 19 ++++-- backend/endpoints/states.py | 19 ++++-- backend/handler/fs_handler/__init__.py | 4 +- backend/handler/scan_handler.py | 36 +++++----- frontend/src/services/api/save.ts | 5 +- frontend/src/services/api/state.ts | 4 +- frontend/src/utils/index.ts | 91 ++++++++++++++++++-------- frontend/src/views/Play/Player.vue | 4 +- 8 files changed, 119 insertions(+), 63 deletions(-) diff --git a/backend/endpoints/saves.py b/backend/endpoints/saves.py index b909a893e..2ed8edba4 100644 --- a/backend/endpoints/saves.py +++ b/backend/endpoints/saves.py @@ -4,7 +4,7 @@ from endpoints.responses import MessageResponse from endpoints.responses.assets import UploadedSavesResponse, SaveSchema from fastapi import APIRouter, File, HTTPException, Request, UploadFile, status from handler import db_save_handler, fs_asset_handler, db_rom_handler -from handler.scan_handler import scan_save +from handler.scan_handler import scan_save, build_asset_file_path from logger.logger import log from config import LIBRARY_BASE_PATH @@ -13,7 +13,10 @@ router = APIRouter() @protected_route(router.post, "/saves", ["assets.write"]) def add_saves( - request: Request, rom_id: int, saves: list[UploadFile] = File(...) + request: Request, + rom_id: int, + saves: list[UploadFile] = File(...), + emulator: str = None, ) -> UploadedSavesResponse: rom = db_rom_handler.get_roms(rom_id) log.info(f"Uploading saves to {rom.name}") @@ -24,15 +27,19 @@ def add_saves( detail="No saves were uploaded", ) - saves_path = fs_asset_handler.build_upload_file_path( - rom.platform.fs_slug, folder=cm.config.SAVES_FOLDER_NAME + saves_path = build_asset_file_path( + rom.platform.fs_slug, folder=cm.config.SAVES_FOLDER_NAME, emulator=emulator ) for save in saves: - fs_asset_handler._write_file(file=save, path=saves_path) + fs_asset_handler._write_file( + file=save, path=f"{LIBRARY_BASE_PATH}/{saves_path}" + ) # Scan or update save - scanned_save = scan_save(platform=rom.platform, file_name=save.filename) + scanned_save = scan_save( + platform=rom.platform, file_name=save.filename, emulator=emulator + ) db_save = db_save_handler.get_save_by_filename(rom.id, save.filename) if db_save: db_save_handler.update_save( diff --git a/backend/endpoints/states.py b/backend/endpoints/states.py index 449b56628..a7cc9ff7d 100644 --- a/backend/endpoints/states.py +++ b/backend/endpoints/states.py @@ -4,7 +4,7 @@ from endpoints.responses import MessageResponse from endpoints.responses.assets import UploadedStatesResponse, StateSchema from fastapi import APIRouter, File, HTTPException, Request, UploadFile, status from handler import db_state_handler, db_rom_handler, fs_asset_handler -from handler.scan_handler import scan_state +from handler.scan_handler import scan_state, build_asset_file_path from logger.logger import log from config import LIBRARY_BASE_PATH @@ -13,7 +13,10 @@ router = APIRouter() @protected_route(router.post, "/states", ["assets.write"]) def add_states( - request: Request, rom_id: int, states: list[UploadFile] = File(...) + request: Request, + rom_id: int, + states: list[UploadFile] = File(...), + emulator: str = None, ) -> UploadedStatesResponse: rom = db_rom_handler.get_roms(rom_id) log.info(f"Uploading states to {rom.name}") @@ -24,15 +27,19 @@ def add_states( detail="No states were uploaded", ) - states_path = fs_asset_handler.build_upload_file_path( - rom.platform.fs_slug, folder=cm.config.STATES_FOLDER_NAME + states_path = build_asset_file_path( + rom.platform.fs_slug, folder=cm.config.STATES_FOLDER_NAME, emulator=emulator ) for state in states: - fs_asset_handler._write_file(file=state, path=states_path) + fs_asset_handler._write_file( + file=state, path=f"{LIBRARY_BASE_PATH}/{states_path}" + ) # Scan or update state - scanned_state = scan_state(platform=rom.platform, file_name=state.filename) + scanned_state = scan_state( + platform=rom.platform, file_name=state.filename, emulator=emulator + ) db_state = db_state_handler.get_state_by_filename(rom.id, state.filename) if db_state: db_state_handler.update_state( diff --git a/backend/handler/fs_handler/__init__.py b/backend/handler/fs_handler/__init__.py index 5d75845ca..3184fcd5e 100644 --- a/backend/handler/fs_handler/__init__.py +++ b/backend/handler/fs_handler/__init__.py @@ -122,5 +122,5 @@ class FSHandler(ABC): def build_upload_file_path( self, fs_slug: str, folder: str = cm.config.ROMS_FOLDER_NAME ): - rom_path = self.get_fs_structure(fs_slug, folder=folder) - return f"{LIBRARY_BASE_PATH}/{rom_path}" + file_path = self.get_fs_structure(fs_slug, folder=folder) + return f"{LIBRARY_BASE_PATH}/{file_path}" diff --git a/backend/handler/scan_handler.py b/backend/handler/scan_handler.py index 4fbf17477..07753d1f9 100644 --- a/backend/handler/scan_handler.py +++ b/backend/handler/scan_handler.py @@ -185,36 +185,34 @@ def _scan_asset(file_name: str, path: str): } -def scan_save(platform: Platform, file_name: str, emulator: str = None) -> Save: - saves_path = fs_asset_handler.get_fs_structure( - platform.fs_slug, folder=cm.config.SAVES_FOLDER_NAME - ) +def build_asset_file_path(fs_slug: str, folder: str, emulator: str = None): + saves_path = fs_asset_handler.get_fs_structure(fs_slug, folder=folder) - # Scan asset with the sames path and emulator folder name if emulator: - return Save(**_scan_asset(file_name, os.path.join(saves_path, emulator))) + return os.path.join(saves_path, emulator) + return saves_path + + +def scan_save(platform: Platform, file_name: str, emulator: str = None) -> Save: + saves_path = build_asset_file_path( + platform.fs_slug, folder=cm.config.SAVES_FOLDER_NAME, emulator=emulator + ) return Save(**_scan_asset(file_name, saves_path)) def scan_state(platform: Platform, file_name: str, emulator: str = None) -> State: - states_path = fs_asset_handler.get_fs_structure( - platform.fs_slug, folder=cm.config.STATES_FOLDER_NAME + states_path = build_asset_file_path( + platform.fs_slug, folder=cm.config.STATES_FOLDER_NAME, emulator=emulator ) - - # Scan asset with the sames path and emulator folder name - if emulator: - return State(**_scan_asset(file_name, os.path.join(states_path, emulator))) - return State(**_scan_asset(file_name, states_path)) def scan_screenshot(file_name: str, platform: Platform = None) -> Screenshot: - screenshots_path = fs_asset_handler.get_fs_structure( + if not platform: + return Screenshot(**_scan_asset(file_name, cm.config.SCREENSHOTS_FOLDER_NAME)) + + screenshots_path = build_asset_file_path( platform.fs_slug, folder=cm.config.SCREENSHOTS_FOLDER_NAME ) - - if platform: - return Screenshot(**_scan_asset(file_name, screenshots_path)) - - return Screenshot(**_scan_asset(file_name, cm.config.SCREENSHOTS_FOLDER_NAME)) + return Screenshot(**_scan_asset(file_name, screenshots_path)) diff --git a/frontend/src/services/api/save.ts b/frontend/src/services/api/save.ts index 5dcbb3c4f..316b390a9 100644 --- a/frontend/src/services/api/save.ts +++ b/frontend/src/services/api/save.ts @@ -7,17 +7,20 @@ export const saveApi = api; async function uploadSaves({ rom, saves, + emulator, }: { rom: Rom; saves: File[]; + emulator?: string; }): Promise<{ data: UploadedSavesResponse }> { let formData = new FormData(); saves.forEach((save) => formData.append("saves", save)); + return api.post("/saves", formData, { headers: { "Content-Type": "multipart/form-data", }, - params: { rom_id: rom.id }, + params: { rom_id: rom.id, emulator }, }); } diff --git a/frontend/src/services/api/state.ts b/frontend/src/services/api/state.ts index 1d7069daa..a36f5ef5d 100644 --- a/frontend/src/services/api/state.ts +++ b/frontend/src/services/api/state.ts @@ -7,9 +7,11 @@ export const stateApi = api; async function uploadStates({ rom, states, + emulator, }: { rom: Rom; states: File[]; + emulator?: string; }): Promise<{ data: UploadedStatesResponse }> { let formData = new FormData(); states.forEach((state) => formData.append("states", state)); @@ -18,7 +20,7 @@ async function uploadStates({ headers: { "Content-Type": "multipart/form-data", }, - params: { rom_id: rom.id }, + params: { rom_id: rom.id, emulator }, }); } diff --git a/frontend/src/utils/index.ts b/frontend/src/utils/index.ts index 50042d027..29ab362b1 100644 --- a/frontend/src/utils/index.ts +++ b/frontend/src/utils/index.ts @@ -244,37 +244,74 @@ export function languageToEmoji(language: string) { export const platformSlugEJSPlatformMap: Record = { "3do": "3do", - "amiga": "amiga", - "arcade": "arcade", - "atari2600": "atari2600", - "atari5200": "atari5200", - "atari7800": "atari7800", - "c64": "c64", - "colecovision": "coleco", - "jaguar": "jaguar", - "lynx": "lynx", - "mame": "mame2003", + amiga: "amiga", + arcade: "arcade", + atari2600: "atari2600", + atari5200: "atari5200", + atari7800: "atari7800", + c64: "c64", + colecovision: "coleco", + jaguar: "jaguar", + lynx: "lynx", + mame: "mame2003", "neo-geo-pocket": "ngp", "neo-geo-pocket-color": "ngp", - "nes": "nes", - "famicom": "nes", - "n64": "n64", - "nds": "nds", - "gba": "gba", - "gb": "gb", + nes: "nes", + famicom: "nes", + n64: "n64", + nds: "nds", + gba: "gba", + gb: "gb", "pc-fx": "pcfx", - "ps": "psx", - "psp": "psp", - "segacd": "segaCD", - "sega32": "sega32x", - "gamegear": "segaGG", - "sms": "segaMS", + ps: "psx", + psp: "psp", + segacd: "segaCD", + sega32: "sega32x", + gamegear: "segaGG", + sms: "segaMS", "genesis-slash-megadrive": "segaMD", - "saturn": "segaSaturn", - "snes": "snes", - "sfam": "snes", + saturn: "segaSaturn", + snes: "snes", + sfam: "snes", "turbografx16--1": "pce", - "virtualboy": "vb", - "wonderswan": "ws", + virtualboy: "vb", + wonderswan: "ws", "wonderswan-color": "ws", } as const; + +export const platformSlugEJSCoreMap: Record = { + "3do": "opera", + amiga: "puae", + arcade: "fbneo", + atari2600: "stella2014", + atari5200: "a5200", + atari7800: "prosystem", + c64: "vice_x64", + colecovision: "gearcoleco", + jaguar: "virtualjaguar", + lynx: "handy", + mame: "mame2003_plus", + "neo-geo-pocket": "mednafen_ngp", + "neo-geo-pocket-color": "mednafen_ngp", + nes: "fceumm", + "famicom": "fceumm", + n64: "mupen64plus_next", + nds: "melonds", + gba: "mgba", + gb: "gambatte", + "pc-fx": "mednafen_pcfx", + ps: "pcsx_rearmed", + psp: "ppsspp", + segacd: "genesis_plus_gx", + sega32: "picodrive", + gamegear: "genesis_plus_gx", + sms: "genesis_plus_gx", + "genesis-slash-megadrive": "genesis_plus_gx", + saturn: "yabause", + snes: "snes9x", + sfam: "snes9x", + "turbografx16--1": "mednafen_pce", + virtualboy: "beetle_vb", + wonderswan: "mednafen_wswan", + "wonderswan-color": "mednafen_wswan", +} as const; diff --git a/frontend/src/views/Play/Player.vue b/frontend/src/views/Play/Player.vue index a15281429..30494b724 100644 --- a/frontend/src/views/Play/Player.vue +++ b/frontend/src/views/Play/Player.vue @@ -4,7 +4,7 @@ import stateApi from "@/services/api/state"; import saveApi, { saveApi as api } from "@/services/api/save"; import screenshotApi from "@/services/api/screenshot"; import type { Rom } from "@/stores/roms"; -import { platformSlugEJSPlatformMap } from "@/utils"; +import { platformSlugEJSPlatformMap, platformSlugEJSCoreMap } from "@/utils"; import type { SaveSchema, StateSchema } from "@/__generated__"; const props = defineProps<{ @@ -171,6 +171,7 @@ window.EJS_onSaveState = function ({ stateApi .uploadStates({ rom: props.rom, + emulator: platformSlugEJSCoreMap[props.rom.platform_slug], states: [ new File([state], buildStateName(), { type: "application/octet-stream", @@ -282,6 +283,7 @@ window.EJS_onSaveSave = function ({ saveApi .uploadSaves({ rom: props.rom, + emulator: platformSlugEJSCoreMap[props.rom.platform_slug], saves: [ new File([save], buildSaveName(), { type: "application/octet-stream",