Commit Graph

84 Commits

Author SHA1 Message Date
Hermes Agent f297d30248 fix: resolveSibling using filename only, not full bundle path
Build & Deploy / build-and-deploy (push) Successful in 46s
bundleFile changed from 'wolf3d.jsdos' to 'wolf3d/wolf3d.jsdos' when
bundles moved inside game directories. resolveSibling(bundleFile + '.tmp')
produced a wrong nested path. Now uses bundlePath.getFileName() to get
just the filename part before appending .tmp.
2026-06-01 12:48:04 +02:00
Hermes Agent 4044ef3786 feat: pre-populate upload title with filename when no IGDB matches
Build & Deploy / build-and-deploy (push) Successful in 2m17s
When a game ZIP is selected and IGDB returns no matches, the search
box is now pre-filled with the filename (minus .zip extension) so
the user can edit it rather than typing from scratch.
2026-06-01 12:41:24 +02:00
Hermes Agent 677740aece fix: prevent layout shift by using 100vw body instead of scrollbar-gutter
Build & Deploy / build-and-deploy (push) Successful in 1m35s
Setting body { width: 100vw; overflow-x: hidden; } means the body is
always the full viewport width regardless of scrollbar presence.
margin: 0 auto centers content within the body, which doesn't
change width when a vertical scrollbar appears — so the content
stays in place.

html { overflow-x: hidden; } clips any body overflow past the
viewport (body is 100vw while html content area shrinks with
scrollbar). No gutter discoloration since there's no gutter
reservation — the scrollbar appears naturally on the html element.
2026-05-29 23:32:04 +02:00
Hermes Agent 9bb341eab9 fix: use scrollbar-gutter to prevent layout shift without always showing scrollbar
Build & Deploy / build-and-deploy (push) Successful in 45s
Replaces overflow-y: scroll with scrollbar-gutter: stable on html.
This reserves the scrollbar gutter space in the layout at all times,
so the content width never changes when a scrollbar appears/disappears.
The scrollbar itself only shows when content overflows (as desired).
Works on all modern browsers (Chrome 94+, Firefox 97+, Safari 15.4+).
2026-05-29 23:27:59 +02:00
Hermes Agent e2dca1db39 fix: force scrollbar visibility to prevent layout shift on tall pages
Build & Deploy / build-and-deploy (push) Successful in 56s
Add overflow-y: scroll to body so the scrollbar is always present,
preventing the ~15px layout shift when a page exceeds viewport height
(e.g., games with long descriptions). Also add overflow-x: hidden to
guard against any horizontal overflow breaking the layout.
2026-05-29 23:23:25 +02:00
Hermes Agent ab1ba503ff feat: store .jsdos bundle inside game directory instead of as flat file
Build & Deploy / build-and-deploy (push) Successful in 52s
Before: data/games/{id}.jsdos (flat, alongside the game dir)
After:  data/games/{id}/{id}.jsdos (inside the game directory)

Benefits:
- Delete is atomic — removing the game dir removes everything
- Cleaner data directory structure
- No orphan .jsdos files on delete

