/// <summary> /// Saves the local stack traces (saved by calls to <see cref="TryAddStackTraceForDesyncLog"/>) around the area /// where a desync occurred to disk, and sends a packet to the arbiter (via the host) to make it do the same /// </summary> /// <param name="local">The local client's opinion, to dump the stacks from</param> /// <param name="remote">A remote client's opinion, used to find where the desync occurred</param> private void SaveStackTracesToDisk(ClientSyncOpinion local, ClientSyncOpinion remote) { Log.Message($"Saving {local.desyncStackTraces.Count} traces to disk"); //Find the length of whichever stack trace is shorter. int diffAt = -1; int count = Math.Min(local.desyncStackTraceHashes.Count, remote.desyncStackTraceHashes.Count); //Find the point at which the hashes differ - this is where the desync occurred. for (int i = 0; i < count; i++) { if (local.desyncStackTraceHashes[i] != remote.desyncStackTraceHashes[i]) { diffAt = i; break; } } if (diffAt == -1) { diffAt = count; } //Dump the stack traces to disk File.WriteAllText("local_traces.txt", local.GetFormattedStackTracesForRange(diffAt - 40, diffAt + 40)); //Trigger a call to ClientConnection#HandleDebug on the arbiter instance so that arbiter_traces.txt is saved too Multiplayer.Client.Send(Packets.Client_Debug, local.startTick, diffAt - 40, diffAt + 40); }
/// <summary> /// Get a nicely formatted string containing local stack traces (saved by calls to <see cref="TryAddStackTraceForDesyncLog"/>) /// around the area where a desync occurred /// </summary> /// <param name="dumpFrom">The client's opinion to dump the stacks from</param> /// <param name="compareTo">Another client's opinion, used to find where the desync occurred</param> /// <returns></returns> private string GetDesyncStackTraces(ClientSyncOpinion dumpFrom, ClientSyncOpinion compareTo, out int diffAt) { //Find the length of whichever stack trace is shorter. diffAt = -1; int count = Math.Min(dumpFrom.desyncStackTraceHashes.Count, compareTo.desyncStackTraceHashes.Count); //Find the point at which the hashes differ - this is where the desync occurred. for (int i = 0; i < count; i++) { if (dumpFrom.desyncStackTraceHashes[i] != compareTo.desyncStackTraceHashes[i]) { diffAt = i; break; } } if (diffAt == -1) { diffAt = count; } return(dumpFrom.GetFormattedStackTracesForRange(diffAt - 40, diffAt + 40, diffAt)); }