mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-23 11:40:23 +00:00
sec: require strict majority in 1v1 winner-vote consensus (backport) (#4581)
**Add approved & assigned issue number here:** Resolves #4136 ## Description: Backport of #4580 to `main`. `VoteRound.result()` (used by `handleWinner` in `GameServer.ts` to reach consensus on a reported game winner) accepted an exact tie as a majority: `votes * 2 >= totalUniqueIPs`. In a 1v1 game the electorate is 2 unique IPs, so a single client's vote alone satisfied `1 * 2 >= 2` and was accepted immediately — letting one player unilaterally declare themselves the winner without any agreement from the other player, and without the server ever checking the report against the actual simulation outcome. This fixes the comparison to require a strict majority (`votes * 2 > totalUniqueIPs`), so a 1v1 now requires both clients to agree. Legitimate forfeit-on-disconnect is unaffected: once a player actually disconnects, the electorate shrinks to 1 unique IP, and the sole remaining vote still resolves immediately (`1 * 2 > 1`). The `v32` hotfix (#4580) is being deployed first; this PR keeps `main` in sync with the same fix. ## Please complete the following: - [x] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] I have added relevant tests to the test directory ## Please put your Discord username so you can be contacted if a bug or regression is found: jish
This commit is contained in:
@@ -22,10 +22,13 @@ export class VoteRound<T> {
|
||||
}
|
||||
|
||||
// Returns the winning value once some candidate holds a strict majority of
|
||||
// `totalUniqueIPs` (votes * 2 >= total), else null.
|
||||
// `totalUniqueIPs` (votes * 2 > total), else null. A tie (e.g. 1 of 2 IPs)
|
||||
// does not count as a majority: with exactly 2 electors, both must agree,
|
||||
// otherwise one of two players in a 1v1 could unilaterally declare
|
||||
// themselves the winner. (#4136)
|
||||
result(totalUniqueIPs: number): { value: T; votes: number } | null {
|
||||
for (const candidate of this.candidates.values()) {
|
||||
if (candidate.ips.size * 2 >= totalUniqueIPs) {
|
||||
if (candidate.ips.size * 2 > totalUniqueIPs) {
|
||||
return { value: candidate.value, votes: candidate.ips.size };
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user