Also updated frontend bundleUrl() to use game.bundle_file from
the backend, making it path-agnostic. Old flat layout is still
served via StaticResource for backward compat.
2026-05-29 23:07:07 +02:00
Hermes Agent 4c3ded802b fix: valid Java char literal for backslash in UploadResource.java
Build & Deploy / build-and-deploy (push) Successful in 45s
replace('\', '/') is Java source for a char literal representing
a single backslash character. The previous commit had a single
backslash byte between quotes which made Java interpret it as
\\' (escaped single-quote) causing unclosed char literal errors.
2026-05-29 23:01:35 +02:00
Hermes Agent 9b95e5b994 feat: stream setup .jsdos bundles on-the-fly instead of duplicating game data
Build & Deploy / build-and-deploy (push) Failing after 1m20s
- Add streamSetupBundle() to GameService — reads main bundle as zip,
  replaces config files (.jsdos/dosbox.conf, .jsdos/jsdos.json) with
  setup variants pointing to SETUP.EXE, streams directly to response
- Add GET /api/games/{id}/setup-bundle endpoint that calls the above
- Remove .setup.jsdos disk creation during upload — setupExe is still
  detected and stored in game metadata, but no duplicate bundle is saved
- Update frontend api.js to point setupBundleUrl() to the new endpoint
- Fix pre-existing backslash escaping bug in UploadResource.java path
  normalization (replace('\', '/') instead of replace('\\', '/'))
2026-05-29 18:08:04 +02:00
Hermes Agent 5f69ea5ead fix: remove injected js-dos CSS/script on Play unmount to prevent style leaking into other pages
Build & Deploy / build-and-deploy (push) Successful in 48s
2026-05-29 15:15:02 +02:00
Hermes Agent e39ee05a16 fix: add missing closing brace to load() method
Build & Deploy / build-and-deploy (push) Successful in 38s
2026-05-29 14:56:12 +02:00
Hermes Agent 2ab6b19598 Fix upload dialog re-trigger + add game size to detail page
Build & Deploy / build-and-deploy (push) Failing after 34s
- Fixed: navigating back to library no longer re-opens file dialog
  (prev-value guard in uploadTriggered effect)
- Added bundleSize field to Game, populated at load time from .jsdos file
- Game detail page shows file size next to DOS badge (e.g. 'DOS · 127 MB')
2026-05-29 14:54:13 +02:00
Hermes Agent 02d0c4f377 Add executable picker in game edit UI
Build & Deploy / build-and-deploy (push) Successful in 49s
- Added 'executables' (full list) and 'executable' (selected) fields to Game
- Upload now stores ALL discoverable .exe/.com/.bat files in game metadata
- Added setExecutable() to GameService that patches the .jsdos bundle
  (updates dosbox.conf + jsdos.json inside the ZIP) when changing executable
- GameResource PATCH handler delegates executable changes to bundle patching
- GameDetail edit mode shows a radio-button picker of all executables
- Heuristics remain as first-guess default, user can always override
- No re-upload needed to fix wrong executable selection
2026-05-29 10:31:25 +02:00
Hermes Agent e262a46487 Add path=c:\ to autoexec for DOS extender findability
Build & Deploy / build-and-deploy (push) Successful in 47s
When the main executable is in a subdirectory but DOS4GW.EXE (or other
DOS extender) is at the ZIP root, DOS/4GW fails with 'No such file or
directory' because it only searches the current directory and PATH.
Adding 'path=c:\' before the 'cd' command ensures root-level DOS
extenders are always findable regardless of where the game EXE lives.
2026-05-29 10:15:23 +02:00
Hermes Agent 815247f760 Fix setupExe metadata + improve PKSFX detection
Build & Deploy / build-and-deploy (push) Successful in 50s
- Added 'sfx' and 'makesfx' to SKIP_EXE_NAMES
- Increased self-extractor detection buffer to 32KB
- Fixed false-positive risk: PK signatures only checked after offset 0x40
  using proper signature comparison (not sequential byte matching)
- Fixed setupExe metadata: only set when setup bundle was actually created,
  preventing phantom Setup button when setup exe is Windows
2026-05-29 10:07:52 +02:00
Hermes Agent 54542612a5 Skip self-extracting archive executables (PKSFX etc.)
Build & Deploy / build-and-deploy (push) Successful in 53s
- Added archiver/compression tool names to SKIP_EXE_NAMES (pksfx,
  pkzip, pkunzip, unzip, arj, rar, lha, etc.)
- Added isLikelySelfExtractor() which reads the EXE body looking for
  PKWARE signatures (PKZIP/PKSFX strings and PK\x03\x04 local file
  headers) — catches renamed self-extractors regardless of filename
- Both filters applied during findMainExe candidate collection
2026-05-29 09:57:34 +02:00
Hermes Agent 473fb7a216 Check setup EXE's own platform before creating setup bundle
Build & Deploy / build-and-deploy (push) Successful in 40s
Previously only checked the main game's platform. Fallout's SETUP.EXE
is a Windows executable even though FALLOUT.EXE is DOS — creating a
.setup.jsdos bundle for it would show 'This program cannot run in DOS mode'.
Now detects the setup EXE's own header and skips if it targets Windows.
2026-05-29 09:41:45 +02:00
Hermes Agent 45d145a950 Prefer larger files over shallow depth in findMainExe
Build & Deploy / build-and-deploy (push) Successful in 45s
Size is a better indicator of 'this is the actual game' than depth.
A 1MB+ FALLOUT.EXE in a subdirectory should beat a 50KB BOOTME.EXE
at the root. Sort order: non-installer → DOS → size → depth.
2026-05-29 09:40:06 +02:00
Hermes Agent dee37b3f01 Prefer DOS executables over Windows in findMainExe
Build & Deploy / build-and-deploy (push) Successful in 46s
When a ZIP contains both a DOS version (FALLOUT.EXE) and a Windows
version (FALLOUTW.EXE), the sort now prefers DOS executables.
This reads the EXE header during candidate collection and ranks:
  non-installer → DOS platform → depth → size

Fixes Fallout being mis-detected as a Windows game.
2026-05-29 09:34:57 +02:00
Hermes Agent fa1804dc65 Fix Java type inference in comparator chain
Build & Deploy / build-and-deploy (push) Successful in 41s
2026-05-29 09:30:04 +02:00
Hermes Agent 12db0e9bb9 Fix: prioritize non-installer executables over depth in findMainExe
Build & Deploy / build-and-deploy (push) Failing after 33s
The sort was: depth → non-installer → size.
This meant a root-level SETUP.EXE (depth 1, installer) beat a
subdirectory FALLOUT.EXE (depth 2, non-installer).

New sort: non-installer → depth → size.
Now any non-installer game EXE wins over installers regardless of depth.
2026-05-29 09:28:05 +02:00
Hermes Agent 27a9c180d7 Fix: skip DOS extender executables (DOS4GW etc.) when finding main game exe
Build & Deploy / build-and-deploy (push) Successful in 1m35s
DOS4GW.EXE is a 32-bit DOS extender that ships with many DOS games
(DOOM, Fallout, Duke Nukem 3D, etc.). The findMainExe algorithm was
picking it as the main executable because it's typically large and at
the ZIP root, causing the autoexec to run 'DOS4GW' with no arguments
→ 'DOS/4GW fatal error (1004): syntax is DOS/4GW <executable.xxx>'

Added SKIP_EXE_NAMES set with known DOS extenders, DPMI hosts,
debuggers, memory managers, and uninstallers.
2026-05-29 09:15:23 +02:00
Hermes Agent 3f69820911 Move Reset button to bottom of sidebar
Build & Deploy / build-and-deploy (push) Successful in 49s
2026-05-28 23:58:10 +02:00
Hermes Agent 13293b325e Restructure layout: search in sidebar, upload in header
Build & Deploy / build-and-deploy (push) Successful in 58s
- Removed toolbar (Library title, search, upload button) from library
- Moved search box into the sidebar alongside Year/Genre filters
- Removed 'Filters' heading from sidebar
- Replaced 'Library' nav button in header with '+ Upload' button
- Genre filters now sorted by count (desc) instead of alphabetically
- Cleaned up unused CSS
2026-05-28 23:16:22 +02:00
droideparanoico b8ccba4d20 Actualizar README.md
Build & Deploy / build-and-deploy (push) Successful in 12s
2026-05-28 23:14:35 +02:00
Hermes Agent 676e101ffc Library filters sidebar, clickable tags, remove Ready badge
Build & Deploy / build-and-deploy (push) Successful in 59s
- GameCard: removed 'Ready' badge from covers (keep '🪟 Win' for
  Windows games only — it's informative since they can't be played)
- Library: sidebar with Year + Genre checkbox filter groups
  - Each shows up to 5 items with game counts, 'Show all' button
  - Active filters shown as removable chips above the grid
  - Reset button clears all filters
  - Filters reflected in URL hash (#/?genre=FPS&year=1996)
- GameDetail: year and genre tags are now clickable links to
  #/?year=1996 or #/?genre=FPS, which opens the Library with that
  filter pre-applied
- App.svelte: parses query params from hash and passes to Library
2026-05-28 22:56:51 +02:00
Hermes Agent e15ce10f5a Upload progress spinner + duplicate game detection
Build & Deploy / build-and-deploy (push) Successful in 1m20s
Two features:

1. Progress indicator: when upload starts, the dialog switches from
   IGDB results to a centered spinner with 'Uploading and processing'
   text + filename. The Cancel button stays visible but disabled.

2. Duplicate game blocking: before upload, checks if a game with the
   same title (case-insensitive) already exists in the library.
   Frontend checks against the loaded games list; backend also
   checks as a second line of defense. Shows ⚠️ message in dialog.
   Existing unique-ID suffix logic (foo-2, foo-3) is still in place
   but now only reached when titles actually differ.
2026-05-28 22:28:27 +02:00
Hermes Agent a9e52ade68 Resilient flatten: catch exceptions + return meaningful error messages
Build & Deploy / build-and-deploy (push) Successful in 47s
- Wrap flattenSingleDir in try-catch — if it fails, the upload continues
  and the cd <subdir> fix in dosbox.conf handles subdirectory executables
- Add global catch to upload method returning the actual exception
  message instead of a generic 500
- This will help diagnose why the user's King's Quest VI zip fails:
  flattening can throw on special filenames, Mac resource forks,
  symlinks, or other unusual ZIP contents
2026-05-28 16:13:11 +02:00
Hermes Agent ff7b7b446f Fix IGDB result selection: use DOM data attributes + pass igdb_id to backend
Build & Deploy / build-and-deploy (push) Successful in 58s
Two issues fixed:

1. Frontend closure bug: IGDB result buttons used Svelte {#each} closure
   with onclick={() => doUpload(result.name)}. When clicking the 3rd
   result, the 1st result's handler sometimes fired. Fixed by reading
   data-name from e.currentTarget.dataset instead of JS closure.

2. Backend scrape mismatch: when user selected 'Blood' from IGDB
   results, backend's autoScrape searched for 'Blood' and could match
   'Captain Blood' first (alphabetical), overwriting metadata.
   Now passes igdb_id along with title so backend uses the EXACT
   IGDB entry the user selected via applyIgdbId() instead of
   auto-searching.
2026-05-28 16:00:51 +02:00
Hermes Agent a4b633ae86 Fix crash in detectPlatform: handle negative e_lfanew offset
Build & Deploy / build-and-deploy (push) Successful in 53s
For pure DOS executables, the e_lfanew field at MZ header offset 0x3C
is uninitialized garbage. Duke Nukem 2's EXE had bytes that form a
negative int32 (-1878619136), which was used as an array index causing
ArrayIndexOutOfBoundsException.

Now checks peOffset < 0 and returns 'dos' (no Windows signature found).
2026-05-28 15:53:51 +02:00
Hermes Agent 41d1e22522 Fix platform detection: LE (DOS/4GW extender) is DOS, not Windows
Build & Deploy / build-and-deploy (push) Successful in 48s
Many classic DOS games (Blood, DOOM, Duke Nukem 3D, Quake) use
DOS/4GW or DOS/32A — 32-bit DOS extenders with Linear Executable
(LE) format. My code was detecting LE as 'windows', causing these
games to be incorrectly flagged as unplayable.

Only PE (Portable Executable / Win32) and NE (New Executable /
Windows 3.x) are actually Windows.
2026-05-28 15:46:36 +02:00
Hermes Agent 95c7ba7192 Fix upload dialog: search box button always searches
Build & Deploy / build-and-deploy (push) Successful in 44s
Previously when no IGDB matches were found, the button next to the
search box changed from 'Search' to 'Upload' after the first search.
Since the text is editable and users may want to refine their query,
this button should always trigger a search.

Upload is still available via:
- The 'Upload anyway as "..."' button (shown after failed search)
- The 'Use filename: ...' button at the bottom
2026-05-28 15:03:13 +02:00
Hermes Agent 5b55a53b73 Skip creating .setup.jsdos bundles for Windows games
Build & Deploy / build-and-deploy (push) Successful in 47s
- Move platform detection before setup bundle creation
- Only create setup bundle when platform != 'windows'
- Also hide the Setup button in GameDetail for Windows games
- Windows setup executables (INSTALL.EXE) can't run in DOSBox anyway
2026-05-28 14:57:13 +02:00
Hermes Agent 733bdaa44f Fix js-dos ZIP extraction: write dirs shallowest-first, then files
Build & Deploy / build-and-deploy (push) Successful in 1m40s
js-dos v8's C extraction code (jsdos-libzip.c) iterates ZIP entries
linearly and calls mkdir() on each directory entry. If a child
directory appears before its parent, mkdir() fails with perror()
and exit(1) — fatal crash with 'No such file or directory'.

Previous approach wrote directory entries interleaved with files,
deepest-first (from the file path right-to-left). Now:

Phase 1: Walk entire file tree to discover ALL directories
Phase 2: Write ALL dir entries sorted (shallowest first via TreeSet
         natural ordering — '/' sorts before any letter)
Phase 3: Write .jsdos/ config files
Phase 4: Write game files (parents already exist from Phase 2)

This guarantees that mkdir("NAS50TH/TRACKS/") runs before
mkdir("NAS50TH/TRACKS/WILKES/"), which runs before open().
2026-05-28 14:43:28 +02:00
Hermes Agent f9967eacf8 Auto-exclude disk image files (.img .iso .ccd .sub etc.) from .jsdos bundles
Build & Deploy / build-and-deploy (push) Successful in 48s
Many DOS game ZIPs include CloneCD backups (.ccd/.img/.sub) or
other disk images that are not needed for gameplay — the game data
is already extracted in the working directory. These can be 300MB+
and cause WASM memory exhaustion in js-dos.

Added a SKIP_EXT set that filters out known disk image extensions
during game file pass. The .jsdos config pass is unaffected.
2026-05-28 13:54:56 +02:00
Hermes Agent eb37cd43bb Fix ZIP entry order: write .jsdos/ config first, then game files sorted
Build & Deploy / build-and-deploy (push) Successful in 40s
js-dos reads ZIP entries sequentially and needs .jsdos/dosbox.conf and
.jsdos/jsdos.json first to configure DOSBox. Java's Files.walk() uses
filesystem readdir order which put them at the very end of the ZIP
(after the 328MB CloneCD image), causing extraction failures.

Now:
1. First pass: walk .jsdos/ directory and write config files first
2. Second pass: walk everything else (excluding .jsdos/) in sorted order
3. All directory ancestors are still added as explicit entries
4. .sorted() ensures deterministic, alphabetical entry order
2026-05-28 13:47:52 +02:00
Hermes Agent 8f14ecb5a1 Fix nested directory entries: add full ancestor chain to ZIP
Build & Deploy / build-and-deploy (push) Successful in 45s
Previously only the immediate parent directory was added as a ZIP
entry. For deeply nested paths like NAS50TH/TRACKS/WILKES/WILKES.DAT,
only NAS50TH/TRACKS/WILKES/ was created — but NAS50TH/TRACKS/ and
NAS50TH/ were skipped (they're only parents of other directories,
never the immediate parent of a file).

Emscripten's FS.createDirectory() fails if parent doesn't exist,
so intermediate directories must be in the ZIP too.

Now walks up the full ancestor chain with a while loop.
2026-05-28 13:37:21 +02:00
Hermes Agent 5a3500c586 Fix js-dos ZIP extraction: add explicit directory entries to bundles
Build & Deploy / build-and-deploy (push) Successful in 46s
js-dos uses Emscripten's virtual filesystem which requires explicit
ZIP directory entries (names ending with '/') to create directories.
Java's ZipOutputStream only writes file entries, so subdirectories
like NAS50TH/TRACKS/WILKES/ were never created — causing Emscripten
'No such file or directory' errors for any path inside them.

- createBundle: before writing each file entry, add its parent
  directory as an explicit ZIP entry if not already added
- Affects all games with subdirectory structures (NASCAR Racing 2,
  Gus Goes to Cyberopolis, etc.)
- Use a HashSet to track already-added directories (no duplicates)
2026-05-28 13:28:10 +02:00
Hermes Agent 65e098244a Add platform auto-detection and UI flagging for Windows games
Build & Deploy / build-and-deploy (push) Successful in 49s
- Game.java: add 'platform' field ('dos'/'windows') + 'isPlayable' helper
- UploadResource.java: detect EXE type by reading PE/NE header during upload
- GameResource.java: allow PATCH to update platform
- GameCard.svelte: show 🪟 Win badge for Windows games (blue style)
- GameDetail.svelte: show platform badge, disable Play for Windows with
  'Unplayable' button; add platform dropdown to edit form
- Play.svelte: show blocking overlay for Windows games with 'Try anyway'
  option for users who want to attempt it
2026-05-28 13:16:04 +02:00
Hermes Agent efa0aa5f81 Fix MoO2 subdirectory bug + remove sockdrive references
Build & Deploy / build-and-deploy (push) Successful in 36s
- Fix flattenSingleDir: flatten when exactly 1 root directory exists,
  even if other metadata files (file_id.diz, *.nfo) are present at root
- Fix buildDosboxConf/buildJsdosJson: add 'cd <dir>' before executable
  when it lives in a subdirectory, since DOS treats '/' as switch char
  (previously 'mastori2/ORION2.EXE' was parsed as command 'mastori2'
  with switch '/ORION2.EXE')
- Remove SockdriveResource.java entirely
- Remove bundleType field from Game.java (was 'standard'/'sockdrive')
- Simplify GameResource.java download endpoint
- Clean up upload resource
2026-05-28 12:10:43 +02:00
David Alvarez ba34065278 fix: remove zos.setLevel(0) from createBundle — default DEFLATE is more reliable with emscripten libzip extraction
Build & Deploy / build-and-deploy (push) Successful in 17s
2026-05-28 10:06:28 +02:00
David Alvarez e11f19c769 fix: remove sockdrive mode, always create .jsdos ZIP bundles
Build & Deploy / build-and-deploy (push) Successful in 40s
js-dos v8's window.Dos(container, { url }) expects the URL to point
to a .jsdos ZIP archive, not a loose dosbox.conf file. The
'sockdrive' mode was serving game files loosely with a URL pointing
to a raw config file, causing: 'Unable to add .jsdos/jsdos.json
into bundle.zip'.

Changes:
- Removed SOCKDRIVE_THRESHOLD_MB and the entire sockdrive branch
- Always create a .jsdos ZIP bundle via createBundle()
- Optimized createBundle: no temp dir copy (saves 2x I/O for large
  games), uses STORE compression (level 0) since DOS files are
  often already compressed
- Removed dirSizeMB(), copyDir() and setup config builders —
  no longer needed after removing sockdrive mode
- frontend bundleUrl()/setupBundleUrl() always use the standard
  /games/{id}.jsdos path
- GameService.delete cleanup simplified
2026-05-28 09:45:45 +02:00
David Alvarez 6840b3eee1 fix: raise upload limit from 200MB to 2048MB for large DOS games
Build & Deploy / build-and-deploy (push) Successful in 56s
The previous 200M limit on quarkus.http.limits.max-body-size and
multipart input-part.max-size rejected games over 200MB. DOS CD-ROM
games can easily exceed this (e.g. DOOM 95 full CD, Diablo). Raised
to 2048M to cover the largest DOS/CD-ROM game archives.
2026-05-28 09:32:33 +02:00
David Alvarez 5f5cb8411f feat: SETUP.EXE detection + separate setup .jsdos bundle
Build & Deploy / build-and-deploy (push) Successful in 1m1s
When a game archive contains SETUP.EXE, INSTALL.EXE, CONFIG.EXE or
CUSTOM.EXE (or .com/.bat variants), the upload now:

- Detects and stores the path in game metadata (setup_exe / has_setup)
- Generates a second .jsdos bundle with SETUP.EXE as autoexec:
  - Standard mode: {gameId}.setup.jsdos (full game + setup autoexec)
  - Sockdrive mode: .jsdos-setup/ directory alongside .jsdos/
- Both bundles share the same game files; only the autoexec differs

Frontend changes:
- Router strips query params from hash so ?setup=1 doesn't leak into id
- GameDetail shows a "Setup" button between Play and Edit (only when
  game.has_setup is true), navigating to /play/{id}?setup=1
- Play.svelte detects ?setup=1, loads setupBundleUrl() instead, and
  shows setup-specific overlay text

Persistence is handled automatically by js-dos v8 via the built-in
auto-save mechanism (ci.persist() → browser OPFS), so any config
changes made via SETUP.EXE survive across sessions.
2026-05-27 16:49:15 +02:00
David Alvarez 00267da3dd fix: manual title input searches IGDB first, warns before uploading
Build & Deploy / build-and-deploy (push) Successful in 45s
Flow when auto-search finds nothing:
1. User types a title → presses Enter/clicks button
2. System searches IGDB with that title
3a. Results found → shown as selectable cards
3b. No results → warning + amber 'Upload anyway as xxx' button
4. Button label changes: 'Search' → 'Upload' after manual search

Also changed Enter key behavior: first press searches, second
press uploads (if no results after manual search)
2026-05-27 11:57:16 +02:00
David Alvarez 61a83cff65 fix: increase max upload body size to 200MB
Build & Deploy / build-and-deploy (push) Successful in 46s
Quarkus defaults to 10MB max body size. DOS games like
Warcraft 2 (50-100MB) were silently rejected. Added:
- quarkus.http.limits.max-body-size=200M
- quarkus.resteasy-reactive.multipart.input-part.max-size=200M
2026-05-27 11:49:45 +02:00
David Alvarez 72391fb577 feat: auto-search IGDB on file select, pick match or type custom title
Build & Deploy / build-and-deploy (push) Successful in 54s
Upload flow is now:
1. Click +Upload → select a .zip file
2. IGDB is auto-searched with the filename
3. If matches found → show results as selectable cards + fallback
   custom title search at the bottom
4. If no matches → show 'no matches' + manual title + Upload btn
   + a fallback 'Use filename: xxx' button
5. Clicking a result uploads immediately with that game's title
   (so IGDB auto-scrape picks it up correctly)
6. Cancel button to dismiss
2026-05-27 11:25:03 +02:00
David Alvarez 3c49d72f56 refactor: flatten ZIP single-root-directory instead of path splitting
Build & Deploy / build-and-deploy (push) Successful in 1m45s
Completely new approach:
- After unzip, check if extractDir has exactly one entry (a directory)
- If so, move all its contents up and delete the empty folder
- This means game files are always at the bundle root (c:\)
- No more cd/subdirectory handling in config builders
- No more path separator conversions (forward/backslash)
- Removed splitPath() helper entirely
- Config builders are now trivial — relExe is always just a filename
2026-05-27 11:07:39 +02:00
David Alvarez e7b845e8a1 clean: remove all Doom-specific logic, fix path separator in jsdos.json
Build & Deploy / build-and-deploy (push) Successful in 1m5s
Removed:
- injectDoomConfig() — WAD-detection and WASD config injection
- buildDoomDefaultCfg() — Doom config file generator
- All calls to injectDoomConfig in both bundle paths

Fixed:
- buildJsdosJson() now also uses splitPath() helper to handle
  backslash separators (was using lastIndexOf('/') only)
- Extracted shared splitPath() method used by both
  buildJsdosJson and buildDosboxConf

No more game-specific hacks. Just clean config generation.
2026-05-27 10:48:38 +02:00
David Alvarez 596b897df6 fix: use backslash path separator for DOS paths
Build & Deploy / build-and-deploy (push) Successful in 49s
extractDir.relativize() returns paths with native Linux forward
slashes. DOS requires backslashes. Changed .replace('\', '/')
to .replace('/', '\') and updated buildDosboxConf split logic
to also check for backslash separator.
2026-05-27 10:41:45 +02:00
David Alvarez 542db6a916 Fix: handle DOS games in subdirectories inside .jsdos bundles
Build & Deploy / build-and-deploy (push) Successful in 48s
When a ZIP contains game files in a subdirectory (e.g. doomiido/),
findMainExe() correctly finds the executable but the bundle autoexec
was using just the filename, causing DOSBox 'Illegal command' error.

- Use extractDir.relativize() to compute the relative exe path
- buildDosboxConf() now adds 'cd dirname' before running the exe
- buildJsdosJson() uses 'cd dirname && exe' for multi-line script
- Fix applies to both sockdrive and standard bundle paths
2026-05-27 10:36:44 +02:00