Decompiled source of Instaport v1.4.0

BepInEx/plugins/InstaPort/InstaPort.dll

Decompiled 10 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using InstaPort.Core;
using Microsoft.CodeAnalysis;
using SoftReferenceableAssets;
using TMPro;
using Unity.Collections;
using Unity.Jobs;
using Unity.Profiling;
using Unity.Profiling.LowLevel.Unsafe;
using UnityEngine;
using UnityEngine.Jobs;
using UnityEngine.LowLevel;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyFileVersion("0.3.44.0")]
[assembly: AssemblyVersion("0.3.44.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 InstaPort
{
	internal static class ActivationDiagnostics
	{
		private struct Counter
		{
			internal int Calls;

			internal long Total;

			internal long Self;

			internal long Maximum;
		}

		private sealed class Entry
		{
			internal string Name;

			internal int Index;
		}

		private sealed class Group
		{
			internal string Name;

			internal readonly Counter[] Methods = new Counter[64];

			internal int Calls;

			internal int World;

			internal int Remote;

			internal int OmittedDepth;

			internal int Invalid;

			internal int MaxFrame;

			internal long Total;

			internal long Maximum;

			internal long Managed;

			internal long Unaccounted;

			internal void Clear()
			{
				Calls = (World = (Remote = (OmittedDepth = (Invalid = (MaxFrame = 0)))));
				Total = (Maximum = (Managed = (Unaccounted = 0L)));
				Array.Clear(Methods, 0, Methods.Length);
			}
		}

		internal struct Scope : IDisposable
		{
			internal int Epoch;

			public void Dispose()
			{
				if (Epoch != 0)
				{
					Finish(Epoch);
				}
			}
		}

		private struct Sample
		{
			internal NestedTiming.Sample Timing;

			internal int Epoch;

			internal int Index;
		}

		internal const string Owner = "com.easymods.instaport.activation_diagnostics";

		private const int MaximumMethods = 64;

		private const int MaximumPrefabs = 64;

		private static readonly Dictionary<MethodBase, Entry> methods = new Dictionary<MethodBase, Entry>();

		private static readonly List<Entry> entries = new List<Entry>(64);

		private static readonly Dictionary<string, Group> groups = new Dictionary<string, Group>(StringComparer.Ordinal);

		private static readonly List<Group> reports = new List<Group>(65);

		private static readonly List<Entry> methodReports = new List<Entry>(64);

		private static readonly Queue<string> metadata = new Queue<string>();

		private static readonly HashSet<GameObject> described = new HashSet<GameObject>();

		private static readonly Queue<GameObject> shapes = new Queue<GameObject>();

		private static readonly NestedTiming nesting = new NestedTiming(64);

		private static readonly Group other = new Group
		{
			Name = "other_prefabs"
		};

		private static Harmony harmony;

		private static bool attempted;

		private static int mainThread;

		private static int epoch;

		private static int failedHooks;

		private static int omittedPrefabs;

		private static Group current;

		private static long started;

		private static float next;

		private static bool Enabled
		{
			get
			{
				ConfigEntry<bool> timings = Plugin.Timings;
				if (timings != null && timings.Value)
				{
					ConfigEntry<bool> detailedDiagnostics = Plugin.DetailedDiagnostics;
					if (detailedDiagnostics == null || !detailedDiagnostics.Value)
					{
						ConfigEntry<bool> hitchCapture = Plugin.HitchCapture;
						if (hitchCapture == null || !hitchCapture.Value)
						{
							goto IL_0045;
						}
					}
					return (Object)(object)Player.m_localPlayer != (Object)null;
				}
				goto IL_0045;
				IL_0045:
				return false;
			}
		}

		internal static Scope Begin(string prefab, bool world)
		{
			if (harmony == null || Thread.CurrentThread.ManagedThreadId != mainThread || !Enabled || current != null)
			{
				return default(Scope);
			}
			prefab = prefab ?? "unknown";
			if (!groups.TryGetValue(prefab, out var value))
			{
				if (groups.Count >= 64)
				{
					value = other;
					omittedPrefabs++;
				}
				else
				{
					value = new Group
					{
						Name = prefab.Replace(' ', '_')
					};
					groups.Add(prefab, value);
				}
			}
			current = value;
			current.Calls++;
			if (world)
			{
				current.World++;
			}
			else
			{
				current.Remote++;
			}
			nesting.Reset();
			epoch++;
			if (epoch == 0)
			{
				epoch++;
			}
			started = Stopwatch.GetTimestamp();
			return new Scope
			{
				Epoch = epoch
			};
		}

		private static void Finish(int scope)
		{
			if (current != null && scope == epoch && Thread.CurrentThread.ManagedThreadId == mainThread)
			{
				long num = Math.Max(0L, Stopwatch.GetTimestamp() - started);
				current.Total += num;
				if (num > current.Maximum)
				{
					current.Maximum = num;
					current.MaxFrame = Time.frameCount;
				}
				current.Managed += nesting.OuterTicks;
				current.Unaccounted += Math.Max(0L, num - nesting.OuterTicks);
				current.OmittedDepth += nesting.Omitted;
				current.Invalid += nesting.Invalid;
				current = null;
			}
		}

		private static void Prefix(MethodBase __originalMethod, out Sample __state)
		{
			__state = default(Sample);
			if (current != null && Thread.CurrentThread.ManagedThreadId == mainThread && methods.TryGetValue(__originalMethod, out var value))
			{
				__state = new Sample
				{
					Timing = nesting.Begin(Stopwatch.GetTimestamp()),
					Epoch = epoch,
					Index = value.Index
				};
			}
		}

		private static Exception Finalizer(Sample __state, Exception __exception)
		{
			if (current != null && __state.Epoch == epoch && Thread.CurrentThread.ManagedThreadId == mainThread && nesting.End(__state.Timing, Stopwatch.GetTimestamp(), out var inclusive, out var exclusive))
			{
				ref Counter reference = ref current.Methods[__state.Index];
				reference.Calls++;
				reference.Total += inclusive;
				reference.Self += exclusive;
				reference.Maximum = Math.Max(reference.Maximum, inclusive);
			}
			return __exception;
		}

		private static void Install(string typeName, params string[] names)
		{
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Expected O, but got Unknown
			//IL_014b: Expected O, but got Unknown
			Type type = typeof(Player).Assembly.GetType(typeName);
			if (type == null)
			{
				return;
			}
			foreach (string text in names)
			{
				MethodInfo[] array = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo in array)
				{
					if (!(methodInfo.Name != text) && !methodInfo.IsAbstract && !methodInfo.ContainsGenericParameters && !methods.ContainsKey(methodInfo) && entries.Count < 64)
					{
						Entry entry = new Entry
						{
							Name = typeName + "." + text,
							Index = entries.Count
						};
						Patches patchInfo = Harmony.GetPatchInfo((MethodBase)methodInfo);
						ReadOnlyCollection<string> readOnlyCollection = ((patchInfo != null) ? patchInfo.Owners : null);
						string text2 = ((readOnlyCollection == null || readOnlyCollection.Count == 0) ? "none" : string.Join(",", readOnlyCollection));
						methods.Add(methodInfo, entry);
						try
						{
							harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(ActivationDiagnostics), "Prefix", (Type[])null)
							{
								priority = 800
							}, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(ActivationDiagnostics), "Finalizer", (Type[])null)
							{
								priority = 0
							}, (HarmonyMethod)null);
							entries.Add(entry);
							metadata.Enqueue("method=" + entry.Name + " owners=" + text2);
						}
						catch
						{
							methods.Remove(methodInfo);
							failedHooks++;
						}
					}
				}
			}
		}

		private static void Setup()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			attempted = true;
			mainThread = Thread.CurrentThread.ManagedThreadId;
			harmony = new Harmony("com.easymods.instaport.activation_diagnostics");
			Install("ZNetView", "Awake", "LoadFields");
			Install("ZNetScene", "AddInstance");
			Install("TreeBase", "Awake", "OnEnable");
			Install("TreeLog", "Awake", "OnEnable");
			Install("Piece", "Awake", "OnEnable");
			Install("WearNTear", "Awake", "OnEnable", "SetupColliders", "UpdateVisual", "UpdateSnowVisual", "GetHighlightRenderers");
			Install("Destructible", "Awake", "OnEnable");
			Install("MineRock", "Awake", "OnEnable");
			Install("MineRock5", "Awake", "OnEnable");
			Install("StaticPhysics", "Awake", "OnEnable");
			Install("SlowUpdate", "Awake");
			Install("ZSyncTransform", "Awake", "OnEnable");
			Install("ZSyncAnimation", "Awake", "OnEnable");
			Install("LodFadeIn", "Awake", "OnEnable");
			Install("LodFadeInOut", "Awake", "OnEnable");
			Install("LodGroup", "Awake", "OnEnable");
			Install("RandomSpawn", "Awake", "OnEnable");
			Install("SnapToGround", "Awake", "OnEnable");
			Install("SpawnArea", "Awake", "OnEnable");
			Install("TimedDestruction", "Awake", "OnEnable");
			Install("TerrainModifier", "Awake", "OnEnable");
			Install("TerrainComp", "Awake", "OnEnable");
			InstallPieceHooks();
			PortalDiagnostics.Event("activation_diagnostics_available", "hooks=" + entries.Count + " failed_hooks=" + failedHooks + " prefab_cap=" + 64 + " callback_depth_cap=64 scoped_only=True remainder_unclassified=True");
		}

		private static void InstallPieceHooks()
		{
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Expected O, but got Unknown
			//IL_01ac: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method(typeof(Piece), "Awake", (Type[])null, (Type[])null);
			Patches val = ((methodInfo == null) ? null : Harmony.GetPatchInfo((MethodBase)methodInfo));
			if (val == null)
			{
				return;
			}
			List<Patch> list = new List<Patch>();
			list.AddRange(val.Prefixes);
			list.AddRange(val.Postfixes);
			list.AddRange(val.Finalizers);
			int num = 0;
			foreach (Patch item in list)
			{
				MethodInfo patchMethod = item.PatchMethod;
				if (num >= 16 || entries.Count >= 64)
				{
					break;
				}
				if (item.owner != null && !item.owner.StartsWith("com.easymods.instaport", StringComparison.Ordinal) && !(patchMethod == null) && !patchMethod.IsAbstract && !patchMethod.ContainsGenericParameters && !methods.ContainsKey(patchMethod))
				{
					Entry entry = new Entry();
					entry.Name = "hook:" + item.owner + ":" + patchMethod.DeclaringType.Name + "." + patchMethod.Name;
					entry.Index = entries.Count;
					Entry entry2 = entry;
					methods.Add(patchMethod, entry2);
					try
					{
						harmony.Patch((MethodBase)patchMethod, new HarmonyMethod(typeof(ActivationDiagnostics), "Prefix", (Type[])null)
						{
							priority = 800
						}, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(ActivationDiagnostics), "Finalizer", (Type[])null)
						{
							priority = 0
						}, (HarmonyMethod)null);
						entries.Add(entry2);
						num++;
						metadata.Enqueue("method=" + entry2.Name + " owner=" + item.owner + " attribution=individual_hook");
					}
					catch
					{
						methods.Remove(patchMethod);
						failedHooks++;
					}
				}
			}
		}

		private static string Ms(long ticks)
		{
			return ((double)ticks * 1000.0 / (double)Stopwatch.Frequency).ToString("F2");
		}

		internal static void SlowPrefab(GameObject prefab, double milliseconds)
		{
			if (Enabled && (Object)(object)prefab != (Object)null && milliseconds >= 2.0 && described.Count < 32 && described.Add(prefab))
			{
				shapes.Enqueue(prefab);
			}
		}

		private static void DescribeOne()
		{
			if (shapes.Count == 0 || (Plugin.Instance?.Client?.RemainingPreparation).GetValueOrDefault() < 0.2)
			{
				return;
			}
			GameObject val = shapes.Dequeue();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			long timestamp = Stopwatch.GetTimestamp();
			try
			{
				Collider[] componentsInChildren = val.GetComponentsInChildren<Collider>(true);
				int num = 0;
				int num2 = 0;
				int num3 = 0;
				long num4 = 0L;
				Collider[] array = componentsInChildren;
				foreach (Collider obj in array)
				{
					MeshCollider val2 = (MeshCollider)(object)((obj is MeshCollider) ? obj : null);
					if (val2 == null)
					{
						continue;
					}
					num++;
					if (val2.convex)
					{
						num3++;
					}
					if ((Object)(object)val2.sharedMesh != (Object)null)
					{
						if (val2.sharedMesh.isReadable)
						{
							num2++;
						}
						num4 += val2.sharedMesh.vertexCount;
					}
				}
				PortalDiagnostics.Event("activation_shape", "prefab=" + ((Object)val).name.Replace(' ', '_') + " colliders=" + componentsInChildren.Length + " mesh_colliders=" + num + " convex=" + num3 + " readable_meshes=" + num2 + " collider_vertices=" + num4 + " renderers=" + val.GetComponentsInChildren<Renderer>(true).Length + " skinned_renderers=" + val.GetComponentsInChildren<SkinnedMeshRenderer>(true).Length + " snapshot_only=true physics_cause_unproven=true");
			}
			finally
			{
				Plugin.Instance?.Client?.SpendPreparation((double)(Stopwatch.GetTimestamp() - timestamp) * 1000.0 / (double)Stopwatch.Frequency);
			}
		}

		internal static void Tick()
		{
			try
			{
				if (!Enabled)
				{
					if (harmony != null)
					{
						Reset();
					}
					return;
				}
				if (!attempted)
				{
					Setup();
				}
				DescribeOne();
				for (int i = 0; i < 4; i++)
				{
					if (metadata.Count <= 0)
					{
						break;
					}
					PortalDiagnostics.Event("activation_patch_owners", metadata.Dequeue());
				}
				if (Time.unscaledTime < next)
				{
					return;
				}
				next = Time.unscaledTime + 5f;
				reports.Clear();
				foreach (Group value in groups.Values)
				{
					if (value.Calls > 0)
					{
						reports.Add(value);
					}
				}
				if (other.Calls > 0)
				{
					reports.Add(other);
				}
				reports.Sort((Group a, Group b) => b.Total.CompareTo(a.Total));
				int num = Math.Min(4, reports.Count);
				for (int num2 = 0; num2 < num; num2++)
				{
					Group group = reports[num2];
					PortalDiagnostics.Event("activation_work", "prefab=" + group.Name + " calls=" + group.Calls + " world=" + group.World + " remote=" + group.Remote + " total_ms=" + Ms(group.Total) + " max_ms=" + Ms(group.Maximum) + " max_frame=" + group.MaxFrame + " managed_outer_ms=" + Ms(group.Managed) + " unclassified_ms=" + Ms(group.Unaccounted) + " omitted_depth=" + group.OmittedDepth + " invalid_samples=" + group.Invalid);
					methodReports.Clear();
					foreach (Entry entry3 in entries)
					{
						if (group.Methods[entry3.Index].Calls > 0)
						{
							methodReports.Add(entry3);
						}
					}
					methodReports.Sort((Entry a, Entry b) => group.Methods[b.Index].Self.CompareTo(group.Methods[a.Index].Self));
					for (int num3 = 0; num3 < Math.Min(6, methodReports.Count); num3++)
					{
						Entry entry2 = methodReports[num3];
						Counter counter = group.Methods[entry2.Index];
						PortalDiagnostics.Event("activation_callback", "prefab=" + group.Name + " method=" + entry2.Name + " calls=" + counter.Calls + " inclusive_ms=" + Ms(counter.Total) + " exclusive_ms=" + Ms(counter.Self) + " max_call_ms=" + Ms(counter.Maximum) + " includes_patches=True");
					}
				}
				if (reports.Count > 0)
				{
					PortalDiagnostics.Event("activation_diagnostics", "prefabs=" + groups.Count + " omitted_prefab_rows=" + Math.Max(0, reports.Count - num) + " grouped_overflow_activations=" + omittedPrefabs + " nested_totals=True hook_overhead_not_measured=True");
				}
				foreach (Group value2 in groups.Values)
				{
					value2.Clear();
				}
				other.Clear();
				omittedPrefabs = 0;
			}
			catch (Exception ex)
			{
				Reset();
				attempted = true;
				PortalDiagnostics.Event("activation_diagnostics_unavailable", "cause=" + ex.GetType().Name);
			}
		}

		internal static void Reset()
		{
			current = null;
			epoch++;
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
			harmony = null;
			attempted = false;
			failedHooks = (omittedPrefabs = 0);
			methods.Clear();
			entries.Clear();
			groups.Clear();
			reports.Clear();
			methodReports.Clear();
			metadata.Clear();
			described.Clear();
			shapes.Clear();
			other.Clear();
			nesting.Reset();
			next = 0f;
		}
	}
	internal static class ArrivalSafety
	{
		private sealed class Sector
		{
			internal readonly StructuralReadiness Policy;

			internal bool Active;

			internal float Used;

			internal string Reason = "unprobed";

			internal int Missing;

			internal int PhysicsGeneration = -1;

			internal double EvidenceAt;

			internal Sector(float now, bool active)
			{
				Policy = new StructuralReadiness(now);
				Used = now;
				Active = active;
			}
		}

		private sealed class PieceState
		{
			internal object Sector;

			internal int Generation = -1;

			internal float PlacedAt = float.NegativeInfinity;
		}

		private sealed class TerrainState
		{
			internal ZDO Data;

			internal TerrainComp Component;
		}

		internal readonly struct RecordState
		{
			internal readonly int Prefab;

			internal readonly bool Persistent;

			internal readonly ObjectType Type;

			internal readonly uint Revision;

			internal RecordState(ZDO data)
			{
				//IL_001a: 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)
				Prefab = data.GetPrefab();
				Persistent = data.Persistent;
				Type = data.Type;
				Revision = data.DataRevision;
			}
		}

		private const int MaximumSectors = 128;

		private const int ProbesPerFrame = 2;

		private static readonly Dictionary<Vector2s, Sector> sectors;

		private static readonly List<ZDO> records;

		private static readonly Dictionary<Vector2s, double> objectProofs;

		private const int MaximumObjectProofs = 512;

		private static int reusedObjectProofs;

		private static int objectCellScans;

		private static readonly Dictionary<int, bool> structuralPrefabs;

		private static ConditionalWeakTable<WearNTear, PieceState> pieces;

		private static ConditionalWeakTable<ZNetView, TerrainState> terrainComponents;

		private static readonly Func<ZNetScene, ZDO, bool> valid;

		private static readonly Action<WearNTear> clear;

		private static readonly FieldRef<Heightmap, MeshCollider> terrainCollider;

		private static readonly FieldRef<TerrainComp, uint> terrainRevision;

		private static readonly FieldRef<TerrainComp, bool> terrainInitialized;

		private static ZNetScene scene;

		private static Vector2s origin;

		private static SimulationDistance distance;

		private static bool haveOrigin;

		private static int frame;

		private static int probes;

		private static int capacity;

		private static int errors;

		private static int blocked;

		private static int allowed;

		private static int invalidations;

		private static int unsupported;

		private static int releases;

		private static float nextReport;

		private static float nextError;

		private static long geometryGeneration;

		private static long physicsGeneration;

		private static int probeCount;

		private static int scannedRecords;

		private static double probeMs;

		private static double maxProbeMs;

		private static int mainThread;

		private static int externalDirty;

		private static readonly Dictionary<string, int> reasons;

		private static readonly Dictionary<string, int> dirtySources;

		private static int scanCoalesced;

		private static int unchangedTerrainReceives;

		private static int terrainLookups;

		private static int terrainCacheHits;

		private static int nonStructuralChanges;

		private static readonly Dictionary<int, int> movedPrefabs;

		static ArrivalSafety()
		{
			sectors = new Dictionary<Vector2s, Sector>();
			records = new List<ZDO>(1024);
			objectProofs = new Dictionary<Vector2s, double>();
			structuralPrefabs = new Dictionary<int, bool>();
			pieces = new ConditionalWeakTable<WearNTear, PieceState>();
			terrainComponents = new ConditionalWeakTable<ZNetView, TerrainState>();
			valid = AccessTools.MethodDelegate<Func<ZNetScene, ZDO, bool>>(AccessTools.Method(typeof(ZNetScene), "IsPrefabZDOValid", (Type[])null, (Type[])null), (object)null, true);
			clear = AccessTools.MethodDelegate<Action<WearNTear>>(AccessTools.Method(typeof(WearNTear), "ClearCachedSupport", (Type[])null, (Type[])null), (object)null, true);
			terrainCollider = AccessTools.FieldRefAccess<Heightmap, MeshCollider>("m_collider");
			terrainRevision = AccessTools.FieldRefAccess<TerrainComp, uint>("m_lastDataRevision");
			terrainInitialized = AccessTools.FieldRefAccess<TerrainComp, bool>("m_initialized");
			frame = -1;
			physicsGeneration = -1L;
			mainThread = Thread.CurrentThread.ManagedThreadId;
			reasons = new Dictionary<string, int>();
			dirtySources = new Dictionary<string, int>();
			movedPrefabs = new Dictionary<int, int>();
		}

		internal static void Initialize()
		{
			mainThread = Thread.CurrentThread.ManagedThreadId;
			if (valid == null || clear == null || terrainCollider == null || terrainRevision == null || terrainInitialized == null)
			{
				throw new InvalidOperationException("Structural safety API unavailable.");
			}
			GuardArrivalSupport.Initialize();
		}

		internal static void Track(Vector3 destination)
		{
			foreach (Sector value in sectors.Values)
			{
				value.Policy.Activate(Time.unscaledTime);
			}
		}

		internal static void Reset()
		{
			sectors.Clear();
			records.Clear();
			objectProofs.Clear();
			reusedObjectProofs = (objectCellScans = 0);
			structuralPrefabs.Clear();
			pieces = new ConditionalWeakTable<WearNTear, PieceState>();
			terrainComponents = new ConditionalWeakTable<ZNetView, TerrainState>();
			scene = null;
			haveOrigin = false;
			frame = -1;
			probes = (capacity = (errors = (blocked = (allowed = (invalidations = (unsupported = (releases = 0)))))));
			nextReport = (nextError = 0f);
			reasons.Clear();
			dirtySources.Clear();
			scanCoalesced = (unchangedTerrainReceives = (terrainLookups = (terrainCacheHits = 0)));
			geometryGeneration = 0L;
			physicsGeneration = -1L;
			nonStructuralChanges = 0;
			movedPrefabs.Clear();
			probeCount = (scannedRecords = 0);
			probeMs = (maxProbeMs = 0.0);
		}

		private static bool NativeSector(Vector2s sector)
		{
			//IL_0000: 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_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)
			int num = Math.Max(Math.Abs(sector.x - origin.x), Math.Abs(sector.y - origin.y));
			if (num != 0)
			{
				if (num <= ((SimulationDistance)(ref distance)).NearSimulationDistance)
				{
					if (!((SimulationDistance)(ref distance)).IsClassic)
					{
						return ZoneSystem.instance.ZonesWithinRadius(origin, sector, ((SimulationDistance)(ref distance)).NearSimulationDistance, false);
					}
					return true;
				}
				return false;
			}
			return true;
		}

		private static void Context()
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: 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_0141: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)scene != (Object)(object)ZNetScene.instance)
			{
				Reset();
				scene = ZNetScene.instance;
			}
			if (Interlocked.Exchange(ref externalDirty, 0) != 0)
			{
				foreach (Sector value in sectors.Values)
				{
					value.Policy.Invalidate();
				}
				objectProofs.Clear();
				geometryGeneration++;
			}
			if (frame != Time.frameCount)
			{
				frame = Time.frameCount;
				probes = 0;
			}
			Vector2s zone = ZoneSystem.GetZone(ZNet.instance.GetReferencePosition());
			SimulationDistance syncedSimulationDistance = ZNet.instance.GetSyncedSimulationDistance();
			bool num = !haveOrigin || zone != origin || ((SimulationDistance)(ref syncedSimulationDistance)).NearSimulationDistance != ((SimulationDistance)(ref distance)).NearSimulationDistance || ((SimulationDistance)(ref syncedSimulationDistance)).TotalSimulationDistance != ((SimulationDistance)(ref distance)).TotalSimulationDistance || ((SimulationDistance)(ref syncedSimulationDistance)).IsClassic != ((SimulationDistance)(ref distance)).IsClassic;
			origin = zone;
			distance = syncedSimulationDistance;
			haveOrigin = true;
			if (!num)
			{
				return;
			}
			objectProofs.Clear();
			foreach (KeyValuePair<Vector2s, Sector> sector in sectors)
			{
				bool flag = NativeSector(sector.Key);
				if (flag && !sector.Value.Active)
				{
					sector.Value.Policy.Activate(Time.unscaledTime);
				}
				else
				{
					sector.Value.Policy.Invalidate();
				}
				sector.Value.Active = flag;
			}
		}

		private static Sector Entry(Vector2s zone)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			if (sectors.TryGetValue(zone, out var value))
			{
				value.Used = Time.unscaledTime;
				return value;
			}
			if (sectors.Count >= 128)
			{
				Vector2s key = default(Vector2s);
				Sector sector = null;
				foreach (KeyValuePair<Vector2s, Sector> sector3 in sectors)
				{
					if (!sector3.Value.Active && (sector == null || sector3.Value.Used < sector.Used))
					{
						key = sector3.Key;
						sector = sector3.Value;
					}
				}
				if (sector == null)
				{
					capacity++;
					return null;
				}
				sectors.Remove(key);
			}
			Sector sector2 = new Sector(Time.unscaledTime, NativeSector(zone));
			sectors.Add(zone, sector2);
			return sector2;
		}

		internal static void Dirty(Vector2s changed, string source = "sector")
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			if (OffThread() || (sectors.Count == 0 && objectProofs.Count == 0))
			{
				return;
			}
			dirtySources.TryGetValue(source, out var value);
			dirtySources[source] = value + 1;
			geometryGeneration++;
			objectProofs.Remove(changed);
			Vector2s key = default(Vector2s);
			for (int i = -1; i <= 1; i++)
			{
				for (int j = -1; j <= 1; j++)
				{
					((Vector2s)(ref key))..ctor(changed.x + i, changed.y + j);
					if (sectors.TryGetValue(key, out var value2))
					{
						value2.Policy.Invalidate();
						value2.Reason = "changed";
						invalidations++;
					}
				}
			}
		}

		internal static void Dirty(ZDO data, string source = "record")
		{
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			if (OffThread())
			{
				return;
			}
			try
			{
				if (sectors.Count == 0 && objectProofs.Count == 0)
				{
					return;
				}
				if (!StructuralRecord(data))
				{
					nonStructuralChanges++;
					return;
				}
				if (source == "move_before")
				{
					ConfigEntry<bool> timings = Plugin.Timings;
					if (timings != null && timings.Value)
					{
						int prefab = data.GetPrefab();
						if (movedPrefabs.TryGetValue(prefab, out var value))
						{
							movedPrefabs[prefab] = value + 1;
						}
						else if (movedPrefabs.Count < 16)
						{
							movedPrefabs[prefab] = 1;
						}
					}
				}
				Dirty(data.GetSector(), source);
			}
			catch (Exception e)
			{
				Error(e);
			}
		}

		private static bool OffThread()
		{
			if (Thread.CurrentThread.ManagedThreadId == mainThread)
			{
				return false;
			}
			Interlocked.Exchange(ref externalDirty, 1);
			return true;
		}

		internal static RecordState BeforeReceive(ZDO data)
		{
			if (OffThread())
			{
				return default(RecordState);
			}
			return new RecordState(data);
		}

		internal static void Received(ZDO data, RecordState before)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Invalid comparison between Unknown and I4
			//IL_00b4: 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_009b: Unknown result type (might be due to invalid IL or missing references)
			if (OffThread())
			{
				return;
			}
			try
			{
				if ((sectors.Count != 0 || objectProofs.Count != 0) && StructuralRecord(data))
				{
					ZNetScene instance = ZNetScene.instance;
					GameObject val = ((instance != null) ? instance.GetPrefab(data.GetPrefab()) : null);
					bool flag = (int)data.Type == 3 || ((Object)(object)val != (Object)null && (Object)(object)val.GetComponent<TerrainComp>() != (Object)null);
					if (!data.Created || before.Prefab != data.GetPrefab() || before.Persistent != data.Persistent || before.Type != data.Type || (flag && before.Revision != data.DataRevision))
					{
						Dirty(data.GetSector(), flag ? "receive_terrain" : "receive_static");
					}
					else if (flag)
					{
						unchangedTerrainReceives++;
					}
				}
			}
			catch (Exception e)
			{
				Error(e);
			}
		}

		private static bool StructuralRecord(ZDO data)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Invalid comparison between Unknown and I4
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Invalid comparison between Unknown and I4
			if (data == null || (!data.Persistent && (int)data.Type != 3))
			{
				return false;
			}
			if ((int)data.Type == 3 || (Object)(object)ZNetScene.instance == (Object)null)
			{
				return true;
			}
			int prefab = data.GetPrefab();
			if (structuralPrefabs.TryGetValue(prefab, out var value))
			{
				return value;
			}
			GameObject prefab2 = ZNetScene.instance.GetPrefab(prefab);
			if ((Object)(object)prefab2 == (Object)null)
			{
				return true;
			}
			value = (Object)(object)prefab2.GetComponent<Character>() == (Object)null && (Object)(object)prefab2.GetComponent<ItemDrop>() == (Object)null && (Object)(object)prefab2.GetComponent<Rigidbody>() == (Object)null && MayProvideSupport(prefab2);
			if (structuralPrefabs.Count < 2048)
			{
				structuralPrefabs.Add(prefab, value);
			}
			return value;
		}

		private static bool MayProvideSupport(GameObject prefab)
		{
			if ((Object)(object)prefab.GetComponentInChildren<WearNTear>(true) != (Object)null || (Object)(object)prefab.GetComponentInChildren<Piece>(true) != (Object)null || (Object)(object)prefab.GetComponentInChildren<TerrainComp>(true) != (Object)null || (Object)(object)prefab.GetComponentInChildren<TerrainModifier>(true) != (Object)null || (Object)(object)prefab.GetComponentInChildren<Heightmap>(true) != (Object)null || (Object)(object)prefab.GetComponentInChildren<LocationProxy>(true) != (Object)null)
			{
				return true;
			}
			bool flag = (Object)(object)prefab.GetComponentInChildren<Rigidbody>(true) != (Object)null || (Object)(object)prefab.GetComponentInChildren<Character>(true) != (Object)null || (Object)(object)prefab.GetComponentInChildren<ItemDrop>(true) != (Object)null;
			MonoBehaviour[] componentsInChildren = prefab.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val in componentsInChildren)
			{
				if ((Object)(object)val == (Object)null || ((object)val).GetType().Assembly != typeof(Player).Assembly)
				{
					return true;
				}
				switch (((object)val).GetType().Name)
				{
				case "Fish":
				case "RandomFlyingBird":
				case "Projectile":
				case "Ragdoll":
				case "LuredWisp":
					flag = true;
					break;
				}
			}
			if (!flag)
			{
				return true;
			}
			int mask = LayerMask.GetMask(new string[5] { "piece", "Default", "static_solid", "Default_small", "terrain" });
			if (mask == 0)
			{
				return true;
			}
			Collider[] componentsInChildren2 = prefab.GetComponentsInChildren<Collider>(true);
			foreach (Collider val2 in componentsInChildren2)
			{
				if ((Object)(object)val2 != (Object)null && !val2.isTrigger && (Object)(object)val2.attachedRigidbody == (Object)null && (mask & (1 << ((Component)val2).gameObject.layer)) != 0)
				{
					return true;
				}
			}
			return false;
		}

		internal static void Dirty(Component component, string source = "component")
		{
			//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)
			if (OffThread())
			{
				return;
			}
			try
			{
				if ((Object)(object)component != (Object)null)
				{
					Dirty(ZoneSystem.GetZone(component.transform.position), source);
				}
			}
			catch (Exception e)
			{
				Error(e);
			}
		}

		internal static void Placed(WearNTear piece)
		{
			//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)
			try
			{
				if (!((Object)(object)piece == (Object)null) && !((Object)(object)Plugin.Instance == (Object)null))
				{
					if ((Object)(object)ZNet.instance != (Object)null && (Object)(object)ZNetScene.instance != (Object)null && (Object)(object)ZoneSystem.instance != (Object)null)
					{
						Context();
						Entry(ZoneSystem.GetZone(((Component)piece).transform.position));
					}
					pieces.GetValue(piece, (WearNTear _) => new PieceState()).PlacedAt = Time.unscaledTime;
				}
			}
			catch (Exception e)
			{
				Error(e);
			}
		}

		internal static void SawPiece(WearNTear piece, ZNetView view)
		{
			//IL_0054: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Plugin.Instance == (Object)null || (Object)(object)piece == (Object)null || (Object)(object)view == (Object)null || !view.IsValid() || (Object)(object)ZNet.instance == (Object)null || (Object)(object)ZNetScene.instance == (Object)null || (Object)(object)ZoneSystem.instance == (Object)null || !PortalClient.NormallyActive(((Component)piece).transform.position))
			{
				return;
			}
			try
			{
				Context();
				Entry(ZoneSystem.GetZone(((Component)piece).transform.position));
			}
			catch (Exception e)
			{
				Error(e);
			}
		}

		private static TerrainComp TerrainComponent(ZNetView view, ZDO data)
		{
			if (terrainComponents.TryGetValue(view, out var value) && value.Data == data)
			{
				terrainCacheHits++;
				return value.Component;
			}
			terrainLookups++;
			terrainComponents.Remove(view);
			TerrainComp component = ((Component)view).GetComponent<TerrainComp>();
			terrainComponents.Add(view, new TerrainState
			{
				Data = data,
				Component = component
			});
			return component;
		}

		internal static void TerrainAwake(TerrainComp terrain)
		{
			try
			{
				ZNetView val = ((terrain != null) ? ((Component)terrain).GetComponent<ZNetView>() : null);
				if ((Object)(object)val != (Object)null)
				{
					terrainComponents.Remove(val);
					Dirty(val.GetZDO(), "terrain_awake");
				}
			}
			catch (Exception e)
			{
				Error(e);
			}
		}

		private static bool Probe(Vector2s center, Sector entry)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			long timestamp = Stopwatch.GetTimestamp();
			probeCount++;
			try
			{
				return ProbeCore(center, entry);
			}
			finally
			{
				double num = (double)(Stopwatch.GetTimestamp() - timestamp) * 1000.0 / (double)Stopwatch.Frequency;
				probeMs += num;
				maxProbeMs = Math.Max(maxProbeMs, num);
			}
		}

		private static bool ProbeCore(Vector2s center, Sector entry)
		{
			//IL_0023: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			entry.Missing = 0;
			entry.EvidenceAt = Time.unscaledTime;
			Vector2s val = default(Vector2s);
			for (int i = -1; i <= 1; i++)
			{
				for (int j = -1; j <= 1; j++)
				{
					((Vector2s)(ref val))..ctor(center.x + i, center.y + j);
					if (NativeSector(val))
					{
						if (!ZoneSystem.instance.IsZoneLoaded(val))
						{
							entry.Reason = "zone";
							return false;
						}
						if (LocationPreparation.PendingInSector(val))
						{
							entry.Reason = "location";
							return false;
						}
						Heightmap val2 = Heightmap.FindHeightmap(ZoneSystem.GetZonePos(val));
						MeshCollider val3 = (((Object)(object)val2 == (Object)null) ? null : terrainCollider.Invoke(val2));
						if (RemoteTerrainRebuild.PendingInSector(val) || (Object)(object)val2 == (Object)null || val2.IsDistantLod || !((Component)val2).gameObject.activeInHierarchy || val2.HaveQueuedRebuild() || (Object)(object)val3 == (Object)null || !((Collider)val3).enabled || (Object)(object)val3.sharedMesh == (Object)null || val3.sharedMesh.vertexCount == 0)
						{
							entry.Reason = "terrain";
							return false;
						}
					}
				}
			}
			Vector2s val4 = default(Vector2s);
			for (int k = -1; k <= 1; k++)
			{
				for (int l = -1; l <= 1; l++)
				{
					((Vector2s)(ref val4))..ctor(center.x + k, center.y + l);
					double num = Time.unscaledTime;
					if (objectProofs.TryGetValue(val4, out var value) && num >= value && num - value < 0.25)
					{
						entry.EvidenceAt = Math.Min(entry.EvidenceAt, value);
						reusedObjectProofs++;
						continue;
					}
					objectProofs.Remove(val4);
					objectCellScans++;
					records.Clear();
					ZDOMan.instance.FindSectorObjects(val4, new SimulationDistance(0, 0, true), records, (List<ZDO>)null);
					scannedRecords += records.Count;
					foreach (ZDO record in records)
					{
						if (StructuralRecord(record) && NativeSceneResidency.KeepsAt(record, origin, distance) && valid(scene, record))
						{
							ZNetView val5 = scene.FindInstance(record);
							if ((Object)(object)val5 == (Object)null || !((Component)val5).gameObject.activeInHierarchy || val5.GetZDO() != record)
							{
								entry.Missing++;
								entry.Reason = "objects";
								return false;
							}
							TerrainComp val6 = TerrainComponent(val5, record);
							if ((Object)(object)val6 != (Object)null && (!terrainInitialized.Invoke(val6) || terrainRevision.Invoke(val6) != record.DataRevision))
							{
								entry.Reason = "terrain_data";
								return false;
							}
						}
					}
					if (objectProofs.Count < 512)
					{
						objectProofs[val4] = num;
					}
				}
			}
			entry.Reason = ((entry.Missing > 0) ? "objects" : "ready");
			if (entry.Missing != 0)
			{
				return false;
			}
			if (entry.PhysicsGeneration != entry.Policy.Generation)
			{
				if (physicsGeneration != geometryGeneration)
				{
					Physics.SyncTransforms();
					physicsGeneration = geometryGeneration;
				}
				entry.PhysicsGeneration = entry.Policy.Generation;
			}
			return true;
		}

		internal static bool DeferSupport(WearNTear piece)
		{
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Plugin.Instance == (Object)null || (Object)(object)piece == (Object)null)
			{
				return false;
			}
			try
			{
				ZNetView component = ((Component)piece).GetComponent<ZNetView>();
				if (!((Object)(object)component == (Object)null) && component.IsValid() && component.IsOwner())
				{
					PortalClient client = Plugin.Instance.Client;
					if (client == null || !client.IsObserver(component.GetZDO()))
					{
						if ((Object)(object)ZNetScene.instance == (Object)null || (Object)(object)ZoneSystem.instance == (Object)null || (Object)(object)ZNet.instance == (Object)null || ZDOMan.instance == null)
						{
							return Block("context");
						}
						Context();
						Sector sector = Entry(ZoneSystem.GetZone(((Component)piece).transform.position));
						if (sector == null)
						{
							return Block("capacity");
						}
						float unscaledTime = Time.unscaledTime;
						PieceState value = pieces.GetValue(piece, (WearNTear _) => new PieceState());
						bool flag = (double)value.PlacedAt >= sector.Policy.ActivatedAt;
						if (!flag && !double.IsNegativeInfinity(sector.Policy.LastProbe) && (double)unscaledTime >= sector.Policy.ActivatedAt && (double)unscaledTime - sector.Policy.ActivatedAt < 29.25)
						{
							return Block("activation_grace");
						}
						if (sector.Policy.ProbeDue(unscaledTime))
						{
							if (probes >= 2)
							{
								return Block("probe_budget");
							}
							probes++;
							bool complete = Probe(ZoneSystem.GetZone(((Component)piece).transform.position), sector);
							sector.Policy.Observe(unscaledTime, complete, sector.EvidenceAt);
						}
						else if (!sector.Policy.Complete)
						{
							scanCoalesced++;
						}
						if (!sector.Policy.Allow(unscaledTime, flag))
						{
							return Block(sector.Policy.Complete ? sector.Policy.Reason(unscaledTime, flag) : sector.Reason);
						}
						if (value.Sector != sector || value.Generation != sector.Policy.Generation)
						{
							clear(piece);
							value.Sector = sector;
							value.Generation = sector.Policy.Generation;
							releases++;
						}
						allowed++;
						Report();
						return false;
					}
				}
				return false;
			}
			catch (Exception e)
			{
				Error(e);
				return Block("error");
			}
		}

		private static bool Block(string reason)
		{
			blocked++;
			reasons.TryGetValue(reason, out var value);
			reasons[reason] = value + 1;
			Report();
			return true;
		}

		private static void Error(Exception e)
		{
			errors++;
			objectProofs.Clear();
			foreach (Sector value in sectors.Values)
			{
				value.Policy.Invalidate();
				value.Reason = "error";
			}
			if (Time.unscaledTime < nextError)
			{
				return;
			}
			nextError = Time.unscaledTime + 5f;
			try
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("Structural support deferred after readiness check failed: " + e.GetType().Name));
				}
			}
			catch (Exception)
			{
			}
		}

		private static void Report()
		{
			if (Time.unscaledTime < nextReport)
			{
				return;
			}
			nextReport = Time.unscaledTime + 5f;
			try
			{
				PortalDiagnostics.Event("structural_guard", "sectors=" + sectors.Count + " deferred=" + blocked + " allowed=" + allowed + " invalidations=" + invalidations + " cache_releases=" + releases + " capacity_deferrals=" + capacity + " errors=" + errors + " unsupported_verdicts=" + unsupported + " reasons=" + string.Join(",", reasons.Select((KeyValuePair<string, int> x) => x.Key + ":" + x.Value)) + " probes=" + probeCount + " scanned_records=" + scannedRecords + " probe_cpu_ms=" + probeMs.ToString("F2") + " max_probe_ms=" + maxProbeMs.ToString("F2") + " coalesced_scan_calls=" + scanCoalesced + " unchanged_terrain_receives=" + unchangedTerrainReceives + " object_cell_scans=" + objectCellScans + " reused_object_cells=" + reusedObjectProofs + " proof_cache_cells=" + objectProofs.Count + " proof_max_age_s=" + 0.3 + " terrain_component_lookups=" + terrainLookups + " terrain_component_cache_hits=" + terrainCacheHits + " invalidation_sources=" + string.Join(",", dirtySources.Select((KeyValuePair<string, int> x) => x.Key + ":" + x.Value)) + " ignored_nonstructural_changes=" + nonStructuralChanges + " moved_structural_prefabs=" + string.Join(",", movedPrefabs.Select(delegate(KeyValuePair<int, int> x)
				{
					ZNetScene instance = ZNetScene.instance;
					object obj;
					if (instance == null)
					{
						obj = null;
					}
					else
					{
						GameObject prefab = instance.GetPrefab(x.Key);
						obj = ((prefab != null) ? ((Object)prefab).name : null);
					}
					if (obj == null)
					{
						obj = x.Key.ToString();
					}
					return (string?)obj + ":" + x.Value;
				})) + " activation_grace_s=30 expiry_release=false player_wait=false");
			}
			catch (Exception)
			{
			}
			blocked = (allowed = (invalidations = (releases = (capacity = (errors = (unsupported = 0))))));
			reasons.Clear();
			probeCount = (scannedRecords = 0);
			probeMs = (maxProbeMs = 0.0);
			scanCoalesced = (unchangedTerrainReceives = (terrainLookups = (terrainCacheHits = 0)));
			reusedObjectProofs = (objectCellScans = 0);
			dirtySources.Clear();
			nonStructuralChanges = 0;
			movedPrefabs.Clear();
		}

		internal static void Unsupported(WearNTear piece)
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			unsupported++;
			if (unsupported > 8)
			{
				return;
			}
			try
			{
				ZNetView component = ((Component)piece).GetComponent<ZNetView>();
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("[IP STRUCTURE] native_unsupported prefab=" + ((Object)piece).name + " object=" + (((component == null) ? null : ((object)Unsafe.As<ZDOID, ZDOID>(ref component.GetZDO()?.m_uid)/*cast due to .constrained prefix*/).ToString()) ?? "none") + " position=" + ((object)((Component)piece).transform.position/*cast due to .constrained prefix*/).ToString() + " loading_dependencies_complete=true support_damage_branch=true"));
				}
			}
			catch (Exception)
			{
			}
		}

		internal static void Trace(Component item, string kind, HitData hit = null)
		{
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			ConfigEntry<bool> timings = Plugin.Timings;
			if (timings == null || !timings.Value || (Object)(object)item == (Object)null || kind != "building")
			{
				return;
			}
			try
			{
				ZNetView component = item.GetComponent<ZNetView>();
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("[IP STRUCTURE] destruction_request prefab=" + ((Object)item).name + " object=" + (((component == null) ? null : ((object)Unsafe.As<ZDOID, ZDOID>(ref component.GetZDO()?.m_uid)/*cast due to .constrained prefix*/).ToString()) ?? "none") + " position=" + ((object)item.transform.position/*cast due to .constrained prefix*/).ToString() + " hit_type=" + ((hit == null) ? "none" : ((object)Unsafe.As<HitType, HitType>(ref hit.m_hitType)/*cast due to .constrained prefix*/).ToString()) + " owner=" + ((Object)(object)component != (Object)null && component.IsOwner())));
				}
			}
			catch (Exception)
			{
			}
		}
	}
	[HarmonyPatch(typeof(WearNTear), "UpdateWear")]
	internal static class GuardArrivalSupport
	{
		private static readonly Action<WearNTear> update = AccessTools.MethodDelegate<Action<WearNTear>>(AccessTools.Method(typeof(WearNTear), "UpdateSupport", (Type[])null, (Type[])null), (object)null, true);

		private static readonly Func<WearNTear, bool> have = AccessTools.MethodDelegate<Func<WearNTear, bool>>(AccessTools.Method(typeof(WearNTear), "HaveSupport", (Type[])null, (Type[])null), (object)null, true);

		internal static void Initialize()
		{
			if (update == null || have == null)
			{
				throw new InvalidOperationException("Native support delegates unavailable.");
			}
		}

		public static void UpdateSupport(WearNTear piece)
		{
			if (!ArrivalSafety.DeferSupport(piece))
			{
				update(piece);
			}
		}

		public static bool HaveSupport(WearNTear piece)
		{
			if (ArrivalSafety.DeferSupport(piece))
			{
				return true;
			}
			bool num = have(piece);
			if (!num)
			{
				ArrivalSafety.Unsupported(piece);
			}
			return num;
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			MethodInfo nativeUpdate = AccessTools.Method(typeof(WearNTear), "UpdateSupport", (Type[])null, (Type[])null);
			MethodInfo nativeHave = AccessTools.Method(typeof(WearNTear), "HaveSupport", (Type[])null, (Type[])null);
			if (list.Count((CodeInstruction i) => CodeInstructionExtensions.Calls(i, nativeUpdate)) != 1 || list.Count((CodeInstruction i) => CodeInstructionExtensions.Calls(i, nativeHave)) != 1)
			{
				throw new InvalidOperationException("Structural safety patch layout changed; InstaPort loading must remain disabled.");
			}
			foreach (CodeInstruction item in list)
			{
				if (CodeInstructionExtensions.Calls(item, nativeUpdate))
				{
					item.opcode = OpCodes.Call;
					item.operand = AccessTools.Method(typeof(GuardArrivalSupport), "UpdateSupport", (Type[])null, (Type[])null);
				}
				else if (CodeInstructionExtensions.Calls(item, nativeHave))
				{
					item.opcode = OpCodes.Call;
					item.operand = AccessTools.Method(typeof(GuardArrivalSupport), "HaveSupport", (Type[])null, (Type[])null);
				}
			}
			return list;
		}
	}
	[HarmonyPatch(typeof(WearNTear), "Awake")]
	internal static class ObserveStructuralActivation
	{
		private static void Postfix(WearNTear __instance, ZNetView ___m_nview)
		{
			ArrivalSafety.SawPiece(__instance, ___m_nview);
		}
	}
	[HarmonyPatch(typeof(TerrainComp), "Awake")]
	internal static class ObserveStructuralTerrainComponent
	{
		private static void Postfix(TerrainComp __instance)
		{
			ArrivalSafety.TerrainAwake(__instance);
		}
	}
	[HarmonyPatch(typeof(WearNTear), "OnPlaced")]
	internal static class ObserveStructuralPlacement
	{
		private static void Postfix(WearNTear __instance)
		{
			ArrivalSafety.Placed(__instance);
		}
	}
	[HarmonyPatch(typeof(ZNetScene), "CreateObject")]
	internal static class InvalidateStructuralCreation
	{
		private static void Prefix(ZDO zdo)
		{
			ArrivalSafety.Dirty(zdo, "create");
		}
	}
	[HarmonyPatch]
	internal static class InvalidateStructuralRecords
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			yield return AccessTools.Method(typeof(ZDOMan), "AddToSector", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(ZDOMan), "RemoveFromSector", (Type[])null, (Type[])null);
		}

		private static void Prefix(ZDO __0, MethodBase __originalMethod)
		{
			ArrivalSafety.Dirty(__0, __originalMethod.Name);
		}
	}
	[HarmonyPatch(typeof(ZDO), "Deserialize")]
	internal static class InvalidateStructuralReceivedData
	{
		private static void Prefix(ZDO __instance, out ArrivalSafety.RecordState __state)
		{
			__state = ArrivalSafety.BeforeReceive(__instance);
		}

		private static void Postfix(ZDO __instance, ArrivalSafety.RecordState __state)
		{
			ArrivalSafety.Received(__instance, __state);
		}
	}
	[HarmonyPatch(typeof(ZDO), "InternalSetPosition")]
	internal static class InvalidateStructuralMovement
	{
		private static void Prefix(ZDO __instance, Vector3 __0, out bool __state)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			__state = __instance.GetPosition() != __0;
			if (__state)
			{
				ArrivalSafety.Dirty(__instance, "move_before");
			}
		}

		private static void Postfix(ZDO __instance, bool __state)
		{
			if (__state)
			{
				ArrivalSafety.Dirty(__instance, "move_after");
			}
		}
	}
	[HarmonyPatch]
	internal static class InvalidateStructuralTerrain
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			yield return AccessTools.Method(typeof(Heightmap), "Poke", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(Heightmap), "Regenerate", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(Heightmap), "OnDestroy", (Type[])null, (Type[])null);
		}

		private static void Prefix(Heightmap __instance, MethodBase __originalMethod)
		{
			ArrivalSafety.Dirty((Component)(object)__instance, "terrain_" + __originalMethod.Name);
		}
	}
	[HarmonyPatch]
	internal static class InvalidateStructuralUnload
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			yield return AccessTools.Method(typeof(ZNetView), "ResetZDO", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(ZNetView), "OnDestroy", (Type[])null, (Type[])null);
		}

		private static void Prefix(ZNetView __instance, MethodBase __originalMethod)
		{
			ArrivalSafety.Dirty(__instance.GetZDO(), __originalMethod.Name);
		}
	}
	[HarmonyPatch(typeof(Destructible), "Destroy", new Type[] { typeof(HitData) })]
	internal static class DiagnoseArrivalDestructible
	{
		private static void Prefix(Destructible __instance, HitData __0)
		{
			try
			{
				ArrivalSafety.Trace((Component)(object)__instance, "destructible", __0);
			}
			catch (Exception)
			{
			}
		}
	}
	[HarmonyPatch(typeof(ZNetScene), "Destroy", new Type[] { typeof(GameObject) })]
	internal static class DiagnoseArrivalNetworkDestruction
	{
		private static void Prefix(GameObject go)
		{
			try
			{
				if ((Object)(object)go != (Object)null)
				{
					ArrivalSafety.Trace((Component)(object)go.transform, "network_destroy");
				}
			}
			catch (Exception)
			{
			}
		}
	}
	internal static class AssetIntegrationPacing
	{
		private static readonly TemporarySetting<ThreadPriority> lease = new TemporarySetting<ThreadPriority>();

		private static float nextReport;

		internal static void Tick()
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			_ = Player.m_localPlayer;
			PortalClient portalClient = Plugin.Instance?.Client;
			Plugin instance = Plugin.Instance;
			bool active = instance != null && instance.Running && Plugin.PaceAssetIntegration.Value && StreamingController.Active && portalClient != null && (portalClient.NeedsDestinationPreparation || PortalAssetWarmup.PendingAssets > 0 || LocationPreparation.HasPendingWork || PortalArrival.LocalStreamingBusy);
			ThreadPriority desired = (ThreadPriority)((portalClient != null && portalClient.DisplayFrameMs < 1000.0 / (double)Plugin.MinimumFps.Value) ? 1 : 0);
			Adjust(active, desired);
		}

		private unsafe static void Adjust(bool active, ThreadPriority desired)
		{
			//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_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Invalid comparison between Unknown and I4
			//IL_001f: 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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Invalid comparison between Unknown and I4
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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_0032: 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)
			ThreadPriority backgroundLoadingPriority = Application.backgroundLoadingPriority;
			bool flag = (int)backgroundLoadingPriority == 0 || (int)backgroundLoadingPriority == 1 || (int)backgroundLoadingPriority == 2 || (int)backgroundLoadingPriority == 4;
			ThreadPriority val = lease.Adjust(active, backgroundLoadingPriority, desired, flag && backgroundLoadingPriority > desired);
			if (val != backgroundLoadingPriority)
			{
				Application.backgroundLoadingPriority = val;
				if (Time.unscaledTime >= nextReport)
				{
					nextReport = Time.unscaledTime + 5f;
					PortalDiagnostics.Event("asset_integration_priority", "active=" + active + " previous=" + ((object)(*(ThreadPriority*)(&backgroundLoadingPriority))/*cast due to .constrained prefix*/).ToString() + " current=" + ((object)(*(ThreadPriority*)(&val))/*cast due to .constrained prefix*/).ToString() + " pending_assets=" + PortalAssetWarmup.PendingAssets + " location_pending=" + LocationPreparation.HasPendingWork + " single_asset_can_exceed_budget=true");
				}
			}
		}

		internal static void Reset()
		{
			Adjust(active: false, (ThreadPriority)0);
		}
	}
	internal static class AsyncIntegrationBudget
	{
		private static readonly IntegrationTimeLease lease = new IntegrationTimeLease();

		private static float nextReport;

		internal static void Update(bool work)
		{
			float integrationTimeMS = AsyncInstantiateOperation.GetIntegrationTimeMS();
			float num = lease.Adjust(work, integrationTimeMS, StreamingController.HiddenIntegrationHeadroom ? 2f : 1f);
			if (!float.IsNaN(integrationTimeMS) && num != integrationTimeMS)
			{
				AsyncInstantiateOperation.SetIntegrationTimeMS(num);
				if (Time.unscaledTime >= nextReport)
				{
					nextReport = Time.unscaledTime + 2f;
					PortalDiagnostics.Event("async_integration_budget", "previous_ms=" + integrationTimeMS.ToString("F2") + " target_ms=" + num.ToString("F2") + " active=" + work);
				}
			}
		}

		internal static void Reset()
		{
			Update(work: false);
		}
	}
	internal static class AsyncIntegrationDiagnostics
	{
		private sealed class Sample
		{
			internal int Frame;

			internal int Locations;

			internal int Scenery;

			internal int LocationDone;

			internal int SceneryDone;

			internal int Names;

			internal double Ms;

			internal bool Charged;

			internal readonly string[] Prefabs = new string[8];

			internal readonly bool[] IsLocation = new bool[8];

			internal void CopyFrom(Sample s)
			{
				Frame = s.Frame;
				Locations = s.Locations;
				Scenery = s.Scenery;
				LocationDone = s.LocationDone;
				SceneryDone = s.SceneryDone;
				Names = s.Names;
				Ms = s.Ms;
				Charged = s.Charged;
				Array.Copy(s.Prefabs, Prefabs, 8);
				Array.Copy(s.IsLocation, IsLocation, 8);
			}

			internal void Clear()
			{
				Ms = 0.0;
				Names = (LocationDone = (SceneryDone = 0));
				Array.Clear(Prefabs, 0, 8);
			}
		}

		private static readonly Sample current = new Sample();

		private static readonly Sample[] worst = new Sample[4]
		{
			new Sample(),
			new Sample(),
			new Sample(),
			new Sample()
		};

		private static bool collecting;

		private static int outsidePhase;

		internal static void Begin(int frame)
		{
			current.Clear();
			current.Frame = frame;
			current.Locations = LocationPreparation.PendingOperations;
			current.Scenery = PortalAsync.PendingOperations;
			collecting = true;
		}

		internal static void Completion(bool location, string prefab)
		{
			ConfigEntry<bool> timings = Plugin.Timings;
			if (timings == null || !timings.Value)
			{
				return;
			}
			if (!collecting)
			{
				outsidePhase++;
				return;
			}
			if (location)
			{
				current.LocationDone++;
			}
			else
			{
				current.SceneryDone++;
			}
			if (current.Names != 8)
			{
				current.IsLocation[current.Names] = location;
				current.Prefabs[current.Names++] = prefab;
			}
		}

		internal static void End(double milliseconds, bool charged)
		{
			if (!collecting)
			{
				return;
			}
			collecting = false;
			current.Ms = milliseconds;
			current.Charged = charged;
			if (milliseconds < 2.0)
			{
				return;
			}
			int num = 0;
			for (int i = 1; i < worst.Length; i++)
			{
				if (worst[i].Ms < worst[num].Ms)
				{
					num = i;
				}
			}
			if (milliseconds > worst[num].Ms)
			{
				worst[num].CopyFrom(current);
			}
		}

		internal static void Report()
		{
			Sample[] array = worst;
			foreach (Sample sample in array)
			{
				if (sample.Ms < 2.0)
				{
					continue;
				}
				StringBuilder stringBuilder = new StringBuilder();
				for (int j = 0; j < sample.Names; j++)
				{
					if (j > 0)
					{
						stringBuilder.Append(',');
					}
					stringBuilder.Append(sample.IsLocation[j] ? "location:" : "scenery:").Append(sample.Prefabs[j]?.Replace(' ', '_'));
				}
				PortalDiagnostics.Event("async_integration_frame", "frame=" + sample.Frame + " engine_ms=" + sample.Ms.ToString("F2") + " location_awaiting=" + sample.Locations + " scenery_awaiting=" + sample.Scenery + " location_completed=" + sample.LocationDone + " scenery_completed=" + sample.SceneryDone + " completion_sample=" + stringBuilder?.ToString() + " sample_omitted=" + Math.Max(0, sample.LocationDone + sample.SceneryDone - sample.Names) + " budget_charged=" + sample.Charged + " correlation_only=True");
				sample.Clear();
			}
			if (outsidePhase > 0)
			{
				PortalDiagnostics.Event("async_completion_delivery", "outside_engine_phase=" + outsidePhase);
			}
			outsidePhase = 0;
		}

		internal static void Reset()
		{
			collecting = false;
			outsidePhase = 0;
			current.Clear();
			Sample[] array = worst;
			for (int i = 0; i < array.Length; i++)
			{
				array[i].Clear();
			}
		}
	}
	internal static class BaseJoinPacing
	{
		private static readonly BaseJoinWindow window = new BaseJoinWindow();

		private static Player observed;

		private static ZNetScene scene;

		private static int yields;

		private static int samples;

		private static float first;

		private static float worst;

		private static readonly int[] histogram = new int[128];

		internal static bool Headless
		{
			get
			{
				if (!Application.isBatchMode)
				{
					if ((Object)(object)ZNet.instance != (Object)null)
					{
						return ZNet.instance.IsDedicated();
					}
					return false;
				}
				return true;
			}
		}

		internal static bool YieldOptional => window.YieldOptional;

		private static void ClearStats()
		{
			yields = (samples = 0);
			worst = 0f;
			Array.Clear(histogram, 0, histogram.Length);
		}

		private static int P95()
		{
			int num = 0;
			for (int i = 0; i < histogram.Length; i++)
			{
				num += histogram[i];
				if (num * 20 >= samples * 19)
				{
					return i;
				}
			}
			return 127;
		}

		internal static void Tick()
		{
			ZNetScene instance = ZNetScene.instance;
			Player localPlayer = Player.m_localPlayer;
			if (scene != instance || observed != localPlayer)
			{
				scene = instance;
				observed = localPlayer;
				window.Reset();
				ClearStats();
				first = Time.unscaledTime;
			}
			if (window.Watching && Object.op_Implicit((Object)(object)instance) && Object.op_Implicit((Object)(object)localPlayer) && !((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsDedicated())
			{
				int count = Api.Instances.Invoke(instance).Count;
				int count2 = WearNTear.GetAllInstances().Count;
				float unscaledTime = Time.unscaledTime;
				float num = Time.unscaledDeltaTime * 1000f;
				if (num > 0f && !float.IsNaN(num))
				{
					samples++;
					worst = Math.Max(num, worst);
					histogram[(int)Math.Min(127.0, Math.Ceiling(num))]++;
				}
				if (window.Sample(unscaledTime, num, Plugin.MinimumFps.Value, count, count2) && yields++ == 0)
				{
					PortalDiagnostics.Event("base_join", "phase=busy objects=" + count + " building_pieces=" + count2);
				}
				if (!window.Watching && yields > 0)
				{
					PortalDiagnostics.Event("base_join", "phase=released elapsed_s=" + (unscaledTime - first).ToString("F2") + " yielded_frames=" + yields + " objects=" + count + " samples=" + samples + " frame_p95_ms_bin=" + P95() + " max_frame_ms=" + worst.ToString("F2") + NativeSpawnOrdering.Stats);
				}
			}
		}
	}
	internal static class BuildingReturnShell
	{
		private sealed class Section
		{
			internal Mesh mesh;

			internal int sub;

			internal Matrix4x4 matrix;

			internal RenderParams draw;
		}

		private sealed class Stamp
		{
			internal ZDOID id;

			internal int prefab;

			internal uint revision;

			internal Vector3 position;

			internal Quaternion rotation;

			internal Section[] slices;

			internal LinkedListNode<Stamp> order;

			internal LinkedListNode<Stamp> treeOrder;

			internal bool missing;

			internal Tile tile;

			internal Bounds bounds;
		}

		private sealed class Tile
		{
			internal long key;

			internal Bounds bounds;

			internal readonly List<Stamp> items = new List<Stamp>();
		}

		private sealed class Map
		{
			internal Vector3 point;

			internal int version = -1;

			internal float reach;

			internal readonly List<Tile> tiles = new List<Tile>();

			internal void Index(Vector3 p)
			{
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: 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_0023: 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_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0081: Unknown result type (might be due to invalid IL or missing references)
				float value = Plugin.FarBuildingDistance.Value;
				if (version == tileVersion && reach == value)
				{
					Vector3 val = p - point;
					if (((Vector3)(ref val)).sqrMagnitude < 36f)
					{
						return;
					}
				}
				point = p;
				reach = value;
				version = tileVersion;
				tiles.Clear();
				foreach (Tile value2 in tilesByKey.Values)
				{
					if (((Bounds)(ref value2.bounds)).SqrDistance(p) <= value * value)
					{
						tiles.Add(value2);
					}
				}
				tiles.Sort(Compare);
			}

			private int Compare(Tile a, Tile b)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				return ((Bounds)(ref a.bounds)).SqrDistance(point).CompareTo(((Bounds)(ref b.bounds)).SqrDistance(point));
			}

			internal void Clear()
			{
				tiles.Clear();
				version = -1;
			}
		}

		private const int Pieces = 2048;

		private const int Trees = 384;

		private const int Sections = 4864;

		private const int PerPiece = 6;

		private const int MaxDraws = 256;

		private const float Seconds = 25f;

		private const float TileSide = 96f;

		private static readonly Dictionary<ZDOID, Stamp> stamps = new Dictionary<ZDOID, Stamp>();

		private static readonly LinkedList<Stamp> order = new LinkedList<Stamp>();

		private static readonly List<Section> scratch = new List<Section>(6);

		private static readonly List<Material> mats = new List<Material>(4);

		private static readonly LinkedList<Stamp> trees = new LinkedList<Stamp>();

		private static readonly Dictionary<long, Tile> tilesByKey = new Dictionary<long, Tile>();

		private static Map visible = new Map();

		private static Map next = new Map();

		private static int tileVersion;

		private static int peakCopies;

		private static readonly Plane[] planes = (Plane[])(object)new Plane[6];

		private static Vector3 landing;

		private static float deadline;

		private static bool active;

		private static int missing;

		private static int sections;

		private static int capturedFrame = -1;

		private static int captures;

		private static int submitted;

		private static int peak;

		private static int windows;

		private static float frameMs = 16f;

		internal static bool HasRecords => stamps.Count != 0;

		internal static bool WindowActive => active;

		internal static int LastDraws => submitted;

		internal static string Stats => " return_stamps=" + stamps.Count + " tree_stamps=" + trees.Count + " max_shell_copies=" + peakCopies + " shell_sections=" + sections + " shell_windows=" + windows + " peak_shell_draws=" + peak;

		private static long TileKey(Vector3 pos)
		{
			//IL_0000: 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)
			return ((long)(int)Math.Floor(pos.x / 96f) << 32) | (uint)(int)Math.Floor(pos.z / 96f);
		}

		internal static void Prime(Vector3 point)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			if (tilesByKey.Count != 0)
			{
				next.Index(point);
			}
		}

		internal static bool Knows(ZDO z)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if (z != null)
			{
				return stamps.ContainsKey(z.m_uid);
			}
			return false;
		}

		internal static int DrawLimit(float ms)
		{
			if (!(ms >= 28f))
			{
				if (!(ms >= 19f))
				{
					return 256;
				}
				return 96;
			}
			return 48;
		}

		internal static void Forget(ZDOID id)
		{
			//IL_0005: 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)
			if (!stamps.TryGetValue(id, out var value))
			{
				return;
			}
			stamps.Remove(id);
			order.Remove(value.order);
			if (value.treeOrder != null)
			{
				trees.Remove(value.treeOrder);
			}
			if (value.tile != null)
			{
				Tile tile = value.tile;
				tile.items.Remove(value);
				if (tile.items.Count == 0)
				{
					tilesByKey.Remove(tile.key);
					tileVersion++;
				}
			}
			sections -= value.slices.Length;
			if (value.missing)
			{
				missing--;
			}
			value.missing = false;
		}

		internal static void Observe(WearNTear w, ZDO z, List<MeshRenderer> renderers)
		{
			ObserveCore((Component)(object)w, w, ((Component)w).transform, z, renderers);
		}

		internal static void ObserveTree(TreeBase tree, ZDO z, List<MeshRenderer> renderers)
		{
			if (Object.op_Implicit((Object)(object)tree))
			{
				ObserveCore((Component)(object)tree, null, ((Component)tree).transform, z, renderers);
			}
		}

		private static void ObserveCore(Component root, WearNTear w, Transform rootTransform, ZDO z, List<MeshRenderer> renderers)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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_0073: 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_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0604: Unknown result type (might be due to invalid IL or missing references)
			//IL_0609: Unknown result type (might be due to invalid IL or missing references)
			//IL_0610: Unknown result type (might be due to invalid IL or missing references)
			//IL_0615: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_065e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0663: Unknown result type (might be due to invalid IL or missing references)
			//IL_0572: Unknown result type (might be due to invalid IL or missing references)
			//IL_0681: Unknown result type (might be due to invalid IL or missing references)
			//IL_069e: Unknown result type (might be due to invalid IL or missing references)
			//IL_06f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_06cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0719: Unknown result type (might be due to invalid IL or missing references)
			//IL_0308: Unknown result type (might be due to invalid IL or missing references)
			//IL_030d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Expected O, but got Unknown
			//IL_0394: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0418: Unknown result type (might be due to invalid IL or missing references)
			//IL_044a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0458: Unknown result type (might be due to invalid IL or missing references)
			//IL_0462: Unknown result type (might be due to invalid IL or missing references)
			//IL_0464: Unknown result type (might be due to invalid IL or missing references)
			//IL_0481: Unknown result type (might be due to invalid IL or missing references)
			//IL_0483: Unknown result type (might be due to invalid IL or missing references)
			//IL_0489: Unknown result type (might be due to invalid IL or missing references)
			//IL_048b: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c9: Expected O, but got Unknown
			bool flag = (Object)(object)w == (Object)null;
			if (!Plugin.FarBuildings.Value || !Object.op_Implicit((Object)(object)root) || z == null || renderers.Count == 0 || renderers.Count > 24)
			{
				return;
			}
			if (stamps.TryGetValue(z.m_uid, out var value))
			{
				if (!value.missing && value.prefab == z.GetPrefab() && value.revision == z.DataRevision && value.position == z.GetPosition() && value.rotation == z.GetRotation())
				{
					return;
				}
				Forget(z.m_uid);
			}
			if (capturedFrame != Time.frameCount)
			{
				capturedFrame = Time.frameCount;
				captures = 0;
			}
			if (captures >= 6)
			{
				return;
			}
			captures++;
			scratch.Clear();
			foreach (MeshRenderer renderer in renderers)
			{
				if (!Object.op_Implicit((Object)(object)renderer) || !((Renderer)renderer).enabled || !((Component)renderer).gameObject.activeInHierarchy || (Object.op_Implicit((Object)(object)w) && ((Object)(object)renderer == (Object)(object)w.m_snow || (Object)(object)renderer == (Object)(object)w.m_snowWorn || (Object)(object)renderer == (Object)(object)w.m_snowBroken)) || ((Renderer)renderer).forceRenderingOff || ((Renderer)renderer).isPartOfStaticBatch || Object.op_Implicit((Object)(object)renderer.additionalVertexStreams) || Object.op_Implicit((Object)(object)((Renderer)renderer).probeAnchor) || Object.op_Implicit((Object)(object)((Renderer)renderer).lightProbeProxyVolumeOverride) || (((Renderer)renderer).lightmapIndex >= 0 && ((Renderer)renderer).lightmapIndex < 65534) || (((Renderer)renderer).realtimeLightmapIndex >= 0 && ((Renderer)renderer).realtimeLightmapIndex < 65534))
				{
					continue;
				}
				LODGroup componentInParent = ((Component)renderer).GetComponentInParent<LODGroup>();
				if (Object.op_Implicit((Object)(object)componentInParent) && componentInParent.enabled)
				{
					if (!((Component)componentInParent).transform.IsChildOf(rootTransform))
					{
						continue;
					}
					LOD[] lODs = componentInParent.GetLODs();
					if (lODs.Length == 0)
					{
						continue;
					}
					int num = 0;
					if (flag)
					{
						num = lODs.Length - 1;
						while (num >= 0 && !Array.Exists(lODs[num].renderers, (Renderer x) => x is MeshRenderer))
						{
							num--;
						}
					}
					if (num < 0 || Array.IndexOf(lODs[num].renderers, (Renderer)(object)renderer) < 0)
					{
						continue;
					}
				}
				MeshFilter component = ((Component)renderer).GetComponent<MeshFilter>();
				Mesh val = ((component != null) ? component.sharedMesh : null);
				if (!Object.op_Implicit((Object)(object)val) || val.subMeshCount < 1 || val.subMeshCount > 6 || val.vertexCount > (flag ? 6500 : 24000))
				{
					continue;
				}
				((Renderer)renderer).GetSharedMaterials(mats);
				if (mats.Count != val.subMeshCount)
				{
					continue;
				}
				Matrix4x4 localToWorldMatrix = ((Renderer)renderer).localToWorldMatrix;
				if (!(((Matrix4x4)(ref localToWorldMatrix)).determinant > 0f))
				{
					continue;
				}
				bool flag2 = ((Renderer)renderer).HasPropertyBlock();
				MaterialPropertyBlock val2 = null;
				if (flag2)
				{
					val2 = new MaterialPropertyBlock();
					((Renderer)renderer).GetPropertyBlock(val2);
					if (val2.isEmpty)
					{
						val2 = null;
					}
				}
				for (int num2 = 0; num2 < mats.Count; num2++)
				{
					Material val3 = mats[num2];
					if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.shader) || val3.renderQueue > 2500 || (int)val.GetTopology(num2) != 0)
					{
						continue;
					}
					if (scratch.Count >= 6)
					{
						scratch.Clear();
						return;
					}
					MaterialPropertyBlock matProps = val2;
					if (flag2)
					{
						MaterialPropertyBlock val4 = new MaterialPropertyBlock();
						((Renderer)renderer).GetPropertyBlock(val4, num2);
						if (!val4.isEmpty)
						{
							matProps = val4;
						}
					}
					RenderParams val5 = new RenderParams(val3);
					((RenderParams)(ref val5)).matProps = matProps;
					((RenderParams)(ref val5)).layer = ((Component)renderer).gameObject.layer;
					((RenderParams)(ref val5)).renderingLayerMask = ((Renderer)renderer).renderingLayerMask;
					((RenderParams)(ref val5)).worldBounds = ((Renderer)renderer).bounds;
					((RenderParams)(ref val5)).receiveShadows = ((Renderer)renderer).receiveShadows;
					((RenderParams)(ref val5)).shadowCastingMode = (ShadowCastingMode)0;
					((RenderParams)(ref val5)).rendererPriority = ((Renderer)renderer).rendererPriority;
					((RenderParams)(ref val5)).lightProbeUsage = ((Renderer)renderer).lightProbeUsage;
					((RenderParams)(ref val5)).reflectionProbeUsage = ((Renderer)renderer).reflectionProbeUsage;
					RenderParams draw = val5;
					scratch.Add(new Section
					{
						mesh = val,
						sub = num2,
						matrix = localToWorldMatrix,
						draw = draw
					});
				}
			}
			if (scratch.Count == 0)
			{
				return;
			}
			if (flag && trees.Count >= 384)
			{
				Forget(trees.First.Value.id);
			}
			while (order.Count > 0 && (stamps.Count >= 2432 || (!flag && stamps.Count - trees.Count >= 2048) || sections + scratch.Count > 4864))
			{
				Stamp value2 = order.First.Value;
				if (!flag && stamps.Count - trees.Count >= 2048)
				{
					LinkedListNode<Stamp> first = order.First;
					while (first != null && first.Value.treeOrder != null)
					{
						first = first.Next;
					}
					if (first != null)
					{
						value2 = first.Value;
					}
				}
				Forget(value2.id);
			}
			Stamp stamp = new Stamp
			{
				id = z.m_uid,
				prefab = z.GetPrefab(),
				revision = z.DataRevision,
				position = z.GetPosition(),
				rotation = z.GetRotation(),
				slices = scratch.ToArray()
			};
			stamp.order = order.AddLast(stamp);
			if (flag)
			{
				stamp.treeOrder = trees.AddLast(stamp);
			}
			stamp.bounds = ((RenderParams)(ref stamp.slices[0].draw)).worldBounds;
			for (int num3 = 1; num3 < stamp.slices.Length; num3++)
			{
				((Bounds)(ref stamp.bounds)).Encapsulate(((RenderParams)(ref stamp.slices[num3].draw)).worldBounds);
			}
			long key = TileKey(stamp.position);
			if (!tilesByKey.TryGetValue(key, out var value3))
			{
				Dictionary<long, Tile> dictionary = tilesByKey;
				Tile obj = new Tile
				{
					key = key,
					bounds = stamp.bounds
				};
				value3 = obj;
				dictionary[key] = obj;
				tileVersion++;
			}
			else
			{
				((Bounds)(ref value3.bounds)).Encapsulate(stamp.bounds);
			}
			stamp.tile = value3;
			value3.items.Add(stamp);
			stamps.Add(stamp.id, stamp);
			sections += stamp.slices.Length;
			scratch.Clear();
		}

		internal static void Removed(ZDO z)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			if (z != null && stamps.TryGetValue(z.m_uid, out var value))
			{
				if (z.GetPrefab() != value.prefab || z.GetPosition() != value.position || z.GetRotation() != value.rotation || z.DataRevision != value.revision)
				{
					Forget(value.id);
				}
				else if (!value.missing)
				{
					value.missing = true;
					missing++;
				}
			}
		}

		internal static void Appeared(ZDO z)
		{
			//IL_0009: 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)
			if (z != null && stamps.TryGetValue(z.m_uid, out var value) && value.missing)
			{
				Forget(z.m_uid);
			}
		}

		internal static void Begin(Vector3 point)
		{
			//IL_002e: 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_005b: 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)
			if (active && Time.unscaledTime < deadline)
			{
				Vector3 val = point - landing;
				if (((Vector3)(ref val)).sqrMagnitude < 36f)
				{
					return;
				}
			}
			landing = point;
			deadline = Time.unscaledTime + 25f;
			active = true;
			windows++;
			next.Index(point);
			Map map = visible;
			visible = next;
			next = map;
			frameMs = Math.Max(1f, Math.Min(100f, Time.unscaledDeltaTime * 1000f));
		}

		internal static void Render(Camera cam, Player player, ZNetScene scene)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: 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_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			submitted = 0;
			if (!active)
			{
				return;
			}
			if (!(Time.unscaledTime >= deadline) && Object.op_Implicit((Object)(object)player) && Object.op_Implicit((Object)(object)scene) && Object.op_Implicit((Object)(object)cam) && !((Character)player).InInterior())
			{
				Vector3 val = ((Component)player).transform.position - landing;
				if (!(((Vector3)(ref val)).sqrMagnitude > 9216f))
				{
					if (missing == 0)
					{
						return;
					}
					visible.Index(landing);
					float num = Math.Max(1f, Math.Min(100f, Time.unscaledDeltaTime * 1000f));
					frameMs += (num - frameMs) * ((num > frameMs) ? 0.35f : 0.06f);
					int num2 = DrawLimit(frameMs);
					int num3 = 0;
					int num4 = 0;
					GeometryUtility.CalculateFrustumPlanes(cam, planes);
					ReturnDrawQueue.Begin(num2);
					foreach (Tile tile in visible.tiles)
					{
						if (!GeometryUtility.TestPlanesAABB(planes, tile.bounds))
						{
							continue;
						}
						foreach (Stamp item in tile.items)
						{
							if (!item.missing)
							{
								continue;
							}
							val = item.position - landing;
							if (((Vector3)(ref val)).sqrMagnitude > visible.reach * visible.reach)
							{
								continue;
							}
							if (++num4 > 2432)
							{
								break;
							}
							if (!GeometryUtility.TestPlanesAABB(planes, item.bounds))
							{
								continue;
							}
							if (++num3 > num2 * 12 || ReturnDrawQueue.Full)
							{
								break;
							}
							ZDOMan instance = ZDOMan.instance;
							ZDO val2 = ((instance != null) ? instance.GetZDO(item.id) : null);
							if (val2 != null && (val2.GetPrefab() != item.prefab || val2.GetPosition() != item.position || val2.GetRotation() != item.rotation || val2.DataRevision != item.revision || Object.op_Implicit((Object)(object)scene.FindInstance(val2))))
							{
								item.missing = false;
								missing--;
								continue;
							}
							Section[] slices = item.slices;
							foreach (Section section in slices)
							{
								RenderParams draw = section.draw;
								if (Object.op_Implicit((Object)(object)section.mesh) && Object.op_Implicit((Object)(object)((RenderParams)(ref draw)).material) && GeometryUtility.TestPlanesAABB(planes, ((RenderParams)(ref draw)).worldBounds))
								{
									((RenderParams)(ref draw)).camera = cam;
									ReturnDrawQueue.Add(draw, section.mesh, section.sub, section.matrix);
								}
							}
						}
						if (num3 > num2 * 12 || ReturnDrawQueue.Full || num4 > 2432)
						{
							break;
						}
					}
					ReturnDrawQueue.Flush();
					submitted = ReturnDrawQueue.Draws;
					peak = Math.Max(peak, submitted);
					peakCopies = Math.Max(peakCopies, ReturnDrawQueue.Copies);
					return;
				}
			}
			active = false;
			visible.Clear();
		}

		internal static void Reset()
		{
			stamps.Clear();
			order.Clear();
			trees.Clear();
			tilesByKey.Clear();
			visible.Clear();
			next.Clear();
			ReturnDrawQueue.Reset();
			mats.Clear();
			scratch.Clear();
			active = false;
			tileVersion = 0;
			windows = (missing = (sections = (submitted = (peak = (peakCopies = (captures = 0))))));
			capturedFrame = -1;
		}
	}
	internal static class BuildingVisuals
	{
		private sealed class Part
		{
			internal WearNTear Wear;

			internal ZNetView View;

			internal ZDOID Id;

			internal MeshRenderer High;

			internal MeshRenderer Low;

			internal MeshFilter HighFilter;

			internal MeshFilter LowFilter;

			internal Mesh HighMesh;

			internal Mesh LowMesh;

			internal Matrix4x4 HighPose;

			internal Matrix4x4 LowPose;

			internal Renderer[] Draws;

			internal Material Material;

			internal Key Key;

			internal Bucket Pending;

			internal Batch Group;

			internal bool Hidden;

			internal int HighId;

			internal int LowId;
		}

		private struct Key : IEquatable<Key>
		{
			internal int X;

			internal int Y;

			internal int Z;

			internal int Layer;

			internal int Mat;

			internal int Cast;

			internal int Probe;

			internal int Reflection;

			internal int Motion;

			internal int Priority;

			internal int SortLayer;

			internal int Order;

			internal uint Mask;

			internal bool Shadows;

			internal bool Occludes;

			internal Vector3 Origin => new Vector3((float)(X * 24), (float)(Y * 24), (float)(Z * 24));

			internal Vector3 Center => Origin + Vector3.one * 12f;

			public bool Equals(Key b)
			{
				if (X == b.X && Y == b.Y && Z == b.Z && Layer == b.Layer && Mat == b.Mat && Cast == b.Cast && Probe == b.Probe && Reflection == b.Reflection && Motion == b.Motion && Priority == b.Priority && SortLayer == b.SortLayer && Order == b.Order && Mask == b.Mask && Shadows == b.Shadows)
				{
					return Occludes == b.Occludes;
				}
				return false;
			}

			public override bool Equals(object o)
			{
				if (o is Key b)
				{
					return Equals(b);
				}
				return false;
			}

			public override int GetHashCode()
			{
				return (X * 73856093) ^ (Y * 19349663) ^ (Z * 83492791) ^ Mat ^ (Layer << 21);
			}

			internal static Key From(Vector3 p, MeshRenderer r, Material mat)
			{
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: 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_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_006a: Expected I4, but got Unknown
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0077: Expected I4, but got Unknown
				//IL_007a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0084: Expected I4, but got Unknown
				//IL_0094: Unknown result type (might be due to invalid IL or missing references)
				//IL_009e: Expected I4, but got Unknown
				return new Key
				{
					X = DrawCellPolicy.Cell(p.x),
					Y = DrawCellPolicy.Cell(p.y),
					Z = DrawCellPolicy.Cell(p.z),
					Mat = ((Object)mat).GetInstanceID(),
					Layer = ((Component)r).gameObject.layer,
					Cast = (int)((Renderer)r).shadowCastingMode,
					Probe = (int)((Renderer)r).lightProbeUsage,
					Reflection = (int)((Renderer)r).reflectionProbeUsage,
					Mask = ((Renderer)r).renderingLayerMask,
					Motion = (int)((Renderer)r).motionVectorGenerationMode,
					Priority = ((Renderer)r).rendererPriority,
					SortLayer = ((Renderer)r).sortingLayerID,
					Order = ((Renderer)r).sortingOrder,
					Shadows = ((Renderer)r).receiveShadows,
					Occludes = ((Renderer)r).allowOcclusionWhenDynamic
				};
			}
		}

		private sealed class Bucket
		{
			internal Key Key;

			internal List<Part> Items = new List<Part>(24);

			internal int High;

			internal int Low;

			internal float Since;
		}

		private sealed class Batch
		{
			internal Key Key;

			internal List<Part> Items;

			internal GameObject Go;

			internal MeshFilter Filter;

			internal MeshRenderer Renderer;

			internal Mesh High;

			internal Mesh Low;

			internal int Verts;

			internal int Detached;

			internal int Index = -1;

			internal int Tier = -1;

			internal bool Paused;

			internal bool Closed;

			internal float LastSeen;

			internal float PausedAt;

			internal float BridgeAt = -1f;
		}

		private static readonly Dictionary<Key, Bucket> gathering = new Dictionary<Key, Bucket>();

		private static readonly Queue<Bucket> schedule = new Queue<Bucket>();

		private static readonly List<Batch> batches = new List<Batch>();

		private static readonly Dictionary<WearNTear, Part> live = new Dictionary<WearNTear, Part>(ReferenceIdentity<WearNTear>.Instance);

		private static readonly Dictionary<ZDOID, Part> ids = new Dictionary<ZDOID, Part>();

		private static readonly HashSet<int> unsupportedMesh = new HashSet<int>();

		private static int failedCombines;

		private static readonly Dictionary<int, bool> allowed = new Dictionary<int, bool>();

		private static readonly List<MeshRenderer> renderers = new List<MeshRenderer>(16);

		private static readonly List<Material> materials = new List<Material>(2);

		private static Harmony optional;

		private static ZNetScene scene;

		private static GameObject root;

		private static bool conflict;

		private static bool checkedMods;

		private static bool disabled;

		private static bool installed;

		private static bool companion;

		private static readonly Queue<WearNTear> rebind = new Queue<WearNTear>();

		private static readonly Queue<WearNTear> incoming = new Queue<WearNTear>();

		private static readonly HashSet<WearNTear> queued = new HashSet<WearNTear>(ReferenceIdentity<WearNTear>.Instance);

		private static bool accepting;

		private static bool clearing;

		private static bool haveEye;

		private static Vector3 lastEye;

		private static readonly Dictionary<int, bool> shellCatalogue = new Dictionary<int, bool>();

		private static int eagerFrame = -1;

		private static int eagerCount;

		private static int bridged;

		private static double eagerMs;

		private static bool shellFailed;

		private static bool treeReady;

		private static ZDO lastPrime;

		private static ZDOID lastPrimeId;

		private static readonly Queue<TreeBase> newTrees = new Queue<TreeBase>(384);

		private static readonly List<MeshRenderer> treeMeshes = new List<MeshRenderer>(8);

		private static ZNetScene treeScene;

		private static int surveyLeft;

		private static int reusedGroups;

		private static int reusedParts;

		private static int cursor;

		private static int auditCursor;

		private static int auditPart;

		private static int pending;

		private static int totalVerts;

		private static int builds;

		private static int invalidations;

		private static int noBatch;

		private static int blockedMaterials;

		private static int unreadable;

		private static int discovered;

		private static int orphanCount;

		private static float nextReport;

		private static float nextBuild;

		private static float nextVisibility;

		private static float nextAudit;

		private static float nextSlowBuild;

		private static double buildMs;

		private static double maxBuild;

		private static double tickMs;

		private static void TreeStarted(TreeBase __instance)
		{
			if (!treeReady || conflict || disabled || !Plugin.FarBuildings.Value || !Object.op_Implicit((Object)(object)__instance))
			{
				return;
			}
			ZNetScene instance = ZNetScene.instance;
			if (Object.op_Implicit((Object)(object)instance))
			{
				if (instance != treeScene)
				{
					newTrees.Clear();
					treeScene = instance;
				}
				if (newTrees.Count < 384)
				{
					newTrees.Enqueue(__instance);
				}
			}
		}

		private static void TreeChanged(TreeBase __instance)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)__instance) && BuildingReturnShell.HasRecords)
			{
				ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
				ZDO val = ((component != null) ? component.GetZDO() : null);
				if (val != null)
				{
					BuildingReturnShell.Forget(val.m_uid);
				}
			}
		}

		private static void SnapshotTree()
		{
			//IL_0049: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			if (newTrees.Count == 0)
			{
				return;
			}
			TreeBase val = newTrees.Dequeue();
			if (!Object.op_Implicit((Object)(object)val) || !((Behaviour)val).isActiveAndEnabled)
			{
				return;
			}
			ZNetView component = ((Component)val).GetComponent<ZNetView>();
			ZDO val2 = (Object.op_Implicit((Object)(object)component) ? component.GetZDO() : null);
			if (val2 != null && !(val2.m_uid == ZDOID.None) && val2.Persistent && !((Object)(object)scene.FindInstance(val2) != (Object)(object)component))
			{
				Vector3 val3 = ((Component)val).transform.position - val2.GetPosition();
				if (!(((Vector3)(ref val3)).sqrMagnitude > 0.01f) && !Object.op_Implicit((Object)(object)((Component)val).GetComponentInParent<Rigidbody>()) && !Object.op_Implicit((Object)(object)((Component)val).gameObject.GetComponentInChildren<Animator>(true)) && !Object.op_Implicit((Object)(object)((Component)val).gameObject.GetComponentInChildren<Animation>(true)) && !Object.op_Implicit((Object)(object)((Component)val).gameObject.GetComponentInChildren<Rigidbody>(true)))
				{
					treeMeshes.Clear();
					((Component)val).GetComponentsInChildren<MeshRenderer>(false, treeMeshes);
					BuildingReturnShell.ObserveTree(val, val2, treeMeshes);
				}
			}
		}

		private static double Ms(long start)
		{
			return (double)(Stopwatch.GetTimestamp() - start) * 1000.0 / (double)Stopwatch.Frequency;
		}

		internal static void Install()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Invalid comparison between Unknown and I4
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			if (Application.isBatchMode || (int)SystemInfo.graphicsDeviceType == 4 || installed)
			{
				return;
			}
			installed = true;
			try
			{
				optional = new Harmony("com.easymods.instaport.rendercells");
				Hook(typeof(WearNTear), "Awake", Type.EmptyTypes, null, "Appeared");
				Hook(typeof(WearNTear), "Start", Type.EmptyTypes, null, "Started");
				Hook(typeof(WearNTear), "OnDestroy", Type.EmptyTypes, "Unloaded", null);
				Hook(typeof(WearNTear), "Destroy", new Type[2]
				{
					typeof(HitData),
					typeof(bool)
				}, "Edit", null);
				Hook(typeof(WearNTear), "Highlight", Type.EmptyTypes, "Edit", null);
				Hook(typeof(WearNTear), "RPC_HealthChanged", new Type[2]
				{
					typeof(long),
					typeof(float)
				}, "Edit", null);
				Hook(typeof(WearNTear), "RPC_SetSnow", new Type[2]
				{
					typeof(long),
					typeof(float)
				}, "E