Request resync instead of crashing on missing Shardok results (#4622)

* Request resync instead of crashing on missing Shardok results

When HandleUpdates detects missing results (expected > existing + new),
likely due to dropped packets on bad network, request a full resync
instead of throwing an exception.

Changes:
- ShardokGameModel.HandleUpdates now returns bool (true=ok, false=need resync)
- EagleGameModel marks game for resync and clears history on mismatch
- CustomBattleHandler clears history and continues on mismatch

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Add missing UnityEngine using statement for Debug.Log

Fixes build error: error CS0103: The name 'Debug' does not exist in the current context

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
2025-12-03 20:45:41 -08:00
committed by GitHub
co-authored by Claude
parent 7db07dc371
commit 83c4ac7d38
3 changed files with 26 additions and 5 deletions
@@ -187,9 +187,14 @@ public class CustomBattleHandler : MonoBehaviour, IClientConnectionSubscriber {
case GameUpdate.GameUpdateDetailsOneofCase.ShardokActionResultResponse:
foreach (var resp in gameUpdate.ShardokActionResultResponse
.ShardokGameResponses) {
_shardokModel.HandleUpdates(
var updatesOk = _shardokModel.HandleUpdates(
resp.ActionResultViews,
resp.NewResultViewCount);
if (!updatesOk) {
// In custom battle mode, just clear and continue
_shardokModel.History.Clear();
continue;
}
_shardokModel.HandleAvailableCommands(resp.AvailableCommands);
}
@@ -316,9 +316,17 @@ namespace eagle {
}
}
shardokGameModel.HandleUpdates(
var updatesOk = shardokGameModel.HandleUpdates(
oneResponse.ActionResultViews,
oneResponse.NewResultViewCount);
if (!updatesOk) {
// Missing results - mark for resync and clear history
MarkShardokForResync(oneResponse.ShardokGameId);
shardokGameModel.History.Clear();
continue;
}
shardokGameModel.HandleAvailableCommands(oneResponse.AvailableCommands);
// Clear resync flag after successfully receiving updates
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using eagle;
using eagle0;
using UnityEngine;
using Net.Eagle0.Shardok.Api;
using Net.Eagle0.Shardok.Common;
using UnityGoDiceInterface;
@@ -173,7 +174,10 @@ public class ShardokGameModel {
return null;
}
public void HandleUpdates(
/// <summary>
/// Returns true if updates were handled successfully, false if a resync is needed.
/// </summary>
public bool HandleUpdates(
IEnumerable<ActionResultView> newHistory,
int expectedNewResultCount) {
var existingHistoryCount = History.Count();
@@ -182,12 +186,16 @@ public class ShardokGameModel {
var diff = existingHistoryCount + newHistoryCount - expectedNewResultCount;
History.RemoveRange(existingHistoryCount - diff, diff);
} else if (expectedNewResultCount > existingHistoryCount + newHistoryCount) {
throw new ArgumentException(
$"Should have {expectedNewResultCount} results but we have {existingHistoryCount + newHistoryCount}");
// Missing results - likely due to dropped packets on bad network.
// Request a full resync instead of crashing.
Debug.Log(
$"ShardokGameModel: Missing results (expected {expectedNewResultCount}, have {existingHistoryCount + newHistoryCount}). Requesting resync.");
return false;
}
foreach (ActionResultView entry in newHistory) { HandleNewHistoryEntry(entry); }
if (newHistoryCount > 0 && UpdateAction != null) { UpdateAction.Invoke(); }
return true;
}
public void HandleAvailableCommands(AvailableCommands newCommands) {