Conversation
IrPgFKS0
added a commit
to IrPgFKS0/BeamMP-Launcher
that referenced
this pull request
Sep 14, 2026
Same change submitted upstream as BeamMP#274 (draft), extracted against upstream/master; this region of the fork was byte-identical, so the patch is identical. Diagnosed from a report that the combined binary works on two CachyOS boxes but fails on Fedora with "The game directory was not found" followed by "cannot get file size: integrity.json" -- upstream issue BeamMP#251. Three defects in the __linux__ branch: 1. The candidate loop `break`s at the first steamapps dir that merely HAS a libraryfolders.vdf, not one that lists the game -- so a machine with both a native and a Flatpak Steam only ever gets the first examined. Every existing candidate is now searched. This is the likely Fedora cause (Steam there usually comes from Flathub while a stray ~/.steam/root sorts first) and explains why Arch-based boxes are unaffected: for them the first candidate IS the right one. 2. `childs["apps"]->attribs` is UB for a library entry with no "apps" block -- childs maps to shared_ptr, so operator[] inserts a value-initialised null and the -> dereferences it. Demonstrated against the vendored vdf_parser, not assumed: a two-entry vdf whose first library has no "apps" block yields nullptr for that key. Now find() + null check. 3. Every failure path returned with GameDir empty, and main() went on to PreGame(GetGameDir()) -> CheckVer() -> file_size() on a nonexistent path. That is the confusing second error users report; it is only a consequence of the first. They now throw a descriptive message. LegitimacyCheck() is already wrapped in a try/catch in main() that logs and rethrows -- that handler was simply unreachable for this path. Plus two missing Steam locations: ~/.local/share/Steam/steamapps (native install with no ~/.steam symlinks) and the Flatpak data directory proper (~/.var/app/com.valvesoftware.Steam/.local/share/Steam/steamapps). Case-sensitive path resolution is deliberately NOT included -- that is upstream's open BeamMP#259, and these compose with it rather than conflicting. The fork had previously skipped BeamMP#259 as "game-launch-on-Linux only, not our deployment"; Linux clients are now in scope, so it is worth revisiting separately. NOT BUILT: the container toolchain is down (Docker engine returning 500; WSL2 reports the Virtual Machine Platform disabled), so no Linux binary carries this yet and the exe version is deliberately NOT bumped. The new VDF logic was compiled and exercised with MSVC against the real parser header; the rest of the translation unit is unverified on GCC. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
IrPgFKS0
added a commit
to IrPgFKS0/BeamMP
that referenced
this pull request
Sep 14, 2026
… ledger Mod side is version + notes only -- the one real mod change in this build is the physmult global-leak fix already committed in f41d7bd, which had been sitting unbuilt since h98 went out. This is the build it rides into. The reason for the build is launcher-side: on Linux the client could fail to find BeamNG and quit with a misleading "cannot get file size: integrity.json". Reported as upstream issue BeamMP#251, reproduced by a user whose two CachyOS machines work and whose Fedora machine does not. Three causes, all in code this fork inherited byte-identically from upstream -- see BeamMP-Launcher b1938c6, offered upstream as BeamMP/BeamMP-Launcher#274. Ledger: h99 added, h96 demoted out of the "previous build" slot, kept-tag list extended to five (h99/h98/h96/h94/0.38-rollback). The AGPL source offer now names lan-release-p13h99 -- it must always name a tag that `git ls-remote --tags` actually shows, which is the invariant that had quietly broken before h98. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Author
|
Update: I was able to build this on Linux after all (my container toolchain is working again), so the caveat in the description about the full translation unit being unverified on GCC no longer applies — it compiles clean, and the resulting binary contains the new code paths. Still happy to rework or split this however suits you. |
… a null
Three separate reasons `LegitimacyCheck()` can fail to find BeamNG on Linux, all in the
`__linux__` branch of src/Security/BeamNG.cpp.
1. The candidate loop `break`s at the first steamapps directory that merely *has* a
libraryfolders.vdf, so if that Steam install is not the one the game is registered in,
the remaining candidates are never examined. A machine with both a native and a Flatpak
Steam only ever gets the first one looked at. Every candidate that exists is now
searched, and the loop stops when the game is actually found.
2. `folderInfo.second->childs["apps"]->attribs` is undefined behaviour for any library
entry without an "apps" block. `childs` is
`unordered_map<string, shared_ptr<basic_object>>`, so `operator[]` on a missing key
value-initialises a null `shared_ptr` and inserts it, and the `->` then dereferences
null. A library folder with no games installed has exactly that shape. Looked up with
`find()` and null-checked instead. (Verified against the vendored vdf_parser: parsing a
libraryfolders.vdf whose first entry has no "apps" block yields a null for that key.)
3. On failure the function returned with `GameDir` empty, and main() went straight on to
`PreGame(GetGameDir())` -> `CheckVer()` -> `std::filesystem::file_size()` on a path that
does not exist. Users therefore saw
[ERROR] The game directory was not found.
[ERROR] Exception in main(): filesystem error: cannot get file size:
No such file or directory [integrity.json]
and reported the second line, which is only a consequence of the first. These now throw
with a message that says what was looked for. `LegitimacyCheck()` is already called
inside a try/catch in main() that logs and rethrows, so this is the path that error
handling was written for; it was simply unreachable before.
Also adds two Steam locations that were missing: `~/.local/share/Steam/steamapps` (a native
install where the `~/.steam` symlinks are absent) and
`~/.var/app/com.valvesoftware.Steam/.local/share/Steam/steamapps` (Flatpak's real data
directory, rather than only the `.steam/root` symlink inside the sandbox).
Deliberately does NOT touch case-sensitive path resolution -- that is what BeamMP#259 addresses,
and these changes compose with it rather than conflicting.
Refs BeamMP#251
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three separate reasons
LegitimacyCheck()can fail to find BeamNG on Linux, all in the__linux__branch of
src/Security/BeamNG.cpp. Each is visible by reading the code; the second and third arealso demonstrable.
1. The search stops at the first Steam install
It breaks as soon as it finds a steamapps folder that merely has a
libraryfolders.vdf— not onethat actually lists the game. A machine with more than one Steam install (a native one plus Flatpak
is common) only ever gets the first examined; if the game is registered in the other, detection
fails even though everything is installed correctly.
Now every candidate that exists is searched, stopping when the game is actually found.
2. Null dereference on a library with no
appsblockchildsisunordered_map<string, shared_ptr<basic_object>>, sooperator[]on a missing keyvalue-initialises a null
shared_ptr, inserts it, and the->dereferences null. A libraryfolder entry with no games installed has exactly that shape.
I checked this against the vendored
vdf_parser.hpprather than assuming. Parsing:childs["apps"]yieldsnullptrfor entry"0". Withfind()+ a null check the entry isskipped and the game is correctly found in entry
"1".3. A detection failure is reported, then ignored
All three failure paths
returnwithGameDirempty, andmain()continues straight intoPreGame(GetGameDir())→CheckVer()→std::filesystem::file_size()on a path that does notexist. That is why the report in #251 shows two errors:
The second is only a consequence of the first, but it is the one that looks like the bug. These now
throw with a message saying what was searched for.
LegitimacyCheck()is already called insidea
try/catchinmain()that logs and rethrows — this change simply makes that handlerreachable; it could not fire for this path before.
Also
Two Steam locations that were missing from the candidate list:
~/.local/share/Steam/steamapps— a native install where the~/.steamsymlinks are absent~/.var/app/com.valvesoftware.Steam/.local/share/Steam/steamapps— Flatpak's real datadirectory, rather than only the
.steam/rootsymlink inside the sandboxScope
This deliberately does not touch case-sensitive path resolution. That is what #259 addresses,
and these changes compose with it rather than conflicting — if a library path's casing does not
match the disk, #259's resolver is still what is needed.
Refs #251.
Testing
Verified the new library-scanning logic against the real
vdf_parser.hpp: an entry without anappsblock is skipped rather than dereferenced, a vdf that does not list284160yields nothingso the outer loop continues, and the upstream expression is confirmed to produce the null described
above.
I was not able to run a full Linux build locally (my container toolchain is broken at the
moment), so the complete translation unit is unverified on GCC — hence draft. The change is
confined to the
__linux__branch and uses no API the surrounding code does not already use(
debug(std::string)appears a few lines above;.containsis already used onattribs).Transparency: this fix came out of debugging a LAN-only fork of the launcher, and was written with
AI assistance and reviewed by me. I am not making the template's self-authorship declaration, and
I am filing it as a draft so maintainers can decide how they want to treat it. Happy to rework,
split, or close it.