Skip to content

Reimplement synchronization hash with exact native byte matching - #219

Merged
TheRedDaemon merged 5 commits into
sourcehold:mainfrom
Krarilotus:feat/replay-sync-hash
Sep 7, 2026
Merged

Reimplement synchronization hash with exact native byte matching#219
TheRedDaemon merged 5 commits into
sourcehold:mainfrom
Krarilotus:feat/replay-sync-hash

Conversation

@Krarilotus

@KrarilotusKrarilotus commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

TL;DR: Reimplements the checksum used by the game's synchronization checks. Preserves the original calculation and documents its equivalent C++ loop beside the implementation.

DirectionAlgorithmState::computeHash at 0x0046CD30 adds each signed byte to a 32-bit accumulator and rotates it left once, processing one byte per four units of the supplied count. The assembly keeps the original 16-byte unrolled loop; the short C++ comment explains the same calculation without obscuring it with register details.

The current source was rebuilt into the full OpenSHC.dll with MSVC 2005 SP1 x86 and RelWithDebInfo. Reccmp reports 100% against Crusader 1.41 SHA256 3bb0a8c1e72331b3a30a5aa93ed94beca0081b476b04c1960e26d5b45387ac5a. The soft status entry is updated accordingly. A current Windows SDK manifest tool was used locally because the legacy tool crashes; no build override is part of the PR.

The PR contains the implementation and its status entry. Auxiliary validation scripts and their README were removed following review; native bytecode comparison is the verification basis. The DLL has not been deployed into a game.

@gynt

gynt commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

reccmp says 0% matching, how come?

---+++@@ -0x46cd30,12 +0x10007110,12 @@
0x46cd30 : -push ebp
0x46cd31 : -mov ebp, esp
0x46cd33 : -push ecx
0x46cd34 : -push ebx
0x46cd35 : -push esi
0x46cd36 : -mov dword ptr [ebp - 4], 0
0x46cd3d : -mov esi, dword ptr [ebp + 0xc]
0x46cd40 : -mov edx, dword ptr [ebp + 8]
0x46cd43 : -mov ecx, 0
0x46cd48 : -cmp edx, 0x40
0x46cd4b : -jl 0x77
0x46cd4d : -mov eax, dword ptr [esi]
: +mov edx, dword ptr [esp + 4] (computeHash.cpp:13)
: +xor eax, eax
: +cmp edx, 4
: +jl 0x13
: +mov ecx, dword ptr [esp + 8]
: +shr edx, 2
: +add eax, dword ptr [ecx] (computeHash.cpp:14)
: +add ecx, 4
: +rol eax, 1 (computeHash.cpp:15)
: +sub edx, 1
: +jne -0xc
: +ret 8 (computeHash.cpp:19)
OpenSHC::Map::Navigation::DirectionAlgorithmState::computeHash is only 0.00% similar to the original, diff above

@KrarilotusKrarilotus changed the title Reimplement synchronization hash with native equivalence checksReimplement synchronization hash with exact native byte matchingSep 5, 2026
@gynt

gynt commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Looks good now!

@TheRedDaemonTheRedDaemon left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A verification through an CPU emulator... that is certainly impressive.

@gynt, I also want you to weigh in on this:
I assume that, once the match is basically 100 percent, that one does not need such a verification, since it kinda is the prove that the code we have produces what the game runs.

I also think it would produce a lot of bloat if done for a lot of functions.
What I think could be practical instead would be tests like this for functions that we are unable to match, providing a bit of prove still.

I do not know, Krarilotus, if you use this to run the reimplementation process against, but it is very important that the verification is also or even primarily done against the bytecode of the game (with reccmp).

What you definitly can do if you want is provide an agent skill (in an extra PR) for creating something like this for a specific function, even if the actual validation script is not checked in. Might help creating others if needed.

Comment threadsrc/OpenSHC/Map/Navigation/DirectionAlgorithmState/computeHash.cpp Outdated
@Krarilotus

Copy link
Copy Markdown
ContributorAuthor

Addressed in 33ce4c2: the full readable C++ loop now sits directly above the inline assembly, including initialization, the byte-count condition and return. I also removed the investigation harness and its README from this PR; the final change is one implementation file.

The primary verification is against the original machine code. Freshly compiling the updated source still matches all 181 native function bytes in both executables. The assembly is unchanged from the isolated linked DLL that reported 100% reccmp at 0x46CD30. The 980 emulator cases per executable also still pass, but that supplementary tooling remains local. The PR description now leads with byte matching and gives the linked reccmp command.

@Krarilotus

Copy link
Copy Markdown
ContributorAuthor

Rechecked the current implementation against the review: the equivalent C++ loop is above the assembly, and the auxiliary test scripts/README are absent from the PR. I rebuilt the full RelWithDebInfo DLL with MSVC 2005 SP1; computeHash now has a fresh 100% reccmp result against the original executable. Added the missing soft status entry in 563ad67 and updated the description to reflect this verification.

@TheRedDaemonTheRedDaemon left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Look good. Thank you!

@TheRedDaemon
TheRedDaemon merged commit 527c3be into sourcehold:mainSep 7, 2026
1 check passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@Krarilotus@gynt@TheRedDaemon