Skip to content

stats#3800

Draft
evanpelle wants to merge 1 commit intomainfrom
stats-fix
Draft

stats#3800
evanpelle wants to merge 1 commit intomainfrom
stats-fix

Conversation

@evanpelle
Copy link
Copy Markdown
Collaborator

If this PR fixes an issue, link it below. If not, delete these two lines.
Resolves #(issue number)

Description:

Describe the PR.

Please complete the following:

  • I have added screenshots for all UI updates
  • I process any text displayed to the user through translateText() and I've added it to the en.json file
  • I have added relevant tests to the test directory
  • I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced

Please put your Discord username so you can be contacted if a bug or regression is found:

DISCORD_USERNAME

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 29, 2026

Walkthrough

Winner-vote aggregation logic has been modified to group votes using a SHA-256 hash derived from both the winner choice and all player statistics, applying deterministic JSON serialization with a custom replacer function, replacing the previous direct stringification approach.

Changes

Cohort / File(s) Summary
Vote Aggregation Logic
src/server/GameServer.ts
Modified winner-vote grouping mechanism to use SHA-256 digest computed from both clientMsg.winner and clientMsg.allPlayersStats with a replacer function, changing how vote equality is determined while preserving vote-counting and selection control flow.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🎮 Votes now hashed with double weight,
Winner and stats must correlate,
SHA-256 seals the game's debate,
Fairness fortified, no room to cheat! ✨

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description contains only boilerplate template text with incomplete checklists and placeholders; it does not describe any actual changes made in the pull request. Replace the template with a concrete description of the changes, including why the SHA-256 digest approach was adopted and how it affects vote aggregation behavior.
Title check ❓ Inconclusive The title 'stats' is vague and does not clearly describe the main change; it could refer to any modification related to statistics without providing meaningful context about the actual implementation change. Revise the title to be more specific about the core change, such as 'Use SHA-256 digest for winner-vote aggregation' or similar descriptive phrasing that clarifies what was modified.
✅ Passed checks (3 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/server/GameServer.ts`:
- Around line 1204-1214: The code that computes winnerKey currently
canonicalizes the payload using the replacer before hashing, which removes
property-order differences used as a tamper signal; in the createHash(...) block
that builds winnerKey (referencing createHash, winnerKey, replacer,
clientMsg.winner, clientMsg.allPlayersStats, and JSON.stringify), stop passing
the replacer to JSON.stringify so the raw serialization (including original
property order) is hashed instead—keep the same createHash(...).digest("hex")
flow but use JSON.stringify({...}) without the replacer to preserve
ordering-based tamper detection.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 15a471d0-6a01-4965-bc50-81854c5bb650

📥 Commits

Reviewing files that changed from the base of the PR and between dd52e97 and e5d6096.

📒 Files selected for processing (1)
  • src/server/GameServer.ts

Comment thread src/server/GameServer.ts
Comment on lines +1204 to +1214
const winnerKey = createHash("sha256")
.update(
JSON.stringify(
{
winner: clientMsg.winner,
allPlayersStats: clientMsg.allPlayersStats,
},
replacer,
),
)
.digest("hex");
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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Do not canonicalize winner votes before grouping.

Using replacer on Line 1211 removes key-order differences, so a modified client can submit the same winner payload with reordered properties and still be counted with honest votes. This vote path intentionally used raw JSON.stringify ordering as part of the tamper signal, so keep the hash if you want, but hash the raw serialization instead.

🔧 Proposed fix
     const winnerKey = createHash("sha256")
       .update(
-        JSON.stringify(
-          {
-            winner: clientMsg.winner,
-            allPlayersStats: clientMsg.allPlayersStats,
-          },
-          replacer,
-        ),
+        JSON.stringify({
+          winner: clientMsg.winner,
+          allPlayersStats: clientMsg.allPlayersStats,
+        }),
       )
       .digest("hex");

Based on learnings, "In voting systems, using JSON.stringify for object comparison can be intentionally kept to detect modified clients - if property ordering differs from expected, it may indicate client tampering and should be treated as separate votes for security reasons."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/server/GameServer.ts` around lines 1204 - 1214, The code that computes
winnerKey currently canonicalizes the payload using the replacer before hashing,
which removes property-order differences used as a tamper signal; in the
createHash(...) block that builds winnerKey (referencing createHash, winnerKey,
replacer, clientMsg.winner, clientMsg.allPlayersStats, and JSON.stringify), stop
passing the replacer to JSON.stringify so the raw serialization (including
original property order) is hashed instead—keep the same
createHash(...).digest("hex") flow but use JSON.stringify({...}) without the
replacer to preserve ordering-based tamper detection.

@github-project-automation github-project-automation Bot moved this from Triage to Development in OpenFront Release Management Apr 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Development

Development

Successfully merging this pull request may close these issues.

1 participant