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 FastLoading v0.6.2
FastLoading.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Threading; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("FastLoading")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.6.2.0")] [assembly: AssemblyInformationalVersion("0.6.2+c0444277fc1967d3a2723dc7596b93dfd2f32465")] [assembly: AssemblyProduct("FastLoading")] [assembly: AssemblyTitle("FastLoading")] [assembly: AssemblyVersion("0.6.2.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ValheimFrameBudget { internal static class ArrivalFloor { private const float VanillaDeadline = 15f; private const float NearRadius = 8f; private static readonly List<ZDO> _temp = new List<ZDO>(); private static bool _armed; private static Vector3 _point; private static float _since; private static float _lastCall; private static float _nextCountAt; private static float _grewAt; private static int _known; private static int _knownAtStart; private static bool _waiting; internal static bool Applied { get; set; } public static int Holds { get; private set; } private static BudgetConfig Cfg => FrameBudgetPlugin.Cfg; private static bool Enabled { get { if (Cfg != null) { return Cfg.Enabled.Value; } return false; } } public static bool FloorReady(ZoneSystem zones, Vector3 point, out float height) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) height = 0f; if ((Object)(object)zones == (Object)null) { return false; } bool flag = zones.FindFloor(point, ref height); if (!Enabled || !LoadMode.ReadDistantNow()) { _armed = false; _waiting = false; return flag; } float realtimeSinceStartup = Time.realtimeSinceStartup; if (_armed && !(realtimeSinceStartup - _lastCall > 0.5f)) { Vector3 val = point - _point; if (!(((Vector3)(ref val)).sqrMagnitude > 0.01f)) { goto IL_0073; } } Begin(point); goto IL_0073; IL_0073: _lastCall = realtimeSinceStartup; if (!flag) { return false; } if (point.y - height <= Tuning.ArrivalMaxDrop) { Release(); return true; } if (realtimeSinceStartup >= _nextCountAt) { _nextCountAt = realtimeSinceStartup + 0.2f; int num = CountKnown(point); if (num > _known) { _known = num; _grewAt = realtimeSinceStartup; } } float num2 = ((_known > _knownAtStart) ? Tuning.ArrivalQuiet : Tuning.ArrivalFirstWait); if (!(realtimeSinceStartup - _grewAt < num2) && ((Object)(object)ZNetScene.instance == (Object)null || ZNetScene.instance.IsAreaReady(point))) { Release(); return true; } float num3 = Mathf.Clamp(Tuning.ArrivalFloorWait, 0f, 14f); float num4 = LoadMode.ReadTimerNow(Player.m_localPlayer); if (realtimeSinceStartup - _since > num3 || num4 > 14f) { Release(); return true; } _waiting = true; return false; } private static void Begin(Vector3 point) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) _armed = true; _waiting = false; _point = point; _since = Time.realtimeSinceStartup; _grewAt = _since; _nextCountAt = _since + 0.2f; _known = CountKnown(point); _knownAtStart = _known; } private static int CountKnown(Vector3 point) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) if (ZDOMan.instance == null || (Object)(object)ZoneSystem.instance == (Object)null) { return 0; } _temp.Clear(); SectorObjects.FindNeighbourhood(ZoneSystem.GetZone(point), _temp); int num = 0; foreach (ZDO item in _temp) { Vector3 val = item.GetPosition() - point; if (((Vector3)(ref val)).sqrMagnitude <= 64f) { num++; } } return num; } private static void Release() { _armed = false; if (_waiting) { _waiting = false; Holds++; } } } [HarmonyPatch(typeof(Player), "UpdateTeleport")] internal static class Patch_Player_UpdateTeleport_Floor { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> list = new List<CodeInstruction>(instructions); MethodInfo methodInfo = AccessTools.Method(typeof(ZoneSystem), "FindFloor", new Type[2] { typeof(Vector3), typeof(float).MakeByRefType() }, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(ArrivalFloor), "FloorReady", (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null) { FrameBudgetPlugin.Log.LogError((object)"[portal] ZoneSystem.FindFloor unavailable; arrival floor check disabled"); return list; } int num = 0; foreach (CodeInstruction item in list) { if ((item.opcode == OpCodes.Callvirt || item.opcode == OpCodes.Call) && item.operand as MethodInfo == methodInfo) { num++; } } if (num != 1) { FrameBudgetPlugin.Log.LogError((object)$"[portal] expected one FindFloor call in UpdateTeleport, found {num}; arrival floor check disabled"); return list; } foreach (CodeInstruction item2 in list) { if ((!(item2.opcode != OpCodes.Callvirt) || !(item2.opcode != OpCodes.Call)) && !(item2.operand as MethodInfo != methodInfo)) { item2.opcode = OpCodes.Call; item2.operand = methodInfo2; break; } } ArrivalFloor.Applied = true; return list; } } internal static class ArrivalGround { private const float RiseMargin = 0.25f; private const float SinkMargin = 0.05f; private const float StrayRadius = 4f; private static FieldRef<Character, Rigidbody> _body; private static FieldRef<Character, float> _maxAir; private static bool _resolved; private static bool _armed; private static Vector3 _point; private static float _baseGround; private static float _until; public static int Lifts { get; private set; } private static BudgetConfig Cfg => FrameBudgetPlugin.Cfg; private static bool Enabled { get { if (Cfg != null) { return Cfg.Enabled.Value; } return false; } } public static void Tick() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) if (!Enabled) { _armed = false; return; } if (LoadMode.JustFinished) { Arm(); } if (!_armed) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || Time.realtimeSinceStartup > _until) { _armed = false; return; } Vector3 position = ((Component)localPlayer).transform.position; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(position.x - _point.x, position.z - _point.z); float num = default(float); float num2 = default(float); if (((Vector2)(ref val)).sqrMagnitude > 16f) { _armed = false; } else if (!((Object)(object)ZoneSystem.instance == (Object)null) && ZoneSystem.instance.GetGroundHeight(_point, ref num) && !(num < _baseGround + 0.25f) && ZoneSystem.instance.GetGroundHeight(position, ref num2)) { if (position.y >= num2 - 0.05f) { _armed = false; } else { Lift(localPlayer, num2); } } } private static void Arm() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) _armed = false; if (LoadMode.IsDistant && !((Object)(object)ZoneSystem.instance == (Object)null)) { _point = LoadMode.Target; if (ZoneSystem.instance.GetGroundHeight(_point, ref _baseGround)) { _armed = true; _until = Time.realtimeSinceStartup + Mathf.Max(0f, Tuning.ArrivalGroundWatch); } } } private static void Lift(Player player, float ground) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) _armed = false; Resolve(); Vector3 position = ((Component)player).transform.position; position.y = ground + 0.1f; ((Component)player).transform.position = position; if (_body != null) { Rigidbody val = _body.Invoke((Character)(object)player); if ((Object)(object)val != (Object)null) { val.linearVelocity = Vector3.zero; } } if (_maxAir != null) { _maxAir.Invoke((Character)(object)player) = position.y; } Lifts++; } private static void Resolve() { if (!_resolved) { _resolved = true; _body = TryField<Rigidbody>("m_body"); _maxAir = TryField<float>("m_maxAirAltitude"); } } private static FieldRef<Character, T> TryField<T>(string name) { try { return AccessTools.FieldRefAccess<Character, T>(name); } catch (Exception ex) { FrameBudgetPlugin.Log.LogError((object)("[portal] Character." + name + " unavailable: " + ex.GetType().Name)); return null; } } } internal static class DungeonFade { private static float _fadeOutUntil; internal static float Seconds { get { BudgetConfig cfg = FrameBudgetPlugin.Cfg; if (cfg == null || !cfg.Enabled.Value) { return 0f; } return Mathf.Clamp(cfg.PortalDungeonFade.Value, 0f, 2f); } } internal static float? Duration(Player player) { float seconds = Seconds; if (seconds <= 0f || (Object)(object)player == (Object)null || ((Character)player).IsDead() || player.IsSleeping()) { return null; } if (((Character)player).IsTeleporting() && !LoadMode.ReadDistantNow()) { _fadeOutUntil = Time.time + seconds; return seconds * 0.8f; } if (!(Time.time < _fadeOutUntil)) { return null; } return seconds; } } [HarmonyPatch(typeof(Hud), "GetFadeDuration")] internal static class Patch_Hud_GetFadeDuration_Dungeon { private static void Postfix(Player player, ref float __result) { float? num = DungeonFade.Duration(player); if (num.HasValue) { __result = num.Value; } } } internal static class GhostZones { public static int Held { get; private set; } private static bool Enabled { get { if (FrameBudgetPlugin.Cfg != null) { return FrameBudgetPlugin.Cfg.Enabled.Value; } return false; } } public static bool Allow(Vector3 refPoint) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (!Enabled || !LoadMode.Active || (Object)(object)ZNet.instance == (Object)null) { return true; } Vector2s zone = ZoneSystem.GetZone(ZNet.instance.GetReferencePosition()); if (ZoneSystem.GetZone(refPoint) != zone) { return true; } Held++; return false; } } [HarmonyPatch(typeof(ZoneSystem), "CreateGhostZones")] internal static class Patch_ZoneSystem_CreateGhostZones { private static bool Prefix(Vector3 refPoint, ref bool __result) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if (GhostZones.Allow(refPoint)) { return true; } __result = false; return false; } } internal static class InstantiateBench { private const int WarmUp = 64; private static readonly FieldInfo Instances = AccessTools.Field(typeof(ZNetScene), "m_instances"); private static bool _done; private static readonly bool Enabled = Array.IndexOf(Environment.GetCommandLineArgs(), "-fastloading-bench") >= 0; private const int Count = 1000; public static bool Pending { get { if (Enabled && !_done && (Object)(object)Player.m_localPlayer != (Object)null && (Object)(object)ZNetScene.instance != (Object)null) { return Time.timeSinceLevelLoad > 20f; } return false; } } public static IEnumerator Run() { _done = true; int total; List<KeyValuePair<GameObject, int>> list = Census(out total); if (list.Count == 0) { FrameBudgetPlugin.Log.LogWarning((object)"[bench] nothing loaded to measure"); yield break; } ReportCensus(list, total); PrefabSurvey.Report(list, 20); GameObject prefab = list[0].Key; int value = list[0].Value; int count = 1000; GameObject host = new GameObject("FastLoadingBench"); host.SetActive(false); Transform parent = host.transform; FrameBudgetPlugin.Log.LogWarning((object)$"[bench] prefab {((Object)prefab).name} ({value} live instances), {count} copies, Awake suppressed"); Warm(prefab, parent); yield return null; Stopwatch sw = Stopwatch.StartNew(); for (int i = 0; i < count; i++) { Object.Instantiate<GameObject>(prefab, parent); } double sync = sw.Elapsed.TotalMilliseconds; Clear(parent); yield return null; sw.Restart(); ((AsyncInstantiateOperation)Object.InstantiateAsync<GameObject>(prefab, count, parent)).WaitForCompletion(); double blocked = sw.Elapsed.TotalMilliseconds; Clear(parent); yield return null; sw.Restart(); AsyncInstantiateOperation<GameObject> spread = Object.InstantiateAsync<GameObject>(prefab, count, parent); int frames = 0; while (!((AsyncOperation)spread).isDone) { frames++; yield return null; } double totalMilliseconds = sw.Elapsed.TotalMilliseconds; Clear(parent); Object.Destroy((Object)(object)host); FrameBudgetPlugin.Log.LogWarning((object)$"[bench] sync loop: {sync:0.0}ms total, {sync / (double)count:0.000}ms each"); FrameBudgetPlugin.Log.LogWarning((object)($"[bench] async + WaitForCompletion: {blocked:0.0}ms total, {blocked / (double)count:0.000}ms each, " + $"{((blocked > 0.0) ? (sync / blocked) : 0.0):0.00}x versus the loop")); FrameBudgetPlugin.Log.LogWarning((object)($"[bench] async across frames: {totalMilliseconds:0.0}ms wall over {frames} frames, " + $"{totalMilliseconds / (double)count:0.000}ms each")); } private static void Warm(GameObject prefab, Transform parent) { for (int i = 0; i < 64; i++) { Object.Instantiate<GameObject>(prefab, parent); } Clear(parent); } private static void Clear(Transform parent) { for (int num = parent.childCount - 1; num >= 0; num--) { Object.DestroyImmediate((Object)(object)((Component)parent.GetChild(num)).gameObject); } } private static List<KeyValuePair<GameObject, int>> Census(out int total) { total = 0; List<KeyValuePair<GameObject, int>> list = new List<KeyValuePair<GameObject, int>>(); if (Instances == null || (Object)(object)ZNetScene.instance == (Object)null) { return list; } if (!(Instances.GetValue(ZNetScene.instance) is IDictionary dictionary)) { return list; } Dictionary<int, int> dictionary2 = new Dictionary<int, int>(); foreach (object value2 in dictionary.Values) { ZNetView val = (ZNetView)((value2 is ZNetView) ? value2 : null); ZDO val2 = (((Object)(object)val != (Object)null) ? val.GetZDO() : null); if (val2 != null) { int prefab = val2.GetPrefab(); dictionary2.TryGetValue(prefab, out var value); dictionary2[prefab] = value + 1; total++; } } foreach (KeyValuePair<int, int> item in dictionary2) { GameObject prefab2 = ZNetScene.instance.GetPrefab(item.Key); if ((Object)(object)prefab2 != (Object)null) { list.Add(new KeyValuePair<GameObject, int>(prefab2, item.Value)); } } list.Sort((KeyValuePair<GameObject, int> a, KeyValuePair<GameObject, int> b) => b.Value.CompareTo(a.Value)); return list; } private static void ReportCensus(List<KeyValuePair<GameObject, int>> ranked, int total) { int num = 0; foreach (KeyValuePair<GameObject, int> item in ranked) { if ((Object)(object)item.Key.GetComponent<Piece>() != (Object)null) { num += item.Value; } } int num2 = ((total > 0) ? (num * 100 / total) : 0); FrameBudgetPlugin.Log.LogWarning((object)$"[bench] loaded: {total} objects of {ranked.Count} kinds; {num} are built pieces ({num2}%)"); StringBuilder stringBuilder = new StringBuilder("[bench] top:"); for (int i = 0; i < ranked.Count && i < 15; i++) { stringBuilder.Append(' ').Append(((Object)ranked[i].Key).name).Append('=') .Append(ranked[i].Value); } FrameBudgetPlugin.Log.LogWarning((object)stringBuilder.ToString()); } } internal static class LoadMode { private static FieldRef<Player, Vector3> _targetPos; private static FieldRef<Player, Vector3> _fromPos; private static FieldRef<Player, bool> _distant; private static FieldRef<Player, float> _timer; private static bool _resolved; public static bool Teleporting { get; private set; } public static bool Active { get; private set; } public static bool IsDistant { get; private set; } public static Vector3 Target { get; private set; } public static Vector3 From { get; private set; } public static bool HasFrom { get; private set; } public static bool JustStarted { get; private set; } public static bool JustFinished { get; private set; } public static bool ReadDistantNow() { Player localPlayer = Player.m_localPlayer; if (_distant == null || (Object)(object)localPlayer == (Object)null) { return false; } return _distant.Invoke(localPlayer); } public static float ReadTimerNow(Player player) { if (_timer == null || (Object)(object)player == (Object)null) { return -1f; } return _timer.Invoke(player); } private static FieldRef<Player, T> TryField<T>(string name) { try { return AccessTools.FieldRefAccess<Player, T>(name); } catch (Exception ex) { FrameBudgetPlugin.Log.LogError((object)("[portal] Player." + name + " unavailable: " + ex.GetType().Name)); return null; } } public static void Tick() { //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) if (!_resolved) { _resolved = true; _targetPos = TryField<Vector3>("m_teleportTargetPos"); _fromPos = TryField<Vector3>("m_teleportFromPos"); _distant = TryField<bool>("m_distantTeleport"); _timer = TryField<float>("m_teleportTimer"); if (_targetPos == null) { FrameBudgetPlugin.Log.LogError((object)"[portal] Player.m_teleportTargetPos unavailable; portal acceleration disabled"); } if (_distant == null) { FrameBudgetPlugin.Log.LogError((object)"[portal] Player.m_distantTeleport unavailable; floor grace applies to all teleports"); } } bool teleporting = Teleporting; Player localPlayer = Player.m_localPlayer; bool flag = (Object)(object)localPlayer != (Object)null && _targetPos != null && ((Character)localPlayer).IsTeleporting(); JustStarted = flag && !teleporting; JustFinished = teleporting && !flag; Teleporting = flag; Active = flag && FrameBudgetPlugin.Cfg != null && FrameBudgetPlugin.Cfg.Enabled.Value; if (flag) { Target = _targetPos.Invoke(localPlayer); HasFrom = _fromPos != null; if (HasFrom) { From = _fromPos.Invoke(localPlayer); } IsDistant = _distant != null && _distant.Invoke(localPlayer); if (JustStarted && Active) { TerrainPriority.Request(Target); } if (Active) { TerrainPriority.Prioritize(Target); } } } } internal static class LoadProbe { private static readonly double TicksToMs = 1000.0 / (double)Stopwatch.Frequency; private const int During = 0; private const int After = 1; private const int Idle = -1; internal static readonly bool Enabled = Array.IndexOf(Environment.GetCommandLineArgs(), "-fastloading-probe") >= 0; private const float FrameWindow = 5f; private static volatile int _phase = -1; private static long _startedAt; private static double _zoneReadyMs = -1.0; private static double _areaReadyMs = -1.0; private static double _totalMs; private static int _peakQueue; private static readonly long[] _buildTicks = new long[2]; private static readonly long[] _repeatTicks = new long[2]; private static readonly int[] _buildCount = new int[2]; private static readonly int[] _buildDistant = new int[2]; private static readonly int[] _buildRepeat = new int[2]; private static readonly HashSet<long> _builtZones = new HashSet<long>(); private static readonly object _builtLock = new object(); private static readonly long[] _spawnTicks = new long[2]; private static readonly int[] _spawnOk = new int[2]; private static readonly int[] _spawnBlocked = new int[2]; private static readonly long[] _regenTicks = new long[2]; private static readonly int[] _regenCount = new int[2]; private static readonly long[] _regenLodTicks = new long[2]; private static readonly int[] _regenLodCount = new int[2]; private static readonly long[] _colliderTicks = new long[2]; private static readonly int[] _colliderCount = new int[2]; private static readonly long[] _objectTicks = new long[2]; private static readonly int[] _objectCount = new int[2]; private static readonly int[] _objectCalls = new int[2]; private static readonly int[] _objectPeak = new int[2]; private static readonly long[] _createTicks = new long[2]; private static readonly long[] _removeTicks = new long[2]; private static readonly int[] _removed = new int[2]; private static int _peakInstances; private static int _peakCap; private static Vector2s _gateZone; private static int _gateZdos; private static int _areaZdos; private static readonly int[] _createdInGate = new int[2]; private static readonly int[] _createdOutside = new int[2]; private static readonly List<ZDO> _scratch = new List<ZDO>(); private static readonly List<float> _framesDuring = new List<float>(1024); private static readonly List<float> _framesAfter = new List<float>(1024); private static float _sampleUntil; private static readonly Dictionary<string, long>[] _extra = new Dictionary<string, long>[2] { new Dictionary<string, long>(), new Dictionary<string, long>() }; private static readonly Dictionary<string, int>[] _extraCalls = new Dictionary<string, int>[2] { new Dictionary<string, int>(), new Dictionary<string, int>() }; private static long Now => Stopwatch.GetTimestamp(); private static double MsSince(long from) { return (double)(Now - from) * TicksToMs; } public static void Tick() { if (!Enabled) { if (_phase != -1) { ResetAll(); } return; } if (LoadMode.JustStarted && _phase == 1) { Report(); } if (LoadMode.JustStarted) { Begin(); } if (_phase == 0) { _framesDuring.Add(Time.unscaledDeltaTime * 1000f); SampleTimeline(); } if (LoadMode.JustFinished && _phase == 0) { _totalMs = MsSince(_startedAt); _phase = 1; _framesAfter.Clear(); _sampleUntil = Time.unscaledTime + 5f; } else if (_phase == 1) { _framesAfter.Add(Time.unscaledDeltaTime * 1000f); if (Time.unscaledTime >= _sampleUntil) { Report(); } } } private static void Begin() { _startedAt = Now; _zoneReadyMs = -1.0; _areaReadyMs = -1.0; _totalMs = 0.0; _peakQueue = 0; _framesDuring.Clear(); _framesAfter.Clear(); for (int i = 0; i < 2; i++) { Interlocked.Exchange(ref _buildTicks[i], 0L); Interlocked.Exchange(ref _repeatTicks[i], 0L); Interlocked.Exchange(ref _buildCount[i], 0); Interlocked.Exchange(ref _buildDistant[i], 0); Interlocked.Exchange(ref _buildRepeat[i], 0); _spawnTicks[i] = 0L; _spawnOk[i] = 0; _spawnBlocked[i] = 0; _regenTicks[i] = 0L; _regenCount[i] = 0; _regenLodTicks[i] = 0L; _regenLodCount[i] = 0; _colliderTicks[i] = 0L; _colliderCount[i] = 0; _objectTicks[i] = 0L; _objectCount[i] = 0; _objectCalls[i] = 0; _objectPeak[i] = 0; _createdInGate[i] = 0; _createdOutside[i] = 0; _createTicks[i] = 0L; _removeTicks[i] = 0L; _removed[i] = 0; _extra[i].Clear(); _extraCalls[i].Clear(); } _peakInstances = 0; _peakCap = 0; TerrainRebuild.ResetRun(); CountZdos(); _phase = 0; } private static void CountZdos() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) _gateZdos = 0; _areaZdos = 0; _gateZone = default(Vector2s); if (ZDOMan.instance != null && !((Object)(object)ZNet.instance == (Object)null)) { _gateZone = ZoneSystem.GetZone(LoadMode.Target); _scratch.Clear(); ZDOMan.instance.FindSectorObjects(_gateZone, new SimulationDistance(1, 0, false), _scratch, (List<ZDO>)null); _gateZdos = _scratch.Count; _scratch.Clear(); ZDOMan.instance.FindSectorObjects(_gateZone, ZNet.instance.GetSyncedSimulationDistance(), _scratch, (List<ZDO>)null); _areaZdos = _scratch.Count; _scratch.Clear(); } } public static void ObjectCreated(ZDO zdo) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) int phase = _phase; if (Enabled && phase != -1 && zdo != null) { Vector2s sector = zdo.GetSector(); if (Math.Abs(sector.x - _gateZone.x) <= 1 && Math.Abs(sector.y - _gateZone.y) <= 1) { _createdInGate[phase]++; } else { _createdOutside[phase]++; } } } private static void SampleTimeline() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) Vector3 target = LoadMode.Target; if (_zoneReadyMs < 0.0 && (Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.IsZoneLoaded(target)) { _zoneReadyMs = MsSince(_startedAt); } if (_areaReadyMs < 0.0 && (Object)(object)ZNetScene.instance != (Object)null && ZNetScene.instance.IsAreaReady(target)) { _areaReadyMs = MsSince(_startedAt); } int queueDepth = TerrainPriority.QueueDepth; if (queueDepth > _peakQueue) { _peakQueue = queueDepth; } } public static void Built(Vector3 center, bool distantLod, long ticks) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) int phase = _phase; if (Enabled && phase != -1) { long num = ((long)Math.Round(center.x) << 21) ^ (long)Math.Round(center.z); if (distantLod) { num = ~num; } bool flag; lock (_builtLock) { flag = !_builtZones.Add(num); } Interlocked.Add(ref _buildTicks[phase], ticks); Interlocked.Increment(ref _buildCount[phase]); if (distantLod) { Interlocked.Increment(ref _buildDistant[phase]); } if (flag) { Interlocked.Increment(ref _buildRepeat[phase]); Interlocked.Add(ref _repeatTicks[phase], ticks); } } } public static void Spawned(bool created, long ticks) { int phase = _phase; if (Enabled && phase != -1) { _spawnTicks[phase] += ticks; if (created) { _spawnOk[phase]++; } else { _spawnBlocked[phase]++; } } } public static void Regenerated(long ticks, bool distantLod) { int phase = _phase; if (Enabled && phase != -1) { _regenTicks[phase] += ticks; _regenCount[phase]++; if (distantLod) { _regenLodTicks[phase] += ticks; _regenLodCount[phase]++; } } } public static void ColliderRebuilt(long ticks) { int phase = _phase; if (Enabled && phase != -1) { _colliderTicks[phase] += ticks; _colliderCount[phase]++; } } public static void ObjectsCreated(int count, double ms) { int phase = _phase; if (Enabled && phase != -1) { _objectTicks[phase] += (long)(ms / TicksToMs); _objectCount[phase] += count; _objectCalls[phase]++; if (count > _objectPeak[phase]) { _objectPeak[phase] = count; } } } public static void Created(long ticks, int live) { int phase = _phase; if (Enabled && phase != -1) { _createTicks[phase] += ticks; if (live > _peakInstances) { _peakInstances = live; } if (SpawnRush.LastLoadingLimit > _peakCap) { _peakCap = SpawnRush.LastLoadingLimit; } } } public static void Removed(long ticks, int gone) { int phase = _phase; if (Enabled && phase != -1) { _removeTicks[phase] += ticks; _removed[phase] += gone; } } public static void Extra(string name, long ticks) { int phase = _phase; if (Enabled && phase != -1) { _extra[phase].TryGetValue(name, out var value); _extra[phase][name] = value + ticks; _extraCalls[phase].TryGetValue(name, out var value2); _extraCalls[phase][name] = value2 + 1; } } private static void ReportExtra(string label, int phase) { if (_extra[phase].Count == 0) { return; } StringBuilder stringBuilder = new StringBuilder("[probe] ").Append(label).Append(" suspects:"); foreach (KeyValuePair<string, long> item in _extra[phase]) { _extraCalls[phase].TryGetValue(item.Key, out var value); stringBuilder.Append(' ').Append(item.Key).Append(' ') .Append(((double)item.Value * TicksToMs).ToString("0.0")) .Append("ms x") .Append(value); } FrameBudgetPlugin.Log.LogWarning((object)stringBuilder.ToString()); } private static void Report() { _phase = -1; string text = ((_zoneReadyMs < 0.0) ? "never" : $"{_zoneReadyMs / 1000.0:0.00}s"); string text2 = ((_areaReadyMs < 0.0) ? "never" : $"{_areaReadyMs / 1000.0:0.00}s"); string text3 = ((!SpawnRush.LimitApplied) ? "not patched" : ((_peakCap > 100) ? _peakCap.ToString() : "vanilla")); FrameBudgetPlugin.Log.LogWarning((object)$"[probe] teleport {_totalMs / 1000.0:0.00}s | terrain-ready {text} | area-ready {text2} | spawn cap {text3}"); int num = ((_areaZdos > 0) ? (_gateZdos * 100 / _areaZdos) : 0); FrameBudgetPlugin.Log.LogWarning((object)($"[probe] gate: 3x3 holds {_gateZdos} zdos of {_areaZdos} in the active area ({num}%); " + $"created during {_createdInGate[0]} in gate, {_createdOutside[0]} outside; " + $"after {_createdInGate[1]} in gate, {_createdOutside[1]} outside; " + $"{ViewPriority.Deferred} nature weights deferred since launch")); ReportWork("during", 0); ReportExtra("during", 0); ReportWork("after", 1); ReportExtra("after", 1); ReportFrames("during", _framesDuring); ReportFrames("after", _framesAfter); FrameBudgetPlugin.Log.LogWarning((object)($"[probe] since launch: {TerrainPriority.Requested} terrain requests, {TerrainPriority.Promoted} promoted, " + $"{ZoneRush.ZonesCreated} zones rushed, {PortalWarm.Warms} destinations warmed, prefetch {PortalInterest.Served} peers / {PortalInterest.Queued} zdos; " + $"terrain cache {TerrainCache.Hits} hits / {TerrainCache.Misses} misses, {TerrainCache.Count} zones held; " + $"rebuilds {TerrainRebuild.Deferred} deferred, {TerrainRebuild.Flushed} flushed " + $"(this run: {TerrainRebuild.AllowedNow} allowed, {TerrainRebuild.DeferredNow} deferred); ghost zones held {GhostZones.Held}, range narrowed {LoadRange.Narrowed}, near-jump skips {LoadRange.Skipped}; " + $"arrival {ArrivalFloor.Holds} floor holds, {ArrivalGround.Lifts} ground lifts")); } private static void ReportWork(string label, int phase) { double num = (double)Interlocked.Read(in _buildTicks[phase]) * TicksToMs; double num2 = (double)Interlocked.Read(in _repeatTicks[phase]) * TicksToMs; int num3 = _buildCount[phase]; string text = ((phase == 0) ? $", peak queue {_peakQueue}" : string.Empty); FrameBudgetPlugin.Log.LogWarning((object)($"[probe] {label} builder: {num3} builds ({_buildDistant[phase]} distant lod), {num:0.0}ms, " + $"{((num3 > 0) ? (num / (double)num3) : 0.0):0.0}ms each, {_buildRepeat[phase]} repeats worth {num2:0.0}ms{text}")); FrameBudgetPlugin.Log.LogWarning((object)($"[probe] {label} main: spawnZone {(double)_spawnTicks[phase] * TicksToMs:0.0}ms ({_spawnOk[phase]} created, {_spawnBlocked[phase]} blocked), " + $"regenerate {(double)_regenTicks[phase] * TicksToMs:0.0}ms x{_regenCount[phase]} " + $"(lod {(double)_regenLodTicks[phase] * TicksToMs:0.0}ms x{_regenLodCount[phase]}, collider {(double)_colliderTicks[phase] * TicksToMs:0.0}ms x{_colliderCount[phase]}), " + $"objects {(double)_objectTicks[phase] * TicksToMs:0.0}ms x{_objectCount[phase]} in {_objectCalls[phase]} passes, peak {_objectPeak[phase]}/pass")); string arg = ((phase == 0) ? $", peak live {_peakInstances}" : string.Empty); FrameBudgetPlugin.Log.LogWarning((object)($"[probe] {label} split: create {(double)_createTicks[phase] * TicksToMs:0.0}ms, " + $"remove {(double)_removeTicks[phase] * TicksToMs:0.0}ms destroying {_removed[phase]}{arg}")); } private static void ReportFrames(string label, List<float> frames) { if (frames.Count == 0) { FrameBudgetPlugin.Log.LogWarning((object)("[probe] " + label + " frames: no samples")); return; } frames.Sort(); double num = 0.0; foreach (float frame in frames) { num += (double)frame; } float num2 = frames[frames.Count - 1]; double num3 = num / (double)frames.Count; int num4 = Mathf.Max(1, frames.Count / 100); double num5 = 0.0; for (int i = frames.Count - num4; i < frames.Count; i++) { num5 += (double)frames[i]; } double num6 = num5 / (double)num4; int num7 = 0; int num8 = 0; foreach (float frame2 in frames) { if (frame2 > 33f) { num7++; } if (frame2 > 100f) { num8++; } } FrameBudgetPlugin.Log.LogWarning((object)($"[probe] {label} frames: {frames.Count} samples, avg {num3:0.0}ms, " + $"1% low {num6:0.0}ms ({1000.0 / Math.Max(0.001, num6):0} fps), worst {num2:0.0}ms, " + $">33ms x{num7}, >100ms x{num8}")); } private static void ResetAll() { _phase = -1; _framesDuring.Clear(); _framesAfter.Clear(); } } [HarmonyPatch] internal static class Patch_HeightmapBuilder_Build_Probe { private static bool Prepare() { if (LoadProbe.Enabled) { return TargetMethod() != null; } return false; } private static MethodBase TargetMethod() { return AccessTools.Method(typeof(HeightmapBuilder), "Build", (Type[])null, (Type[])null); } private static void Prefix(out long __state) { __state = Stopwatch.GetTimestamp(); } private static void Postfix(HMBuildData data, long __state) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) if (data != null) { LoadProbe.Built(data.m_center, data.m_distantLod, Stopwatch.GetTimestamp() - __state); } } } [HarmonyPatch] internal static class Patch_ZNetScene_CreateObject_Probe { private static bool Prepare() { if (LoadProbe.Enabled) { return TargetMethod() != null; } return false; } private static MethodBase TargetMethod() { return AccessTools.Method(typeof(ZNetScene), "CreateObject", (Type[])null, (Type[])null); } private static void Postfix(ZDO zdo, GameObject __result) { if ((Object)(object)__result != (Object)null) { LoadProbe.ObjectCreated(zdo); } } } [HarmonyPatch] internal static class Patch_WearNTearUpdater_Probe { private static bool Prepare() { if (LoadProbe.Enabled) { return TargetMethod() != null; } return false; } private static MethodBase TargetMethod() { return AccessTools.Method(typeof(WearNTearUpdater), "UpdateWearNTear", (Type[])null, (Type[])null); } private static void Prefix(out long __state) { __state = Stopwatch.GetTimestamp(); } private static void Postfix(long __state) { LoadProbe.Extra("wearntear", Stopwatch.GetTimestamp() - __state); } } [HarmonyPatch] internal static class Patch_ZDOMan_Update_Probe { private static bool Prepare() { if (LoadProbe.Enabled) { return TargetMethod() != null; } return false; } private static MethodBase TargetMethod() { return AccessTools.Method(typeof(ZDOMan), "Update", (Type[])null, (Type[])null); } private static void Prefix(out long __state) { __state = Stopwatch.GetTimestamp(); } private static void Postfix(long __state) { LoadProbe.Extra("zdoman", Stopwatch.GetTimestamp() - __state); } } [HarmonyPatch] internal static class Patch_ClutterSystem_Update_Probe { private static bool Prepare() { if (LoadProbe.Enabled) { return TargetMethod() != null; } return false; } private static MethodBase TargetMethod() { return AccessTools.Method(typeof(ClutterSystem), "Update", (Type[])null, (Type[])null); } private static void Prefix(out long __state) { __state = Stopwatch.GetTimestamp(); } private static void Postfix(long __state) { LoadProbe.Extra("clutter", Stopwatch.GetTimestamp() - __state); } } [HarmonyPatch] internal static class Patch_ZNetScene_CreateObjects_Split { private static bool Prepare() { if (LoadProbe.Enabled) { return TargetMethod() != null; } return false; } private static MethodBase TargetMethod() { return AccessTools.Method(typeof(ZNetScene), "CreateObjects", (Type[])null, (Type[])null); } private static void Prefix(out long __state) { __state = Stopwatch.GetTimestamp(); } private static void Postfix(ZNetScene __instance, long __state) { LoadProbe.Created(Stopwatch.GetTimestamp() - __state, SpawnCost.Count(__instance)); } } [HarmonyPatch] internal static class Patch_ZNetScene_RemoveObjects_Split { private static bool Prepare() { if (LoadProbe.Enabled) { return TargetMethod() != null; } return false; } private static MethodBase TargetMethod() { return AccessTools.Method(typeof(ZNetScene), "RemoveObjects", (Type[])null, (Type[])null); } private static void Prefix(ZNetScene __instance, out long[] __state) { __state = new long[2] { Stopwatch.GetTimestamp(), SpawnCost.Count(__instance) }; } private static void Postfix(ZNetScene __instance, long[] __state) { LoadProbe.Removed(Stopwatch.GetTimestamp() - __state[0], Mathf.Max(0, (int)__state[1] - SpawnCost.Count(__instance))); } } [HarmonyPatch] internal static class Patch_ZoneSystem_SpawnZone_Probe { private static bool Prepare() { if (LoadProbe.Enabled) { return TargetMethod() != null; } return false; } private static MethodBase TargetMethod() { return AccessTools.Method(typeof(ZoneSystem), "SpawnZone", (Type[])null, (Type[])null); } private static void Prefix(out long __state) { __state = Stopwatch.GetTimestamp(); } private static void Postfix(bool __result, long __state) { LoadProbe.Spawned(__result, Stopwatch.GetTimestamp() - __state); } } [HarmonyPatch] internal static class Patch_Heightmap_Regenerate_Probe { private static bool Prepare() { if (LoadProbe.Enabled) { return TargetMethod() != null; } return false; } private static MethodBase TargetMethod() { return AccessTools.Method(typeof(Heightmap), "Regenerate", (Type[])null, (Type[])null); } private static void Prefix(out long __state) { __state = Stopwatch.GetTimestamp(); } private static void Postfix(Heightmap __instance, long __state) { if (!TerrainRebuild.Skipped) { LoadProbe.Regenerated(Stopwatch.GetTimestamp() - __state, (Object)(object)__instance != (Object)null && __instance.IsDistantLod); } } } [HarmonyPatch] internal static class Patch_Heightmap_RebuildCollisionMesh_Probe { private static bool Prepare() { if (LoadProbe.Enabled) { return TargetMethod() != null; } return false; } private static MethodBase TargetMethod() { return AccessTools.Method(typeof(Heightmap), "RebuildCollisionMesh", (Type[])null, (Type[])null); } private static void Prefix(out long __state) { __state = Stopwatch.GetTimestamp(); } private static void Postfix(long __state) { LoadProbe.ColliderRebuilt(Stopwatch.GetTimestamp() - __state); } } internal static class LoadRange { public static int Narrowed { get; private set; } public static int Skipped { get; private set; } private static bool Enabled { get { if (FrameBudgetPlugin.Cfg != null && FrameBudgetPlugin.Cfg.Enabled.Value) { return FrameBudgetPlugin.Cfg.PortalNarrowRange.Value; } return false; } } private static bool AlreadyLoaded(SimulationDistance actual) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) if (!LoadMode.HasFrom) { return false; } Vector2s zone = ZoneSystem.GetZone(LoadMode.From); Vector2s zone2 = ZoneSystem.GetZone(LoadMode.Target); int num = ((SimulationDistance)(ref actual)).NearSimulationDistance - 1; if (num < 0) { return false; } if (Math.Abs(zone2.x - zone.x) <= num) { return Math.Abs(zone2.y - zone.y) <= num; } return false; } public static SimulationDistance ForStreaming(ZNet net) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) SimulationDistance syncedSimulationDistance = net.GetSyncedSimulationDistance(); if (!Enabled || !LoadMode.Active) { return syncedSimulationDistance; } if (AlreadyLoaded(syncedSimulationDistance)) { Skipped++; return syncedSimulationDistance; } SimulationDistance simulationDistance = SimulationDistance.GetSimulationDistance(0); if (((SimulationDistance)(ref simulationDistance)).NearSimulationDistance >= ((SimulationDistance)(ref syncedSimulationDistance)).NearSimulationDistance) { return syncedSimulationDistance; } Narrowed++; return simulationDistance; } } [HarmonyPatch(typeof(ZNetScene), "CreateDestroyObjects")] internal static class Patch_ZNetScene_CreateDestroyObjects_Range { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> list = new List<CodeInstruction>(instructions); MethodInfo methodInfo = AccessTools.Method(typeof(ZNet), "GetSyncedSimulationDistance", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(LoadRange), "ForStreaming", (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null) { FrameBudgetPlugin.Log.LogError((object)"[portal] GetSyncedSimulationDistance unavailable; narrow range disabled"); return list; } int num = 0; foreach (CodeInstruction item in list) { if ((item.opcode == OpCodes.Call || item.opcode == OpCodes.Callvirt) && item.operand as MethodInfo == methodInfo) { num++; } } if (num != 1) { FrameBudgetPlugin.Log.LogError((object)$"[portal] expected one GetSyncedSimulationDistance call in CreateDestroyObjects, found {num}; narrow range disabled"); return list; } foreach (CodeInstruction item2 in list) { if ((!(item2.opcode != OpCodes.Call) || !(item2.opcode != OpCodes.Callvirt)) && !(item2.operand as MethodInfo != methodInfo)) { item2.opcode = OpCodes.Call; item2.operand = methodInfo2; break; } } return list; } } [BepInPlugin("ru.ivest.valheimframebudget", "FastLoading", "0.6.2")] public class FrameBudgetPlugin : BaseUnityPlugin { public const string Guid = "ru.ivest.valheimframebudget"; public const string Name = "FastLoading"; public const string Version = "0.6.2"; internal static ManualLogSource Log; internal static BudgetConfig Cfg; private Harmony _harmony; private void Awake() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Cfg = new BudgetConfig(((BaseUnityPlugin)this).Config); _harmony = new Harmony("ru.ivest.valheimframebudget"); PatchEach(); } private void PatchEach() { Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(typeof(FrameBudgetPlugin).Assembly); foreach (Type type in typesFromAssembly) { try { _harmony.CreateClassProcessor(type).Patch(); } catch (Exception ex) { Log.LogError((object)("[portal] " + type.Name + " could not be applied and is disabled: " + ex.GetBaseException().Message)); } } } private void Update() { LoadMode.Tick(); LoadProbe.Tick(); if (InstantiateBench.Pending) { ((MonoBehaviour)this).StartCoroutine(InstantiateBench.Run()); } if (Cfg != null && Cfg.Enabled.Value) { if (LoadMode.JustFinished) { TerrainRebuild.Flush(); TerrainRebuild.BeginCatchUp(); } TerrainRebuild.PumpCatchUp(); ArrivalGround.Tick(); PortalInterest.Tick(); PortalInterest.ServerTick(); if (PortalWarm.HasTarget && (Object)(object)Player.m_localPlayer == (Object)null) { PortalWarm.Clear(); } } } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } internal static class Tuning { internal static readonly float FloorGrace = 0.5f; internal static readonly float LoadBudgetMs = 50f; internal static readonly float SpawnBudgetMs = 100f; internal static readonly float WarmRadius = 30f; internal static readonly int SendBoostFactor = 4; internal static readonly float SendBoostSeconds = 8f; internal static readonly float ArrivalMaxDrop = 1.5f; internal static readonly float ArrivalFloorWait = 10f; internal static readonly float ArrivalQuiet = 0.75f; internal static readonly float ArrivalFirstWait = 3f; internal static readonly float ArrivalGroundWatch = 5f; internal static readonly float CatchUpBudgetMs = 6f; internal static readonly float CatchUpSeconds = 6f; internal static readonly bool DeferTerrainRebuilds = false; internal static readonly int CatchUpRebuilds = 0; } internal sealed class ConfigurationManagerAttributes { public int? Order; } internal class BudgetConfig { private const string General = "1 - General"; private const string Transitions = "2 - Transitions"; private const string Multiplayer = "3 - Multiplayer"; public readonly ConfigEntry<bool> Enabled; public readonly ConfigEntry<float> PortalDungeonFade; public readonly ConfigEntry<float> PortalCooldown; public readonly ConfigEntry<bool> PortalNarrowRange; public readonly ConfigEntry<bool> PortalDeferNature; public readonly ConfigEntry<bool> PortalInterestEnabled; public readonly ConfigEntry<bool> PortalSendBoost; private static ConfigDescription Describe(string text, int order, AcceptableValueBase range = null) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown return new ConfigDescription(text, range, new object[1] { new ConfigurationManagerAttributes { Order = order } }); } public BudgetConfig(ConfigFile cfg) { Enabled = cfg.Bind<bool>("1 - General", "Enabled", true, Describe("Enable FastLoading.", 0)); PortalDungeonFade = cfg.Bind<float>("2 - Transitions", "Dungeon fade", 0f, Describe("Seconds of fade to black when entering or leaving a dungeon, 0 to 2. The screen darkens over this time, you are moved while it is black, and it clears again over the same time. 0 keeps the instant switch; vanilla takes about three seconds in all. Portal travel is not affected.", 40, (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f))); PortalCooldown = cfg.Bind<float>("2 - Transitions", "Teleport cooldown", 0.5f, Describe("Seconds before another teleport is allowed, 0.1 to 2. Vanilla waits two; a short pause is kept so that one key press cannot send you straight back through the portal you arrived at.", 30, (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 2f))); PortalNarrowRange = cfg.Bind<bool>("2 - Transitions", "Narrow range while loading", true, Describe("While the loading screen is up, create only the area the arrival waits for (three by three sectors instead of five by five). The rest is created after you arrive, so distant vegetation and buildings appear over the following seconds. Off: a longer loading screen, a complete view on arrival.", 20)); PortalDeferNature = cfg.Bind<bool>("2 - Transitions", "Defer distant nature", true, Describe("While the loading screen is up, create built pieces and everything the arrival needs before distant rocks, trees and bushes. Nothing is skipped; the remaining vegetation appears over the next seconds instead of holding the screen.", 10)); PortalInterestEnabled = cfg.Bind<bool>("3 - Multiplayer", "Early object delivery", true, Describe("As a client, ask the host to send a portal destination's objects while you walk up to the portal. Needs FastLoading on the host as well.", 20)); PortalSendBoost = cfg.Bind<bool>("3 - Multiplayer", "Send boost", true, Describe("As a host, send world objects faster to a player for a few seconds around their portal transition. Vanilla sends about 200 KB a second per player however much bandwidth there is; this raises it four times. Only for players whose game also runs FastLoading.", 10)); MigrateKeys(cfg); } private void MigrateKeys(ConfigFile cfg) { //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Expected O, but got Unknown if (!File.Exists(cfg.ConfigFilePath)) { return; } Dictionary<(string, string), string> dictionary = new Dictionary<(string, string), string>(); string item = ""; string[] array = File.ReadAllLines(cfg.ConfigFilePath); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length == 0 || text[0] == '#') { continue; } if (text[0] == '[' && text[text.Length - 1] == ']') { item = text.Substring(1, text.Length - 2).Trim(); continue; } int num = text.IndexOf('='); if (num > 0) { dictionary[(item, text.Substring(0, num).Trim())] = text.Substring(num + 1).Trim(); } } Dictionary<(string, string), ConfigEntryBase> dictionary2 = new Dictionary<(string, string), ConfigEntryBase> { [("General", "Enabled")] = (ConfigEntryBase)(object)Enabled, [("Portal load", "DungeonFade")] = (ConfigEntryBase)(object)PortalDungeonFade, [("Portal load", "Cooldown")] = (ConfigEntryBase)(object)PortalCooldown, [("Portal load", "NarrowRangeWhileLoading")] = (ConfigEntryBase)(object)PortalNarrowRange, [("Portal load", "DeferDistantNature")] = (ConfigEntryBase)(object)PortalDeferNature, [("Portal load", "MultiplayerInterest")] = (ConfigEntryBase)(object)PortalInterestEnabled, [("Portal load", "SendBoost")] = (ConfigEntryBase)(object)PortalSendBoost }; bool flag = File.Exists(Path.Combine(Paths.ConfigPath, "ru.ivest.portalpreview.cfg")); List<ConfigDefinition> list = new List<ConfigDefinition>(); bool saveOnConfigSet = cfg.SaveOnConfigSet; cfg.SaveOnConfigSet = false; try { foreach (KeyValuePair<(string, string), string> item2 in dictionary) { var (text2, text3) = item2.Key; switch (text2) { case "General": if (text3 == "Enabled") { break; } goto default; default: if (!flag || (!(text2 == "Portal preview") && (!(text2 == "General") || !(text3 == "Hardware profile")))) { continue; } break; case "Portal load": case "World streaming": case "Diagnostics": case "Portal smoke": break; } if (dictionary2.TryGetValue(item2.Key, out var value)) { value.SetSerializedValue(item2.Value); } list.Add(new ConfigDefinition(text2, text3)); } foreach (ConfigDefinition item3 in list) { cfg.Bind<string>(item3, "", (ConfigDescription)null); cfg.Remove(item3); } } finally { cfg.SaveOnConfigSet = saveOnConfigSet; } if (list.Count > 0) { cfg.Save(); } } } internal static class PortalInterest { private const string RpcName = "VFB_PortalInterest"; private static readonly Dictionary<long, Vector3> _interest = new Dictionary<long, Vector3>(); private static readonly Dictionary<long, float> _heardAt = new Dictionary<long, float>(); private const float MinInterval = 0.5f; private static readonly List<ZDO> _temp = new List<ZDO>(); private static FieldInfo _peersField; private static FieldInfo _forceSendField; private static FieldInfo _peerRefField; private static bool _resolved; private static ZRoutedRpc _registeredOn; private static Vector3 _lastSent; private static float _nextSendAt; public static int Served { get; private set; } public static int Queued { get; private set; } private static void EnsureRegistered() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null && instance != _registeredOn) { _registeredOn = instance; _lastSent = Vector3.zero; _heardAt.Clear(); instance.Register<Vector3>("VFB_PortalInterest", (Action<long, Vector3>)RPC_Interest); } } public static void Tick() { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) if (FrameBudgetPlugin.Cfg == null || !FrameBudgetPlugin.Cfg.Enabled.Value || !FrameBudgetPlugin.Cfg.PortalInterestEnabled.Value) { return; } EnsureRegistered(); if (!((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsServer() && ZRoutedRpc.instance != null && PortalWarm.HasTarget && !(Time.realtimeSinceStartup < _nextSendAt)) { Vector3 lastTarget = PortalWarm.LastTarget; Vector3 val = lastTarget - _lastSent; if (!(((Vector3)(ref val)).sqrMagnitude < 1f)) { _nextSendAt = Time.realtimeSinceStartup + 1f; _lastSent = lastTarget; ZRoutedRpc.instance.InvokeRoutedRPC("VFB_PortalInterest", new object[1] { lastTarget }); } } } private static void RPC_Interest(long sender, Vector3 target) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer()) { float realtimeSinceStartup = Time.realtimeSinceStartup; if (!_heardAt.TryGetValue(sender, out var value) || !(realtimeSinceStartup - value < 0.5f)) { _heardAt[sender] = realtimeSinceStartup; _interest[sender] = target; } } } private static bool Resolve() { if (_resolved) { return _peersField != null; } _resolved = true; _peersField = AccessTools.Field(typeof(ZDOMan), "m_peers"); Type type = AccessTools.Inner(typeof(ZDOMan), "ZDOPeer"); _forceSendField = ((type != null) ? AccessTools.Field(type, "m_forceSend") : null); _peerRefField = ((type != null) ? AccessTools.Field(type, "m_peer") : null); if (_peersField == null || _forceSendField == null || _peerRefField == null) { FrameBudgetPlugin.Log.LogError((object)"[portal] ZDOMan.ZDOPeer layout not recognized; multiplayer destination prefetch disabled"); _peersField = null; return false; } return true; } public static void ServerTick() { //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) if (FrameBudgetPlugin.Cfg == null || !FrameBudgetPlugin.Cfg.Enabled.Value || !FrameBudgetPlugin.Cfg.PortalInterestEnabled.Value || _interest.Count == 0 || (Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer() || ZDOMan.instance == null || !Resolve()) { return; } if (!(_peersField.GetValue(ZDOMan.instance) is IList list)) { _interest.Clear(); return; } foreach (object item in list) { object? value = _peerRefField.GetValue(item); ZNetPeer val = (ZNetPeer)((value is ZNetPeer) ? value : null); if (val == null || !_interest.TryGetValue(val.m_uid, out var value2) || !(_forceSendField.GetValue(item) is HashSet<ZDOID> hashSet)) { continue; } _temp.Clear(); SectorObjects.FindNeighbourhood(ZoneSystem.GetZone(value2), _temp); foreach (ZDO item2 in _temp) { if (hashSet.Add(item2.m_uid)) { Queued++; } } Served++; SendBoost.Open(val.m_uid); } _interest.Clear(); } } [HarmonyPatch(typeof(Hud), "UpdateBlackScreen")] internal static class Patch_Hud_UpdateBlackScreen_Portal { private static void Postfix(Hud __instance, Player player) { BudgetConfig cfg = FrameBudgetPlugin.Cfg; if (cfg != null && cfg.Enabled.Value && !((Object)(object)player == (Object)null) && player.ShowTeleportAnimation() && !((Object)(object)__instance.m_loadingScreen == (Object)null)) { __instance.m_loadingScreen.alpha = 1f; } } } internal static class PortalWarm { private static FieldRef<TeleportWorld, ZNetView> _nview; private static bool _resolved; private static TeleportWorld _chosen; private static float _chosenDist; private const float SwitchMargin = 0.8f; private static readonly Dictionary<TeleportWorld, Vector3> _targets = new Dictionary<TeleportWorld, Vector3>(); private static readonly List<TeleportWorld> _stale = new List<TeleportWorld>(); public static Vector3 LastTarget { get; private set; } public static bool HasTarget { get; private set; } public static int Warms { get; private set; } private static void PruneStale() { _stale.Clear(); foreach (TeleportWorld key in _targets.Keys) { if ((Object)(object)key == (Object)null || !Object.op_Implicit((Object)(object)key)) { _stale.Add(key); } } foreach (TeleportWorld item in _stale) { _targets.Remove(item); } } public static void Consider(TeleportWorld portal) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) if (FrameBudgetPlugin.Cfg == null || !FrameBudgetPlugin.Cfg.Enabled.Value) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || (Object)(object)portal == (Object)null) { return; } PruneStale(); float warmRadius = Tuning.WarmRadius; float num = Vector3.Distance(((Component)localPlayer).transform.position, ((Component)portal).transform.position); if (num > warmRadius) { _targets.Remove(portal); if ((Object)(object)_chosen == (Object)(object)portal) { _chosen = null; HasTarget = false; } return; } if (!_resolved) { _resolved = true; try { _nview = AccessTools.FieldRefAccess<TeleportWorld, ZNetView>("m_nview"); } catch (Exception ex) { FrameBudgetPlugin.Log.LogError((object)("[portal] TeleportWorld.m_nview unavailable (" + ex.GetType().Name + "); destination warming disabled")); _nview = null; } } if (_nview == null || ZDOMan.instance == null) { return; } ZNetView val = _nview.Invoke(portal); ZDO val2 = (((Object)(object)val != (Object)null) ? val.GetZDO() : null); if (val2 == null) { return; } ZDOID connectionZDOID = val2.GetConnectionZDOID((ConnectionType)1); if (connectionZDOID == ZDOID.None) { return; } ZDO zDO = ZDOMan.instance.GetZDO(connectionZDOID); if (zDO == null) { ZDOMan.instance.RequestZDO(connectionZDOID); return; } Vector3 position = zDO.GetPosition(); bool num2 = !_targets.ContainsKey(portal); _targets[portal] = position; if (num2) { TerrainPriority.Request(position); Warms++; } if ((Object)(object)_chosen == (Object)(object)portal) { _chosenDist = num; } else { if ((Object)(object)_chosen != (Object)null && Object.op_Implicit((Object)(object)_chosen) && num >= _chosenDist * 0.8f) { return; } _chosen = portal; _chosenDist = num; } LastTarget = position; HasTarget = true; } public static void Clear() { HasTarget = false; _chosen = null; _targets.Clear(); } } [HarmonyPatch(typeof(TeleportWorld), "UpdatePortal")] internal static class Patch_TeleportWorld_UpdatePortal { private static void Postfix(TeleportWorld __instance) { PortalWarm.Consider(__instance); } } internal static class PrefabSurvey { public static void Report(List<KeyValuePair<GameObject, int>> ranked, int depth) { FrameBudgetPlugin.Log.LogWarning((object)"[survey] prefab anatomy: name xN piece=? renderers=N lods=N colliders=N scripts=N | cheapest lod: mesh verts submeshes materials instancing"); for (int i = 0; i < ranked.Count && i < depth; i++) { Describe(ranked[i].Key, ranked[i].Value); } } private static void Describe(GameObject prefab, int population) { StringBuilder stringBuilder = new StringBuilder("[survey] "); stringBuilder.Append(((Object)prefab).name).Append(" x").Append(population); stringBuilder.Append(" piece=").Append(((Object)(object)prefab.GetComponent<Piece>() != (Object)null) ? "yes" : "no"); MeshRenderer[] componentsInChildren = prefab.GetComponentsInChildren<MeshRenderer>(true); LODGroup[] componentsInChildren2 = prefab.GetComponentsInChildren<LODGroup>(true); Collider[] componentsInChildren3 = prefab.GetComponentsInChildren<Collider>(true); MonoBehaviour[] componentsInChildren4 = prefab.GetComponentsInChildren<MonoBehaviour>(true); stringBuilder.Append(" renderers=").Append(componentsInChildren.Length); stringBuilder.Append(" lods=").Append((componentsInChildren2.Length != 0) ? componentsInChildren2[0].lodCount : 0); stringBuilder.Append(" colliders=").Append(componentsInChildren3.Length); stringBuilder.Append(" scripts=").Append(componentsInChildren4.Length); Renderer[] array = Cheapest(componentsInChildren2, componentsInChildren); stringBuilder.Append(" | "); if (array == null || array.Length == 0) { stringBuilder.Append("no renderer"); FrameBudgetPlugin.Log.LogWarning((object)stringBuilder.ToString()); return; } stringBuilder.Append(array.Length).Append(" renderer(s):"); Renderer[] array2 = array; foreach (Renderer val in array2) { if ((Object)(object)val == (Object)null) { continue; } MeshFilter component = ((Component)val).GetComponent<MeshFilter>(); Mesh val2 = (((Object)(object)component != (Object)null) ? component.sharedMesh : null); stringBuilder.Append(' ').Append(((Object)(object)val2 != (Object)null) ? ((Object)val2).name : "none"); stringBuilder.Append('/').Append(((Object)(object)val2 != (Object)null) ? val2.vertexCount : 0).Append('v'); stringBuilder.Append('/').Append(((Object)(object)val2 != (Object)null) ? val2.subMeshCount : 0).Append("sub"); Material[] sharedMaterials = val.sharedMaterials; foreach (Material val3 in sharedMaterials) { if (!((Object)(object)val3 == (Object)null)) { stringBuilder.Append(" [").Append(((Object)val3).name); stringBuilder.Append(val3.enableInstancing ? " inst" : " NOINST"); stringBuilder.Append(']'); } } } FrameBudgetPlugin.Log.LogWarning((object)stringBuilder.ToString()); } private static Renderer[] Cheapest(LODGroup[] groups, MeshRenderer[] fallback) { if (groups.Length == 0 || (Object)(object)groups[0] == (Object)null) { return (Renderer[])(object)fallback; } LOD[] lODs = groups[0].GetLODs(); if (lODs == null || lODs.Length == 0) { return (Renderer[])(object)fallback; } for (int num = lODs.Length - 1; num >= 0; num--) { if (lODs[num].renderers != null && lODs[num].renderers.Length != 0) { return lODs[num].renderers; } } return (Renderer[])(object)fallback; } } internal static class SectorObjects { private static readonly SimulationDistance Neighbourhood = new SimulationDistance(1, 0, true); public static void FindNeighbourhood(Vector2s sector, List<ZDO> results) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) ZDOMan.instance.FindSectorObjects(sector, Neighbourhood, results, (List<ZDO>)null); } } internal static class SendBoost { internal const int Vanilla = 10240; private const int MaxFactor = 16; private const int Ceiling = 262144; private static readonly Dictionary<long, float> _until = new Dictionary<long, float>(); internal static readonly FieldRef<object, ZNetPeer> PeerOf = ResolvePeer(); internal static bool Applied { get; set; } private static FieldRef<object, ZNetPeer> ResolvePeer() { Type type = AccessTools.Inner(typeof(ZDOMan), "ZDOPeer"); try { return (type != null) ? AccessTools.FieldRefAccess<ZNetPeer>(type, "m_peer") : null; } catch (Exception) { return null; } } public static void Open(long uid) { if (FrameBudgetPlugin.Cfg != null) { _until[uid] = Time.realtimeSinceStartup + Mathf.Max(0f, Tuning.SendBoostSeconds); } } public static int Budget(int window, object peer) { if (window <= 0 || _until.Count == 0 || peer == null || PeerOf == null || FrameBudgetPlugin.Cfg == null || !FrameBudgetPlugin.Cfg.Enabled.Value || !FrameBudgetPlugin.Cfg.PortalSendBoost.Value) { return window; } ZNetPeer val = PeerOf.Invoke(peer); if (val == null || !_until.TryGetValue(val.m_uid, out var value)) { return window; } if (Time.realtimeSinceStartup > value) { _until.Remove(val.m_uid); return window; } return (int)Math.Min((long)window * (long)Mathf.Clamp(Tuning.SendBoostFactor, 1, 16), Math.Max(window, 262144)); } } [HarmonyPatch(typeof(ZDOMan), "SendZDOs")] internal static class Patch_ZDOMan_SendZDOs_Boost { private static readonly OpCode[] Small = new OpCode[9] { OpCodes.Ldc_I4_0, OpCodes.Ldc_I4_1, OpCodes.Ldc_I4_2, OpCodes.Ldc_I4_3, OpCodes.Ldc_I4_4, OpCodes.Ldc_I4_5, OpCodes.Ldc_I4_6, OpCodes.Ldc_I4_7, OpCodes.Ldc_I4_8 }; private static readonly OpCode[] Compares = new OpCode[20] { OpCodes.Ble, OpCodes.Ble_S, OpCodes.Ble_Un, OpCodes.Ble_Un_S, OpCodes.Bgt, OpCodes.Bgt_S, OpCodes.Bgt_Un, OpCodes.Bgt_Un_S, OpCodes.Bge, OpCodes.Bge_S, OpCodes.Bge_Un, OpCodes.Bge_Un_S, OpCodes.Blt, OpCodes.Blt_S, OpCodes.Blt_Un, OpCodes.Blt_Un_S, OpCodes.Cgt, OpCodes.Cgt_Un, OpCodes.Clt, OpCodes.Clt_Un }; private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, MethodBase original) { //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Expected O, but got Unknown List<CodeInstruction> list = new List<CodeInstruction>(instructions); MethodInfo methodInfo = AccessTools.Method(typeof(SendBoost), "Budget", (Type[])null, (Type[])null); int num = PeerArgument(original); if (methodInfo == null || SendBoost.PeerOf == null || num < 0) { FrameBudgetPlugin.Log.LogError((object)"[portal] SendZDOs peer or send budget hook unavailable; send boost disabled"); return list; } int num2 = QueueLocal(list); int num3 = BudgetSite(list, num2); if (num3 < 0) { FrameBudgetPlugin.Log.LogError((object)"[portal] the round budget in SendZDOs is not a plain value minus the send queue size; another mod has rewritten the method; send boost disabled"); return list; } int num4 = ((num2 < 0) ? (-1) : GateSite(list, num2)); string text = Describe(list[num3]); List<int> list2 = new List<int> { num3 }; if (num4 >= 0) { list2.Add(num4); } list2.Sort(); for (int num5 = list2.Count - 1; num5 >= 0; num5--) { list.InsertRange(list2[num5] + 1, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[2] { LoadArgument(num), new CodeInstruction(OpCodes.Call, (object)methodInfo) }); } if (num4 < 0) { FrameBudgetPlugin.Log.LogWarning((object)("[portal] send boost raises the round budget of " + text + " only: the round threshold in SendZDOs is not a comparison against a plain value; another mod has changed it")); } else if (text != 10240.ToString()) { FrameBudgetPlugin.Log.LogInfo((object)($"[portal] send window is {text}, not the vanilla {10240}; " + "send boost multiplies what is there")); } SendBoost.Applied = true; return list; } private static int QueueLocal(List<CodeInstruction> code) { for (int i = 0; i + 1 < code.Count; i++) { if (!(code[i].opcode != OpCodes.Callvirt) || !(code[i].opcode != OpCodes.Call)) { MethodInfo methodInfo = code[i].operand as MethodInfo; if (!(methodInfo == null) && !(methodInfo.Name != "GetSendQueueSize") && TryStore(code[i + 1], out var local)) { return local; } } } return -1; } private static int BudgetSite(List<CodeInstruction> code, int queue) { int num = -1; int num2 = 0; for (int i = 0; i + 2 < code.Count; i++) { if (IsWindow(code[i]) && TryLoad(code[i + 1], out var local) && (queue < 0 || local == queue) && (!(code[i + 2].opcode != OpCodes.Sub) || !(code[i + 2].opcode != OpCodes.Sub_Ovf))) { num2++; if (num < 0) { num = i; } } } if (queue >= 0 || num2 == 1) { return num; } return -1; } private static int GateSite(List<CodeInstruction> code, int queue) { for (int i = 0; i + 2 < code.Count; i++) { if (!TryLoad(code[i], out var local) || local != queue || !IsWindow(code[i + 1])) { continue; } OpCode[] compares = Compares; foreach (OpCode opCode in compares) { if (code[i + 2].opcode == opCode) { return i + 1; } } } return -1; } private static int PeerArgument(MethodBase method) { Type type = AccessTools.Inner(typeof(ZDOMan), "ZDOPeer"); if (method == null || type == null) { return -1; } ParameterInfo[] parameters = method.GetParameters(); foreach (ParameterInfo parameterInfo in parameters) { if (parameterInfo.ParameterType == type) { return parameterInfo.Position + ((!method.IsStatic) ? 1 : 0); } } return -1; } private static CodeInstruction LoadArgument(int index) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown return (CodeInstruction)(index switch { 0 => (object)new CodeInstruction(OpCodes.Ldarg_0, (object)null), 1 => (object)new CodeInstruction(OpCodes.Ldarg_1, (object)null), 2 => (object)new CodeInstruction(OpCodes.Ldarg_2, (object)null), 3 => (object)new CodeInstruction(OpCodes.Ldarg_3, (object)null), _ => (object)new CodeInstruction(OpCodes.Ldarg_S, (object)(byte)index), }); } private static bool IsWindow(CodeInstruction ins) { if (TryConst(ins, out var _)) { return true; } if (ins.opcode == OpCodes.Ldsfld) { return (ins.operand as FieldInfo)?.FieldType == typeof(int); } if (ins.opcode == OpCodes.Call && ins.operand is MethodInfo methodInfo) { if (methodInfo.IsStatic && methodInfo.ReturnType == typeof(int)) { return methodInfo.GetParameters().Length == 0; } return false; } return false; } private static string Describe(CodeInstruction ins) { if (TryConst(ins, out var value)) { return value.ToString(); } if (ins.operand is MemberInfo memberInfo) { return memberInfo.DeclaringType?.Name + "." + memberInfo.Name; } return ins.opcode.Name; } private static bool TryConst(CodeInstruction ins, out int value) { value = 0; if (ins.opcode == OpCodes.Ldc_I4 || ins.opcode == OpCodes.Ldc_I4_S) { if (ins.operand == null) { return false; } value = Convert.ToInt32(ins.operand); return true; } for (int i = 0; i < Small.Length; i++) { if (ins.opcode == Small[i]) { value = i; return true; } } if (ins.opcode == OpCodes.Ldc_I4_M1) { value = -1; return true; } return false; } private static bool TryLoad(CodeInstruction ins, out int local) { return Local(ins, out local, OpCodes.Ldloc, OpCodes.Ldloc_S, OpCodes.Ldloc_0, OpCodes.Ldloc_1, OpCodes.Ldloc_2, OpCodes.Ldloc_3); } private static bool TryStore(CodeInstruction ins, out int local) { return Local(ins, out local, OpCodes.Stloc, OpCodes.Stloc_S, OpCodes.Stloc_0, OpCodes.Stloc_1, OpCodes.Stloc_2, OpCodes.Stloc_3); } private static bool Local(CodeInstruction ins, out int local, OpCode full, OpCode compact, OpCode zero, OpCode one, OpCode two, OpCode three) { local = -1; if (ins.opcode == zero) { local = 0; } else if (ins.opcode == one) { local = 1; } else if (ins.opcode == two) { local = 2; } else if (ins.opcode == three) { local = 3; } else if (ins.opcode == full || ins.opcode == compact) { local = Index(ins.operand); } return local >= 0; } private static int Index(object operand) { if (operand is LocalVariableInfo localVariableInfo) { return localVariableInfo.LocalIndex; } if (operand is int) { return (int)operand; } if (operand is short) { return (short)operand; } if (operand is byte) { return (byte)operand; } return -1; } } internal static class SpawnCost { private static readonly FieldInfo Instances = AccessTools.Field(typeof(ZNetScene), "m_instances"); private static long _startedAt; private static int _countBefore; private static double _msPerObject = 0.2; public static double MsPerObject => _msPerObject; public static void Begin(ZNetScene scene) { if (!((Object)(object)scene == (Object)null) && !(Instances == null)) { _countBefore = Count(scene); _startedAt = Stopwatch.GetTimestamp(); } } public static void End(ZNetScene scene) { if (!((Object)(object)scene == (Object)null) && _startedAt != 0L) { double num = (double)(Stopwatch.GetTimestamp() - _startedAt) * 1000.0 / (double)Stopwatch.Frequency; _startedAt = 0L; int num2 = Count(scene) - _countBefore; LoadProbe.ObjectsCreated(Math.Max(0, num2), num); if (num2 > 0) { double num3 = num / (double)num2; _msPerObject = Math.Max(0.01, _msPerObject * 0.8 + num3 * 0.2); } } } internal static int Count(ZNetScene scene) { if (!(Instances.GetValue(scene) is ICollection collection)) { return 0; } return collection.Count; } } [HarmonyPatch(typeof(ZNetScene), "CreateObjects")] internal static class Patch_ZNetScene_MeasureCreation { private static void Prefix(ZNetScene __instance) { SpawnCost.Begin(__instance); } private static void Postfix(ZNetScene __instance) { SpawnCost.End(__instance); } } internal static class SpawnRush { internal static bool ZoneGuarded { get; set; } public static int LastLoadingLimit { get; private set; } = 100; internal static bool LimitApplied { get; set; } internal static bool CatchUpApplied { get; set; } public static bool AreaGate(ZoneSystem zones) { if (LoadMode.Active && ZoneGuarded) { return true; } if ((Object)(object)zones != (Object)null) { return zones.IsActiveAreaLoaded(); } return false; } public static bool ZoneGate(ZoneSystem zones, Vector2s sector, ObjectType type) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)zones == (Object)null) { return false; } if (!zones.IsZoneReadyForType(sector, type)) { return false; } if (LoadMode.Active && !zones.IsZoneLoaded(sector)) { return false; } return true; } public static int PassLimit(int adaptive, int cap) { int num = Mathf.Max(adaptive, cap); if (FrameBudgetPlugin.Cfg == null || !FrameBudgetPlugin.Cfg.Enabled.Value || LoadMode.Active || !TerrainRebuild.CatchingUp) { return num; } double num2 = Tuning.CatchUpBudgetMs; if (num2 <= 0.0) { return num; } double num3 = Math.Max(0.01, SpawnCost.MsPerObject); return Mathf.Clamp((int)(num2 / num3), cap, num); } public static int LoadingScreenLimit() { if (FrameBudgetPlugin.Cfg == null || !FrameBudgetPlugin.Cfg.Enabled.Value || !LoadMode.Active) { LastLoadingLimit = 100; return 100; } double num = SpawnCost.MsPerObject; if (num < 0.01) { num = 0.01; } double num2 = Tuning.SpawnBudgetMs; if (num2 <= 0.0) { LastLoadingLimit = 100; return 100; } LastLoadingLimit = Mathf.Clamp((int)(num2 / num), 100, 20000); return LastLoadingLimit; } } [HarmonyPatch(typeof(ZNetScene), "CreateObjectsSorted")] internal static class Patch_ZNetScene_CreateObjectsSorted_PassLimit { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> list = new List<CodeInstruction>(instructions); MethodInfo methodInfo = AccessTools.Method(typeof(Mathf), "Max", new Type[2] { typeof(int), typeof(int) }, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(SpawnRush), "PassLimit", (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null) { FrameBudgetPlugin.Log.LogError((object)"[portal] Mathf.Max(int,int) unavailable; catch-up limit disabled"); return list; } int num = 0; foreach (CodeInstruction item in list) { if ((item.opcode == OpCodes.Call || item.opcode == OpCodes.Callvirt) && item.operand as MethodInfo == methodInfo) { num++; } } if (num != 1) { FrameBudgetPlugin.Log.LogError((object)$"[portal] expected one Mathf.Max(int,int) in CreateObjectsSorted, found {num}; catch-up limit disabled"); return list; } foreach (CodeInstruction item2 in list) { if ((!(item2.opcode != OpCodes.Call) || !(item2.opcode != OpCodes.Callvirt)) && !(item2.operand as MethodInfo != methodInfo)) { item2.opcode = OpCodes.Call; item2.operand = methodInfo2; break; } } SpawnRush.CatchUpApplied = true; return list; } } [HarmonyPatch(typeof(ZNetScene), "CreateObjectsSorted")] internal static class Patch_ZNetScene_CreateObjectsSorted { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> list = new List<CodeInstruction>(instructions); MethodInfo methodInfo = AccessTools.Method(typeof(ZoneSystem), "IsActiveAreaLoaded", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(SpawnRush), "AreaGate", (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null) { FrameBudgetPlugin.Log.LogError((object)"[portal] IsActiveAreaLoaded unavailable; active-area gate unchanged"); return list; } int num = 0; foreach (CodeInstruction item in list) { if ((item.opcode == OpCodes.Callvirt || item.opcode == OpCodes.Call) && item.operand as MethodInfo == methodInfo) { num++; } } if (num != 1) { FrameBudgetPlugin.Log.LogError((object)$"[portal] expected one IsActiveAreaLoaded call in CreateObjectsSorted, found {num}; active-area gate unchanged"); return list; } foreach (CodeInstruction item2 in list) { if ((!(item2.opcode != OpCodes.Callvirt) || !(item2.opcode != OpCodes.Call)) && !(item2.operand as MethodInfo != methodInfo)) { item2.opcode = OpCodes.Call; item2.operand = methodInfo2; break; } } if (!(SpawnRush.ZoneGuarded = GuardZoneCheck(list))) { FrameBudgetPlugin.Log.LogError((object)"[portal] sector guard unavailable; active-area gate remains unchanged"); } return list; } private static bool GuardZoneCheck(List<CodeInstruction> code) { MethodInfo methodInfo = AccessTools.Method(typeof(ZoneSystem), "IsZoneReadyForType", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(SpawnRush), "ZoneGate", (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null) { return false; } int num = 0; foreach (CodeInstruction item in code) { if ((item.opcode == OpCodes.Callvirt || item.opcode == OpCodes.Call) && item.operand as MethodInfo == methodInfo) { num++; } } if (num != 1) { FrameBudgetPlugin.Log.LogError((object)$"[portal] expected one IsZoneReadyForType call in CreateObjectsSorted, found {num}"); return false; } foreach (CodeInstruction item2 in code) { if ((!(item2.opcode != OpCodes.Callvirt) || !(item2.opcode != OpCodes.Call)) && !(item2.operand as MethodInfo != methodInfo)) { item2.opcode = OpCodes.Call; item2.operand = methodInfo2; return true; } } return false; } } [HarmonyPatch(typeof(ZNetScene), "CreateObjects")] internal static class Patch_ZNetScene_CreateObjects_LoadingLimit { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> list = new List<CodeInstruction>(instructions); MethodInfo methodInfo = AccessTools.Method(typeof(SpawnRush), "LoadingScreenLimit", (Type[])null, (Type[])null); int num = 0; foreach (CodeInstruction item in list) { if ((item.opcode == OpCodes.Ldc_I4 || item.opcode == OpCodes.Ldc_I4_S) && item.operand != null && Convert.ToInt32(item.operand) == 100) { num++; } } if (num != 1 || methodInfo == null) { FrameBudgetPlugin.Log.LogError((object)$"[portal] expected one loading limit of 100 in CreateObjects, found {num}; limit unchanged"); return list; } foreach (CodeInstruction item2 in list) { if ((!(item2.opcode != OpCodes.Ldc_I4) || !(item2.opcode != OpCodes.Ldc_I4_S)) && item2.operand != null && Convert.ToInt32(item2.operand) == 100) { item2.opcode = OpCodes.Call; item2.operand = methodInfo; break; } } SpawnRush.LimitApplied = true; return list; } } internal static class StructureGuard { private static readonly FieldRef<WearNTear, float> CreateTime = Field<WearNTear, float>("m_createTime"); private static readonly FieldRef<ZNetScene, List<ZDO>> Pending = Field<ZNetScene, List<ZDO>>("m_tempCurrentObjects2"); private static readonly HashSet<int> PendingSectors = new HashSet<int>(); private const float MaxHold = 120f; private static int _collectedFrame = -1; internal static bool Available { get { if (CreateTime != null) { return Pending != null; } return false; } } public static int Held { get; private set; } private static FieldRef<TObject, TField> Field<TObject, TField>(string name) { try { return AccessTools.FieldRefAccess<TObject, TField>(name); } catch (Exception) { return null; } } internal static bool MayCheck(WearNTear piece, float time) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) if (FrameBudgetPlugin.Cfg == null || !FrameBudgetPlugin.Cfg.Enabled.Value || (Object)(object)ZNetScene.instance == (Object)null) { return true; } float num = CreateTime.Invoke(piece); if (num < 0f) { return true; } if (time - num > 120f) { return true; } Collect(); if (PendingSectors.Count == 0) { return true; } Vector2s zone = ZoneSystem.GetZone(((Component)piece).transform.position); for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { if (PendingSectors.Contains(Key(zone.x + i, zone.y + j))) { Held++; return false; } } } return true; } private static int Key(int x, int y) { return (x << 16) ^ (y & 0xFFFF); } private static void Collect() { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) if (_collectedFrame == Time.frameCount) { return; } _collectedFrame = Time.frameCount; PendingSectors.Clear(); ZNetScene instance = ZNetScene.instance; List<ZDO> list = Pending.Invoke(instance); if (list == null) { return; } foreach (ZDO item in list) { if (item != null && !item.Created && (Object)(object)instance.GetPrefab(item.GetPrefab()) != (Object)null) { Vector2s sector = item.GetSector(); PendingSectors.Add(Key(sector.x, sector.y)); } } } } [HarmonyPatch(typeof(WearNTear), "ShouldUpdate")] internal static class Patch_WearNTear_ShouldUpdate_Guard { private static bool Prepare() { if (!StructureGuard.Available) { FrameBudgetPlugin.Log.LogError((object)"[portal] WearNTear.m_createTime or ZNetScene.m_tempCurrentObjects2 unavailable; structure guard disabled"); } return StructureGuard.Available; } private static void Postfix(WearNTear __instance, float __0, ref bool __result) { if (__result && !StructureGuard.MayCheck(__instance, __0)) { __result = false; } } } internal static class TeleportCooldown { private const float Vanilla = 2f; internal static bool Applied { get; set; } public static float Seconds() { if (FrameBudgetPlugin.Cfg == null || !FrameBudgetPlugin.Cfg.Enabled.Value) { return 2f; } return Mathf.Clamp(FrameBudgetPlugin.Cfg.PortalCooldown.Value, 0.1f, 2f); } } [HarmonyPatch(typeof(Player), "TeleportTo")] internal static class Patch_Player_TeleportTo_Cooldown { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> list = new List<CodeInstruction>(instructions); FieldInfo fieldInfo = AccessTools.Field(typeof(Player), "m_teleportCooldown"); MethodInfo methodInfo = AccessTools.Method(typeof(TeleportCooldown), "Seconds", (Type[])null, (Type[])null); if (fieldInfo == null || methodInfo == null) { FrameBudgetPlugin.Log.LogError((object)"[portal] Player.m_teleportCooldown unavailable; cooldown unchanged"); return list; } int num = 0; for (int i = 0; i < list.Count - 1; i++) { if (!(list[i].opcode != OpCodes.Ldfld) && !(list[i].operand as FieldInfo != fieldInfo)) { CodeInstruction val = list[i + 1]; if (!(val.opcode != OpCodes.Ldc_R4) && val.operand is float num2 && Mathf.Approximately(num2, 2f)) { val.opcode = OpCodes.Call; val.operand = methodInfo; num++; } } } if (num != 1) { FrameBudgetPlugin.Log.LogError((object)$"[portal] expected one cooldown comparison in TeleportTo, found {num}; cooldown may be unchanged"); return list; } TeleportCooldown.Applied = true; return list; } } internal static class TeleportGates { private const float VanillaFloorGate = 2f; private const float VanillaDistantGate = 8f; private static bool Enabled { get { if (FrameBudgetPlugin.Cfg != null) { return FrameBudgetPlugin.Cfg.Enabled.Value; } return false; } } internal static bool AbortGuarded { get; set; } public static float FloorGrace() { if (!Enabled) { return 2f; } if (LoadMode.ReadDistantNow()) { return 0f; } return Mathf.Max(DungeonFade.Seconds, AbortGuarded ? 0f : Tuning.FloorGrace); } public static bool KeepWaiting(Player player) { bool flag = LoadMode.ReadDistantNow(); if (flag || !Enabled) { return flag; } float num = LoadMode.ReadTimerNow(player); if (num < 0f) { return false; } return num <= Tuning.FloorGrace + DungeonFade.Seconds; } public static float DistantGate() { if (!Enabled || !ArrivalFloor.Applied) { return 8f; } return 0f; } internal static int Count(List<CodeInstruction> code, float value) { int num = 0; foreach (CodeInstruction item in code) { if (item.opcode == OpCodes.Ldc_R4 && item.operand is float num2 && num2 == value) { num++; } } return num; } internal static bool Replace(List<CodeInstruction> code, float value, string hookName) { MethodInfo methodInfo = AccessTools.Method(typeof(TeleportGates), hookName, (Type[])null, (Type[])null); if (methodInfo == null) { return false; } foreach (CodeInstruction item in code) { if (!(item.opcode != OpCodes.Ldc_R4) && item.operand is float num && num == value) { item.opcode = OpCodes.Call; item.operand = methodInfo; return true; } } return false; } } [HarmonyPatch(typeof(Player), "UpdateTeleport")] internal static class Patch_Player_UpdateTeleport { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> list = new List<CodeInstruction>(instructions); int num = TeleportGates.Count(list, 2f); int num2 = TeleportGates.Count(list, 8f); if (num != 1 || num2 != 1) { FrameBudgetPlugin.Log.LogError((object)$"[portal] expected one 2f and one 8f gate in UpdateTeleport, found {num} and {num2}; gates unchanged"); return list; } TeleportGates.Replace(list, 2f, "FloorGrace"); TeleportGates.Replace(list, 8f, "DistantGate"); TeleportGates.AbortGuarded = GuardAbortBranch(list); return list; } private static bool GuardAbortBranch(List<CodeInstruction> code) { FieldInfo fieldInfo = AccessTools.Field(typeof(Player), "m_distantTeleport"); MethodInfo methodInfo = AccessTools.Method(typeof(TeleportGates), "KeepWaiting", (Type[])null, (Type[])null); if (fieldInfo == null || methodInfo == null) { return false; } int num = -1; for (int i = 0; i < code.Count; i++) { if (code[i].opcode == OpCodes.Ldc_R4 && code[i].operand is float num2 && num2 == 15f) { num = i; break; } } if (num < 0) { FrameBudgetPlugin.Log.LogError((object)"[portal] 15f timeout missing from UpdateTeleport; rollback guard unavailable"); return false; } for (int j = num; j < code.Count; j++) { if (!(code[j].opcode != OpCodes.Ldfld) && code[j].operand == fieldInfo) { code[j].opcode = OpCodes.Call; code[j].operand = methodInfo; return true; } } FrameBudgetPlugin.Log.LogError((object)"[portal] m_distantTeleport read after 15f not found; rollback guard unavailable"); return false; } } internal static class TerrainCache { private readonly struct Key { private readonly int _x; private readonly int _z; private readonly int _width; private readonly float _scale; private readonly bool _lod; public Key(Vector3 center, int width, float scale, bool lod) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) _x = Mathf.RoundToInt(center.x); _z = Mathf.RoundToInt(center.z); _width = width; _scale = scale; _lod = lod; } public override int GetHashCode() { return (((((((_x * 397) ^ _z) * 397) ^ _width) * 397) ^ _scale.GetHashCode()) * 397) ^ (_lod ? 1 : 0); } public override bool Equals(object obj) { if (obj is Key key && key._x == _x && key._z == _z && key._width == _width && key._scale == _scale) { return key._lod == _lod; } return false; } } private struct Entry { public HMBuildData Data; public long Stamp; } private static readonly Dictionary<Key, Entry> _entries = new Dictionary<Key, Entry>(); private static readonly List<Key> _victims = new List<Key>(); private static long _clock; private static WorldGenerator _worldGen; public static int Hits { get; private set; } public static int Misses { get; private set; } public static int Count => _entries.Count; private static bool Enabled { get { if (FrameBudgetPlugin.Cfg != null) { return FrameBudgetPlugin.Cfg.Enabled.Value; } return false; } } internal static int Limit => AutoLimit(SystemInfo.systemMemorySize); internal static int AutoLimit(int memoryMB) { if (memoryMB < 30000) { if (memoryMB < 15000) { if (memoryMB < 11000) { return 256; } return 512; } return 1024; } return 2048; } public static void Clear() { _entries.Clear(); _worldGen = null; } private static bool Usable(WorldGenerator worldGen) { if (!Enabled || worldGen == null) { return false; } if (_worldGen != worldGen) { Clear(); _worldGen = worldGen; } return true; } public static bool TryGet(Vector3 center, int width, float scale, bool lod, WorldGenerator worldGen, out HMBuildData data) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) data = null; if (!Usable(worldGen)) { retur