mirror of
https://github.com/InstanceBrick/nightcap.git
synced 2026-10-23 23:01:38 +02:00
* Stop rehashing and recopying the payload during install A first install prepares a ~635 MiB payload, then hashes the whole tree five times and byte-copies it once more into the store. Four of those five passes re-derive digests the same process just computed, under the same lock. PreparePayloadFromArchives hashed the tree to write roblox_payload.json and then immediately verified those hashes against the file it had just written. PayloadStore::Stage hashed the same workspace again before copying it, and Promote hashed the published directory a third time. The guarantee that matters is unchanged: the bytes that land in the immutable store are still hashed in full after the copy. Stage now records which payload it verified, so promotion skips the repeat only for a payload this instance staged; an operator-supplied ID, a directory left by an earlier run, or a fresh process still gets the complete pass. CopyTree now reflinks (FICLONE) or uses copy_file_range before falling back to an ordinary copy, so on btrfs and xfs the staging copy costs no data movement and no extra space. A hard link would be wrong here: CopyTree makes the result read-only while the source stays writable. File hashing moves from the portable foundation::Sha256 to OpenSSL, which reaches the CPU's SHA extensions, and the asset tree hashes its files across cores. Measured on this machine: 182 MB/s to 1518 MB/s, and the 1835-file asset tree of Roblox 2.734.917 reproduces its recorded sha256_tree exactly. MOCKTAIL_UPDATE_TRACE=1 now reports the elapsed time of each install stage, so the breakdown is visible instead of inferred. * Hide the system cursor as soon as the window regains focus Roblox draws its own cursor while it owns the pointer, so Mocktail hides the system one. Losing focus reveals it again, which is right, but regaining focus only set the focused flag and left the re-apply to the next Pump(). Pump() runs at the top of PumpEvents(), before SDL_PollEvent delivers SDL_EVENT_WINDOW_FOCUS_GAINED, so the desktop arrow stayed on screen for at least one whole frame after every alt-tab back into the game, and longer whenever the frame was long. OnFocusGained now pumps the pointer state in the same call, mirroring OnFocusLost and OnRightButton, and its failure is reported like the focus-loss path. An active text field still keeps the system cursor, focused or not. * Cover promotion of a payload the store did not stage Stage() now lets promotion skip the repeat hash for a payload it just wrote, so the boundary of that shortcut needs a test. Nothing covered it: the existing corruption test rewrites roblox_payload.json, which the metadata check catches on its own, and payload_store_test.sh exercises the shell store rather than this class. The new test corrupts only the content bytes, leaving the metadata describing the original payload, then promotes from a second PayloadStore instance. It fails if the shortcut is ever allowed to apply to a payload this instance did not stage. * Restore the full hash at the promotion gate Skipping the rehash for a payload the same instance staged was wrong. The readiness canaries run between Stage() and Promote(): they spawn the real client against the staged directory, for up to 150 seconds, twice for a probation candidate. Trusting the earlier hash across that window drops a deliberate control, and payload_store_test.sh already spelled out why it is there. Promote() and PromoteProbation() call VerifyPreparedPayload() again, as before. The instance no longer tracks what it staged. The two tests now tamper with a staged payload from the instance that staged it, which is the case that was missing: content bytes only, metadata left describing the original payload, so nothing short of hashing the contents can detect it. One covers the asset tree, the other libroblox.so. Promotion still costs a complete pass over ~635 MiB, but OpenSSL and the parallel asset hash make it 3.9 s -> 0.55 s. Stage is 9.5 s -> 0.93 s. A traced install reports promote at 656 ms.