using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("PUP_FPS")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("PUP_FPS")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("2db0cbbd-295f-4eae-b618-895c79638815")] [assembly: AssemblyFileVersion("1.0.7.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.7.0")] [module: UnverifiableCode] [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 ValheimInstanceCombiner { [BepInPlugin("com.pup.instancecombiner.safe", "PUP Safe Building Combiner", "1.0.19")] public class InstanceCombinerMod : BaseUnityPlugin { private sealed class GpuDrawGroup { public Mesh mesh; public int subMesh; public Material material; public bool usesTessellation; public bool tessellationEnabled = true; public readonly List chunks = new List(); } private sealed class BakedRecord { public string customId; public long userId; public uint id; public int prefabHash; public Vector3 position; public Quaternion rotation; public Vector3 scale; } private sealed class CachedColliderData { public byte type; public int layer; public Vector3 position; public Quaternion rotation; public Vector3 scale; public bool trigger; public Vector3 center; public Vector3 size; public float radius; public float height; public int direction; public bool convex; public string meshName; public Mesh mesh; } private sealed class PendingCollider { public GameObject root; public CachedColliderData data; } private sealed class SubClusterCacheEntry { public int x; public int z; public string name; public string fileName; } private sealed class MaterialCombineGroup { public Material source; public readonly List parts = new List(); } [HarmonyPatch(typeof(Player), "OnSpawned")] private static class PlayerSpawnPatch { private static void Postfix() { InstanceCombinerMod instanceCombinerMod = Object.FindFirstObjectByType(); if ((Object)(object)instanceCombinerMod != (Object)null) { instanceCombinerMod.LoadState(); } } } [HarmonyPatch(typeof(WearNTear), "UpdateSupport")] private static class WearNTearSupportPatch { private static bool Prefix() { if (!((Object)(object)Instance == (Object)null)) { return !Instance.ShouldBlockSupportUpdate(); } return true; } } [HarmonyPatch(typeof(ZNet), "SaveWorld")] private static class ZNetSaveWorldPatch { private static void Prefix() { if ((Object)(object)Instance != (Object)null) { Instance.BeforeVanillaWorldSave(); } } } internal static InstanceCombinerMod Instance; private const float CellSize = 64f; private const float ParkingCoordinate = 1900000f; private const string StateHeader = "PUP_SAFE|7|64|GRAUSTEN|SUBCLUSTER16"; private const string BakedKey = "PUP_SAFE_Baked"; private const string PositionKey = "PUP_SAFE_Position"; private const string RotationKey = "PUP_SAFE_Rotation"; private const string ScaleKey = "PUP_SAFE_Scale"; private const string CellXKey = "PUP_SAFE_CellX"; private const string CellZKey = "PUP_SAFE_CellZ"; private const string CustomIdKey = "PUP_GRAUSTEN_ID"; private readonly Harmony harmony = new Harmony("com.pup.instancecombiner.safe"); private readonly Dictionary clusters = new Dictionary(); private readonly Dictionary> generatedMeshes = new Dictionary>(); private readonly Dictionary> records = new Dictionary>(); private readonly Dictionary materialCopies = new Dictionary(StringComparer.Ordinal); private readonly HashSet failedCacheCells = new HashSet(); private readonly Dictionary> hiddenRenderers = new Dictionary>(); private readonly Dictionary> hiddenLodGroups = new Dictionary>(); private static Dictionary meshAssetCache; private bool processing; private bool highlightEnabled; private string worldName = ""; private readonly Dictionary highlightMaterials = new Dictionary(); private float nextCellCheck; private int activeColliderLoads; private int pendingSubClusterLoads; private readonly SortedDictionary> pendingColliders = new SortedDictionary>(); private int queuedColliderCount; private int loadedQueuedColliders; private float supportGuardUntil; private ZNet loadedZNet; private bool safeSaveRestoreInProgress; private bool applicationQuitting; private readonly Dictionary> gpuBakedGroups = new Dictionary>(); private readonly Dictionary> gpuClusterHidden = new Dictionary>(); private readonly Dictionary> precipitationRenderers = new Dictionary>(); private readonly Dictionary skyAlphaPreviousEnabled = new Dictionary(); private readonly Dictionary skyAlphaPreviousLayer = new Dictionary(); private readonly Dictionary skyAlphaPreviousShadowMode = new Dictionary(); private void Awake() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown Instance = this; Camera.onPreCull = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPreCull, (Delegate?)new CameraCallback(OnCameraPreCull)); Camera.onPostRender = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPostRender, (Delegate?)new CameraCallback(OnCameraPostRender)); harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"PUP Safe Building Combiner 1.0.19 loaded (exact darkwood depth renderers)"); } private void OnDestroy() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) Camera.onPreCull = (CameraCallback)Delegate.Remove((Delegate?)(object)Camera.onPreCull, (Delegate?)new CameraCallback(OnCameraPreCull)); Camera.onPostRender = (CameraCallback)Delegate.Remove((Delegate?)(object)Camera.onPostRender, (Delegate?)new CameraCallback(OnCameraPostRender)); RestoreCoordinatesForVanillaSave("plugin unload"); pendingColliders.Clear(); queuedColliderCount = 0; loadedQueuedColliders = 0; activeColliderLoads = 0; Instance = null; harmony.UnpatchSelf(); foreach (Vector2Int item in clusters.Keys.ToList()) { DestroyCluster(item); } foreach (Material value in materialCopies.Values) { if ((Object)(object)value != (Object)null) { Object.Destroy((Object)(object)value); } } foreach (Material value2 in highlightMaterials.Values) { if ((Object)(object)value2 != (Object)null) { Object.Destroy((Object)(object)value2); } } foreach (List value3 in hiddenRenderers.Values) { foreach (MeshRenderer item2 in value3) { if ((Object)(object)item2 != (Object)null) { ((Renderer)item2).enabled = true; } } } hiddenRenderers.Clear(); foreach (List value4 in hiddenLodGroups.Values) { foreach (LODGroup item3 in value4) { if ((Object)(object)item3 != (Object)null) { item3.enabled = true; } } } hiddenLodGroups.Clear(); DisableGpuRenderTest(); } private void OnApplicationQuit() { applicationQuitting = true; RestoreCoordinatesForVanillaSave("application quit"); } private void OnCameraPreCull(Camera camera) { //IL_00a4: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)camera == (Object)null || ((Object)camera).name != "SkyAlphaCamera") { return; } skyAlphaPreviousEnabled.Clear(); skyAlphaPreviousLayer.Clear(); skyAlphaPreviousShadowMode.Clear(); foreach (List value in precipitationRenderers.Values) { foreach (MeshRenderer item in value) { if (!((Object)(object)item == (Object)null)) { skyAlphaPreviousEnabled[item] = ((Renderer)item).enabled; skyAlphaPreviousLayer[item] = ((Component)item).gameObject.layer; skyAlphaPreviousShadowMode[item] = ((Renderer)item).shadowCastingMode; ((Component)item).gameObject.layer = 10; ((Renderer)item).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)item).enabled = true; } } } } private void OnCameraPostRender(Camera camera) { //IL_0099: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)camera == (Object)null || ((Object)camera).name != "SkyAlphaCamera") { return; } foreach (KeyValuePair item in skyAlphaPreviousEnabled) { if ((Object)(object)item.Key != (Object)null) { ((Renderer)item.Key).enabled = item.Value; if (skyAlphaPreviousLayer.TryGetValue(item.Key, out var value)) { ((Component)item.Key).gameObject.layer = value; } if (skyAlphaPreviousShadowMode.TryGetValue(item.Key, out var value2)) { ((Renderer)item.Key).shadowCastingMode = value2; } } } skyAlphaPreviousEnabled.Clear(); skyAlphaPreviousLayer.Clear(); skyAlphaPreviousShadowMode.Clear(); } private void Update() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_0090: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)ZNet.instance == (Object)null) { return; } if (UnityInput.Current.GetKeyDown((KeyCode)91) && !processing) { ((MonoBehaviour)this).StartCoroutine(BakeCell(GetCell(((Component)Player.m_localPlayer).transform.position))); } if (UnityInput.Current.GetKeyDown((KeyCode)93) && !processing) { Vector2Int? val = FindNearestBakedCell(((Component)Player.m_localPlayer).transform.position, 96f); if (val.HasValue) { ((MonoBehaviour)this).StartCoroutine(UnbakeCell(val.Value)); } else { ShowMessage("No baked cluster nearby"); } } if (UnityInput.Current.GetKeyDown((KeyCode)92)) { highlightEnabled = !highlightEnabled; RefreshHighlights(); ShowMessage(highlightEnabled ? "Cluster highlighting enabled" : "Cluster highlighting disabled"); } if (UnityInput.Current.GetKeyDown((KeyCode)289) && !processing) { ((MonoBehaviour)this).StartCoroutine(RestoreAllParked()); } DrawGpuRenderTest(); ProcessPendingColliders(); if (!processing && Time.time >= nextCellCheck) { nextCellCheck = Time.time + 0.5f; UpdateVisibleClusters(); } } private void DrawGpuRenderTest() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: 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_0032: 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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)Player.m_localPlayer).transform.position; Vector3 val = default(Vector3); foreach (KeyValuePair> gpuBakedGroup in gpuBakedGroups) { Vector2Int key = gpuBakedGroup.Key; float num = ((float)((Vector2Int)(ref key)).x + 0.5f) * 64f; float y = position.y; key = gpuBakedGroup.Key; ((Vector3)(ref val))..ctor(num, y, ((float)((Vector2Int)(ref key)).y + 0.5f) * 64f); float num2 = Vector3.Distance(position, val); foreach (GpuDrawGroup item in gpuBakedGroup.Value) { if (item.usesTessellation) { bool flag = (item.tessellationEnabled ? (num2 < 128f) : (num2 < 96f)); if (flag != item.tessellationEnabled) { item.tessellationEnabled = flag; if (flag) { item.material.EnableKeyword("TESSELATION_ON"); } else { item.material.DisableKeyword("TESSELATION_ON"); } } } foreach (Matrix4x4[] chunk in item.chunks) { Graphics.DrawMeshInstanced(item.mesh, item.subMesh, item.material, chunk, chunk.Length, (MaterialPropertyBlock)null, (ShadowCastingMode)0, true, 0); } } } } private void EnableGpuBakedRenderTest(Vector2Int cell, List<(ZNetView view, Piece piece)> targets, GameObject cluster) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Invalid comparison between Unknown and I4 //IL_0140: Unknown result type (might be due to invalid IL or missing references) RemoveGpuBakedCell(cell, restoreRenderers: true); List list = new List(); Dictionary)> dictionary = new Dictionary)>(StringComparer.Ordinal); foreach (var target in targets) { MeshFilter[] componentsInChildren = ((Component)target.piece).GetComponentsInChildren(false); foreach (MeshFilter val in componentsInChildren) { MeshRenderer component = ((Component)val).GetComponent(); if ((Object)(object)component == (Object)null || !((Renderer)component).enabled || (Object)(object)val.sharedMesh == (Object)null || (((Renderer)component).sharedMaterials.Length != 0 && ((Renderer)component).sharedMaterials.All((Material material) => (Object)(object)material != (Object)null && NormalizeMaterialName(((Object)material).name).Equals("crystal_window_lod", StringComparison.OrdinalIgnoreCase)))) { continue; } for (int num = 0; num < val.sharedMesh.subMeshCount && num < ((Renderer)component).sharedMaterials.Length; num++) { Material val2 = ((Renderer)component).sharedMaterials[num]; if (!((Object)(object)val2 == (Object)null)) { string key = $"{((Object)val.sharedMesh).GetInstanceID()}|{num}|{((Object)val2).GetInstanceID()}"; if (!dictionary.TryGetValue(key, out var value)) { value = (dictionary[key] = (val.sharedMesh, num, val2, new List())); } value.Item4.Add(((Component)val).transform.localToWorldMatrix); } } } } foreach (var value2 in dictionary.Values) { Material val3 = Object.Instantiate(value2.Item3); val3.enableInstancing = true; GpuDrawGroup gpuDrawGroup = new GpuDrawGroup { mesh = value2.Item1, subMesh = value2.Item2, material = val3, usesTessellation = val3.IsKeywordEnabled("TESSELATION_ON"), tessellationEnabled = true }; for (int num2 = 0; num2 < value2.Item4.Count; num2 += 1023) { gpuDrawGroup.chunks.Add(value2.Item4.Skip(num2).Take(1023).ToArray()); } list.Add(gpuDrawGroup); } List list2 = new List(); MeshRenderer[] componentsInChildren2 = cluster.GetComponentsInChildren(false); foreach (MeshRenderer val4 in componentsInChildren2) { if (!((Object)(object)val4 == (Object)null) && ((Renderer)val4).enabled && (int)((Renderer)val4).shadowCastingMode != 3) { list2.Add(val4); ((Renderer)val4).enabled = false; } } gpuBakedGroups[cell] = list; gpuClusterHidden[cell] = list2; BuildRoofDepthRenderers(cell, cluster, list); int num3 = list.Sum((GpuDrawGroup group) => group.chunks.Sum((Matrix4x4[] chunk) => chunk.Length)); int num4 = list.Sum((GpuDrawGroup group) => group.chunks.Count); int num5 = list.Count((GpuDrawGroup group) => group.usesTessellation); ((BaseUnityPlugin)this).Logger.LogInfo((object)($"[GPU-BAKE] cell {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}: {targets.Count} parked targets, " + $"{list.Count} groups, {num3} instances, {num4} draw batches, " + $"tessellatedGroups={num5}, shadows=proxy")); } private void BuildRoofDepthRenderers(Vector2Int cell, GameObject root, IEnumerable groups) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: 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_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0119: 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) if ((Object)(object)root == (Object)null || groups == null) { return; } int num = 0; Matrix4x4 worldToLocalMatrix = root.transform.worldToLocalMatrix; foreach (GpuDrawGroup group in groups) { if (group == null || (Object)(object)group.mesh == (Object)null || (Object)(object)group.material == (Object)null || group.subMesh != 0 || !NormalizeMaterialName(((Object)group.material).name).Equals("RoofShingles", StringComparison.OrdinalIgnoreCase)) { continue; } foreach (Matrix4x4[] chunk in group.chunks) { foreach (Matrix4x4 val in chunk) { Matrix4x4 val2 = worldToLocalMatrix * val; GameObject val3 = new GameObject("PUP_DarkwoodDepth") { layer = 10 }; val3.transform.SetParent(root.transform, false); val3.transform.localPosition = Vector4.op_Implicit(((Matrix4x4)(ref val2)).GetColumn(3)); val3.transform.localRotation = ((Matrix4x4)(ref val2)).rotation; val3.transform.localScale = ((Matrix4x4)(ref val2)).lossyScale; val3.AddComponent().sharedMesh = group.mesh; MeshRenderer val4 = val3.AddComponent(); ((Renderer)val4).sharedMaterial = group.material; ((Renderer)val4).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)val4).receiveShadows = false; ((Renderer)val4).enabled = false; RegisterPrecipitationRenderer(cell, val4); num++; } } } } private void DisableGpuRenderTest() { //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) //IL_0021: Unknown result type (might be due to invalid IL or missing references) foreach (Vector2Int item in gpuBakedGroups.Keys.ToList()) { RemoveGpuBakedCell(item, restoreRenderers: true); } } private void RemoveGpuBakedCell(Vector2Int cell, bool restoreRenderers) { //IL_0006: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) if (gpuClusterHidden.TryGetValue(cell, out var value)) { if (restoreRenderers) { foreach (MeshRenderer item in value) { if ((Object)(object)item != (Object)null) { ((Renderer)item).enabled = true; } } } gpuClusterHidden.Remove(cell); } if (!gpuBakedGroups.TryGetValue(cell, out var value2)) { return; } foreach (GpuDrawGroup item2 in value2) { if ((Object)(object)item2.material != (Object)null) { Object.Destroy((Object)(object)item2.material); } } gpuBakedGroups.Remove(cell); } private static Vector2Int GetCell(Vector3 position) { //IL_0000: 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_0022: Unknown result type (might be due to invalid IL or missing references) return new Vector2Int(Mathf.FloorToInt(position.x / 64f), Mathf.FloorToInt(position.z / 64f)); } private void UpdateVisibleClusters() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: 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) if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)ZoneSystem.instance == (Object)null) { return; } Vector3 position = ((Component)Player.m_localPlayer).transform.position; Vector2i zone = ZoneSystem.GetZone(position); int num = Mathf.Max(1, ZoneSystem.instance.m_activeArea); foreach (Vector2Int item in clusters.Keys.ToList()) { if (!CellOverlapsValheimArea(item, zone, num + 1)) { DestroyCluster(item); } } Vector2Int? val = null; float num2 = float.MaxValue; foreach (Vector2Int key in records.Keys) { Vector2Int current2 = key; if (!clusters.ContainsKey(current2) && !failedCacheCells.Contains(current2) && CellOverlapsValheimArea(current2, zone, num)) { Vector3 val2 = new Vector3(((float)((Vector2Int)(ref current2)).x + 0.5f) * 64f, position.y, ((float)((Vector2Int)(ref current2)).y + 0.5f) * 64f) - position; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; if (!(sqrMagnitude >= num2)) { num2 = sqrMagnitude; val = current2; } } } if (val.HasValue && !TryLoadClusterCache(val.Value)) { ManualLogSource logger = ((BaseUnityPlugin)this).Logger; Vector2Int value = val.Value; object arg = ((Vector2Int)(ref value)).x; value = val.Value; logger.LogWarning((object)$"Cached cluster unavailable for visible cell {arg},{((Vector2Int)(ref value)).y}; starting verified rebuild"); ((MonoBehaviour)this).StartCoroutine(RebuildParkedCell(val.Value)); } } private static bool CellOverlapsValheimArea(Vector2Int cell, Vector2i centerZone, int rings) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) float num = (float)((Vector2Int)(ref cell)).x * 64f; float num2 = num + 64f; float num3 = (float)((Vector2Int)(ref cell)).y * 64f; float num4 = num3 + 64f; float num5 = (float)(centerZone.x - rings) * 64f - 32f; float num6 = (float)(centerZone.x + rings) * 64f + 32f; float num7 = (float)(centerZone.y - rings) * 64f - 32f; float num8 = (float)(centerZone.y + rings) * 64f + 32f; if (num2 >= num5 && num <= num6 && num4 >= num7) { return num3 <= num8; } return false; } private IEnumerator BakeCell(Vector2Int cell) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) processing = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Bake start cell {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}"); if (clusters.ContainsKey(cell)) { ShowMessage("This cell is already baked"); processing = false; yield break; } if (records.ContainsKey(cell)) { if (!TryLoadClusterCache(cell)) { ShowMessage("Baked cell cache is missing or corrupted"); } processing = false; yield break; } List<(ZNetView, Piece)> list = CollectTargets(cell); int num = list.Count<(ZNetView, Piece)>(((ZNetView view, Piece piece) target) => (Object)(object)target.piece != (Object)null && ((Object)target.piece).name.IndexOf("flametal", StringComparison.OrdinalIgnoreCase) >= 0); int num2 = list.Count<(ZNetView, Piece)>(((ZNetView view, Piece piece) target) => (Object)(object)target.piece != (Object)null && ((Object)target.piece).name.IndexOf("darkwood_roof", StringComparison.OrdinalIgnoreCase) >= 0); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"[TARGET-FILTER] cell {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}: flametal={num}, darkwood_roof={num2}"); if (list.Count == 0) { ShowMessage("No supported building pieces in this cell"); processing = false; yield break; } List list2 = CreateRecords(list); records[cell] = list2; GameObject val = BuildCluster(cell, list, list2); if ((Object)(object)val == (Object)null) { records.Remove(cell); ShowMessage("Failed to create cluster"); processing = false; yield break; } if (!TrySaveClusterCache(cell, val, list2)) { Object.Destroy((Object)(object)val); records.Remove(cell); ShowMessage("Bake cancelled: cluster cache was not saved"); processing = false; yield break; } failedCacheCells.Remove(cell); clusters[cell] = val; EnableGpuBakedRenderTest(cell, list, val); if (!TrySaveGpuCache(cell, list2)) { RemoveGpuBakedCell(cell, restoreRenderers: true); Object.Destroy((Object)(object)val); clusters.Remove(cell); records.Remove(cell); ShowMessage("Bake cancelled: unreadable GPU cache was not saved"); processing = false; yield break; } if (highlightEnabled) { RefreshHighlights(); } foreach (var item in list) { Park(item.Item1, cell); } Physics.SyncTransforms(); supportGuardUntil = Mathf.Max(supportGuardUntil, Time.time + 10f); SaveState(); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Bake complete cell {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}: {list2.Count} ZDO"); ShowMessage($"Baked objects: {list2.Count}"); processing = false; yield return null; } private IEnumerator RebuildParkedCell(Vector2Int cell) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) processing = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Rebuild parked cell {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}"); List existing; int expected = (records.TryGetValue(cell, out existing) ? existing.Count : 0); int num = RestoreRecords(cell, removeRecords: false); if (num != expected) { ((BaseUnityPlugin)this).Logger.LogError((object)$"Rebuild blocked for cell {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}: restored {num}/{expected}"); processing = false; yield break; } List<(ZNetView view, Piece piece)> targets = new List<(ZNetView, Piece)>(); float deadline = Time.time + 180f; while (Time.time < deadline) { targets = CollectMarkedTargets(cell); if (targets.Count >= expected) { break; } yield return null; } if (targets.Count != expected) { ((BaseUnityPlugin)this).Logger.LogError((object)$"Rebuild timed out for cell {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}: loaded {targets.Count}/{expected}"); ShowMessage("Cluster not created: some pieces are not loaded"); processing = false; yield break; } if (targets.Count > 0) { List list = CreateRecords(targets); GameObject val = BuildCluster(cell, targets, list); if ((Object)(object)val != (Object)null && TrySaveClusterCache(cell, val, list)) { records[cell] = list; clusters[cell] = val; failedCacheCells.Remove(cell); if (highlightEnabled) { RefreshHighlights(); } foreach (var item in targets) { Park(item.view, cell); } Physics.SyncTransforms(); supportGuardUntil = Mathf.Max(supportGuardUntil, Time.time + 10f); SaveState(); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Rebuild complete cell {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}: {list.Count} ZDO"); } else { if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } foreach (BakedRecord item2 in existing) { ZDO zDO = ZDOMan.instance.GetZDO(new ZDOID(item2.userId, item2.id)); if (zDO != null) { ClearBakedMetadata(zDO); } } records.Remove(cell); SaveState(); ((BaseUnityPlugin)this).Logger.LogError((object)$"Rebuild cache save failed cell {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}; objects left safely unpacked"); } } processing = false; yield return null; } private IEnumerator UnbakeCell(Vector2Int cell) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) processing = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Unbake cell {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}"); List value; int expected = (records.TryGetValue(cell, out value) ? value.Count : 0); List unbakeRecords = ((value != null) ? value.ToList() : new List()); if (!TryGetValidatedParkedZDOs(cell, out var parked) || parked.Count != expected) { if ((parked == null || parked.Count == 0) && expected > 0 && TryForgetConfirmedRestoredCell(cell, unbakeRecords, out var message)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)$"Safely removed stale cache cell {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}: {message}"); ShowMessage("Stale cache removed; original objects were verified"); processing = false; yield break; } ((BaseUnityPlugin)this).Logger.LogError((object)$"Unbake blocked for cell {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}: validated {parked?.Count ?? 0}/{expected}"); ShowMessage("Unbake blocked: object validation failed"); processing = false; yield break; } float unbakeStarted = Time.realtimeSinceStartup; supportGuardUntil = Mathf.Max(supportGuardUntil, Time.time + 190f); int restored = 0; while (restored < parked.Count) { float realtimeSinceStartup = Time.realtimeSinceStartup; int num = 0; do { ZDO val = parked[restored++]; Vector3 vec = val.GetVec3("PUP_SAFE_Position", Vector3.zero); Quaternion quaternion = val.GetQuaternion("PUP_SAFE_Rotation", Quaternion.identity); val.SetPosition(vec); val.SetRotation(quaternion); ZNetView val2 = ZNetScene.instance.FindInstance(val); if ((Object)(object)val2 != (Object)null) { ((Component)val2).transform.position = vec; ((Component)val2).transform.rotation = quaternion; HideOriginalRenderers(val2); } num++; } while (restored < parked.Count && num < 128 && (Time.realtimeSinceStartup - realtimeSinceStartup) * 1000f < 2f); yield return null; } float deadline = Time.time + 180f; Queue pending = new Queue(unbakeRecords); int loaded = 0; while (pending.Count != 0 && Time.time < deadline) { int num2 = Mathf.Min(256, pending.Count); for (int i = 0; i < num2; i++) { BakedRecord bakedRecord = pending.Dequeue(); ZDO zDO = ZDOMan.instance.GetZDO(new ZDOID(bakedRecord.userId, bakedRecord.id)); ZNetView val3 = ((zDO != null) ? ZNetScene.instance.FindInstance(zDO) : null); if ((Object)(object)val3 != (Object)null) { HideOriginalRenderers(val3); loaded++; } else { pending.Enqueue(bakedRecord); } } yield return null; } if (loaded != expected) { ((BaseUnityPlugin)this).Logger.LogError((object)$"Unbake staging timed out cell {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}: loaded {loaded}/{expected}; cluster retained"); ShowMessage($"Unbake is waiting for pieces: {loaded}/{expected}"); processing = false; yield break; } int cleared = 0; while (cleared < unbakeRecords.Count) { float realtimeSinceStartup2 = Time.realtimeSinceStartup; int num3 = 0; do { BakedRecord bakedRecord2 = unbakeRecords[cleared++]; ZDO zDO2 = ZDOMan.instance.GetZDO(new ZDOID(bakedRecord2.userId, bakedRecord2.id)); if (zDO2 != null) { ClearBakedMetadata(zDO2); } num3++; } while (cleared < unbakeRecords.Count && num3 < 256 && (Time.realtimeSinceStartup - realtimeSinceStartup2) * 1000f < 2f); yield return null; } records.Remove(cell); Physics.SyncTransforms(); supportGuardUntil = Mathf.Max(supportGuardUntil, Time.time + 10f); int shown = 0; while (shown < unbakeRecords.Count) { float realtimeSinceStartup3 = Time.realtimeSinceStartup; int num4 = 0; do { BakedRecord bakedRecord3 = unbakeRecords[shown++]; ZDO zDO3 = ZDOMan.instance.GetZDO(new ZDOID(bakedRecord3.userId, bakedRecord3.id)); ZNetView val4 = ((zDO3 != null) ? ZNetScene.instance.FindInstance(zDO3) : null); if ((Object)(object)val4 != (Object)null) { ShowOriginalRenderers(val4); } num4++; } while (shown < unbakeRecords.Count && num4 < 128 && (Time.realtimeSinceStartup - realtimeSinceStartup3) * 1000f < 2f); yield return null; } DestroyCluster(cell); SaveState(); ((BaseUnityPlugin)this).Logger.LogInfo((object)($"Unbake complete cell {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}: {restored} ZDO in " + $"{Time.realtimeSinceStartup - unbakeStarted:0.00}s")); ShowMessage($"Restored objects: {restored}"); processing = false; yield return null; } private bool TryForgetConfirmedRestoredCell(Vector2Int cell, List cellRecords, out string message) { //IL_018e: 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) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: 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_0276: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) message = ""; if (cellRecords == null || cellRecords.Count == 0 || ZDOMan.instance == null) { return false; } Dictionary dictionary = new Dictionary(StringComparer.Ordinal); Dictionary> dictionary2 = new Dictionary>(StringComparer.Ordinal); ZNetView[] array = Object.FindObjectsByType((FindObjectsSortMode)0); foreach (ZNetView val in array) { if ((Object)(object)val == (Object)null || !val.IsValid() || val.GetZDO() == null || (Object)(object)((Component)val).GetComponent() == (Object)null) { continue; } ZDO zDO = val.GetZDO(); if (!zDO.GetBool("PUP_SAFE_Baked", false) && !(Mathf.Abs(zDO.GetPosition().x - 1900000f) < 1024f)) { string text = zDO.GetString("PUP_GRAUSTEN_ID", ""); if (!string.IsNullOrEmpty(text) && !dictionary.ContainsKey(text)) { dictionary[text] = zDO; } string key = RecordPositionKey(zDO.GetPrefab(), zDO.GetPosition()); if (!dictionary2.TryGetValue(key, out var value)) { value = (dictionary2[key] = new List()); } value.Add(zDO); } } int num = 0; HashSet used = new HashSet(); foreach (BakedRecord record in cellRecords) { ZDO val2 = ZDOMan.instance.GetZDO(new ZDOID(record.userId, record.id)); if (!MatchesRestoredRecord(val2, record) && !string.IsNullOrEmpty(record.customId)) { dictionary.TryGetValue(record.customId, out var value2); val2 = (MatchesRestoredRecord(value2, record) ? value2 : null); } if (!MatchesRestoredRecord(val2, record)) { string key2 = RecordPositionKey(record.prefabHash, record.position); val2 = null; if (dictionary2.TryGetValue(key2, out var value3)) { val2 = ((IEnumerable)value3).FirstOrDefault((Func)((ZDO candidate) => !used.Contains(candidate.m_uid) && MatchesRestoredRecord(candidate, record))); } } if (val2 == null) { message = $"missing exact prefab/position/rotation match {num + 1}/{cellRecords.Count}"; return false; } if (!used.Add(val2.m_uid)) { message = "one ordinary object matched more than one cache record"; return false; } num++; } records.Remove(cell); DestroyCluster(cell); failedCacheCells.Remove(cell); DeleteCellCacheFiles(cell); SaveState(); message = $"verified {num}/{cellRecords.Count} original objects"; return true; } private static bool MatchesRestoredRecord(ZDO zdo, BakedRecord record) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) if (zdo == null || record == null || zdo.GetBool("PUP_SAFE_Baked", false) || zdo.GetPrefab() != record.prefabHash) { return false; } Vector3 position = zdo.GetPosition(); if (!(Mathf.Abs(position.x - 1900000f) < 1024f)) { Vector3 val = position - record.position; if (!(((Vector3)(ref val)).sqrMagnitude > 0.0004f)) { return Quaternion.Angle(zdo.GetRotation(), record.rotation) <= 0.5f; } } return false; } private void DeleteCellCacheFiles(Vector2Int cell) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) string cachePath = GetCachePath(cell); string directoryName = Path.GetDirectoryName(cachePath); string fileName = Path.GetFileName(cachePath); if (string.IsNullOrEmpty(directoryName) || string.IsNullOrEmpty(fileName) || !Directory.Exists(directoryName)) { return; } string[] files = Directory.GetFiles(directoryName, fileName + "*", SearchOption.TopDirectoryOnly); for (int i = 0; i < files.Length; i++) { string fullPath = Path.GetFullPath(files[i]); string fullPath2 = Path.GetFullPath(directoryName); char directorySeparatorChar = Path.DirectorySeparatorChar; if (fullPath.StartsWith(fullPath2 + directorySeparatorChar, StringComparison.OrdinalIgnoreCase)) { try { File.Delete(fullPath); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not delete stale cache file " + Path.GetFileName(fullPath) + ": " + ex.Message)); } } } } private List<(ZNetView view, Piece piece)> CollectTargets(Vector2Int cell) { //IL_0073: 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) List<(ZNetView, Piece)> list = new List<(ZNetView, Piece)>(); ZNetView[] array = Object.FindObjectsByType((FindObjectsSortMode)0); foreach (ZNetView val in array) { if ((Object)(object)val == (Object)null || !val.IsValid() || val.GetZDO() == null || !ZNetScene.instance.HasPrefab(val.GetZDO().GetPrefab())) { continue; } Piece component = ((Component)val).GetComponent(); if (!((Object)(object)component == (Object)null) && ((Component)component).gameObject.activeInHierarchy && !(GetCell(GetPieceCenter(component)) != cell) && !((Object)(object)((Component)component).GetComponent() == (Object)null)) { bool num = HasMaterialGroup(component, 1); bool targetedUnreadable = IsTargetedUnreadablePiece(val); if (num || (IsSafeStaticPiece(component, targetedUnreadable) && HasSupportedRenderer(component))) { list.Add((val, component)); } } } return list; } private List<(ZNetView view, Piece piece)> CollectMarkedTargets(Vector2Int cell) { List<(ZNetView, Piece)> list = new List<(ZNetView, Piece)>(); ZNetView[] array = Object.FindObjectsByType((FindObjectsSortMode)0); foreach (ZNetView val in array) { if ((Object)(object)val == (Object)null || !val.IsValid() || val.GetZDO() == null) { continue; } ZDO zDO = val.GetZDO(); if (zDO.GetBool("PUP_SAFE_Baked", false) && zDO.GetInt("PUP_SAFE_CellX", int.MinValue) == ((Vector2Int)(ref cell)).x && zDO.GetInt("PUP_SAFE_CellZ", int.MinValue) == ((Vector2Int)(ref cell)).y) { Piece component = ((Component)val).GetComponent(); if (!((Object)(object)component == (Object)null) && ((Component)component).gameObject.activeInHierarchy) { list.Add((val, component)); } } } return list; } private static Vector3 GetPieceCenter(Piece piece) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) Renderer[] componentsInChildren = ((Component)piece).GetComponentsInChildren(false); if (componentsInChildren.Length == 0) { return ((Component)piece).transform.position; } Bounds bounds = componentsInChildren[0].bounds; for (int i = 1; i < componentsInChildren.Length; i++) { ((Bounds)(ref bounds)).Encapsulate(componentsInChildren[i].bounds); } return ((Bounds)(ref bounds)).center; } private static int GetMaterialGroup(Material material) { if ((Object)(object)material == (Object)null) { return 0; } string text = NormalizeMaterialName(((Object)material).name); if (text.StartsWith("Grausten_mat", StringComparison.OrdinalIgnoreCase) || text.StartsWith("Grausten_Broken_mat", StringComparison.OrdinalIgnoreCase) || text.Equals("Grausten_RoofSlab_mat", StringComparison.OrdinalIgnoreCase)) { return 1; } if (text.Equals("woodpole", StringComparison.OrdinalIgnoreCase) || text.Equals("woodpole2", StringComparison.OrdinalIgnoreCase) || text.Equals("woodpole_worn", StringComparison.OrdinalIgnoreCase) || text.Equals("woodwall", StringComparison.OrdinalIgnoreCase) || text.Equals("woodwall_lowlod", StringComparison.OrdinalIgnoreCase) || text.Equals("woodwall_worn", StringComparison.OrdinalIgnoreCase) || text.Equals("woodwall_worn_lowlod", StringComparison.OrdinalIgnoreCase) || text.Equals("stake", StringComparison.OrdinalIgnoreCase) || text.Equals("stake_old", StringComparison.OrdinalIgnoreCase)) { return 2; } if ((text.StartsWith("DarkWood_", StringComparison.OrdinalIgnoreCase) || text.Equals("DarkWood_mat", StringComparison.OrdinalIgnoreCase) || text.Equals("RoofShingles", StringComparison.OrdinalIgnoreCase)) && text.IndexOf("door", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("gate", StringComparison.OrdinalIgnoreCase) < 0) { return 3; } if (text.StartsWith("AshWood_", StringComparison.OrdinalIgnoreCase) && text.IndexOf("door", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("gate", StringComparison.OrdinalIgnoreCase) < 0) { return 4; } if (text.Equals("logwall", StringComparison.OrdinalIgnoreCase) || text.Equals("logwall_broken", StringComparison.OrdinalIgnoreCase) || text.Equals("logwall_worn", StringComparison.OrdinalIgnoreCase) || text.Equals("finewood_log", StringComparison.OrdinalIgnoreCase) || text.Equals("roundlog_new", StringComparison.OrdinalIgnoreCase)) { return 5; } if (text.Equals("straw_roof", StringComparison.OrdinalIgnoreCase) || text.Equals("straw_roof_alpha", StringComparison.OrdinalIgnoreCase) || text.Equals("straw_roof_corner_alpha", StringComparison.OrdinalIgnoreCase) || text.Equals("straw_roof_worn", StringComparison.OrdinalIgnoreCase) || text.Equals("straw_roof_worn_alpha", StringComparison.OrdinalIgnoreCase)) { return 6; } if (text.Equals("stone_mat", StringComparison.OrdinalIgnoreCase) || text.Equals("stone_mat_4x2", StringComparison.OrdinalIgnoreCase) || text.Equals("stonefloor", StringComparison.OrdinalIgnoreCase) || text.Equals("stonefloor_2x2", StringComparison.OrdinalIgnoreCase) || text.Equals("stone_stairs", StringComparison.OrdinalIgnoreCase) || text.Equals("stone", StringComparison.OrdinalIgnoreCase)) { return 7; } if (text.Equals("blackmarble", StringComparison.OrdinalIgnoreCase)) { return 8; } if (text.Equals("dvergr_copper", StringComparison.OrdinalIgnoreCase)) { return 9; } if (text.Equals("flametalbeam_mat", StringComparison.OrdinalIgnoreCase)) { return 10; } if (text.Equals("crystal_window", StringComparison.OrdinalIgnoreCase) || text.Equals("crystal_window_lod", StringComparison.OrdinalIgnoreCase)) { return 11; } return 0; } private static bool HasSupportedRenderer(Piece piece) { return ((Component)piece).GetComponentsInChildren(false).Any((MeshRenderer renderer) => ((Renderer)renderer).sharedMaterials.Any((Material material) => GetMaterialGroup(material) != 0)); } private static bool HasMaterialGroup(Piece piece, int group) { return ((Component)piece).GetComponentsInChildren(false).Any((MeshRenderer renderer) => ((Renderer)renderer).sharedMaterials.Any((Material material) => GetMaterialGroup(material) == group)); } private static bool IsTargetedUnreadablePiece(ZNetView view) { if ((Object)(object)view == (Object)null || view.GetZDO() == null || (Object)(object)ZNetScene.instance == (Object)null) { return false; } GameObject prefab = ZNetScene.instance.GetPrefab(view.GetZDO().GetPrefab()); if ((Object)(object)prefab == (Object)null) { return false; } string text = ((Object)prefab).name ?? ""; if (!text.StartsWith("Piece_flametal_", StringComparison.OrdinalIgnoreCase) && !text.Equals("darkwood_roof", StringComparison.OrdinalIgnoreCase) && !text.Equals("darkwood_roof_45", StringComparison.OrdinalIgnoreCase) && !text.Equals("darkwood_roof_top", StringComparison.OrdinalIgnoreCase)) { return text.Equals("darkwood_roof_top_45", StringComparison.OrdinalIgnoreCase); } return true; } private static bool IsSafeStaticPiece(Piece piece, bool targetedUnreadable) { if ((Object)(object)piece == (Object)null || (Object)(object)((Component)piece).GetComponent() == (Object)null) { return false; } if (((Component)piece).GetComponentsInChildren(true).Length != 0) { return false; } Rigidbody[] componentsInChildren = ((Component)piece).GetComponentsInChildren(true); foreach (Rigidbody val in componentsInChildren) { if ((Object)(object)val != (Object)null && !val.isKinematic) { return false; } } string[] source = new string[17] { "Door", "Container", "CraftingStation", "Fermenter", "Smelter", "Fireplace", "Bed", "Chair", "Ship", "TeleportWorld", "ItemStand", "ArmorStand", "Switch", "Lever", "Sign", "Beehive", "SapCollector" }; Component[] componentsInChildren2 = ((Component)piece).GetComponentsInChildren(true); foreach (Component val2 in componentsInChildren2) { if (!((Object)(object)val2 == (Object)null)) { string typeName = ((object)val2).GetType().Name; if (source.Any((string value) => typeName.Equals(value, StringComparison.OrdinalIgnoreCase))) { return false; } } } MeshRenderer[] componentsInChildren3 = ((Component)piece).GetComponentsInChildren(false); foreach (MeshRenderer val3 in componentsInChildren3) { Material[] sharedMaterials = ((Renderer)val3).sharedMaterials; if (sharedMaterials.Length == 0 || sharedMaterials.Any((Material value) => (Object)(object)value == (Object)null)) { return false; } if (!targetedUnreadable && sharedMaterials.Any((Material value) => NormalizeMaterialName(((Object)value).name).Equals("RoofShingles", StringComparison.OrdinalIgnoreCase))) { return false; } MeshFilter component = ((Component)val3).GetComponent(); if ((Object)(object)component == (Object)null || (Object)(object)component.sharedMesh == (Object)null) { return false; } if (!targetedUnreadable && !component.sharedMesh.isReadable) { return false; } if ((!targetedUnreadable && ((Renderer)val3).sharedMaterials.Length != component.sharedMesh.subMeshCount) || (targetedUnreadable && ((Renderer)val3).sharedMaterials.Length < component.sharedMesh.subMeshCount)) { return false; } } return true; } private List CreateRecords(List<(ZNetView view, Piece piece)> targets) { //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) List list = new List(); foreach (var target in targets) { ZDO zDO = target.view.GetZDO(); string text = zDO.GetString("PUP_GRAUSTEN_ID", ""); if (string.IsNullOrEmpty(text)) { text = "PUP_GRAUSTEN_" + Guid.NewGuid().ToString("N"); zDO.Set("PUP_GRAUSTEN_ID", text); } list.Add(new BakedRecord { customId = text, userId = ((ZDOID)(ref zDO.m_uid)).UserID, id = ((ZDOID)(ref zDO.m_uid)).ID, prefabHash = zDO.GetPrefab(), position = ((Component)target.piece).transform.position, rotation = ((Component)target.piece).transform.rotation, scale = ((Component)target.piece).transform.localScale }); } return list; } private GameObject BuildCluster(Vector2Int cell, List<(ZNetView view, Piece piece)> targets, List cellRecords) { //IL_0033: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_0062: 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_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: Expected O, but got Unknown //IL_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_038f: Unknown result type (might be due to invalid IL or missing references) //IL_0394: Unknown result type (might be due to invalid IL or missing references) //IL_039d: Expected O, but got Unknown //IL_03c4: Unknown result type (might be due to invalid IL or missing references) //IL_03d5: Unknown result type (might be due to invalid IL or missing references) //IL_03df: Unknown result type (might be due to invalid IL or missing references) //IL_0452: Unknown result type (might be due to invalid IL or missing references) //IL_0457: Unknown result type (might be due to invalid IL or missing references) //IL_0460: Expected O, but got Unknown //IL_0480: Unknown result type (might be due to invalid IL or missing references) //IL_0485: Unknown result type (might be due to invalid IL or missing references) //IL_0495: Unknown result type (might be due to invalid IL or missing references) //IL_049a: Unknown result type (might be due to invalid IL or missing references) //IL_04ad: Unknown result type (might be due to invalid IL or missing references) //IL_04b2: Unknown result type (might be due to invalid IL or missing references) //IL_04c5: Unknown result type (might be due to invalid IL or missing references) //IL_04e8: Unknown result type (might be due to invalid IL or missing references) //IL_055f: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) Dictionary> dictionary = new Dictionary>(); List list = new List(); List list2 = new List(); Matrix4x4 val = Matrix4x4.Translate(-new Vector3((float)((Vector2Int)(ref cell)).x * 64f, 0f, (float)((Vector2Int)(ref cell)).y * 64f)); Vector2Int key = default(Vector2Int); CombineInstance item; foreach (var target in targets) { Vector3 pieceCenter = GetPieceCenter(target.piece); int num = Mathf.Clamp(Mathf.FloorToInt((pieceCenter.x - (float)((Vector2Int)(ref cell)).x * 64f) / 16f), 0, 3); int num2 = Mathf.Clamp(Mathf.FloorToInt((pieceCenter.z - (float)((Vector2Int)(ref cell)).y * 64f) / 16f), 0, 3); ((Vector2Int)(ref key))..ctor(num, num2); if (!dictionary.TryGetValue(key, out var value)) { value = (dictionary[key] = new Dictionary(StringComparer.Ordinal)); } MeshFilter[] componentsInChildren = ((Component)target.piece).GetComponentsInChildren(false); foreach (MeshFilter val2 in componentsInChildren) { MeshRenderer component = ((Component)val2).GetComponent(); if ((Object)(object)component == (Object)null || !((Renderer)component).enabled || (Object)(object)val2.sharedMesh == (Object)null || (((Renderer)component).sharedMaterials.Length != 0 && ((Renderer)component).sharedMaterials.All((Material material) => (Object)(object)material != (Object)null && NormalizeMaterialName(((Object)material).name).Equals("crystal_window_lod", StringComparison.OrdinalIgnoreCase))) || !val2.sharedMesh.isReadable) { continue; } Mesh val3 = Object.Instantiate(val2.sharedMesh); list.Add(val3); for (int num3 = 0; num3 < val3.subMeshCount && num3 < ((Renderer)component).sharedMaterials.Length; num3++) { Material val4 = ((Renderer)component).sharedMaterials[num3]; if (!((Object)(object)val4 == (Object)null)) { string key2 = NormalizeMaterialName(((Object)val4).name); if (!value.TryGetValue(key2, out var value2)) { MaterialCombineGroup obj = new MaterialCombineGroup { source = val4 }; value2 = (value[key2] = obj); } List parts = value2.parts; item = default(CombineInstance); ((CombineInstance)(ref item)).mesh = val3; ((CombineInstance)(ref item)).subMeshIndex = num3; ((CombineInstance)(ref item)).transform = val * ((Component)val2).transform.localToWorldMatrix; parts.Add(item); } } } } if (dictionary.Count == 0) { foreach (Mesh item2 in list) { Object.Destroy((Object)(object)item2); } return null; } GameObject val5 = new GameObject($"PUP_SafeCluster_{((Vector2Int)(ref cell)).x}_{((Vector2Int)(ref cell)).y}"); val5.transform.position = new Vector3((float)((Vector2Int)(ref cell)).x * 64f, 0f, (float)((Vector2Int)(ref cell)).y * 64f); foreach (KeyValuePair> item3 in dictionary.OrderBy(delegate(KeyValuePair> keyValuePair) { //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) Vector2Int key4 = keyValuePair.Key; return ((Vector2Int)(ref key4)).y; }).ThenBy(delegate(KeyValuePair> keyValuePair) { //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) Vector2Int key4 = keyValuePair.Key; return ((Vector2Int)(ref key4)).x; })) { List list3 = new List(); List list4 = new List(); foreach (KeyValuePair item4 in item3.Value) { Mesh val6 = new Mesh { indexFormat = (IndexFormat)1 }; val6.CombineMeshes(item4.Value.parts.ToArray(), true, true, false); list.Add(val6); item = default(CombineInstance); ((CombineInstance)(ref item)).mesh = val6; ((CombineInstance)(ref item)).transform = Matrix4x4.identity; list3.Add(item); if (!materialCopies.TryGetValue(item4.Key, out var value3) || (Object)(object)value3 == (Object)null) { value3 = Object.Instantiate(item4.Value.source); materialCopies[item4.Key] = value3; } list4.Add(value3); } Mesh val7 = new Mesh { indexFormat = (IndexFormat)1 }; val7.CombineMeshes(list3.ToArray(), false, false, false); list2.Add(val7); Vector2Int key3 = item3.Key; object arg = ((Vector2Int)(ref key3)).x; key3 = item3.Key; GameObject val8 = new GameObject($"PUP_SubCluster_{arg}_{((Vector2Int)(ref key3)).y}"); val8.transform.SetParent(val5.transform, false); val8.AddComponent().sharedMesh = val7; MeshRenderer val9 = val8.AddComponent(); ((Renderer)val9).sharedMaterials = list4.ToArray(); RegisterPrecipitationRenderer(cell, val9); } CloneOriginalColliders(val5, targets); BuildShadowProxies(val5, targets, list2); foreach (Mesh item5 in list) { if ((Object)(object)item5 != (Object)null) { Object.Destroy((Object)(object)item5); } } generatedMeshes[cell] = list2; return val5; } private void BuildShadowProxies(GameObject root, List<(ZNetView view, Piece piece)> targets, List finalMeshes) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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_0090: 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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: 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_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: 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_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Expected O, but got Unknown //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //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_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) Mesh builtinResource = Resources.GetBuiltinResource("Cube.fbx"); if ((Object)(object)builtinResource == (Object)null) { return; } Dictionary> dictionary = new Dictionary>(); Matrix4x4 worldToLocalMatrix = root.transform.worldToLocalMatrix; Material val = null; Vector2Int key = default(Vector2Int); foreach (var target in targets) { BoxCollider[] componentsInChildren = ((Component)target.piece).GetComponentsInChildren(false); foreach (BoxCollider val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)null || !((Collider)val2).enabled || ((Collider)val2).isTrigger) { continue; } Vector3 val3 = Vector3.Scale(val2.size, ((Component)val2).transform.lossyScale); if (val3.x * val3.y * val3.z < 0.2f) { continue; } Vector3 val4 = ((Component)val2).transform.TransformPoint(val2.center); int num = Mathf.Clamp(Mathf.FloorToInt((val4.x - root.transform.position.x) / 16f), 0, 3); int num2 = Mathf.Clamp(Mathf.FloorToInt((val4.z - root.transform.position.z) / 16f), 0, 3); ((Vector2Int)(ref key))..ctor(num, num2); if (!dictionary.TryGetValue(key, out var value)) { value = (dictionary[key] = new List()); } List list2 = value; CombineInstance item = default(CombineInstance); ((CombineInstance)(ref item)).mesh = builtinResource; ((CombineInstance)(ref item)).subMeshIndex = 0; ((CombineInstance)(ref item)).transform = worldToLocalMatrix * Matrix4x4.TRS(val4, ((Component)val2).transform.rotation, val3); list2.Add(item); if ((Object)(object)val == (Object)null) { MeshRenderer componentInChildren = ((Component)target.piece).GetComponentInChildren(false); if ((Object)(object)componentInChildren != (Object)null) { val = ((Renderer)componentInChildren).sharedMaterial; } } } } if ((Object)(object)val == (Object)null) { return; } Vector2Int val6; foreach (KeyValuePair> item2 in dictionary) { if (item2.Value.Count != 0) { Mesh val5 = new Mesh { indexFormat = (IndexFormat)1 }; val5.CombineMeshes(item2.Value.ToArray(), true, true, false); finalMeshes.Add(val5); val6 = item2.Key; object arg = ((Vector2Int)(ref val6)).x; val6 = item2.Key; GameObject val7 = new GameObject($"PUP_ShadowProxy_{arg}_{((Vector2Int)(ref val6)).y}"); val7.transform.SetParent(root.transform, false); val7.AddComponent().sharedMesh = val5; MeshRenderer obj = val7.AddComponent(); ((Renderer)obj).sharedMaterial = val; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)3; ((Renderer)obj).receiveShadows = false; } } ManualLogSource logger = ((BaseUnityPlugin)this).Logger; val6 = GetCell(root.transform.position); string text = $"[SHADOW-PROXY] cell {((Vector2Int)(ref val6)).x},"; val6 = GetCell(root.transform.position); logger.LogInfo((object)(text + $"{((Vector2Int)(ref val6)).y}: {dictionary.Sum((KeyValuePair> keyValuePair) => keyValuePair.Value.Count)} boxes, " + $"{dictionary.Count} proxy meshes")); } private static void CloneOriginalColliders(GameObject root, List<(ZNetView view, Piece piece)> targets) { foreach (var target in targets) { Collider[] componentsInChildren = ((Component)target.piece).GetComponentsInChildren(false); foreach (Collider val in componentsInChildren) { if ((Object)(object)val != (Object)null && val.enabled) { CloneSingleCollider(root, val); } } } } private static void CloneSingleCollider(GameObject root, Collider source) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("PUP_Collider") { layer = ((Component)source).gameObject.layer }; val.transform.SetParent(root.transform, false); val.transform.position = ((Component)source).transform.position; val.transform.rotation = ((Component)source).transform.rotation; val.transform.localScale = ((Component)source).transform.lossyScale; Collider val2 = null; BoxCollider val3 = (BoxCollider)(object)((source is BoxCollider) ? source : null); if (val3 != null) { BoxCollider obj = val.AddComponent(); obj.center = val3.center; obj.size = val3.size; val2 = (Collider)(object)obj; } else { SphereCollider val4 = (SphereCollider)(object)((source is SphereCollider) ? source : null); if (val4 != null) { SphereCollider obj2 = val.AddComponent(); obj2.center = val4.center; obj2.radius = val4.radius; val2 = (Collider)(object)obj2; } else { CapsuleCollider val5 = (CapsuleCollider)(object)((source is CapsuleCollider) ? source : null); if (val5 != null) { CapsuleCollider obj3 = val.AddComponent(); obj3.center = val5.center; obj3.radius = val5.radius; obj3.height = val5.height; obj3.direction = val5.direction; val2 = (Collider)(object)obj3; } else { MeshCollider val6 = (MeshCollider)(object)((source is MeshCollider) ? source : null); if (val6 != null && (Object)(object)val6.sharedMesh != (Object)null) { MeshCollider obj4 = val.AddComponent(); obj4.sharedMesh = val6.sharedMesh; obj4.convex = val6.convex; val2 = (Collider)(object)obj4; } } } } if ((Object)(object)val2 == (Object)null) { Object.Destroy((Object)(object)val); return; } val2.isTrigger = source.isTrigger; val2.sharedMaterial = source.sharedMaterial; } private void Park(ZNetView view, Vector2Int cell) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)view == (Object)null) && view.GetZDO() != null) { ZDO zDO = view.GetZDO(); zDO.Set("PUP_SAFE_Baked", true); zDO.Set("PUP_SAFE_Position", ((Component)view).transform.position); zDO.Set("PUP_SAFE_Rotation", ((Component)view).transform.rotation); zDO.Set("PUP_SAFE_Scale", ((Component)view).transform.localScale); zDO.Set("PUP_SAFE_CellX", ((Vector2Int)(ref cell)).x); zDO.Set("PUP_SAFE_CellZ", ((Vector2Int)(ref cell)).y); uint iD = ((ZDOID)(ref zDO.m_uid)).ID; float num = 1900000f + (float)(iD % 200) * 0.05f; float num2 = 1900000f + (float)(iD / 200 % 200) * 0.05f; Vector3 position = default(Vector3); ((Vector3)(ref position))..ctor(num, ((Component)view).transform.position.y, num2); zDO.SetPosition(position); ((Component)view).transform.position = position; } } private int RestoreRecords(Vector2Int cell, bool removeRecords) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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) //IL_0045: 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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) if (!TryGetValidatedParkedZDOs(cell, out var parked)) { return 0; } int num = 0; foreach (ZDO item in parked) { Vector3 vec = item.GetVec3("PUP_SAFE_Position", Vector3.zero); Quaternion quaternion = item.GetQuaternion("PUP_SAFE_Rotation", Quaternion.identity); item.SetPosition(vec); item.SetRotation(quaternion); ZNetView val = ZNetScene.instance.FindInstance(item); if ((Object)(object)val != (Object)null) { ((Component)val).transform.position = vec; ((Component)val).transform.rotation = quaternion; ShowOriginalRenderers(val); } if (removeRecords) { ClearBakedMetadata(item); } num++; } if (removeRecords) { records.Remove(cell); } return num; } private bool TryGetValidatedParkedZDOs(Vector2Int cell, out List parked) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) parked = DiscoverTaggedZDOs(cell); if (parked.Count == 0) { return false; } if (records.TryGetValue(cell, out var value) && value.Count != parked.Count) { ((BaseUnityPlugin)this).Logger.LogError((object)$"Restore count mismatch in cell {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}: {parked.Count}/{value.Count}"); return false; } HashSet hashSet = new HashSet(); foreach (ZDO item in parked) { string text = item.GetString("PUP_GRAUSTEN_ID", ""); if (!text.StartsWith("PUP_GRAUSTEN_", StringComparison.Ordinal)) { ((BaseUnityPlugin)this).Logger.LogError((object)$"Restore validation failed in cell {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}: invalid custom ID"); return false; } if (!hashSet.Add(text)) { ((BaseUnityPlugin)this).Logger.LogError((object)$"Restore validation failed in cell {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}: duplicate custom ID {text}"); return false; } if (!ZNetScene.instance.HasPrefab(item.GetPrefab())) { ((BaseUnityPlugin)this).Logger.LogError((object)$"Restore validation failed in cell {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}: prefab unavailable for {text}"); return false; } } if (!RebindCellRecordIds(cell, parked)) { ((BaseUnityPlugin)this).Logger.LogError((object)$"Restore validation failed in cell {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}: ID rebinding failed"); return false; } return true; } private List GetBakedZDOs(Vector2Int cell) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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) if (!records.TryGetValue(cell, out var value)) { return new List(); } return (from record in value select ZDOMan.instance.GetZDO(new ZDOID(record.userId, record.id)) into zdo where zdo != null && zdo.GetBool("PUP_SAFE_Baked", false) && zdo.GetInt("PUP_SAFE_CellX", int.MinValue) == ((Vector2Int)(ref cell)).x && zdo.GetInt("PUP_SAFE_CellZ", int.MinValue) == ((Vector2Int)(ref cell)).y select zdo).ToList(); } private void HideOriginalRenderers(ZNetView view) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)view == (Object)null || view.GetZDO() == null) { return; } ZDOID uid = view.GetZDO().m_uid; if (!hiddenRenderers.TryGetValue(uid, out var value)) { value = (from renderer in ((Component)view).GetComponentsInChildren(true) where (Object)(object)renderer != (Object)null && ((Renderer)renderer).enabled select renderer).ToList(); hiddenRenderers[uid] = value; } MeshRenderer[] componentsInChildren = ((Component)view).GetComponentsInChildren(true); foreach (MeshRenderer val in componentsInChildren) { if ((Object)(object)val != (Object)null) { ((Renderer)val).enabled = false; } } if (!hiddenLodGroups.TryGetValue(uid, out var value2)) { value2 = (from @group in ((Component)view).GetComponentsInChildren(true) where (Object)(object)@group != (Object)null && @group.enabled select @group).ToList(); hiddenLodGroups[uid] = value2; } LODGroup[] componentsInChildren2 = ((Component)view).GetComponentsInChildren(true); foreach (LODGroup val2 in componentsInChildren2) { if ((Object)(object)val2 != (Object)null) { val2.enabled = false; } } foreach (MeshRenderer item in value) { if ((Object)(object)item != (Object)null) { ((Renderer)item).enabled = false; } } } private void ShowOriginalRenderers(ZNetView view) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)view == (Object)null || view.GetZDO() == null) { return; } ZDOID uid = view.GetZDO().m_uid; if (!hiddenRenderers.TryGetValue(uid, out var value)) { return; } foreach (MeshRenderer item in value) { if ((Object)(object)item != (Object)null) { ((Renderer)item).enabled = true; } } hiddenRenderers.Remove(uid); if (!hiddenLodGroups.TryGetValue(uid, out var value2)) { return; } foreach (LODGroup item2 in value2) { if ((Object)(object)item2 != (Object)null) { item2.enabled = true; } } hiddenLodGroups.Remove(uid); } private List GetParkedZDOs(Vector2Int cell) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return GetBakedZDOs(cell); } private List DiscoverTaggedZDOs(Vector2Int cell) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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_0079: 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_0083: 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_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) Dictionary found = new Dictionary(); Action action = delegate(ZDO zdo) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) if (zdo != null && zdo.GetBool("PUP_SAFE_Baked", false) && zdo.GetInt("PUP_SAFE_CellX", int.MinValue) == ((Vector2Int)(ref cell)).x && zdo.GetInt("PUP_SAFE_CellZ", int.MinValue) == ((Vector2Int)(ref cell)).y && zdo.GetString("PUP_GRAUSTEN_ID", "").StartsWith("PUP_GRAUSTEN_", StringComparison.Ordinal)) { found[zdo.m_uid] = zdo; } }; foreach (ZDO bakedZDO in GetBakedZDOs(cell)) { action(bakedZDO); } List list = new List(); Vector2i zone = ZoneSystem.GetZone(new Vector3(1900000f, 0f, 1900000f)); ZDOMan.instance.FindSectorObjects(zone, 0, 0, list, (List)null); foreach (ZDO item in list) { action(item); } if (records.TryGetValue(cell, out var value)) { foreach (Vector2i item2 in new HashSet(value.Select((BakedRecord record) => ZoneSystem.GetZone(record.position)))) { list.Clear(); ZDOMan.instance.FindSectorObjects(item2, 0, 0, list, (List)null); foreach (ZDO item3 in list) { action(item3); } } } ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Restore discovery cell {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}: {found.Count} self-tagged ZDO"); return found.Values.ToList(); } private static string RecordPositionKey(int prefabHash, Vector3 position) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) return string.Join("|", prefabHash.ToString(CultureInfo.InvariantCulture), Mathf.RoundToInt(position.x * 100f).ToString(CultureInfo.InvariantCulture), Mathf.RoundToInt(position.y * 100f).ToString(CultureInfo.InvariantCulture), Mathf.RoundToInt(position.z * 100f).ToString(CultureInfo.InvariantCulture)); } private bool RebindCellRecordIds(Vector2Int cell, List discovered) { //IL_0006: 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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) if (!records.TryGetValue(cell, out var value) || value.Count != discovered.Count) { return false; } Dictionary> dictionary = new Dictionary>(); foreach (ZDO item in discovered) { string key = RecordPositionKey(item.GetPrefab(), item.GetVec3("PUP_SAFE_Position", item.GetPosition())); if (!dictionary.TryGetValue(key, out var value2)) { value2 = (dictionary[key] = new Queue()); } value2.Enqueue(item); } int num = 0; foreach (BakedRecord item2 in value) { string key2 = RecordPositionKey(item2.prefabHash, item2.position); if (!dictionary.TryGetValue(key2, out var value3) || value3.Count == 0) { return false; } ZDO val = value3.Dequeue(); if (item2.userId != ((ZDOID)(ref val.m_uid)).UserID || item2.id != ((ZDOID)(ref val.m_uid)).ID) { num++; } item2.userId = ((ZDOID)(ref val.m_uid)).UserID; item2.id = ((ZDOID)(ref val.m_uid)).ID; item2.customId = val.GetString("PUP_GRAUSTEN_ID", ""); } if (dictionary.Values.Any((Queue queue2) => queue2.Count != 0)) { return false; } if (num > 0) { ((BaseUnityPlugin)this).Logger.LogWarning((object)$"Rebound {num} changed ZDO IDs in cell {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}"); } return true; } private bool ValidateCellRecords(Vector2Int cell, out string error) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) error = ""; if (!records.TryGetValue(cell, out var value) || value.Count == 0) { error = "records missing"; return false; } foreach (BakedRecord item in value) { ZDO zDO = ZDOMan.instance.GetZDO(new ZDOID(item.userId, item.id)); if (zDO == null) { error = $"ZDO missing {item.userId}:{item.id}"; return false; } if (zDO.GetPrefab() != item.prefabHash) { error = $"prefab mismatch {item.userId}:{item.id}"; return false; } if (!zDO.GetBool("PUP_SAFE_Baked", false)) { error = $"baked marker missing {item.userId}:{item.id}"; return false; } if (zDO.GetInt("PUP_SAFE_CellX", int.MinValue) != ((Vector2Int)(ref cell)).x || zDO.GetInt("PUP_SAFE_CellZ", int.MinValue) != ((Vector2Int)(ref cell)).y) { error = $"cell marker mismatch {item.userId}:{item.id}"; return false; } Vector3 val = zDO.GetVec3("PUP_SAFE_Position", new Vector3(float.MaxValue, 0f, 0f)) - item.position; if (((Vector3)(ref val)).sqrMagnitude > 0.0001f) { error = $"position marker mismatch {item.userId}:{item.id}"; return false; } } return true; } private static void ClearBakedMetadata(ZDO zdo) { zdo.RemoveInt("PUP_SAFE_Baked"); zdo.RemoveVec3("PUP_SAFE_Position"); zdo.RemoveQuaternion("PUP_SAFE_Rotation"); zdo.RemoveVec3("PUP_SAFE_Scale"); zdo.RemoveInt("PUP_SAFE_CellX"); zdo.RemoveInt("PUP_SAFE_CellZ"); } private IEnumerator RestoreAllParked() { processing = true; supportGuardUntil = Mathf.Max(supportGuardUntil, Time.time + 10f); ((BaseUnityPlugin)this).Logger.LogWarning((object)"Emergency restore started"); ((BaseUnityPlugin)this).Logger.LogWarning((object)"Emergency support guard enabled for the complete restore"); List list = records.Keys.ToList(); int total = 0; int cleanedStale = 0; int blocked = 0; foreach (Vector2Int item in list) { Vector2Int current = item; if (!records.TryGetValue(current, out var value)) { continue; } int count = value.Count; string message; if (TryGetValidatedParkedZDOs(current, out var parked) && parked.Count == count) { int num = RestoreRecords(current, removeRecords: false); if (num == count) { foreach (BakedRecord item2 in value) { ZDO zDO = ZDOMan.instance.GetZDO(new ZDOID(item2.userId, item2.id)); if (zDO != null) { ClearBakedMetadata(zDO); } } records.Remove(current); DestroyCluster(current); DeleteCellCacheFiles(current); total += num; ((BaseUnityPlugin)this).Logger.LogWarning((object)$"Emergency restore verified cell {((Vector2Int)(ref current)).x},{((Vector2Int)(ref current)).y}: {num}/{count}"); } else { blocked++; ((BaseUnityPlugin)this).Logger.LogError((object)$"Emergency restore blocked cell {((Vector2Int)(ref current)).x},{((Vector2Int)(ref current)).y}: {num}/{count}"); } } else if ((parked == null || parked.Count == 0) && TryForgetConfirmedRestoredCell(current, value.ToList(), out message)) { cleanedStale++; ((BaseUnityPlugin)this).Logger.LogWarning((object)$"Emergency cleanup verified stale cell {((Vector2Int)(ref current)).x},{((Vector2Int)(ref current)).y}: {message}"); } else { blocked++; ((BaseUnityPlugin)this).Logger.LogError((object)($"Emergency restore blocked cell {((Vector2Int)(ref current)).x},{((Vector2Int)(ref current)).y}: " + $"{parked?.Count ?? 0}/{count}; cache preserved")); } yield return null; } Physics.SyncTransforms(); supportGuardUntil = Mathf.Max(supportGuardUntil, Time.time + 10f); SaveState(); ShowMessage($"Emergency restore: {total} objects, {cleanedStale} stale zones, {blocked} blocked"); ((BaseUnityPlugin)this).Logger.LogWarning((object)($"Emergency restore complete: restored={total}, staleCleaned={cleanedStale}, " + $"blocked={blocked}; support guard remains active for 10 seconds")); processing = false; } private Vector2Int? FindNearestBakedCell(Vector3 position, float maxDistance) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_001b: 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_0062: 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_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: 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) Vector2Int cell = GetCell(position); if (records.ContainsKey(cell) || clusters.ContainsKey(cell)) { return cell; } float num = maxDistance * maxDistance; Vector2Int? result = null; foreach (Vector2Int item in records.Keys.Union(clusters.Keys)) { Vector2Int current = item; float num2 = (float)((Vector2Int)(ref current)).x * 64f; float num3 = num2 + 64f; float num4 = (float)((Vector2Int)(ref current)).y * 64f; float num5 = num4 + 64f; float num6 = ((position.x < num2) ? (num2 - position.x) : ((position.x > num3) ? (position.x - num3) : 0f)); float num7 = ((position.z < num4) ? (num4 - position.z) : ((position.z > num5) ? (position.z - num5) : 0f)); float num8 = num6 * num6 + num7 * num7; if (num8 < num) { num = num8; result = current; } } return result; } private void DestroyCluster(Vector2Int cell) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001b: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) RemoveGpuBakedCell(cell, restoreRenderers: false); precipitationRenderers.Remove(cell); if (clusters.TryGetValue(cell, out var value) && (Object)(object)value != (Object)null) { Object.Destroy((Object)(object)value); } clusters.Remove(cell); if (!generatedMeshes.TryGetValue(cell, out var value2)) { return; } foreach (Mesh item in value2) { if ((Object)(object)item != (Object)null) { Object.Destroy((Object)(object)item); } } generatedMeshes.Remove(cell); } private void RefreshHighlights() { ClearHighlightOverlay(); if (!highlightEnabled) { return; } foreach (KeyValuePair cluster in clusters) { if ((Object)(object)cluster.Value != (Object)null) { AddMaterialHighlights(cluster.Value); } } } private Material GetHighlightMaterial(int group) { //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Expected O, but got Unknown //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) if (highlightMaterials.TryGetValue(group, out var value) && (Object)(object)value != (Object)null) { return value; } Color color = (Color)(group switch { 10 => new Color(1f, 0.24f, 0.04f, 0.42f), 9 => new Color(0.1f, 0.9f, 0.82f, 0.42f), 8 => new Color(1f, 0.08f, 0.35f, 0.42f), 7 => new Color(0.65f, 0.68f, 0.72f, 0.42f), 6 => new Color(0.95f, 0.7f, 0.25f, 0.42f), 5 => new Color(1f, 0.85f, 0.05f, 0.42f), 4 => new Color(1f, 0.42f, 0.05f, 0.42f), 3 => new Color(0.65f, 0.15f, 1f, 0.42f), 2 => new Color(0.1f, 1f, 0.25f, 0.42f), 1 => new Color(0.05f, 0.45f, 1f, 0.42f), _ => new Color(0.48f, 0.25f, 0.1f, 0.42f), }); Material val = new Material(Shader.Find("Hidden/Internal-Colored") ?? Shader.Find("Sprites/Default")) { color = color }; val.SetInt("_SrcBlend", 5); val.SetInt("_DstBlend", 10); val.SetInt("_Cull", 0); val.SetInt("_ZWrite", 0); val.SetInt("_ZTest", 8); val.renderQueue = 5000; highlightMaterials[group] = val; return val; } private void AddMaterialHighlights(GameObject root) { //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: 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) MeshFilter[] array = (from value in root.GetComponentsInChildren(false) where (Object)(object)value != (Object)null && ((Object)((Component)value).gameObject).name != "PUP_MaterialHighlight" select value).ToArray(); foreach (MeshFilter val in array) { MeshRenderer component = ((Component)val).GetComponent(); if (!((Object)(object)val.sharedMesh == (Object)null) && !((Object)(object)component == (Object)null)) { int fallbackGroup = ((Renderer)component).sharedMaterials.Select(GetMaterialGroup).FirstOrDefault((int value) => value != 0); if (fallbackGroup == 0) { fallbackGroup = 1; } Material[] sharedMaterials = ((Renderer)component).sharedMaterials.Select(delegate(Material value) { int materialGroup = GetMaterialGroup(value); return GetHighlightMaterial((materialGroup != 0) ? materialGroup : fallbackGroup); }).ToArray(); GameObject val2 = new GameObject("PUP_MaterialHighlight"); val2.transform.SetParent(((Component)val).transform, false); val2.AddComponent().sharedMesh = val.sharedMesh; ((Renderer)val2.AddComponent()).sharedMaterials = sharedMaterials; } } } private void ClearHighlightOverlay() { foreach (GameObject value in clusters.Values) { if (!((Object)(object)value == (Object)null)) { Transform[] array = (from value in value.GetComponentsInChildren(true) where (Object)(object)value != (Object)null && (((Object)value).name == "PUP_MaterialHighlight" || ((Object)value).name == "PUP_GraustenHighlight") select value).ToArray(); for (int num = 0; num < array.Length; num++) { Object.Destroy((Object)(object)((Component)array[num]).gameObject); } } } } private string GetCachePath(Vector2Int cell) { string text = Path.Combine(Paths.ConfigPath, "PUPSafeGraustenCombiner", "ClusterCache"); Directory.CreateDirectory(text); string arg = string.Concat((worldName ?? "world").Select((char ch) => (!Path.GetInvalidFileNameChars().Contains(ch)) ? ch : '_')); return Path.Combine(text, $"{arg}_{((Vector2Int)(ref cell)).x}_{((Vector2Int)(ref cell)).y}_support_guard_v9.bin"); } private string GetGpuCachePath(Vector2Int cell) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return GetCachePath(cell) + ".ugpu"; } private bool TrySaveGpuCache(Vector2Int cell, List cellRecords) { //IL_0006: 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_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) if (!gpuBakedGroups.TryGetValue(cell, out var value)) { return false; } string gpuCachePath = GetGpuCachePath(cell); string text = gpuCachePath + ".tmp"; try { List list = value.Where((GpuDrawGroup group) => group != null && (Object)(object)group.mesh != (Object)null && !group.mesh.isReadable).ToList(); if (list.Count == 0) { if (File.Exists(gpuCachePath)) { File.Delete(gpuCachePath); } if (File.Exists(gpuCachePath + ".bak")) { File.Delete(gpuCachePath + ".bak"); } return true; } using (BinaryWriter binaryWriter = new BinaryWriter(File.Open(text, FileMode.Create, FileAccess.Write, FileShare.None))) { binaryWriter.Write("PUP_GPU_UNREADABLE_CACHE_1"); binaryWriter.Write(GetCellFingerprint(cellRecords)); binaryWriter.Write(list.Count); foreach (GpuDrawGroup item in list) { binaryWriter.Write(NormalizeMeshName(((Object)item.mesh).name)); binaryWriter.Write(item.mesh.vertexCount); binaryWriter.Write(item.mesh.subMeshCount); Bounds bounds = item.mesh.bounds; WriteVector3(binaryWriter, ((Bounds)(ref bounds)).size); binaryWriter.Write(item.subMesh); binaryWriter.Write(NormalizeMaterialName(((Object)item.material).name)); int value2 = item.chunks.Sum((Matrix4x4[] chunk) => chunk.Length); binaryWriter.Write(value2); foreach (Matrix4x4[] chunk in item.chunks) { for (int num = 0; num < chunk.Length; num++) { Matrix4x4 val = chunk[num]; for (int num2 = 0; num2 < 16; num2++) { binaryWriter.Write(((Matrix4x4)(ref val))[num2]); } } } } } ((BaseUnityPlugin)this).Logger.LogInfo((object)$"[GPU-CACHE] saved unreadable cell {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}: {list.Count} groups"); if (File.Exists(gpuCachePath)) { File.Replace(text, gpuCachePath, gpuCachePath + ".bak"); } else { File.Move(text, gpuCachePath); } return true; } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)$"GPU cache write failed {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}: {ex.Message}"); return false; } } private bool TryLoadGpuCache(Vector2Int cell, GameObject root, List cellRecords) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0209: 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_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) string gpuCachePath = GetGpuCachePath(cell); if (!File.Exists(gpuCachePath)) { return true; } List list = new List(); try { using (BinaryReader binaryReader = new BinaryReader(File.OpenRead(gpuCachePath))) { if (binaryReader.ReadString() != "PUP_GPU_UNREADABLE_CACHE_1" || binaryReader.ReadUInt64() != GetCellFingerprint(cellRecords)) { throw new InvalidDataException("GPU cache fingerprint mismatch"); } int num = binaryReader.ReadInt32(); for (int i = 0; i < num; i++) { string text = NormalizeMeshName(binaryReader.ReadString()); int vertexCount = binaryReader.ReadInt32(); int subMeshCount = binaryReader.ReadInt32(); Vector3 boundsSize = ReadVector3(binaryReader); int subMesh = binaryReader.ReadInt32(); string text2 = NormalizeMaterialName(binaryReader.ReadString()); int num2 = binaryReader.ReadInt32(); (Mesh, Material) tuple = ResolveGpuSource(text, vertexCount, subMeshCount, boundsSize, subMesh, text2); if ((Object)(object)tuple.Item1 == (Object)null || (Object)(object)tuple.Item2 == (Object)null) { throw new InvalidDataException("GPU source unavailable: " + text + "/" + text2); } Material val = Object.Instantiate(tuple.Item2); val.enableInstancing = true; GpuDrawGroup gpuDrawGroup = new GpuDrawGroup { mesh = tuple.Item1, subMesh = subMesh, material = val, usesTessellation = val.IsKeywordEnabled("TESSELATION_ON"), tessellationEnabled = true }; Matrix4x4[] array = (Matrix4x4[])(object)new Matrix4x4[num2]; for (int j = 0; j < num2; j++) { Matrix4x4 val2 = default(Matrix4x4); for (int k = 0; k < 16; k++) { ((Matrix4x4)(ref val2))[k] = binaryReader.ReadSingle(); } array[j] = val2; } for (int l = 0; l < array.Length; l += 1023) { int num3 = Mathf.Min(1023, array.Length - l); Matrix4x4[] array2 = (Matrix4x4[])(object)new Matrix4x4[num3]; Array.Copy(array, l, array2, 0, num3); gpuDrawGroup.chunks.Add(array2); } list.Add(gpuDrawGroup); } } gpuBakedGroups[cell] = list; BuildRoofDepthRenderers(cell, root, list); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"[GPU-CACHE] restored unreadable cell {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}: {list.Count} groups"); return true; } catch (Exception ex) { foreach (GpuDrawGroup item in list) { if ((Object)(object)item.material != (Object)null) { Object.Destroy((Object)(object)item.material); } } ((BaseUnityPlugin)this).Logger.LogError((object)$"GPU cache load failed {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}: {ex.Message}"); return false; } } private static (Mesh mesh, Material material) ResolveGpuSource(string meshName, int vertexCount, int subMeshCount, Vector3 boundsSize, int subMesh, string materialName) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) MeshFilter[] array = Resources.FindObjectsOfTypeAll(); foreach (MeshFilter val in array) { if ((Object)(object)val == (Object)null || (Object)(object)val.sharedMesh == (Object)null) { continue; } Mesh sharedMesh = val.sharedMesh; if (!NormalizeMeshName(((Object)sharedMesh).name).Equals(meshName, StringComparison.Ordinal) || sharedMesh.vertexCount != vertexCount || sharedMesh.subMeshCount != subMeshCount) { continue; } Bounds bounds = sharedMesh.bounds; Vector3 val2 = ((Bounds)(ref bounds)).size - boundsSize; if (((Vector3)(ref val2)).sqrMagnitude > 0.0001f) { continue; } MeshRenderer component = ((Component)val).GetComponent(); if (!((Object)(object)component == (Object)null) && subMesh >= 0 && subMesh < ((Renderer)component).sharedMaterials.Length) { Material val3 = ((Renderer)component).sharedMaterials[subMesh]; if ((Object)(object)val3 != (Object)null && NormalizeMaterialName(((Object)val3).name).Equals(materialName, StringComparison.Ordinal)) { return (mesh: sharedMesh, material: val3); } } } return (mesh: null, material: null); } private static ulong GetCellFingerprint(IEnumerable cellRecords) { ulong num = 1469598103934665603uL; foreach (BakedRecord item in from value in cellRecords orderby value.userId, value.id select value) { string text = item.userId.ToString(CultureInfo.InvariantCulture) + ":" + item.id.ToString(CultureInfo.InvariantCulture) + "|" + V(item.position.x) + "|" + V(item.position.y) + "|" + V(item.position.z) + "|" + item.prefabHash.ToString(CultureInfo.InvariantCulture); foreach (char c in text) { num ^= c; num *= 1099511628211L; } } return num; } private bool TrySaveClusterCache(Vector2Int cell, GameObject root, List cellRecords) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) string cachePath = GetCachePath(cell); string text = cachePath + ".tmp"; try { List list = (from value in root.GetComponentsInChildren(false) where (Object)(object)value != (Object)null && (Object)(object)value.sharedMesh != (Object)null && ((Object)((Component)value).gameObject).name.StartsWith("PUP_SubCluster_", StringComparison.Ordinal) select value).OrderBy((MeshFilter value) => ((Object)((Component)value).gameObject).name, StringComparer.Ordinal).ToList(); if (list.Count == 0) { return false; } Collider[] componentsInChildren = root.GetComponentsInChildren(false); List list2 = new List(); ulong cellFingerprint = GetCellFingerprint(cellRecords); foreach (MeshFilter item in list) { string[] array = ((Object)((Component)item).gameObject).name.Split(new char[1] { '_' }); int subX = int.Parse(array[2], CultureInfo.InvariantCulture); int subZ = int.Parse(array[3], CultureInfo.InvariantCulture); string text2 = Path.GetFileName(cachePath) + $".{cellFingerprint:X16}.{subX}_{subZ}.sub"; string path = Path.Combine(Path.GetDirectoryName(cachePath), text2) + ".tmp"; MeshRenderer component = ((Component)item).GetComponent(); using (BinaryWriter binaryWriter = new BinaryWriter(File.Open(path, FileMode.Create, FileAccess.Write, FileShare.None))) { binaryWriter.Write("PUP_SUBCLUSTER_GRAUSTEN_2"); binaryWriter.Write(subX); binaryWriter.Write(subZ); WriteMesh(binaryWriter, item.sharedMesh); Material[] array2 = (((Object)(object)component != (Object)null) ? ((Renderer)component).sharedMaterials : Array.Empty()); binaryWriter.Write(array2.Length); Material[] array3 = array2; foreach (Material val in array3) { binaryWriter.Write(NormalizeMaterialName(((Object)(object)val != (Object)null) ? ((Object)val).name : "")); } Collider[] array4 = componentsInChildren.Where(delegate(Collider val2) { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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) if (((Object)((Component)val2).gameObject).name.StartsWith("PUP_Collider_", StringComparison.Ordinal)) { string[] array6 = ((Object)((Component)val2).gameObject).name.Split(new char[1] { '_' }); if (array6.Length >= 4 && int.TryParse(array6[2], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) && int.TryParse(array6[3], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result2)) { if (result == subX) { return result2 == subZ; } return false; } } Vector3 val3 = root.transform.InverseTransformPoint(((Component)val2).transform.position); int num2 = Mathf.Clamp(Mathf.FloorToInt(val3.x / 16f), 0, 3); int num3 = Mathf.Clamp(Mathf.FloorToInt(val3.z / 16f), 0, 3); return num2 == subX && num3 == subZ; }).ToArray(); binaryWriter.Write(array4.Length); Collider[] array5 = array4; foreach (Collider collider in array5) { WriteCollider(binaryWriter, root.transform, collider); } } list2.Add(new SubClusterCacheEntry { x = subX, z = subZ, name = ((Object)((Component)item).gameObject).name, fileName = text2 }); } using (BinaryWriter binaryWriter2 = new BinaryWriter(File.Open(text, FileMode.Create, FileAccess.Write, FileShare.None))) { binaryWriter2.Write("PUP_CLUSTER_MANIFEST_1"); binaryWriter2.Write(((Vector2Int)(ref cell)).x); binaryWriter2.Write(((Vector2Int)(ref cell)).y); binaryWriter2.Write(cellRecords.Count); binaryWriter2.Write(cellFingerprint); binaryWriter2.Write(list2.Count); foreach (SubClusterCacheEntry item2 in list2) { binaryWriter2.Write(item2.x); binaryWriter2.Write(item2.z); binaryWriter2.Write(item2.name); binaryWriter2.Write(item2.fileName); } } foreach (SubClusterCacheEntry item3 in list2) { string text3 = Path.Combine(Path.GetDirectoryName(cachePath), item3.fileName); string sourceFileName = text3 + ".tmp"; if (File.Exists(text3)) { File.Replace(sourceFileName, text3, text3 + ".bak"); } else { File.Move(sourceFileName, text3); } } if (File.Exists(cachePath)) { File.Replace(text, cachePath, cachePath + ".bak"); } else { File.Move(text, cachePath); } return true; } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)$"Subcluster cache write failed {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}: {ex.Message}"); return false; } } private bool TryLoadClusterCache(Vector2Int cell) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_038d: 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_00a8: 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_01a6: Expected O, but got Unknown //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: 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_02ce: Unknown result type (might be due to invalid IL or missing references) if (!records.TryGetValue(cell, out var value)) { return false; } string cachePath = GetCachePath(cell); if (!File.Exists(cachePath)) { return false; } try { List list = new List(); using (BinaryReader binaryReader = new BinaryReader(File.OpenRead(cachePath))) { if (binaryReader.ReadString() != "PUP_CLUSTER_MANIFEST_1" || binaryReader.ReadInt32() != ((Vector2Int)(ref cell)).x || binaryReader.ReadInt32() != ((Vector2Int)(ref cell)).y) { return false; } int num = binaryReader.ReadInt32(); ulong num2 = binaryReader.ReadUInt64(); if (num != value.Count) { return false; } ulong cellFingerprint = GetCellFingerprint(value); if (num2 != cellFingerprint) { if (!ValidateCellRecords(cell, out var error)) { ((BaseUnityPlugin)this).Logger.LogError((object)$"Legacy cache migration blocked {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}: {error}"); return false; } ((BaseUnityPlugin)this).Logger.LogWarning((object)$"Accepted verified legacy cache order for cell {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}"); } int num3 = binaryReader.ReadInt32(); for (int i = 0; i < num3; i++) { list.Add(new SubClusterCacheEntry { x = binaryReader.ReadInt32(), z = binaryReader.ReadInt32(), name = binaryReader.ReadString(), fileName = binaryReader.ReadString() }); } } GameObject val = new GameObject($"PUP_SafeCluster_{((Vector2Int)(ref cell)).x}_{((Vector2Int)(ref cell)).y}"); val.transform.position = new Vector3((float)((Vector2Int)(ref cell)).x * 64f, 0f, (float)((Vector2Int)(ref cell)).y * 64f); List list2 = new List(); generatedMeshes[cell] = list2; clusters[cell] = val; int priorityX = -1; int priorityZ = -1; if ((Object)(object)Player.m_localPlayer != (Object)null && GetCell(((Component)Player.m_localPlayer).transform.position) == cell) { Vector3 val2 = ((Component)Player.m_localPlayer).transform.position - val.transform.position; priorityX = Mathf.Clamp(Mathf.FloorToInt(val2.x / 16f), 0, 3); priorityZ = Mathf.Clamp(Mathf.FloorToInt(val2.z / 16f), 0, 3); } SubClusterCacheEntry subClusterCacheEntry = list.FirstOrDefault((SubClusterCacheEntry subClusterCacheEntry2) => subClusterCacheEntry2.x == priorityX && subClusterCacheEntry2.z == priorityZ); if (subClusterCacheEntry != null) { LoadSubClusterFile(cachePath, val, list2, subClusterCacheEntry, priority: true); list.Remove(subClusterCacheEntry); } if (!TryLoadGpuCache(cell, val, value)) { DestroyCluster(cell); return false; } supportGuardUntil = Mathf.Max(supportGuardUntil, Time.time + 10f); ((MonoBehaviour)this).StartCoroutine(LoadRemainingSubClusters(cell, cachePath, val, list2, list)); ReparkBakedCell(cell); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Started cached zone cell {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}: {list.Count + ((subClusterCacheEntry != null) ? 1 : 0)} subclusters"); return true; } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)$"Subcluster cache load failed {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}: {ex.Message}"); DestroyCluster(cell); return false; } } private IEnumerator LoadRemainingSubClusters(Vector2Int cell, string manifestPath, GameObject root, List owned, List entries) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) pendingSubClusterLoads++; try { foreach (SubClusterCacheEntry entry in entries) { if ((Object)(object)root == (Object)null) { yield break; } try { LoadSubClusterFile(manifestPath, root, owned, entry, priority: false); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)$"Subcluster load failed {entry.x},{entry.z}: {ex.Message}"); DestroyCluster(cell); failedCacheCells.Add(cell); yield break; } yield return null; } } finally { InstanceCombinerMod instanceCombinerMod = this; instanceCombinerMod.pendingSubClusterLoads--; instanceCombinerMod.supportGuardUntil = Mathf.Max(instanceCombinerMod.supportGuardUntil, Time.time + 10f); } } private void LoadSubClusterFile(string manifestPath, GameObject root, List owned, SubClusterCacheEntry entry, bool priority) { //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Expected O, but got Unknown //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) using BinaryReader binaryReader = new BinaryReader(File.OpenRead(Path.Combine(Path.GetDirectoryName(manifestPath), entry.fileName))); string text = binaryReader.ReadString(); bool flag = text == "PUP_SUBCLUSTER_GRAUSTEN_2"; if ((!flag && text != "PUP_SUBCLUSTER_GRAUSTEN_1") || binaryReader.ReadInt32() != entry.x || binaryReader.ReadInt32() != entry.z) { throw new InvalidDataException("Subcluster header mismatch"); } Mesh val = ReadMesh(binaryReader); owned.Add(val); int num = binaryReader.ReadInt32(); Material[] array = (Material[])(object)new Material[num]; for (int i = 0; i < num; i++) { string name = NormalizeMaterialName(binaryReader.ReadString()); Material val2 = ((IEnumerable)Resources.FindObjectsOfTypeAll()).FirstOrDefault((Func)((Material value) => (Object)(object)value != (Object)null && NormalizeMaterialName(((Object)value).name) == name)); if ((Object)(object)val2 == (Object)null) { throw new InvalidDataException("Material unavailable: " + name); } array[i] = val2; } int num2 = binaryReader.ReadInt32(); List list = new List(num2); for (int num3 = 0; num3 < num2; num3++) { list.Add(ReadColliderData(binaryReader, flag, owned)); } if (priority) { foreach (CachedColliderData item in list) { CreateCachedCollider(root, item); } } else { QueueCachedColliders(root, list); } GameObject val3 = new GameObject(entry.name); val3.transform.SetParent(root.transform, false); val3.AddComponent().sharedMesh = val; if (array.Length != 0) { MeshRenderer val4 = val3.AddComponent(); ((Renderer)val4).sharedMaterials = array; RegisterPrecipitationRenderer(GetCell(root.transform.position), val4); if (highlightEnabled) { AddMaterialHighlights(val3); } } } private void RegisterPrecipitationRenderer(Vector2Int cell, MeshRenderer renderer) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)renderer == (Object)null)) { if (!precipitationRenderers.TryGetValue(cell, out var value)) { value = new List(); precipitationRenderers[cell] = value; } value.Add(renderer); } } private bool TrySaveLegacyClusterCache(Vector2Int cell, GameObject root, List cellRecords) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) string cachePath = GetCachePath(cell); string text = cachePath + ".tmp"; try { MeshFilter[] array = (from value in root.GetComponentsInChildren(false) where (Object)(object)value != (Object)null && (Object)(object)value.sharedMesh != (Object)null select value).ToArray(); if (array.Length == 0) { return false; } using (BinaryWriter binaryWriter = new BinaryWriter(File.Open(text, FileMode.Create, FileAccess.Write, FileShare.None))) { binaryWriter.Write("PUP_CLUSTER_GRAUSTEN_4"); binaryWriter.Write(((Vector2Int)(ref cell)).x); binaryWriter.Write(((Vector2Int)(ref cell)).y); binaryWriter.Write(cellRecords.Count); binaryWriter.Write(GetCellFingerprint(cellRecords)); binaryWriter.Write(array.Length); MeshFilter[] array2 = array; foreach (MeshFilter val in array2) { MeshRenderer component = ((Component)val).GetComponent(); if ((Object)(object)component == (Object)null) { throw new InvalidDataException("Subcluster renderer missing"); } binaryWriter.Write(((Object)((Component)val).gameObject).name); WriteVector3(binaryWriter, ((Component)val).transform.localPosition); WriteMesh(binaryWriter, val.sharedMesh); binaryWriter.Write(((Renderer)component).sharedMaterials.Length); Material[] sharedMaterials = ((Renderer)component).sharedMaterials; foreach (Material val2 in sharedMaterials) { binaryWriter.Write(NormalizeMaterialName(((Object)(object)val2 != (Object)null) ? ((Object)val2).name : "")); } } Collider[] componentsInChildren = root.GetComponentsInChildren(false); binaryWriter.Write(componentsInChildren.Length); Collider[] array3 = componentsInChildren; foreach (Collider collider in array3) { WriteCollider(binaryWriter, root.transform, collider); } } using (BinaryReader binaryReader = new BinaryReader(File.OpenRead(text))) { if (binaryReader.ReadString() != "PUP_CLUSTER_GRAUSTEN_4") { return false; } } if (File.Exists(cachePath)) { File.Replace(text, cachePath, cachePath + ".bak"); } else { File.Move(text, cachePath); } return true; } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)$"Cluster cache write failed {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}: {ex.Message}"); return false; } } private bool TryLoadLegacyClusterCache(Vector2Int cell) { //IL_000c: 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_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Expected O, but got Unknown //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: 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_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_034c: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_0289: 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) if (!records.TryGetValue(cell, out var value)) { return false; } string cachePath = GetCachePath(cell); if (!File.Exists(cachePath)) { return false; } GameObject root = null; List list = new List(); try { using (BinaryReader binaryReader = new BinaryReader(File.OpenRead(cachePath))) { string text = binaryReader.ReadString(); bool flag = text == "PUP_CLUSTER_GRAUSTEN_4"; if ((!flag && text != "PUP_CLUSTER_GRAUSTEN_3") || binaryReader.ReadInt32() != ((Vector2Int)(ref cell)).x || binaryReader.ReadInt32() != ((Vector2Int)(ref cell)).y || binaryReader.ReadInt32() != value.Count || binaryReader.ReadUInt64() != GetCellFingerprint(value)) { return false; } root = new GameObject($"PUP_SafeCluster_{((Vector2Int)(ref cell)).x}_{((Vector2Int)(ref cell)).y}"); root.transform.position = new Vector3((float)((Vector2Int)(ref cell)).x * 64f, 0f, (float)((Vector2Int)(ref cell)).y * 64f); int num = binaryReader.ReadInt32(); for (int i = 0; i < num; i++) { string text2 = binaryReader.ReadString(); Vector3 localPosition = ReadVector3(binaryReader); Mesh val = ReadMesh(binaryReader); list.Add(val); int num2 = binaryReader.ReadInt32(); Material[] array = (Material[])(object)new Material[num2]; for (int j = 0; j < num2; j++) { string name = NormalizeMaterialName(binaryReader.ReadString()); Material val2 = ((IEnumerable)Resources.FindObjectsOfTypeAll()).FirstOrDefault((Func)((Material val4) => (Object)(object)val4 != (Object)null && NormalizeMaterialName(((Object)val4).name) == name)); if ((Object)(object)val2 == (Object)null) { throw new InvalidDataException("Material unavailable: " + name); } array[j] = val2; } GameObject val3 = new GameObject(text2); val3.transform.SetParent(root.transform, false); val3.transform.localPosition = localPosition; val3.AddComponent().sharedMesh = val; ((Renderer)val3.AddComponent()).sharedMaterials = array; } int num3 = binaryReader.ReadInt32(); List list2 = new List(num3); for (int num4 = 0; num4 < num3; num4++) { list2.Add(ReadColliderData(binaryReader, flag, list)); } if ((Object)(object)Player.m_localPlayer != (Object)null && GetCell(((Component)Player.m_localPlayer).transform.position) == cell) { Vector3 player = ((Component)Player.m_localPlayer).transform.position; List list3 = list2.Where(delegate(CachedColliderData data) { //IL_000c: 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_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) Vector3 val4 = root.transform.TransformPoint(data.position); float num5 = val4.x - player.x; float num6 = val4.z - player.z; return num5 * num5 + num6 * num6 <= 576f && Mathf.Abs(val4.y - player.y) <= 32f; }).ToList(); foreach (CachedColliderData item in list3) { CreateCachedCollider(root, item); list2.Remove(item); } ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Priority colliders ready cell {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}: {list3.Count}"); } QueueCachedColliders(root, list2); } clusters[cell] = root; generatedMeshes[cell] = list; if (highlightEnabled) { RefreshHighlights(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Loaded cached cluster cell {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}: {value.Count} ZDO"); return true; } catch (Exception ex) { if ((Object)(object)root != (Object)null) { Object.Destroy((Object)(object)root); } foreach (Mesh item2 in list) { if ((Object)(object)item2 != (Object)null) { Object.Destroy((Object)(object)item2); } } ((BaseUnityPlugin)this).Logger.LogError((object)$"Cluster cache load failed {((Vector2Int)(ref cell)).x},{((Vector2Int)(ref cell)).y}: {ex.Message}"); return false; } } private static string NormalizeMaterialName(string name) { return name.Replace(" (Instance)", "").Replace("(Instance)", "").Replace(" (Clone)", "") .Replace("(Clone)", "") .Trim(); } private static void WriteVector3(BinaryWriter writer, Vector3 value) { //IL_0001: 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_0019: Unknown result type (might be due to invalid IL or missing references) writer.Write(value.x); writer.Write(value.y); writer.Write(value.z); } private static Vector3 ReadVector3(BinaryReader reader) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) return new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); } private static void WriteQuaternion(BinaryWriter writer, Quaternion value) { //IL_0001: 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_0019: 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) writer.Write(value.x); writer.Write(value.y); writer.Write(value.z); writer.Write(value.w); } private static Quaternion ReadQuaternion(BinaryReader reader) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) return new Quaternion(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); } private static void WriteMesh(BinaryWriter writer, Mesh mesh) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) Vector3[] vertices = mesh.vertices; Vector3[] normals = mesh.normals; Vector4[] tangents = mesh.tangents; Vector2[] uv = mesh.uv; writer.Write(vertices.Length); Vector3[] array = vertices; foreach (Vector3 value in array) { WriteVector3(writer, value); } writer.Write(normals.Length); array = normals; foreach (Vector3 value2 in array) { WriteVector3(writer, value2); } writer.Write(tangents.Length); Vector4[] array2 = tangents; foreach (Vector4 val in array2) { writer.Write(val.x); writer.Write(val.y); writer.Write(val.z); writer.Write(val.w); } writer.Write(uv.Length); Vector2[] array3 = uv; foreach (Vector2 val2 in array3) { writer.Write(val2.x); writer.Write(val2.y); } writer.Write(mesh.subMeshCount); for (int j = 0; j < mesh.subMeshCount; j++) { int[] triangles = mesh.GetTriangles(j); writer.Write(triangles.Length); int[] array4 = triangles; foreach (int value3 in array4) { writer.Write(value3); } } } private static Mesh ReadMesh(BinaryReader reader) { //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_000d: Expected O, but got Unknown //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) Mesh val = new Mesh { indexFormat = (IndexFormat)1 }; Vector3[] array = (Vector3[])(object)new Vector3[reader.ReadInt32()]; for (int i = 0; i < array.Length; i++) { array[i] = ReadVector3(reader); } Vector3[] array2 = (Vector3[])(object)new Vector3[reader.ReadInt32()]; for (int j = 0; j < array2.Length; j++) { array2[j] = ReadVector3(reader); } Vector4[] array3 = (Vector4[])(object)new Vector4[reader.ReadInt32()]; for (int k = 0; k < array3.Length; k++) { array3[k] = new Vector4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); } Vector2[] array4 = (Vector2[])(object)new Vector2[reader.ReadInt32()]; for (int l = 0; l < array4.Length; l++) { array4[l] = new Vector2(reader.ReadSingle(), reader.ReadSingle()); } val.vertices = array; if (array2.Length == array.Length) { val.normals = array2; } if (array3.Length == array.Length) { val.tangents = array3; } if (array4.Length == array.Length) { val.uv = array4; } int num = (val.subMeshCount = reader.ReadInt32()); for (int m = 0; m < num; m++) { int[] array5 = new int[reader.ReadInt32()]; for (int n = 0; n < array5.Length; n++) { array5[n] = reader.ReadInt32(); } val.SetTriangles(array5, m, false); } val.RecalculateBounds(); return val; } private static void WriteCollider(BinaryWriter writer, Transform root, Collider collider) { //IL_004e: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0085: 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) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) byte value = (byte)((collider is BoxCollider) ? 1 : ((collider is SphereCollider) ? 2 : ((collider is CapsuleCollider) ? 3 : ((collider is MeshCollider) ? 4 : 0)))); writer.Write(value); writer.Write(((Component)collider).gameObject.layer); WriteVector3(writer, root.InverseTransformPoint(((Component)collider).transform.position)); WriteQuaternion(writer, Quaternion.Inverse(root.rotation) * ((Component)collider).transform.rotation); WriteVector3(writer, ((Component)collider).transform.lossyScale); writer.Write(collider.isTrigger); BoxCollider val = (BoxCollider)(object)((collider is BoxCollider) ? collider : null); if (val != null) { WriteVector3(writer, val.center); WriteVector3(writer, val.size); return; } SphereCollider val2 = (SphereCollider)(object)((collider is SphereCollider) ? collider : null); if (val2 != null) { WriteVector3(writer, val2.center); writer.Write(val2.radius); return; } CapsuleCollider val3 = (CapsuleCollider)(object)((collider is CapsuleCollider) ? collider : null); if (val3 != null) { WriteVector3(writer, val3.center); writer.Write(val3.radius); writer.Write(val3.height); writer.Write(val3.direction); return; } MeshCollider val4 = (MeshCollider)(object)((collider is MeshCollider) ? collider : null); if (val4 != null) { writer.Write(val4.convex); writer.Write(NormalizeMeshName(((Object)(object)val4.sharedMesh != (Object)null) ? ((Object)val4.sharedMesh).name : "")); bool flag = (Object)(object)val4.sharedMesh != (Object)null && val4.sharedMesh.isReadable; writer.Write(flag); if (flag) { WriteMesh(writer, val4.sharedMesh); } } } private static void ReadCollider(BinaryReader reader, GameObject root, List owned) { //IL_000f: 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_0016: 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) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) byte b = reader.ReadByte(); int layer = reader.ReadInt32(); Vector3 localPosition = ReadVector3(reader); Quaternion localRotation = ReadQuaternion(reader); Vector3 localScale = ReadVector3(reader); bool isTrigger = reader.ReadBoolean(); GameObject val = new GameObject("PUP_Collider") { layer = layer }; val.transform.SetParent(root.transform, false); val.transform.localPosition = localPosition; val.transform.localRotation = localRotation; val.transform.localScale = localScale; Collider val2 = null; switch (b) { case 1: { BoxCollider obj3 = val.AddComponent(); obj3.center = ReadVector3(reader); obj3.size = ReadVector3(reader); val2 = (Collider)(object)obj3; break; } case 2: { SphereCollider obj2 = val.AddComponent(); obj2.center = ReadVector3(reader); obj2.radius = reader.ReadSingle(); val2 = (Collider)(object)obj2; break; } case 3: { CapsuleCollider obj4 = val.AddComponent(); obj4.center = ReadVector3(reader); obj4.radius = reader.ReadSingle(); obj4.height = reader.ReadSingle(); obj4.direction = reader.ReadInt32(); val2 = (Collider)(object)obj4; break; } case 4: { bool convex = reader.ReadBoolean(); string text = NormalizeMeshName(reader.ReadString()); Mesh val3 = ResolveMeshAsset(text); if ((Object)(object)val3 == (Object)null) { throw new InvalidDataException("Collider mesh unavailable: " + text); } MeshCollider obj = val.AddComponent(); obj.convex = convex; obj.sharedMesh = val3; val2 = (Collider)(object)obj; break; } } if ((Object)(object)val2 != (Object)null) { val2.isTrigger = isTrigger; } else { Object.Destroy((Object)(object)val); } } private static CachedColliderData ReadColliderData(BinaryReader reader, bool embeddedColliderMeshes, List owned) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) CachedColliderData cachedColliderData = new CachedColliderData { type = reader.ReadByte(), layer = reader.ReadInt32(), position = ReadVector3(reader), rotation = ReadQuaternion(reader), scale = ReadVector3(reader), trigger = reader.ReadBoolean() }; if (cachedColliderData.type == 1) { cachedColliderData.center = ReadVector3(reader); cachedColliderData.size = ReadVector3(reader); } else if (cachedColliderData.type == 2) { cachedColliderData.center = ReadVector3(reader); cachedColliderData.radius = reader.ReadSingle(); } else if (cachedColliderData.type == 3) { cachedColliderData.center = ReadVector3(reader); cachedColliderData.radius = reader.ReadSingle(); cachedColliderData.height = reader.ReadSingle(); cachedColliderData.direction = reader.ReadInt32(); } else if (cachedColliderData.type == 4) { cachedColliderData.convex = reader.ReadBoolean(); cachedColliderData.meshName = NormalizeMeshName(reader.ReadString()); if (embeddedColliderMeshes && reader.ReadBoolean()) { cachedColliderData.mesh = ReadMesh(reader); owned?.Add(cachedColliderData.mesh); } } return cachedColliderData; } private void QueueCachedColliders(GameObject root, List items) { //IL_0039: 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_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)root == (Object)null || items == null || items.Count == 0) { return; } Vector3 val = (((Object)(object)Player.m_localPlayer != (Object)null) ? ((Component)Player.m_localPlayer).transform.position : root.transform.position); bool flag = queuedColliderCount == 0; foreach (CachedColliderData item in items) { Vector3 val2 = root.transform.TransformPoint(item.position) - val; int key = Mathf.Clamp(Mathf.FloorToInt(((Vector3)(ref val2)).sqrMagnitude / 64f), 0, 1000000); if (!pendingColliders.TryGetValue(key, out var value)) { value = new Queue(); pendingColliders[key] = value; } value.Enqueue(new PendingCollider { root = root, data = item }); queuedColliderCount++; } if (flag && queuedColliderCount > 0) { activeColliderLoads = 1; loadedQueuedColliders = 0; ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Background collider queue started: {queuedColliderCount}"); } } private void ProcessPendingColliders() { if (queuedColliderCount == 0) { return; } float num = ((Time.unscaledDeltaTime > 0.025f) ? 0.5f : ((Time.unscaledDeltaTime > 0.018f) ? 0.9f : 1.5f)); float realtimeSinceStartup = Time.realtimeSinceStartup; int num2 = 0; while (pendingColliders.Count != 0) { KeyValuePair> keyValuePair = pendingColliders.First(); PendingCollider pendingCollider = keyValuePair.Value.Dequeue(); if (keyValuePair.Value.Count == 0) { pendingColliders.Remove(keyValuePair.Key); } queuedColliderCount--; if ((Object)(object)pendingCollider.root != (Object)null) { CreateCachedCollider(pendingCollider.root, pendingCollider.data); loadedQueuedColliders++; } num2++; if (queuedColliderCount <= 0 || num2 >= 64 || !((Time.realtimeSinceStartup - realtimeSinceStartup) * 1000f < num)) { break; } } if (queuedColliderCount == 0) { activeColliderLoads = 0; supportGuardUntil = Mathf.Max(supportGuardUntil, Time.time + 10f); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Background colliders ready: {loadedQueuedColliders}"); loadedQueuedColliders = 0; } } private static void CreateCachedCollider(GameObject root, CachedColliderData data) { //IL_0017: 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_0029: Expected O, but got Unknown //IL_0042: 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_0064: 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) //IL_008d: 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_00db: Unknown result type (might be due to invalid IL or missing references) if (data.type == 0 || (Object)(object)root == (Object)null) { return; } GameObject val = new GameObject("PUP_Collider") { layer = data.layer }; val.transform.SetParent(root.transform, false); val.transform.localPosition = data.position; val.transform.localRotation = data.rotation; val.transform.localScale = data.scale; Collider val2 = null; if (data.type == 1) { BoxCollider obj = val.AddComponent(); obj.center = data.center; obj.size = data.size; val2 = (Collider)(object)obj; } else if (data.type == 2) { SphereCollider obj2 = val.AddComponent(); obj2.center = data.center; obj2.radius = data.radius; val2 = (Collider)(object)obj2; } else if (data.type == 3) { CapsuleCollider obj3 = val.AddComponent(); obj3.center = data.center; obj3.radius = data.radius; obj3.height = data.height; obj3.direction = data.direction; val2 = (Collider)(object)obj3; } else if (data.type == 4) { Mesh val3 = (((Object)(object)data.mesh != (Object)null) ? data.mesh : ResolveMeshAsset(data.meshName)); if ((Object)(object)val3 != (Object)null) { MeshCollider obj4 = val.AddComponent(); obj4.convex = data.convex; obj4.sharedMesh = val3; val2 = (Collider)(object)obj4; } else { InstanceCombinerMod instance = Instance; if (instance != null) { ((BaseUnityPlugin)instance).Logger.LogError((object)("Cached MeshCollider unavailable: " + data.meshName)); } } } if ((Object)(object)val2 != (Object)null) { val2.isTrigger = data.trigger; } else { Object.Destroy((Object)(object)val); } } private static string NormalizeMeshName(string name) { return name.Replace(" (Instance)", "").Replace("(Instance)", "").Replace(" (Clone)", "") .Replace("(Clone)", "") .Trim(); } private static Mesh ResolveMeshAsset(string name) { if (string.IsNullOrEmpty(name)) { return null; } if (meshAssetCache == null) { meshAssetCache = new Dictionary(StringComparer.Ordinal); Mesh[] array = Resources.FindObjectsOfTypeAll(); foreach (Mesh val in array) { if (!((Object)(object)val == (Object)null)) { string key = NormalizeMeshName(((Object)val).name); if (!meshAssetCache.ContainsKey(key)) { meshAssetCache[key] = val; } } } } meshAssetCache.TryGetValue(name, out var value); return value; } private string GetStatePath() { if ((Object)(object)ZNet.instance == (Object)null) { return ""; } worldName = ZNet.instance.GetWorldName(); string text = Path.Combine(Paths.ConfigPath, "PUPSafeGraustenCombiner"); Directory.CreateDirectory(text); return Path.Combine(text, "SafeState_" + worldName + ".txt"); } private void SaveState() { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: 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_009a: Unknown result type (might be due to invalid IL or missing references) string statePath = GetStatePath(); if (string.IsNullOrEmpty(statePath)) { return; } string text = statePath + ".tmp"; List list = new List { "PUP_SAFE|7|64|GRAUSTEN|SUBCLUSTER16" }; foreach (KeyValuePair> record in records) { foreach (BakedRecord item in record.Value) { string[] array = new string[15]; Vector2Int key = record.Key; array[0] = ((Vector2Int)(ref key)).x.ToString(CultureInfo.InvariantCulture); key = record.Key; array[1] = ((Vector2Int)(ref key)).y.ToString(CultureInfo.InvariantCulture); array[2] = item.userId.ToString(CultureInfo.InvariantCulture); array[3] = item.id.ToString(CultureInfo.InvariantCulture); array[4] = item.prefabHash.ToString(CultureInfo.InvariantCulture); array[5] = V(item.position.x); array[6] = V(item.position.y); array[7] = V(item.position.z); array[8] = V(item.rotation.x); array[9] = V(item.rotation.y); array[10] = V(item.rotation.z); array[11] = V(item.rotation.w); array[12] = V(item.scale.x); array[13] = V(item.scale.y); array[14] = V(item.scale.z); list.Add(string.Join("|", array)); } } File.WriteAllLines(text, list); if (File.Exists(statePath)) { File.Replace(text, statePath, statePath + ".bak"); } else { File.Move(text, statePath); } } private void LoadState() { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02db: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) string text = (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetWorldName() : ""); if (loadedZNet == ZNet.instance) { return; } loadedZNet = ZNet.instance; foreach (Vector2Int item2 in clusters.Keys.ToList()) { DestroyCluster(item2); } clusters.Clear(); generatedMeshes.Clear(); records.Clear(); failedCacheCells.Clear(); pendingColliders.Clear(); queuedColliderCount = 0; loadedQueuedColliders = 0; activeColliderLoads = 0; worldName = text; string statePath = GetStatePath(); if (File.Exists(statePath)) { string[] array = File.ReadAllLines(statePath); if (array.Length == 0 || array[0] != "PUP_SAFE|7|64|GRAUSTEN|SUBCLUSTER16") { ((BaseUnityPlugin)this).Logger.LogError((object)"State format or cell size mismatch; automatic loading disabled"); ShowMessage("State file is incompatible; automatic loading disabled"); return; } Vector3 position = default(Vector3); Vector2Int key = default(Vector2Int); foreach (string item3 in array.Skip(1)) { string[] array2 = item3.Split(new char[1] { '|' }); if (array2.Length != 15 || !int.TryParse(array2[0], out var result) || !int.TryParse(array2[1], out var result2) || !long.TryParse(array2[2], out var result3) || !uint.TryParse(array2[3], out var result4) || !int.TryParse(array2[4], out var result5)) { continue; } float[] array3 = new float[10]; bool flag = true; for (int i = 0; i < array3.Length; i++) { flag &= float.TryParse(array2[i + 5], NumberStyles.Float, CultureInfo.InvariantCulture, out array3[i]); } if (flag) { ((Vector3)(ref position))..ctor(array3[0], array3[1], array3[2]); ((Vector2Int)(ref key))..ctor(result, result2); if (!records.ContainsKey(key)) { records[key] = new List(); } records[key].Add(new BakedRecord { userId = result3, id = result4, prefabHash = result5, position = position, rotation = new Quaternion(array3[3], array3[4], array3[5], array3[6]), scale = new Vector3(array3[7], array3[8], array3[9]) }); } } } int num = 0; ZDOID item = default(ZDOID); foreach (Vector2Int item4 in records.Keys.ToList()) { List list = records[item4]; HashSet hashSet = new HashSet(); List list2 = new List(list.Count); foreach (BakedRecord item5 in list) { ((ZDOID)(ref item))..ctor(item5.userId, item5.id); if (hashSet.Add(item)) { list2.Add(item5); } else { num++; } } records[item4] = list2; } bool num2 = RecoverRecordsFromParkedZDOs(); int num3 = RestoreLegacyParkedCoordinates(); if (num2 || num > 0 || num3 > 0) { SaveState(); } if (num > 0) { ((BaseUnityPlugin)this).Logger.LogWarning((object)$"Removed duplicate state records: {num}"); } ((BaseUnityPlugin)this).Logger.LogInfo((object)($"Loaded safe state: {records.Sum((KeyValuePair> entry) => entry.Value.Count)} ZDO; " + $"legacy positions migrated={num3}")); } private int RestoreLegacyParkedCoordinates() { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: 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_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) int num = 0; foreach (BakedRecord item in records.Values.SelectMany((List value) => value)) { ZDO zDO = ZDOMan.instance.GetZDO(new ZDOID(item.userId, item.id)); if (zDO != null && zDO.GetBool("PUP_SAFE_Baked", false)) { Vector3 position = zDO.GetPosition(); if (!(Mathf.Abs(position.x) < 950000f) || !(Mathf.Abs(position.z) < 950000f)) { Vector3 vec = zDO.GetVec3("PUP_SAFE_Position", item.position); zDO.SetPosition(vec); num++; } } } if (num > 0) { ((BaseUnityPlugin)this).Logger.LogWarning((object)$"Migrated {num} legacy parked objects to vanilla world coordinates"); } return num; } private bool RecoverRecordsFromParkedZDOs() { //IL_0017: 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_0021: 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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: 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_010f: 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_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) bool result = false; List list = new List(); Vector2i zone = ZoneSystem.GetZone(new Vector3(1900000f, 0f, 1900000f)); ZDOMan.instance.FindSectorObjects(zone, 0, 0, list, (List)null); HashSet hashSet = new HashSet(records.Values.SelectMany((List value) => value).Select((Func)((BakedRecord record) => new ZDOID(record.userId, record.id)))); Vector2Int key = default(Vector2Int); foreach (ZDO item in list) { if (item == null || !item.GetBool("PUP_SAFE_Baked", false) || hashSet.Contains(item.m_uid)) { continue; } string text = item.GetString("PUP_GRAUSTEN_ID", ""); if (!text.StartsWith("PUP_GRAUSTEN_", StringComparison.Ordinal)) { continue; } Vector3 vec = item.GetVec3("PUP_SAFE_Position", Vector3.zero); Quaternion quaternion = item.GetQuaternion("PUP_SAFE_Rotation", Quaternion.identity); Vector3 vec2 = item.GetVec3("PUP_SAFE_Scale", Vector3.one); ((Vector2Int)(ref key))..ctor(item.GetInt("PUP_SAFE_CellX", int.MinValue), item.GetInt("PUP_SAFE_CellZ", int.MinValue)); if (((Vector2Int)(ref key)).x != int.MinValue && ((Vector2Int)(ref key)).y != int.MinValue) { if (!records.ContainsKey(key)) { records[key] = new List(); } records[key].Add(new BakedRecord { customId = text, userId = ((ZDOID)(ref item.m_uid)).UserID, id = ((ZDOID)(ref item.m_uid)).ID, prefabHash = item.GetPrefab(), position = vec, rotation = quaternion, scale = vec2 }); hashSet.Add(item.m_uid); result = true; } } return result; } private static string V(float value) { return value.ToString("R", CultureInfo.InvariantCulture); } private int RestoreCoordinatesForVanillaSave(string reason) { //IL_005d: 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_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) int num = 0; if (ZDOMan.instance == null) { return num; } foreach (BakedRecord item in records.Values.SelectMany((List value) => value)) { ZDO zDO = ZDOMan.instance.GetZDO(new ZDOID(item.userId, item.id)); if (zDO != null && zDO.GetBool("PUP_SAFE_Baked", false)) { Vector3 vec = zDO.GetVec3("PUP_SAFE_Position", item.position); zDO.SetPosition(vec); ZNetView val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.FindInstance(zDO) : null); if ((Object)(object)val != (Object)null) { ((Component)val).transform.position = vec; } num++; } } if (num > 0) { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"[VANILLA-SAFE] restored {num} ZDO before {reason}"); } return num; } private void ReparkBakedCell(Vector2Int cell) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_00e6: Unknown result type (might be due to invalid IL or missing references) if (!records.TryGetValue(cell, out var value) || ZDOMan.instance == null) { return; } Vector3 position = default(Vector3); foreach (BakedRecord item in value) { ZDO zDO = ZDOMan.instance.GetZDO(new ZDOID(item.userId, item.id)); if (zDO != null && zDO.GetBool("PUP_SAFE_Baked", false)) { uint iD = ((ZDOID)(ref zDO.m_uid)).ID; ((Vector3)(ref position))..ctor(1900000f + (float)(iD % 200) * 0.05f, item.position.y, 1900000f + (float)(iD / 200 % 200) * 0.05f); zDO.SetPosition(position); ZNetView val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.FindInstance(zDO) : null); if ((Object)(object)val != (Object)null) { ((Component)val).transform.position = position; } } } } private IEnumerator ReparkAfterVanillaSave(ZNet saveNet) { yield return null; while (!applicationQuitting && (Object)(object)ZNet.instance == (Object)(object)saveNet && (Object)(object)saveNet != (Object)null && saveNet.IsSaving()) { yield return null; } if (!applicationQuitting && (Object)(object)ZNet.instance == (Object)(object)saveNet && (Object)(object)saveNet != (Object)null) { foreach (Vector2Int item in records.Keys.ToList()) { ReparkBakedCell(item); } ((BaseUnityPlugin)this).Logger.LogInfo((object)$"[VANILLA-SAFE] save finished; reparked {records.Sum((KeyValuePair> value) => value.Value.Count)} ZDO"); } safeSaveRestoreInProgress = false; } private void BeforeVanillaWorldSave() { if (!safeSaveRestoreInProgress && records.Count != 0) { safeSaveRestoreInProgress = true; RestoreCoordinatesForVanillaSave("world save"); ((MonoBehaviour)this).StartCoroutine(ReparkAfterVanillaSave(ZNet.instance)); } } private bool ShouldBlockSupportUpdate() { if (!processing && activeColliderLoads <= 0 && pendingSubClusterLoads <= 0) { return Time.time < supportGuardUntil; } return true; } private void ShowMessage(string message) { if ((Object)(object)MessageHud.instance != (Object)null) { MessageHud.instance.ShowMessage((MessageType)2, message, 0, (Sprite)null, false); } } } }