Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of RustyHeathensServerSync v1.0.0
RustyHeathensServerSync.dll
Decompiled a week agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Security.Cryptography; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using HarmonyLib; using UnityEngine; [assembly: AssemblyCompany("RustyLaserGaming")] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyTitle("Rusty Heathens ServerSync")] [assembly: AssemblyDescription("Heathens' Haven desync diagnostics and guarded bounded scheduler. Reviewed for Valheim 1.0.17 / network 40.")] [assembly: AssemblyProduct("Rusty Heathens ServerSync")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: CompilationRelaxations(8)] [assembly: AssemblyVersion("1.0.0.0")] namespace RustyHeathens.ServerSync; internal static class CompatibilityRules { internal static bool IsSupported(string gameVersion, uint networkVersion) { if (networkVersion != 40) { return false; } if (!(gameVersion == "1.0.16")) { return gameVersion == "1.0.17"; } return true; } } internal static class MethodFingerprint { private static readonly Dictionary<ushort, OpCode> Codes = MakeCodes(); private static Dictionary<ushort, OpCode> MakeCodes() { Dictionary<ushort, OpCode> dictionary = new Dictionary<ushort, OpCode>(); FieldInfo[] fields = typeof(OpCodes).GetFields(BindingFlags.Static | BindingFlags.Public); foreach (FieldInfo fieldInfo in fields) { if (!(fieldInfo.FieldType != typeof(OpCode))) { OpCode value = (OpCode)fieldInfo.GetValue(null); dictionary[(ushort)value.Value] = value; } } return dictionary; } internal static string Raw(MethodInfo method) { if (method == null || method.GetMethodBody() == null) { return "missing"; } return Hash(method.GetMethodBody().GetILAsByteArray()); } internal static string Normalized(MethodInfo method) { if (method == null || method.GetMethodBody() == null) { return "missing"; } byte[] iLAsByteArray = method.GetMethodBody().GetILAsByteArray(); StringBuilder stringBuilder = new StringBuilder(); int num = 0; while (num < iLAsByteArray.Length) { ushort num2 = iLAsByteArray[num++]; if (num2 == 254) { Need(iLAsByteArray, num, 1); num2 = (ushort)(0xFE00 | iLAsByteArray[num++]); } if (!Codes.TryGetValue(num2, out var value)) { throw new InvalidOperationException("Unknown IL opcode."); } stringBuilder.Append(num2.ToString("x4", CultureInfo.InvariantCulture)).Append(':'); int num3 = 0; switch (value.OperandType) { case OperandType.ShortInlineBrTarget: case OperandType.ShortInlineI: case OperandType.ShortInlineVar: num3 = 1; break; case OperandType.InlineVar: num3 = 2; break; case OperandType.InlineBrTarget: case OperandType.InlineI: case OperandType.ShortInlineR: num3 = 4; break; case OperandType.InlineI8: case OperandType.InlineR: num3 = 8; break; case OperandType.InlineSwitch: { Need(iLAsByteArray, num, 4); int num4 = BitConverter.ToInt32(iLAsByteArray, num); if (num4 < 0 || num4 > 10000) { throw new InvalidOperationException("Invalid switch."); } num3 = checked(4 + num4 * 4); break; } case OperandType.InlineField: case OperandType.InlineMethod: case OperandType.InlineTok: case OperandType.InlineType: { Need(iLAsByteArray, num, 4); MemberInfo memberInfo = method.Module.ResolveMember(BitConverter.ToInt32(iLAsByteArray, num)); Type type = memberInfo as Type; if (type != null) { stringBuilder.Append(type.Name); } else { stringBuilder.Append(memberInfo.DeclaringType.Name).Append("::").Append(memberInfo.Name); } num += 4; break; } case OperandType.InlineString: Need(iLAsByteArray, num, 4); stringBuilder.Append("string:").Append(method.Module.ResolveString(BitConverter.ToInt32(iLAsByteArray, num))); num += 4; break; default: throw new InvalidOperationException("Unsupported IL operand in guard."); case OperandType.InlineNone: break; } Need(iLAsByteArray, num, num3); for (int i = 0; i < num3; i++) { stringBuilder.Append(iLAsByteArray[num++].ToString("x2", CultureInfo.InvariantCulture)); } stringBuilder.Append('\n'); } return Hash(Encoding.UTF8.GetBytes(stringBuilder.ToString())); } private static void Need(byte[] bytes, int offset, int size) { if (size < 0 || offset < 0 || offset > bytes.Length - size) { throw new InvalidOperationException("Truncated IL method."); } } private static string Hash(byte[] bytes) { using SHA256 sHA = SHA256.Create(); byte[] array = sHA.ComputeHash(bytes); return BitConverter.ToString(array).Replace("-", "").ToLowerInvariant(); } } public enum SyncMode { Observe, BoundedScheduler } [BepInPlugin("com.rustylasergaming.serversync", "Rusty Heathens ServerSync", "1.0.0")] public sealed class Plugin : BaseUnityPlugin { internal sealed class PeerStats { internal string Label; internal readonly RunningStats SendDuration = new RunningStats(); internal int QueuePeak; internal int LastQueue; internal long QueueLimitedAttempts; internal long CallsWithoutData; internal int PingMs; internal float QualityLocal; internal float QualityRemote; internal float OutBytesSec; internal float InBytesSec; internal string Transport; internal bool TransportStatsAvailable; internal bool TransportStatsUnsupportedLogged; internal long LastCycleStart; internal readonly RunningStats VisitGap = new RunningStats(); } public const string PluginId = "com.rustylasergaming.serversync"; public const string PluginName = "Rusty Heathens ServerSync"; public const string PluginVersion = "1.0.0"; internal static Plugin Current; private ConfigEntry<SyncMode> mode; private ConfigEntry<bool> diagnostics; private ConfigEntry<int> reportSeconds; private ConfigEntry<int> maxCalls; private ConfigEntry<float> budgetMs; private ConfigEntry<float> maxFrameMs; private ConfigEntry<float> saveCooldownSeconds; private Harmony harmony; private bool bindingsReady; private bool schedulerCompatible; private bool schedulerFaulted; private bool overlappingPatches; private bool otherNetworkPlugin; private bool diagnosticFaulted; private bool isServer; private bool isDedicated; private ZNet lastNet; private double nextReport; private double nextPeerSample; private double nextConflictCheck; private double lastSave = -1000000.0; private int nextLabel = 1; private long extraCalls; private long reportSerial; private string lastEffectiveState = ""; [ThreadStatic] internal static bool ExtraInvocation; private readonly RunningStats frames = new RunningStats(); private readonly RunningStats cycles = new RunningStats(); private readonly RunningStats saveDispatch = new RunningStats(); private readonly Dictionary<ZNetPeer, PeerStats> peers = new Dictionary<ZNetPeer, PeerStats>(); private static readonly object[] ZeroDt = new object[1] { 0f }; internal static readonly BindingFlags InstanceFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; internal static MethodInfo SendCycle; internal static MethodInfo SendOne; internal static MethodInfo SaveWorld; internal static FieldInfo NextPeer; internal static FieldInfo ZdoPeers; internal static FieldInfo WrappedPeer; internal static double Now => (double)Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency; internal bool Measuring { get { if (bindingsReady && diagnostics.Value) { return !diagnosticFaulted; } return false; } } private bool ExtraEnabled { get { if (bindingsReady && schedulerCompatible && !schedulerFaulted && !overlappingPatches && !otherNetworkPlugin && isServer && isDedicated) { return mode.Value == SyncMode.BoundedScheduler; } return false; } } private void Awake() { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Expected O, but got Unknown //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Expected O, but got Unknown //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Expected O, but got Unknown //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Expected O, but got Unknown Current = this; mode = ((BaseUnityPlugin)this).Config.Bind<SyncMode>("General", "Mode", SyncMode.Observe, "Observe changes no sending decisions. BoundedScheduler is an UNVALIDATED dedicated-server experiment. Restart after editing."); diagnostics = ((BaseUnityPlugin)this).Config.Bind<bool>("Diagnostics", "Enabled", true, "Record bounded summary lines in BepInEx/LogOutput.log. No player names, account IDs or IPs are emitted by this plugin."); reportSeconds = ((BaseUnityPlugin)this).Config.Bind<int>("Diagnostics", "ReportIntervalSeconds", 10, new ConfigDescription("Summary interval, seconds.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(5, 120), new object[0])); maxCalls = ((BaseUnityPlugin)this).Config.Bind<int>("Scheduler", "MaxNativeCallsPerUpdate", 2, new ConfigDescription("Includes the original call. Never starts another round in the same update. Ignored in Observe.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 3), new object[0])); budgetMs = ((BaseUnityPlugin)this).Config.Bind<float>("Scheduler", "StartBudgetMilliseconds", 2f, new ConfigDescription("Do not START another native call after this elapsed budget. A native call can overrun it; it cannot be interrupted.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), new object[0])); maxFrameMs = ((BaseUnityPlugin)this).Config.Bind<float>("Scheduler", "SkipExtraCallsAboveFrameMilliseconds", 100f, new ConfigDescription("Do not add work on an already slow frame.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(20f, 500f), new object[0])); saveCooldownSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Scheduler", "PauseAfterSaveDispatchSeconds", 2f, new ConfigDescription("Pause additional work briefly after SaveWorld returns. This is not whole-save timing.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 30f), new object[0])); try { BindNativeMethods(); string text = ((object)Version.CurrentVersion/*cast due to .constrained prefix*/).ToString(); uint num = ReadRuntimeNetworkVersion(); if (!CompatibilityRules.IsSupported(text, num)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[RHSS] Unsupported game/network version. No native hooks installed. game=" + text + " network=" + num + ". Reviewed targets: 1.0.16/40 and 1.0.17/40.")); return; } schedulerCompatible = Match(SendCycle, "dd2e102940bf06a36ab8cf0e96f7937fb610e50437af8b9610429bb7bc0736d0", "caadd5a991c3b2bc979b726f4e82d634b0606d71097724c36d992055083985d3") && Match(SendOne, "35b3b63e6528c9d38f220578bd4e3f86cddb6c694de50eb32e8edfef56c1a8a5", "5238fd12d2398c6e5e1c859bc0e488f53497a5c8238e64903215d060621d542d"); harmony = new Harmony("com.rustylasergaming.serversync"); Patch(SendCycle, typeof(CycleHooks)); Patch(SendOne, typeof(SendHooks)); if (SaveWorld != null) { Patch(SaveWorld, typeof(SaveHooks)); } bindingsReady = true; CheckConflicts(); ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Concat("[RHSS] 1.0.0 loaded. game=", text, " network=", num, " configured_mode=", mode.Value, " native_scheduler_guard=", schedulerCompatible, " compat=reviewed-1.0.16-1.0.17 mod_admission_enforcement=NOT_IMPLEMENTED. No queue limits, ownership, inventories or save contents are modified.")); if (!schedulerCompatible) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"[RHSS] Native method fingerprint differs. Additional scheduling is disabled; diagnostics only."); } } catch (Exception ex) { bindingsReady = false; schedulerFaulted = true; if (harmony != null) { harmony.UnpatchSelf(); } ((BaseUnityPlugin)this).Logger.LogError((object)("[RHSS] Initialization failed; this plugin's hooks were removed. " + ex)); } } private static uint ReadRuntimeNetworkVersion() { FieldInfo field = typeof(Version).GetField("c_networkVersion", BindingFlags.Static | BindingFlags.Public); if (field == null) { throw new InvalidOperationException("Version.c_networkVersion was not found."); } object value = (field.IsLiteral ? field.GetRawConstantValue() : field.GetValue(null)); return Convert.ToUInt32(value, CultureInfo.InvariantCulture); } private static void BindNativeMethods() { SendCycle = typeof(ZDOMan).GetMethod("SendZDOToPeers2", InstanceFlags, null, new Type[1] { typeof(float) }, null); NextPeer = typeof(ZDOMan).GetField("m_nextSendPeer", InstanceFlags); ZdoPeers = typeof(ZDOMan).GetField("m_peers", InstanceFlags); SendOne = null; MethodInfo[] methods = typeof(ZDOMan).GetMethods(InstanceFlags); foreach (MethodInfo methodInfo in methods) { ParameterInfo[] parameters = methodInfo.GetParameters(); if (methodInfo.Name == "SendZDOs" && methodInfo.ReturnType == typeof(bool) && parameters.Length == 2 && parameters[1].ParameterType == typeof(bool)) { if (SendOne != null) { throw new InvalidOperationException("Ambiguous SendZDOs signature."); } SendOne = methodInfo; WrappedPeer = parameters[0].ParameterType.GetField("m_peer", InstanceFlags); } } SaveWorld = typeof(ZNet).GetMethod("SaveWorld", InstanceFlags, null, new Type[1] { typeof(bool) }, null); if (SendCycle == null || SendCycle.ReturnType != typeof(void) || NextPeer == null || NextPeer.FieldType != typeof(int) || ZdoPeers == null || SendOne == null || WrappedPeer == null || WrappedPeer.FieldType != typeof(ZNetPeer)) { throw new InvalidOperationException("Required reviewed network method/field signatures were not found."); } } private static bool Match(MethodInfo method, string raw, string normalized) { try { return MethodFingerprint.Raw(method) == raw || MethodFingerprint.Normalized(method) == normalized; } catch { return false; } } private void Patch(MethodInfo method, Type hooks) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_0027: Expected O, but got Unknown harmony.Patch((MethodBase)method, new HarmonyMethod(hooks, "Prefix", (Type[])null), new HarmonyMethod(hooks, "Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } internal static double Elapsed(long start) { return 1000.0 * (double)(Stopwatch.GetTimestamp() - start) / (double)Stopwatch.Frequency; } private string EffectiveState() { if (!bindingsReady) { return "inactive"; } if (mode.Value == SyncMode.Observe) { return "observe"; } if (!isServer || !isDedicated) { return "observe:not-dedicated-server"; } if (!schedulerCompatible) { return "observe:method-guard-failed"; } if (schedulerFaulted) { return "observe:scheduler-fault"; } if (overlappingPatches || otherNetworkPlugin) { return "observe:network-overlap"; } return "bounded-scheduler:experimental"; } private void Update() { if (!bindingsReady) { return; } try { ZNet instance = ZNet.instance; if ((Object)(object)instance != (Object)(object)lastNet) { lastNet = instance; peers.Clear(); nextLabel = 1; frames.Reset(); cycles.Reset(); saveDispatch.Reset(); extraCalls = 0L; lastSave = -1000000.0; nextReport = Now + (double)reportSeconds.Value; } isServer = (Object)(object)instance != (Object)null && instance.IsServer(); isDedicated = (Object)(object)instance != (Object)null && instance.IsDedicated(); if ((Object)(object)instance == (Object)null) { return; } if (Measuring) { frames.Add((double)Time.unscaledDeltaTime * 1000.0); } double now = Now; if (now >= nextConflictCheck) { nextConflictCheck = now + 1.0; CheckConflicts(); } string text = EffectiveState(); if (text != lastEffectiveState) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("[RHSS] effective_mode=" + text)); lastEffectiveState = text; } if (Measuring) { if (now >= nextPeerSample) { nextPeerSample = now + 1.0; SamplePeers(instance); } if (now >= nextReport) { nextReport = now + (double)reportSeconds.Value; Report(instance); } } } catch (Exception ex) { DiagnosticFault(ex); } } private void CheckConflicts() { bool flag = ForeignOwner(SendCycle) || ForeignOwner(SendOne); bool flag2 = false; foreach (PluginInfo value in Chainloader.PluginInfos.Values) { if (!(value.Metadata.GUID == "com.rustylasergaming.serversync")) { string text = (value.Metadata.GUID + " " + value.Metadata.Name).ToLowerInvariant(); if (text.Contains("ghettonetwork") || text.Contains("vbnettweaks") || text.Contains("valheimplus") || value.Metadata.Name.Equals("Network", StringComparison.OrdinalIgnoreCase)) { flag2 = true; break; } } } if ((!overlappingPatches && flag) || (!otherNetworkPlugin && flag2)) { List<string> list = new List<string>(); AddForeignOwners(SendCycle, list); AddForeignOwners(SendOne, list); ((BaseUnityPlugin)this).Logger.LogWarning((object)("[RHSS] Networking overlap detected. Additional scheduling is disabled. Existing mods were not removed. owners=" + ((list.Count == 0) ? "name-detected-network-plugin" : string.Join(",", list.ToArray())))); } overlappingPatches = flag; otherNetworkPlugin = flag2; } private static bool ForeignOwner(MethodBase method) { if (method == null) { return true; } Patches patchInfo = Harmony.GetPatchInfo(method); if (patchInfo == null) { return false; } foreach (string owner in patchInfo.Owners) { if (owner != "com.rustylasergaming.serversync") { return true; } } return false; } private static void AddForeignOwners(MethodBase method, List<string> owners) { if (method == null) { return; } Patches patchInfo = Harmony.GetPatchInfo(method); if (patchInfo == null) { return; } foreach (string owner in patchInfo.Owners) { if (!(owner == "com.rustylasergaming.serversync") && !owners.Contains(owner)) { owners.Add(owner); } } } internal void AfterNativeCycle(ZDOMan instance, long start) { if (start == 0 || ExtraInvocation) { return; } double value = Elapsed(start); if (Measuring) { cycles.Add(value); } if (!ExtraEnabled) { return; } int num = 1; while (true) { int nextPeer; int peerCount; try { nextPeer = (int)NextPeer.GetValue(instance); peerCount = ((ZdoPeers.GetValue(instance) is IList list) ? list.Count : 0); } catch (Exception ex) { schedulerFaulted = true; ((BaseUnityPlugin)this).Logger.LogError((object)("[RHSS] Scheduler field access failed; disabled until restart. " + ex)); break; } if (!SchedulingRules.MayStep(nextPeer, peerCount, num, maxCalls.Value, Elapsed(start), budgetMs.Value, (double)Time.unscaledDeltaTime * 1000.0, maxFrameMs.Value, Now - lastSave < (double)saveCooldownSeconds.Value, ExtraEnabled, schedulerCompatible)) { break; } ExtraInvocation = true; try { SendCycle.Invoke(instance, ZeroDt); extraCalls++; num++; } catch (Exception ex2) { schedulerFaulted = true; ((BaseUnityPlugin)this).Logger.LogError((object)("[RHSS] Extra native call failed; optimization disabled until restart. " + ex2)); throw; } finally { ExtraInvocation = false; } } } internal PeerStats GetStats(object wrapped) { if (!Measuring || wrapped == null) { return null; } object? value = WrappedPeer.GetValue(wrapped); ZNetPeer peer = (ZNetPeer)((value is ZNetPeer) ? value : null); return GetStats(peer); } private PeerStats GetStats(ZNetPeer peer) { if (peer == null) { return null; } if (!peers.TryGetValue(peer, out var value)) { if (peers.Count >= 128) { return null; } value = new PeerStats(); value.Label = "peer" + nextLabel++; value.Transport = ((peer.m_socket == null) ? "unknown" : ((object)peer.m_socket).GetType().Name); peers.Add(peer, value); } return value; } internal void SendStarting(object wrapped, ref SendState state) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown if (!Measuring) { return; } try { PeerStats stats = GetStats(wrapped); if (stats != null) { ZNetPeer val = (ZNetPeer)WrappedPeer.GetValue(wrapped); int num = (stats.LastQueue = val.m_socket.GetSendQueueSize()); if (num > stats.QueuePeak) { stats.QueuePeak = num; } if (num > 8192) { stats.QueueLimitedAttempts++; } long timestamp = Stopwatch.GetTimestamp(); if (stats.LastCycleStart != 0) { stats.VisitGap.Add(1000.0 * (double)(timestamp - stats.LastCycleStart) / (double)Stopwatch.Frequency); } stats.LastCycleStart = timestamp; state.Stats = stats; state.Start = timestamp; } } catch (Exception ex) { DiagnosticFault(ex); } } internal void SendFinished(SendState state, bool sent) { if (Measuring && state.Start != 0 && state.Stats != null) { state.Stats.SendDuration.Add(Elapsed(state.Start)); if (!sent) { state.Stats.CallsWithoutData++; } } } internal void SaveFinished(long start) { lastSave = Now; if (Measuring && start != 0) { saveDispatch.Add(Elapsed(start)); } } private void SamplePeers(ZNet net) { List<ZNetPeer> list = net.GetPeers(); List<ZNetPeer> list2 = new List<ZNetPeer>(); foreach (ZNetPeer key in peers.Keys) { if (!list.Contains(key)) { list2.Add(key); } } foreach (ZNetPeer item in list2) { peers.Remove(item); } foreach (ZNetPeer item2 in list) { if (item2 == null || item2.m_socket == null || !item2.IsReady()) { continue; } PeerStats stats = GetStats(item2); if (stats == null) { continue; } stats.LastQueue = item2.m_socket.GetSendQueueSize(); if (stats.LastQueue > stats.QueuePeak) { stats.QueuePeak = stats.LastQueue; } stats.TransportStatsAvailable = false; if (!(stats.Transport == "ZSteamSocket")) { continue; } try { item2.m_socket.GetConnectionQuality(ref stats.QualityLocal, ref stats.QualityRemote, ref stats.PingMs, ref stats.OutBytesSec, ref stats.InBytesSec); stats.TransportStatsAvailable = stats.PingMs > 0 || stats.QualityLocal > 0f || stats.QualityRemote > 0f; } catch (InvalidOperationException ex) { stats.TransportStatsAvailable = false; stats.PingMs = 0; stats.QualityLocal = 0f; stats.QualityRemote = 0f; stats.OutBytesSec = 0f; stats.InBytesSec = 0f; if (!stats.TransportStatsUnsupportedLogged) { stats.TransportStatsUnsupportedLogged = true; ((BaseUnityPlugin)this).Logger.LogWarning((object)("[RHSS] Steam transport quality counters are unavailable on this dedicated server; continuing with queue/frame/native-cycle diagnostics. " + ex.Message)); } } } } private void Report(ZNet net) { reportSerial++; int num = ((!isServer && ZDOMan.instance != null) ? ZDOMan.instance.GetClientChangeQueue() : (-1)); ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format(CultureInfo.InvariantCulture, "[RHSS] sample={0} role={1} mode={2} peers={3} frame_avg_ms={4:F2} frame_max_ms={5:F2} native_cycle_calls={6} native_cycle_avg_ms={7:F3} native_cycle_max_ms={8:F3} extra_native_calls={9} save_dispatch_calls={10} save_dispatch_max_ms={11:F2} local_change_queue={12}", reportSerial, isServer ? "server" : "client", EffectiveState(), peers.Count, frames.Mean, frames.Max, cycles.Count, cycles.Mean, cycles.Max, extraCalls, saveDispatch.Count, saveDispatch.Max, num)); foreach (PeerStats value in peers.Values) { ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format(CultureInfo.InvariantCulture, "[RHSS] sample={0} {1} transport={2} queue_now_bytes={3} queue_peak_observed_bytes={4} queue_limited_attempts={5} native_send_calls={6} native_send_avg_ms={7:F3} native_send_max_ms={8:F3} visit_gap_avg_ms={9:F2} visit_gap_max_ms={10:F2} calls_without_data={11} transport_stats_available={12} ping_ms={13} quality_local={14:F3} quality_remote={15:F3} out_bytes_sec={16:F0} in_bytes_sec={17:F0}", reportSerial, value.Label, value.Transport, value.LastQueue, value.QueuePeak, value.QueueLimitedAttempts, value.SendDuration.Count, value.SendDuration.Mean, value.SendDuration.Max, value.VisitGap.Mean, value.VisitGap.Max, value.CallsWithoutData, value.TransportStatsAvailable, value.PingMs, value.QualityLocal, value.QualityRemote, value.OutBytesSec, value.InBytesSec)); value.SendDuration.Reset(); value.VisitGap.Reset(); value.QueuePeak = Math.Max(0, value.LastQueue); value.QueueLimitedAttempts = 0L; value.CallsWithoutData = 0L; } frames.Reset(); cycles.Reset(); saveDispatch.Reset(); extraCalls = 0L; } private void DiagnosticFault(Exception ex) { if (!diagnosticFaulted) { diagnosticFaulted = true; schedulerFaulted = true; ((BaseUnityPlugin)this).Logger.LogError((object)("[RHSS] Diagnostic failure; sampling and optimization disabled until restart. " + ex)); } } private void OnDestroy() { bindingsReady = false; if (harmony != null) { harmony.UnpatchSelf(); } if ((Object)(object)Current == (Object)(object)this) { Current = null; } } } internal struct SendState { internal long Start; internal Plugin.PeerStats Stats; } internal static class CycleHooks { public static void Prefix(ref long __state) { __state = ((Plugin.ExtraInvocation || (Object)(object)Plugin.Current == (Object)null) ? 0 : Stopwatch.GetTimestamp()); } public static void Postfix(ZDOMan __instance, long __state) { if ((Object)(object)Plugin.Current != (Object)null) { Plugin.Current.AfterNativeCycle(__instance, __state); } } } internal static class SendHooks { public static void Prefix(object __0, ref SendState __state) { __state = default(SendState); if ((Object)(object)Plugin.Current != (Object)null) { Plugin.Current.SendStarting(__0, ref __state); } } public static void Postfix(SendState __state, bool __result) { if ((Object)(object)Plugin.Current != (Object)null) { Plugin.Current.SendFinished(__state, __result); } } } internal static class SaveHooks { public static void Prefix(ref long __state) { __state = Stopwatch.GetTimestamp(); } public static void Postfix(long __state) { if ((Object)(object)Plugin.Current != (Object)null) { Plugin.Current.SaveFinished(__state); } } } internal static class SchedulingRules { internal static bool MayStep(int nextPeer, int peerCount, int callsThisUpdate, int maxCalls, double elapsedMs, double budgetMs, double frameMs, double maxFrameMs, bool savingRecently, bool enabled, bool compatible) { if (!enabled || !compatible || savingRecently) { return false; } if (peerCount < 2 || nextPeer < 0 || nextPeer >= peerCount) { return false; } if (maxCalls < 1 || maxCalls > 3 || callsThisUpdate >= maxCalls) { return false; } if (!Finite(elapsedMs) || !Finite(budgetMs) || !Finite(frameMs) || !Finite(maxFrameMs)) { return false; } if (elapsedMs < 0.0 || budgetMs <= 0.0 || budgetMs > 5.0 || elapsedMs >= budgetMs) { return false; } if (frameMs >= 0.0 && maxFrameMs > 0.0) { return frameMs <= maxFrameMs; } return false; } private static bool Finite(double value) { if (!double.IsNaN(value)) { return !double.IsInfinity(value); } return false; } } internal sealed class RunningStats { internal long Count; internal double Sum; internal double Max; internal double Mean { get { if (Count != 0) { return Sum / (double)Count; } return 0.0; } } internal void Add(double value) { if (!double.IsNaN(value) && !double.IsInfinity(value) && !(value < 0.0)) { Count++; Sum += value; if (value > Max) { Max = value; } } } internal void Reset() { Count = 0L; Sum = 0.0; Max = 0.0; } }