Repository navigation
Multiplayer review fixes: race messages carry their race number (0.4.1) - #6
Merged
Merged
Conversation
Session::resetReplication cleared the snapshot, ambient and traffic queues but not the players' inputs, the own-car states, the prop states or the rules states, so whatever a race left untaken was handed to the next one. And ENet holds unreliable packets under load, so an input could arrive after the next race had started: car states and inputs number their samples from 1 each race and carried no race number, so a host that took an input numbered 5000 dropped the client's real inputs (from 1) as already applied for about 83 s. The queues are now cleared between races, and Session stamps every race-time message (inputs, car states, traffic, props) with its race number and drops one from another race (protocol 19; the rules' messages already carried theirs). Found by the multiplayer code review. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- The joiner's password field takes 25 characters, as the host's does (both are UIMenu::AddTextField with 0x19 in MM2): a host's 25-character password could not be typed, and five tries locked the joiner out. - A change to the shared cruise traffic (on/off, traffic and police density) clears a joiner's READY like every other host setting. - A player who quit the race is no longer sent the host's prop states: with no car it counted as near every slot and got them all, in full. - The debug autopilot keeps a destination it cannot route to instead of rebuilding its driver and logging every frame. - A client's input message is encoded once: Session::sendPlayerInput returns the bytes it sent, as the other send calls do. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The race number test now also sends race 2's input and car states and checks they arrive, so a mismatch between the stamping and the check would show as lost states rather than pass unnoticed. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The bundled DirectMusic library used C11 <threads.h> wherever the compiler had it, and MSVC's C11 threads live in vcruntime140_threads.dll (VS 2022 17.8+). The packages ship the other VC++ runtime DLLs but not that one, so openmm2.exe failed to load before main on a PC without a recent VC++ redistributable (found by unpacking the 0.4.0 installer and running it under Wine: status c0000135). MSVC now uses the library's Win32 threads, as MinGW already did. The Windows CI job could not see this, since its runner has Visual Studio: a new step reads every packaged program's and DLL's imports with dumpbin and fails when a VC++ runtime DLL is not in the package, or any other DLL is neither there nor part of Windows. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
When copying the game data failed, setup removed all of <install dir>\gamedata. On a reinstall or update over an installation that had copied the data already, a copy that then failed (a bad disc, a full drive) deleted the good copy too. Setup now notes whether gamedata\ was there before it copies. If it was not, everything in it came from this copy and is removed as before. If it was, nothing is removed (--import-source deletes its own .part files on failure and replaces an archive only once it is complete), and when the earlier copy still passes --check-source, openmm2-install.ini keeps pointing at it rather than at the source that just failed. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Setup now finds the installed version (HKLM\Software\OpenMM2: InstallDir, Version) and updates it in its folder: - The welcome page says what will happen: a new installation, an update from X to Y, a repair (the same version again) or a downgrade. An update skips the licence and directory pages, and the game data page, pre-filled from openmm2-install.ini as before, reads Install: Next, Next, Install. /D= still installs elsewhere. - An older setup asks before it replaces a newer version. A silent one refuses with exit code 3 unless given /ALLOWDOWNGRADE. - Before it changes anything, setup checks that openmm2.exe and mm2tool.exe are not running, by opening them for writing (a running program's executable cannot be), and asks to close OpenMM2 with Retry/Cancel. A silent install stops with exit code 4. The uninstaller checks too. - Setup writes install-manifest.txt, the list of the files it installed (generated with the File lists). Before copying the new files, an update removes the previous version's: those in its manifest, or, for 0.4.1 and earlier, which wrote none, every name those releases installed (LegacyFiles.nsh, from the release installers 0.1.0 to 0.4.0, which include the MSVC runtime DLLs) and this version installs. The uninstaller removes what the manifest lists, so files a newer version dropped no longer stay behind, and neither does the folder. Manifest entries that could reach outside the install folder, into gamedata\ or openmm2-install.ini are skipped. gamedata\, openmm2-install.ini and the per-user settings are never removed. - The choice of shortcuts and developer tools is recorded (StartMenuShortcut, DesktopShortcut, Tools) and preselected on the next update. For 0.4.1 and earlier, setup keeps what is there: a deleted shortcut is not created again. A shortcut that is switched off is removed. - /D= naming another folder moves the installation: the old folder loses its program files, uninstaller and firewall rule, keeps gamedata\ and openmm2-install.ini (whose game data the new installation keeps using), and is removed if nothing else is left. The registration stays single. - A file that cannot be written (another program holds it) stops setup (AllowSkipFiles off) instead of being skipped, which left an old file in place and still reported success. Such a failure ends with exit code 1, not NSIS's 2, which here means the /SOURCE game data was rejected. - A silent update that re-checks the last installation's game data (say, a disc that is not in the drive) keeps the setting instead of failing with exit code 2. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
RunWithProgress read the copy's output with System::Call '*$7(&m4096 .r3)'. For such an output the System plug-in allocates NSIS_MAX_STRLEN (1024) bytes and then copies all 4096 into them, so each chunk of output overran the heap by 3 KB. Under Wine this made setup crash on exit (access violation, exit code 0xC0000005) depending only on where things landed in memory: the same installer crashed every time from one path and never from another, and the 0.4.0 scripts do the same. Windows' heap is as likely to be hit. Read at most NSIS_MAX_STRLEN - 1 bytes per chunk and convert them with MultiByteToWideChar into a buffer of the right size, as UTF-8, which is what OpenMM2 prints. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
packaging/windows/test-installer.sh stages a Windows build's app and tools components, packs them into installers of made-up versions (one with extra files the next one drops) and builds the v0.4.0 installer scripts as the last release without update support. With synthetic game data (three small PKZIP .AR archives that pass --check-source) it checks, in fresh Wine prefixes, the installed files, install-manifest.txt, openmm2-install.ini, the registry and the shortcuts for: - a new installation, and uninstalling it; - an update from 0.4.0 (MSVC runtime DLLs removed, game data and settings kept, a deleted desktop shortcut not re-created, the tools kept), then through a version that drops files, a repair, a silent downgrade with and without /ALLOWDOWNGRADE, openmm2.exe held open and running (setup and uninstaller), another file held open, a copy of the game data that fails over an earlier copy, and a manifest with entries that point outside the folder or into the game data; - updates without game data, then uninstalling: nothing is left; - /D= moving the installation to another folder; - the wizard, driven by a small helper that reads and clicks it: the pages of a new installation and of an update (Next, Next, Install), the repair and downgrade texts, the downgrade question and the Retry/Cancel question while OpenMM2 runs. Wine uses its null graphics driver, so nothing appears on a desktop. The MinGW CI job runs it with the Windows makensis.exe 3.13 through Wine (NSIS is not packaged for Arch Linux), pinned by hash and cached. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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.
Fixes from the multiplayer code review after 0.4.0. Version 0.4.1; the network protocol goes to 19, so 0.4.0 and 0.4.1 can't play together.
Session::resetReplicationleft the players' inputs, own-car states, prop states and rules states queued from one race into the next.Sessionstamps every race-time message (inputs, car states, traffic, props) with its race number and drops mismatches. The rules' messages already carried theirs.AddTextField0x19 for both).Testing: 1051/1051 tests pass with game data, without it, and under
-D_GLIBCXX_ASSERTIONS.🤖 Generated with Claude Code