Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ValheimEnhancedEdition v1.1.0
BepInEx/plugins/ValheimEnhancedEdition/ValheimEnhancedEdition.dll
Decompiled 3 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; using System.Threading; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Unity.Collections; using Unity.Jobs; using Unity.Profiling; using UnityEngine; using UnityEngine.LowLevel; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: AssemblyVersion("0.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace PerfMod { internal static class CreateDestroySkip { private static readonly FieldRef<ZNetScene, List<ZDO>> Near = AccessTools.FieldRefAccess<ZNetScene, List<ZDO>>("m_tempCurrentObjects"); private static readonly FieldRef<ZNetScene, List<ZDO>> Distant = AccessTools.FieldRefAccess<ZNetScene, List<ZDO>>("m_tempCurrentDistantObjects"); private static readonly FieldRef<ZNetScene, List<ZNetView>> Removed = AccessTools.FieldRefAccess<ZNetScene, List<ZNetView>>("m_tempRemoved"); private static long s_version; private static long s_versionAtFull = -1L; private static Vector2s s_zoneAtFull; private static int s_nearDistAtFull = -1; private static int s_totalDistAtFull = -1; private static int s_createdThisCall; private static bool s_classicAtFull; private static bool s_lastFullIdle; private static bool s_skipped; private static float s_lastFullTime = -100f; internal static void Patch(Harmony h) { //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Expected O, but got Unknown //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Expected O, but got Unknown P(typeof(ZNetScene), "CreateDestroyObjects", "Pre", "Post"); P(typeof(ZNetScene), "CreateObject", null, "Created"); P(typeof(ZDOMan), "AddToSector", null, "Bump"); P(typeof(ZDOMan), "InitialAddToSector", null, "Bump"); P(typeof(ZDOMan), "RemoveFromSector", null, "Bump"); P(typeof(ZDOMan), "AddIfPortal", null, "Bump"); P(typeof(ZDOMan), "HandleDestroyedZDO", null, "Bump"); P(typeof(ZDOMan), "DestroyZDO", null, "Bump"); P(typeof(ZDOMan), "Load", null, "Bump"); P(typeof(ZDOMan), "LoadChunks", null, "Bump"); h.Patch((MethodBase)AccessTools.PropertySetter(typeof(ZDO), "Distant"), (HarmonyMethod)null, new HarmonyMethod(typeof(CreateDestroySkip), "Bump", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); P(typeof(ZNetScene), "AddInstance", null, "Bump"); h.Patch((MethodBase)AccessTools.Method(typeof(ZNetScene), "Destroy", new Type[1] { typeof(GameObject) }, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(CreateDestroySkip), "Bump", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); P(typeof(ZNetScene), "OnZDODestroyed", null, "Bump"); void P(Type t, string m, string pre = null, string post = null) { //IL_0022: 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) h.Patch((MethodBase)AccessTools.Method(t, m, (Type[])null, (Type[])null), (pre == null) ? ((HarmonyMethod)null) : new HarmonyMethod(typeof(CreateDestroySkip), pre, (Type[])null), (post == null) ? ((HarmonyMethod)null) : new HarmonyMethod(typeof(CreateDestroySkip), post, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } private static void Bump() { s_version++; } private static void Created() { s_createdThisCall++; } private static bool Pre() { //IL_0039: 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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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) s_createdThisCall = 0; s_skipped = false; if (!Plugin.CreateSkipOn.Value || (Object)(object)ZNet.instance == (Object)null || (Object)(object)ZoneSystem.instance == (Object)null) { return true; } Vector2s zone = ZoneSystem.GetZone(ZNet.instance.GetReferencePosition()); SimulationDistance syncedSimulationDistance = ZNet.instance.GetSyncedSimulationDistance(); if (!s_lastFullIdle || s_version != s_versionAtFull || !(zone == s_zoneAtFull) || ((SimulationDistance)(ref syncedSimulationDistance)).NearSimulationDistance != s_nearDistAtFull || ((SimulationDistance)(ref syncedSimulationDistance)).TotalSimulationDistance != s_totalDistAtFull || ((SimulationDistance)(ref syncedSimulationDistance)).IsClassic != s_classicAtFull || !(Time.time - s_lastFullTime < 1f)) { return true; } s_skipped = true; return false; } private static void Post(ZNetScene __instance) { //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: 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) if (s_skipped) { s_skipped = false; return; } List<ZDO> list = Near.Invoke(__instance); List<ZDO> list2 = Distant.Invoke(__instance); bool flag = false; for (int i = 0; i < list.Count; i++) { if (flag) { break; } if (!list[i].Created) { flag = true; } } for (int j = 0; j < list2.Count; j++) { if (flag) { break; } if (!list2[j].Created) { flag = true; } } s_lastFullIdle = s_createdThisCall == 0 && Removed.Invoke(__instance).Count == 0 && !flag; s_versionAtFull = s_version; s_zoneAtFull = ZoneSystem.GetZone(ZNet.instance.GetReferencePosition()); SimulationDistance syncedSimulationDistance = ZNet.instance.GetSyncedSimulationDistance(); s_nearDistAtFull = ((SimulationDistance)(ref syncedSimulationDistance)).NearSimulationDistance; s_totalDistAtFull = ((SimulationDistance)(ref syncedSimulationDistance)).TotalSimulationDistance; s_classicAtFull = ((SimulationDistance)(ref syncedSimulationDistance)).IsClassic; s_lastFullTime = Time.time; } } internal static class FarLandsLink { internal const string Guid = "ru.ivest.farlands"; private static bool s_looked; private static bool s_present; private static bool s_told; private static Func<bool> s_active; private static Func<float> s_size; private static ConfigEntry<bool> s_enabled; private static ConfigEntry<float> s_terrain; private static ConfigEntry<float> s_forest; private static ConfigEntry<bool> s_bEnabled; private static ConfigEntry<float> s_bDistance; private static ConfigEntry<float> s_bHandoff; private static long s_warnedWorld = -1L; private static float s_next = -1f; private static bool s_drawing; private static float s_reach; private static float s_forestRange; private static bool s_loggedDrawing; private static float s_loggedReach; internal const string BuildingsWarning = "FarLands far buildings are on: set [Buildings] Enabled = false in ru.ivest.farlands.cfg, or bases are drawn twice."; internal static bool Present { get { Look(); return s_present; } } internal static bool Drawing { get { Refresh(); return s_drawing; } } internal static float Reach { get { Refresh(); return s_reach; } } internal static float ForestRange { get { Refresh(); return s_forestRange; } } internal static bool BuildingsOn { get { Look(); if (s_present && s_bEnabled != null) { return s_bEnabled.Value; } return false; } } private static void Look() { if (s_looked) { return; } s_looked = true; try { if (Chainloader.PluginInfos.TryGetValue("ru.ivest.farlands", out var value) && !((Object)(object)value.Instance == (Object)null)) { s_present = true; ConfigFile config = value.Instance.Config; config.TryGetEntry<bool>("General", "Enabled", ref s_enabled); config.TryGetEntry<float>("General", "TerrainDistance", ref s_terrain); config.TryGetEntry<float>("General", "ForestDistance", ref s_forest); config.TryGetEntry<bool>("Buildings", "Enabled", ref s_bEnabled); config.TryGetEntry<float>("Buildings", "Distance", ref s_bDistance); config.TryGetEntry<float>("Buildings", "HandoffDistance", ref s_bHandoff); Type? type = ((object)value.Instance).GetType().Assembly.GetType("FarLands.FarLandsReach", throwOnError: false); MethodInfo methodInfo = type?.GetProperty("Active", BindingFlags.Static | BindingFlags.Public)?.GetGetMethod(); MethodInfo methodInfo2 = type?.GetProperty("Size", BindingFlags.Static | BindingFlags.Public)?.GetGetMethod(); if (methodInfo != null && methodInfo2 != null) { s_active = (Func<bool>)Delegate.CreateDelegate(typeof(Func<bool>), methodInfo); s_size = (Func<float>)Delegate.CreateDelegate(typeof(Func<float>), methodInfo2); } Plugin.Log.LogInfo((object)(string.Format("far builds: FarLands {0} found ({1}; land {2:0} m, trees {3:0} m; ", value.Metadata.Version, (s_active != null) ? "its live reach read" : "its settings only", F(s_terrain, 4000f), F(s_forest, 2500f)) + ((s_bEnabled == null) ? "no far buildings of its own)" : string.Format("its far buildings {0}, to {1:0} m, from {2:0} m)", s_bEnabled.Value ? "on" : "off", F(s_bDistance, 2500f), F(s_bHandoff, 250f))))); } } catch (Exception e) { Fail(e); } } private static void Fail(Exception e) { s_active = null; s_size = null; if (!s_told) { s_told = true; Plugin.Log.LogWarning((object)("far builds: FarLands could not be read (" + e.Message + "); going by its settings, or as if it were absent")); } } private static float F(ConfigEntry<float> e, float def) { return e?.Value ?? def; } private static void Refresh() { if (Time.unscaledTime < s_next && s_next >= 0f) { return; } s_next = Time.unscaledTime + 0.25f; Look(); s_drawing = false; s_reach = 0f; s_forestRange = 0f; if (!s_present) { return; } float num = F(s_terrain, 4000f); if (s_active != null) { try { s_drawing = s_active(); if (s_drawing) { num = s_size() * 0.5f; } } catch (Exception e) { Fail(e); s_drawing = s_enabled == null || s_enabled.Value; } } else { s_drawing = s_enabled == null || s_enabled.Value; } if (s_drawing) { s_reach = Mathf.Max(0f, num); s_forestRange = Mathf.Clamp(F(s_forest, 2500f), 0f, s_reach); } if (s_drawing != s_loggedDrawing || Mathf.Abs(s_reach - s_loggedReach) > 1f) { s_loggedDrawing = s_drawing; s_loggedReach = s_reach; Plugin.Log.LogInfo((object)(s_drawing ? $"far builds: FarLands drawing (land {s_reach:0} m, its trees {s_forestRange:0} m)" : "far builds: FarLands not drawing")); } } internal static void WarnBuildings() { if (!BuildingsOn) { return; } long num = ((ZNet.World != null) ? ZNet.World.m_uid : 0); if (num == s_warnedWorld) { return; } s_warnedWorld = num; Plugin.Log.LogWarning((object)"FarLands far buildings are on: set [Buildings] Enabled = false in ru.ivest.farlands.cfg, or bases are drawn twice."); try { Console instance = Console.instance; if (instance != null) { instance.Print("Valheim Enhanced Edition: FarLands far buildings are on: set [Buildings] Enabled = false in ru.ivest.farlands.cfg, or bases are drawn twice."); } MessageHud instance2 = MessageHud.instance; if (instance2 != null) { instance2.ShowMessage((MessageType)2, "FarLands far buildings are on: set [Buildings] Enabled = false in ru.ivest.farlands.cfg, or bases are drawn twice.", 0, (Sprite)null, false, true); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("far builds: the FarLands warning wasn't shown on screen: " + ex.Message)); } } } internal struct FarEntry { public int Prefab; public float X; public float Y; public float Z; public float QX; public float QY; public float QZ; public float QW; public bool Scaled; public float SX; public float SY; public float SZ; public bool Snow; } internal static class FarManifest { internal const int Protocol = 1; internal const float Area = 64f; internal const float Zone = 64f; private const long TerrainMark = 9103745171752747008L; internal static long AreaOf(float x, float z) { return ((long)(int)Math.Floor(x / 64f) << 32) ^ (uint)(int)Math.Floor(z / 64f); } internal static long TerrainId(int zoneX, int zoneZ) { return (long)(0x7E57000000000000L | ((ulong)(ushort)(short)zoneX << 16) | (ushort)(short)zoneZ); } internal static bool IsTerrain(long id) { return (id & -281474976710656L) == 9103745171752747008L; } internal static void TerrainZone(long id, out int zoneX, out int zoneZ) { zoneX = (short)(ushort)(id >> 16); zoneZ = (short)(ushort)id; } internal static void TerrainOrigin(long id, out float x, out float z) { TerrainZone(id, out var zoneX, out var zoneZ); x = (float)zoneX * 64f - 32f; z = (float)zoneZ * 64f - 32f; } internal static uint HashBytes(byte[] b) { uint num = 2166136261u; foreach (byte b2 in b) { num ^= b2; num *= 16777619; } if (num != 0) { return num; } return 1u; } internal static void OriginOf(long id, out float x, out float z) { x = (float)(int)(id >> 32) * 64f; z = (float)(int)id * 64f; } private static ushort Local(float v, float origin) { return (ushort)Math.Max(0, Math.Min(65535, (int)Math.Round((v - origin) / 64f * 65535f))); } private static float Unlocal(ushort v, float origin) { return origin + (float)(int)v * 0.0009765774f; } private static sbyte Q(float v) { return (sbyte)Math.Max(-127, Math.Min(127, (int)Math.Round(v * 127f))); } internal static FarEntry Quantize(long id, FarEntry e) { OriginOf(id, out var x, out var z); FarEntry result = e; result.X = Unlocal(Local(e.X, x), x); result.Z = Unlocal(Local(e.Z, z), z); float num = Q(e.QX); float num2 = Q(e.QY); float num3 = Q(e.QZ); float num4 = Q(e.QW); float num5 = (float)Math.Sqrt(num * num + num2 * num2 + num3 * num3 + num4 * num4); if (num5 < 1E-06f) { num4 = 1f; num5 = 1f; } result.QX = num / num5; result.QY = num2 / num5; result.QZ = num3 / num5; result.QW = num4 / num5; return result; } internal static void Write(BinaryWriter w, long id, List<FarEntry> list) { OriginOf(id, out var x, out var z); w.Write(id); w.Write(list.Count); foreach (FarEntry item in list) { w.Write(item.Prefab); w.Write(Local(item.X, x)); w.Write(Local(item.Z, z)); w.Write(item.Y); w.Write(Q(item.QX)); w.Write(Q(item.QY)); w.Write(Q(item.QZ)); w.Write(Q(item.QW)); w.Write((byte)((item.Scaled ? 1u : 0u) | (uint)(item.Snow ? 2 : 0))); if (item.Scaled) { w.Write(item.SX); w.Write(item.SY); w.Write(item.SZ); } } } internal static List<FarEntry> Read(BinaryReader r, out long id) { id = r.ReadInt64(); return ReadBody(r, id); } internal static List<FarEntry> ReadBody(BinaryReader r, long id) { int num = r.ReadInt32(); if (num < 0 || num > 1000000) { throw new InvalidDataException("bad piece count " + num); } OriginOf(id, out var x, out var z); List<FarEntry> list = new List<FarEntry>(num); for (int i = 0; i < num; i++) { FarEntry item = new FarEntry { Prefab = r.ReadInt32() }; item.X = Unlocal(r.ReadUInt16(), x); item.Z = Unlocal(r.ReadUInt16(), z); item.Y = r.ReadSingle(); float num2 = r.ReadSByte(); float num3 = r.ReadSByte(); float num4 = r.ReadSByte(); float num5 = r.ReadSByte(); float num6 = (float)Math.Sqrt(num2 * num2 + num3 * num3 + num4 * num4 + num5 * num5); if (num6 < 1E-06f) { num5 = 1f; num6 = 1f; } item.QX = num2 / num6; item.QY = num3 / num6; item.QZ = num4 / num6; item.QW = num5 / num6; byte b = r.ReadByte(); item.Scaled = (b & 1) != 0; item.Snow = (b & 2) != 0; if (item.Scaled) { item.SX = r.ReadSingle(); item.SY = r.ReadSingle(); item.SZ = r.ReadSingle(); } list.Add(item); } return list; } internal static uint Hash(long id, List<FarEntry> list) { MemoryStream memoryStream = new MemoryStream(); using (BinaryWriter w = new BinaryWriter(memoryStream)) { Write(w, id, Sorted(list)); } byte[] array = memoryStream.ToArray(); uint num = 2166136261u; byte[] array2 = array; foreach (byte b in array2) { num ^= b; num *= 16777619; } if (num != 0) { return num; } return 1u; } internal static List<FarEntry> Sorted(List<FarEntry> list) { List<FarEntry> list2 = new List<FarEntry>(list); list2.Sort(delegate(FarEntry a, FarEntry b) { int num = a.Prefab.CompareTo(b.Prefab); if (num != 0) { return num; } num = a.X.CompareTo(b.X); if (num != 0) { return num; } num = a.Z.CompareTo(b.Z); return (num != 0) ? num : a.Y.CompareTo(b.Y); }); return list2; } internal static byte[] WriteIndex(Dictionary<long, uint> index) { MemoryStream memoryStream = new MemoryStream(); using (BinaryWriter binaryWriter = new BinaryWriter(memoryStream)) { binaryWriter.Write(1); binaryWriter.Write(index.Count); foreach (KeyValuePair<long, uint> item in index) { binaryWriter.Write(item.Key); binaryWriter.Write(item.Value); } } return memoryStream.ToArray(); } internal static Dictionary<long, uint> ReadIndex(byte[] data) { using BinaryReader binaryReader = new BinaryReader(new MemoryStream(data)); if (binaryReader.ReadInt32() != 1) { return null; } int num = binaryReader.ReadInt32(); if (num < 0 || num > 10000000) { throw new InvalidDataException("bad index size " + num); } Dictionary<long, uint> dictionary = new Dictionary<long, uint>(num); for (int i = 0; i < num; i++) { dictionary[binaryReader.ReadInt64()] = binaryReader.ReadUInt32(); } return dictionary; } } internal static class FarNet { private class HashJob { public volatile bool Done; public Dictionary<long, uint> Result; public Exception Error; } private const string Hello = "VEE_FarHello"; private const string Index = "VEE_FarIndex"; private const string Want = "VEE_FarWant"; private const string Cells = "VEE_FarCells"; private const string Changed = "VEE_FarChanged"; private static ZRoutedRpc s_registeredOn; private static int s_errors; private static readonly HashSet<long> s_subs = new HashSet<long>(); private static readonly Dictionary<long, uint> s_index = new Dictionary<long, uint>(); private static readonly Dictionary<long, List<FarEntry>> s_lists = new Dictionary<long, List<FarEntry>>(); private static readonly FieldRef<ZDOMan, Dictionary<ZDOID, ZDO>> ZdosById = AccessTools.FieldRefAccess<ZDOMan, Dictionary<ZDOID, ZDO>>("m_objectsByID"); private static List<ZDO> s_scan; private static int s_scanAt; private static long s_scanTicks; private static int s_scanFrames; private static float s_scanStarted; private static Dictionary<long, List<FarEntry>> s_scanLists; private static bool s_scanned; private static float s_nextScan; private static HashSet<int> s_pieceHashes; private static HashSet<int> s_syncScale; private static HashSet<int> s_terrainHashes; private static Dictionary<long, byte[]> s_scanTerrain; private static readonly Dictionary<long, byte[]> s_terrain = new Dictionary<long, byte[]>(); private const float RescanSeconds = 20f; private static HashJob s_hashing; private const int ReplyBytes = 65536; private static float s_helloAt = -1f; private static Dictionary<long, uint> s_remote; private static bool s_inFlight; private static bool s_told; private static float s_sentAt; private static float s_nextWant; private static bool Serving { get { if (Plugin.FarServeOn != null) { return Plugin.FarServeOn.Value; } return true; } } internal static bool RemoteReady => s_remote != null; internal static bool NoServerMod { get { if (s_remote == null && s_helloAt >= 0f) { return Time.unscaledTime - s_helloAt > 20f; } return false; } } internal static void Tick() { if ((Object)(object)ZNet.instance == (Object)null || ZRoutedRpc.instance == null) { if (s_registeredOn != null) { Reset(); } return; } if (s_registeredOn != ZRoutedRpc.instance) { Reset(); s_registeredOn = ZRoutedRpc.instance; ZRoutedRpc.instance.Register<ZPackage>("VEE_FarHello", (Action<long, ZPackage>)OnHello); ZRoutedRpc.instance.Register<ZPackage>("VEE_FarWant", (Action<long, ZPackage>)OnWant); ZRoutedRpc.instance.Register<ZPackage>("VEE_FarIndex", (Action<long, ZPackage>)OnIndex); ZRoutedRpc.instance.Register<ZPackage>("VEE_FarCells", (Action<long, ZPackage>)OnCells); ZRoutedRpc.instance.Register<ZPackage>("VEE_FarChanged", (Action<long, ZPackage>)OnChanged); } try { if (ZNet.instance.IsServer()) { ServerTick(); } else { ClientTick(); } } catch (Exception ex) { if (s_errors++ < 5) { Plugin.Log.LogWarning((object)("far view on servers: " + ex)); } } } private static void Reset() { s_registeredOn = null; s_subs.Clear(); s_index.Clear(); s_lists.Clear(); s_terrain.Clear(); s_scan = null; s_hashing = null; s_scanned = false; s_nextScan = 0f; s_pieceHashes = null; s_helloAt = -1f; s_remote = null; s_inFlight = false; s_told = false; MergeRender.RemoteReset(); } private static byte[] Pack(byte[] raw) { return Utils.Compress(raw); } private static byte[] Unpack(byte[] data) { return Utils.Decompress(data); } private static void OnHello(long sender, ZPackage pkg) { if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer() || !Serving) { return; } int num = pkg.ReadInt(); if (num != 1) { Plugin.Log.LogInfo((object)$"far view on servers: a client with protocol {num} (ours {1}) asked: not served"); return; } bool flag = s_subs.Count == 0; s_subs.Add(sender); Plugin.Log.LogInfo((object)$"far view on servers: client {sender} subscribed ({s_subs.Count} now)"); if (s_scanned) { SendIndex(sender); } else if (flag && s_scan == null) { s_nextScan = 0f; } } private static void SendIndex(long peer) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(Pack(FarManifest.WriteIndex(s_index))); ZRoutedRpc.instance.InvokeRoutedRPC(peer, "VEE_FarIndex", new object[1] { val }); } private static void OnWant(long sender, ZPackage pkg) { //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Expected O, but got Unknown if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer() || !Serving || !s_subs.Contains(sender)) { return; } int num = Math.Min(pkg.ReadInt(), 64); MemoryStream memoryStream = new MemoryStream(); int num2 = 0; using (BinaryWriter binaryWriter = new BinaryWriter(memoryStream)) { List<long> list = new List<long>(); for (int i = 0; i < num; i++) { list.Add(pkg.ReadLong()); } MemoryStream memoryStream2 = new MemoryStream(); using (BinaryWriter binaryWriter2 = new BinaryWriter(memoryStream2)) { foreach (long item in list) { if (memoryStream2.Length > 131072) { break; } uint value; uint num3 = (s_index.TryGetValue(item, out value) ? value : 0u); binaryWriter2.Write(num3); if (FarManifest.IsTerrain(item)) { binaryWriter2.Write(item); byte[] value2; byte[] array = ((num3 != 0 && s_terrain.TryGetValue(item, out value2)) ? value2 : new byte[0]); binaryWriter2.Write(array.Length); binaryWriter2.Write(array); } else { FarManifest.Write(binaryWriter2, item, (num3 != 0 && s_lists.TryGetValue(item, out var value3)) ? value3 : new List<FarEntry>()); } num2++; } } binaryWriter.Write(num2); binaryWriter.Write(memoryStream2.ToArray()); } ZPackage val = new ZPackage(); val.Write(Pack(memoryStream.ToArray())); ZRoutedRpc.instance.InvokeRoutedRPC(sender, "VEE_FarCells", new object[1] { val }); } private static void ServerTick() { //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: 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_0215: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_023f: 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_025b: Unknown result type (might be due to invalid IL or missing references) //IL_032a: Unknown result type (might be due to invalid IL or missing references) //IL_0331: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: 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_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_02ea: 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_0302: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_031e: Unknown result type (might be due to invalid IL or missing references) //IL_080d: Unknown result type (might be due to invalid IL or missing references) //IL_0814: Expected O, but got Unknown if (!Serving || s_subs.Count == 0) { return; } if (Time.frameCount % 120 == 0) { s_subs.RemoveWhere((long id) => ZNet.instance.GetPeer(id) == null); } if (s_subs.Count == 0) { return; } if (s_scan == null) { if (Time.unscaledTime < s_nextScan || ZDOMan.instance == null || (Object)(object)ZNetScene.instance == (Object)null) { return; } if (s_pieceHashes == null) { Pieces(); } s_scan = new List<ZDO>(ZdosById.Invoke(ZDOMan.instance).Values); s_scanAt = 0; s_scanLists = new Dictionary<long, List<FarEntry>>(); s_scanTerrain = new Dictionary<long, byte[]>(); s_scanTicks = 0L; s_scanFrames = 0; s_scanStarted = Time.unscaledTime; } long timestamp = Stopwatch.GetTimestamp(); long num = timestamp + (long)(2.0 / Clock.TickMs); if (s_scanAt < s_scan.Count) { s_scanFrames++; } while (s_scanAt < s_scan.Count) { if ((s_scanAt & 0xFF) == 0 && Stopwatch.GetTimestamp() > num) { s_scanTicks += Stopwatch.GetTimestamp() - timestamp; return; } ZDO val = s_scan[s_scanAt]; if (val != null && val.IsValid()) { if (s_terrainHashes.Contains(val.GetPrefab())) { byte[] byteArray = val.GetByteArray(ZDOVars.s_TCData, (byte[])null); if (byteArray != null && byteArray.Length != 0) { Vector2s zone = ZoneSystem.GetZone(val.GetPosition()); s_scanTerrain[FarManifest.TerrainId(zone.x, zone.y)] = byteArray; } } else if (s_pieceHashes.Contains(val.GetPrefab())) { Vector3 position = val.GetPosition(); Quaternion rotation = val.GetRotation(); FarEntry item = new FarEntry { Prefab = val.GetPrefab(), X = position.x, Y = position.y, Z = position.z, QX = rotation.x, QY = rotation.y, QZ = rotation.z, QW = rotation.w, Snow = (val.GetFloat(ZDOVars.s_snow, 0f) > 0.25f) }; if (s_syncScale.Contains(item.Prefab)) { Vector3 vec = val.GetVec3(ZDOVars.s_scaleHash, Vector3.zero); if (vec == Vector3.zero) { float num2 = val.GetFloat(ZDOVars.s_scaleScalarHash, 0f); if (num2 > 0f) { ((Vector3)(ref vec))..ctor(num2, num2, num2); } } if (vec != Vector3.zero) { item.Scaled = true; item.SX = vec.x; item.SY = vec.y; item.SZ = vec.z; } } long key = FarManifest.AreaOf(position.x, position.z); if (!s_scanLists.TryGetValue(key, out var value)) { value = (s_scanLists[key] = new List<FarEntry>()); } value.Add(item); } } s_scanAt++; } if (s_hashing == null) { s_scanTicks += Stopwatch.GetTimestamp() - timestamp; Dictionary<long, List<FarEntry>> lists = s_scanLists; Dictionary<long, byte[]> terrain = s_scanTerrain; HashJob job = (s_hashing = new HashJob()); ThreadPool.QueueUserWorkItem(delegate { Dictionary<long, uint> dictionary = new Dictionary<long, uint>(lists.Count + terrain.Count); try { foreach (KeyValuePair<long, List<FarEntry>> item2 in lists) { dictionary[item2.Key] = FarManifest.Hash(item2.Key, item2.Value); } foreach (KeyValuePair<long, byte[]> item3 in terrain) { dictionary[item3.Key] = FarManifest.HashBytes(item3.Value); } } catch (Exception error) { job.Error = error; } job.Result = dictionary; job.Done = true; }); } else { if (!s_hashing.Done) { return; } HashJob hashJob = s_hashing; s_hashing = null; if (hashJob.Error != null) { s_scan = null; s_scanLists = null; s_nextScan = Time.unscaledTime + 20f; throw hashJob.Error; } List<KeyValuePair<long, uint>> list2 = new List<KeyValuePair<long, uint>>(); Dictionary<long, uint> result = hashJob.Result; if (s_scanned) { foreach (KeyValuePair<long, uint> item4 in result) { if (!s_index.TryGetValue(item4.Key, out var value2) || value2 != item4.Value) { list2.Add(item4); } } foreach (KeyValuePair<long, uint> item5 in s_index) { if (!result.ContainsKey(item5.Key)) { list2.Add(new KeyValuePair<long, uint>(item5.Key, 0u)); } } } int num3 = s_scanLists.Values.Sum((List<FarEntry> l) => l.Count); s_index.Clear(); foreach (KeyValuePair<long, uint> item6 in result) { s_index[item6.Key] = item6.Value; } s_lists.Clear(); foreach (KeyValuePair<long, List<FarEntry>> s_scanList in s_scanLists) { s_lists[s_scanList.Key] = s_scanList.Value; } s_terrain.Clear(); foreach (KeyValuePair<long, byte[]> item7 in s_scanTerrain) { s_terrain[item7.Key] = item7.Value; } int num4 = s_scanTerrain.Values.Sum((byte[] b) => b.Length); string text = $"scan of {s_scan.Count} objects: {(double)s_scanTicks * Clock.TickMs:0.0} ms main thread over {s_scanFrames} frames, {Time.unscaledTime - s_scanStarted:0.00} s with the hashing"; s_scan = null; s_scanLists = null; s_scanTerrain = null; s_nextScan = Time.unscaledTime + 20f; if (!s_scanned) { s_scanned = true; Plugin.Log.LogInfo((object)$"far view on servers: {num3} pieces in {s_lists.Count} areas, terrain edits in {s_terrain.Count} zones ({num4 / 1024} KB); sending the index to {s_subs.Count} clients; {text}"); { foreach (long s_sub in s_subs) { SendIndex(s_sub); } return; } } if (list2.Count <= 0) { return; } MemoryStream memoryStream = new MemoryStream(); using (BinaryWriter binaryWriter = new BinaryWriter(memoryStream)) { binaryWriter.Write(list2.Count); foreach (KeyValuePair<long, uint> item8 in list2) { binaryWriter.Write(item8.Key); binaryWriter.Write(item8.Value); } } byte[] array = Pack(memoryStream.ToArray()); foreach (long s_sub2 in s_subs) { ZPackage val2 = new ZPackage(); val2.Write(array); ZRoutedRpc.instance.InvokeRoutedRPC(s_sub2, "VEE_FarChanged", new object[1] { val2 }); } Plugin.Log.LogInfo((object)$"far view on servers: {list2.Count} areas changed; {text}"); } } private static void Pieces() { s_pieceHashes = new HashSet<int>(); s_syncScale = new HashSet<int>(); s_terrainHashes = new HashSet<int>(); foreach (GameObject prefab in ZNetScene.instance.m_prefabs) { if ((Object)(object)prefab != (Object)null && (Object)(object)prefab.GetComponent<TerrainComp>() != (Object)null) { s_terrainHashes.Add(StringExtensionMethods.GetStableHashCode(((Object)prefab).name)); } else if (!((Object)(object)prefab == (Object)null) && !((Object)(object)prefab.GetComponent<WearNTear>() == (Object)null) && !((Object)(object)prefab.GetComponentInChildren<Rigidbody>(true) != (Object)null)) { int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)prefab).name); s_pieceHashes.Add(stableHashCode); ZNetView component = prefab.GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.m_syncInitialScale) { s_syncScale.Add(stableHashCode); } } } } private static void ClientTick() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Expected O, but got Unknown if (Plugin.FarOn == null || !Plugin.FarOn.Value || (Object)(object)Player.m_localPlayer == (Object)null || ZNet.World == null) { return; } if (s_helloAt < 0f) { s_helloAt = Time.unscaledTime; ZPackage val = new ZPackage(); val.Write(1); ZRoutedRpc.instance.InvokeRoutedRPC("VEE_FarHello", new object[1] { val }); } if (NoServerMod && !s_told) { s_told = true; Plugin.Log.LogInfo((object)("far view on servers: this server doesn't serve far view (no Valheim Enhanced Edition there)" + ((Plugin.FarVisitedOn != null && Plugin.FarVisitedOn.Value) ? "; far copies of the bases you visit are kept" : "; far view stays off ([Far builds] VisitedOnServers keeps copies of the bases you visit)"))); } if (s_remote == null) { return; } if (s_inFlight && Time.unscaledTime - s_sentAt > 15f) { s_inFlight = false; } if (s_inFlight || Time.unscaledTime < s_nextWant) { return; } List<long> list = MergeRender.RemoteWanted(s_remote, 24); if (list.Count == 0) { s_nextWant = Time.unscaledTime + 1f; return; } ZPackage val2 = new ZPackage(); val2.Write(list.Count); foreach (long item in list) { val2.Write(item); } ZRoutedRpc.instance.InvokeRoutedRPC("VEE_FarWant", new object[1] { val2 }); s_inFlight = true; s_sentAt = Time.unscaledTime; s_nextWant = Time.unscaledTime + 1f; } private static void OnIndex(long sender, ZPackage pkg) { if (!((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsServer()) { Dictionary<long, uint> dictionary = FarManifest.ReadIndex(Unpack(pkg.ReadByteArray())); if (dictionary == null) { Plugin.Log.LogInfo((object)"far view on servers: the server's protocol differs: far view stays off here"); return; } s_remote = dictionary; Plugin.Log.LogInfo((object)$"far view on servers: the server serves far view ({dictionary.Count} areas with pieces)"); MergeRender.RemoteIndex(dictionary); } } private static void OnCells(long sender, ZPackage pkg) { if ((Object)(object)ZNet.instance == (Object)null || ZNet.instance.IsServer() || s_remote == null) { return; } s_inFlight = false; using BinaryReader binaryReader = new BinaryReader(new MemoryStream(Unpack(pkg.ReadByteArray()))); int num = binaryReader.ReadInt32(); using BinaryReader binaryReader2 = new BinaryReader(new MemoryStream(binaryReader.ReadBytes((int)(binaryReader.BaseStream.Length - binaryReader.BaseStream.Position)))); for (int i = 0; i < num; i++) { uint num2 = binaryReader2.ReadUInt32(); long num3 = binaryReader2.ReadInt64(); if (num2 == 0) { s_remote.Remove(num3); } else { s_remote[num3] = num2; } if (FarManifest.IsTerrain(num3)) { int count = binaryReader2.ReadInt32(); MergeRender.RemoteTerrain(num3, num2, binaryReader2.ReadBytes(count)); } else { MergeRender.RemoteArea(num3, num2, FarManifest.ReadBody(binaryReader2, num3)); } } } private static void OnChanged(long sender, ZPackage pkg) { if ((Object)(object)ZNet.instance == (Object)null || ZNet.instance.IsServer() || s_remote == null) { return; } using BinaryReader binaryReader = new BinaryReader(new MemoryStream(Unpack(pkg.ReadByteArray()))); int num = binaryReader.ReadInt32(); for (int i = 0; i < num; i++) { long num2 = binaryReader.ReadInt64(); uint num3 = binaryReader.ReadUInt32(); if (num3 == 0) { s_remote.Remove(num2); } else { s_remote[num2] = num3; } MergeRender.RemoteChanged(num2, num3); } } } internal static class FarQuadric { internal struct Stats { public int Points; public int Passes; public long Free; public long Border; public long NonManifold; public long OddBorder; public long NoWedge; public long Flip; public long OverBound; } internal sealed class Scratch { internal readonly Run R = new Run(); internal readonly Dictionary<Key, int> WeldHead = new Dictionary<Key, int>(); internal int[] WeldNext; internal int[] Rep; internal float[] Pos; internal float[] Nrm; internal float[] Uv; internal readonly Dictionary<(int, int, int, int, int), int> SimKey = new Dictionary<(int, int, int, int, int), int>(); internal readonly List<int> SimKeep = new List<int>(); internal int[] SimMap; internal int[] SimTri; } internal struct Key : IEquatable<Key> { public float X; public float Y; public float Z; public bool Equals(Key o) { if (X == o.X && Y == o.Y) { return Z == o.Z; } return false; } public override bool Equals(object o) { if (o is Key o2) { return Equals(o2); } return false; } public override int GetHashCode() { int num = (X.GetHashCode() * 73856093) ^ (Y.GetHashCode() * 19349663) ^ (Z.GetHashCode() * 83492791); return num ^ (num >>> 15); } } internal sealed class Run { private int[] m_pt; private double[] m_px; private double[] m_py; private double[] m_pz; private double[] m_q; private double[] m_w; private int[] m_tri; private int m_tn; private int m_np; private readonly Dictionary<Key, int> m_map = new Dictionary<Key, int>(); internal int Passes; internal long Free; internal long Border; internal long NonManifold; internal long OddBorder; internal long NoWedge; internal long Flip; internal long OverBound; private int[] m_off; private int[] m_adj; private byte[] m_kind; private bool[] m_locked; private int[] m_remap; private readonly List<int> m_moved = new List<int>(); private readonly List<int> m_mapFrom = new List<int>(8); private readonly List<int> m_mapTo = new List<int>(8); private int[] m_fill; private int[] m_candU; private int[] m_candV; private int[] m_order; private double[] m_keys; private double[] m_candCost; internal int TriCount => m_tn; internal int PointCount => m_np; internal void Init(float[] pos, int n, int[] tri, int[] weld) { Passes = 0; m_tn = 0; double num = 0.0; double num2 = 0.0; double num3 = 0.0; for (int i = 0; i < n; i++) { num += (double)pos[i * 3]; num2 += (double)pos[i * 3 + 1]; num3 += (double)pos[i * 3 + 2]; } if (n > 0) { num /= (double)n; num2 /= (double)n; num3 /= (double)n; } Grow(ref m_pt, n); Grow(ref m_px, n); Grow(ref m_py, n); Grow(ref m_pz, n); m_map.Clear(); m_np = 0; for (int j = 0; j < n; j++) { Key key = new Key { X = pos[j * 3] + 0f, Y = pos[j * 3 + 1] + 0f, Z = pos[j * 3 + 2] + 0f }; if (!m_map.TryGetValue(key, out var value)) { value = m_np++; m_map[key] = value; m_px[value] = (double)key.X - num; m_py[value] = (double)key.Y - num2; m_pz[value] = (double)key.Z - num3; } m_pt[j] = value; } Grow(ref m_q, m_np * 10); Grow(ref m_w, m_np); Array.Clear(m_q, 0, m_np * 10); Array.Clear(m_w, 0, m_np); Grow(ref m_off, m_np + 1); Grow(ref m_adj, tri.Length); Grow(ref m_kind, m_np); Grow(ref m_locked, m_np); Grow(ref m_fill, m_np); Grow(ref m_remap, n); for (int k = 0; k < n; k++) { m_remap[k] = k; } Grow(ref m_tri, tri.Length); for (int l = 0; l + 2 < tri.Length; l += 3) { int num4 = tri[l]; int num5 = tri[l + 1]; int num6 = tri[l + 2]; if (weld != null) { num4 = weld[num4]; num5 = weld[num5]; num6 = weld[num6]; } int num7 = m_pt[num4]; int num8 = m_pt[num5]; int num9 = m_pt[num6]; if (num7 != num8 && num8 != num9 && num7 != num9) { m_tri[m_tn * 3] = num4; m_tri[m_tn * 3 + 1] = num5; m_tri[m_tn * 3 + 2] = num6; m_tn++; } } InitQuadrics(); } internal int[] Faces() { int[] array = new int[m_tn * 3]; Array.Copy(m_tri, array, array.Length); return array; } private int P(int t, int k) { return m_pt[m_tri[t * 3 + k]]; } private void BuildAdjacency() { Array.Clear(m_off, 0, m_np + 1); for (int i = 0; i < m_tn * 3; i++) { m_off[m_pt[m_tri[i]] + 1]++; } for (int j = 0; j < m_np; j++) { m_off[j + 1] += m_off[j]; } int[] fill = m_fill; Array.Copy(m_off, fill, m_np); for (int k = 0; k < m_tn; k++) { for (int l = 0; l < 3; l++) { m_adj[fill[P(k, l)]++] = k; } } } private int EdgeCount(int a, int b) { int num = 0; for (int i = m_off[a]; i < m_off[a + 1]; i++) { int t = m_adj[i]; int num2 = P(t, 0); int num3 = P(t, 1); int num4 = P(t, 2); if ((num2 == a && num3 == b) || (num3 == a && num4 == b) || (num4 == a && num2 == b)) { num++; } } return num; } private int Opposite(int a, int b) { for (int i = m_off[b]; i < m_off[b + 1]; i++) { int num = m_adj[i]; int num2 = P(num, 0); int num3 = P(num, 1); int num4 = P(num, 2); if ((num2 == b && num3 == a) || (num3 == b && num4 == a) || (num4 == b && num2 == a)) { return num; } } return -1; } private int CornerOf(int t, int p) { if (P(t, 0) != p) { if (P(t, 1) != p) { return 2; } return 1; } return 0; } private void AddPlane(int p, double a, double b, double c, double d, double w) { int num = p * 10; m_q[num] += w * a * a; m_q[num + 1] += w * b * b; m_q[num + 2] += w * c * c; m_q[num + 3] += w * a * b; m_q[num + 4] += w * a * c; m_q[num + 5] += w * b * c; m_q[num + 6] += w * a * d; m_q[num + 7] += w * b * d; m_q[num + 8] += w * c * d; m_q[num + 9] += w * d * d; } private bool FaceNormal(int t, out double nx, out double ny, out double nz, out double len) { int num = P(t, 0); int num2 = P(t, 1); int num3 = P(t, 2); double num4 = m_px[num2] - m_px[num]; double num5 = m_py[num2] - m_py[num]; double num6 = m_pz[num2] - m_pz[num]; double num7 = m_px[num3] - m_px[num]; double num8 = m_py[num3] - m_py[num]; double num9 = m_pz[num3] - m_pz[num]; nx = num5 * num9 - num6 * num8; ny = num6 * num7 - num4 * num9; nz = num4 * num8 - num5 * num7; len = Math.Sqrt(nx * nx + ny * ny + nz * nz); if (len <= 1E-12) { return false; } nx /= len; ny /= len; nz /= len; return true; } private void InitQuadrics() { BuildAdjacency(); for (int i = 0; i < m_tn; i++) { if (!FaceNormal(i, out var nx, out var ny, out var nz, out var len)) { continue; } double num = len * 0.5; int num2 = P(i, 0); double d = 0.0 - (nx * m_px[num2] + ny * m_py[num2] + nz * m_pz[num2]); for (int j = 0; j < 3; j++) { int num3 = P(i, j); AddPlane(num3, nx, ny, nz, d, num); m_w[num3] += num; } for (int k = 0; k < 3; k++) { int num4 = P(i, k); int num5 = P(i, (k + 1) % 3); int num6 = Opposite(num4, num5); double num7; if (num6 < 0) { num7 = 10.0; } else { int num8 = m_tri[i * 3 + k]; int num9 = m_tri[i * 3 + (k + 1) % 3]; int num10 = m_tri[num6 * 3 + CornerOf(num6, num4)]; int num11 = m_tri[num6 * 3 + CornerOf(num6, num5)]; if (num8 == num10 && num9 == num11) { continue; } num7 = 1.0; } double num12 = m_px[num5] - m_px[num4]; double num13 = m_py[num5] - m_py[num4]; double num14 = m_pz[num5] - m_pz[num4]; double num15 = num12 * num12 + num13 * num13 + num14 * num14; if (!(num15 <= 1E-12)) { double num16 = num13 * nz - num14 * ny; double num17 = num14 * nx - num12 * nz; double num18 = num12 * ny - num13 * nx; double num19 = Math.Sqrt(num16 * num16 + num17 * num17 + num18 * num18); if (!(num19 <= 1E-12)) { num16 /= num19; num17 /= num19; num18 /= num19; double d2 = 0.0 - (num16 * m_px[num4] + num17 * m_py[num4] + num18 * m_pz[num4]); AddPlane(num4, num16, num17, num18, d2, num15 * num7); AddPlane(num5, num16, num17, num18, d2, num15 * num7); } } } } } private double Cost(int p, int v) { int num = p * 10; double num2 = m_px[v]; double num3 = m_py[v]; double num4 = m_pz[v]; double val = m_q[num] * num2 * num2 + m_q[num + 1] * num3 * num3 + m_q[num + 2] * num4 * num4 + 2.0 * (m_q[num + 3] * num2 * num3 + m_q[num + 4] * num2 * num4 + m_q[num + 5] * num3 * num4) + 2.0 * (m_q[num + 6] * num2 + m_q[num + 7] * num3 + m_q[num + 8] * num4) + m_q[num + 9]; return Math.Max(0.0, val) / Math.Max(m_w[p], 1E-12); } private void Classify() { for (int i = 0; i < m_np; i++) { int num = 0; int num2 = 0; bool flag = false; for (int j = m_off[i]; j < m_off[i + 1]; j++) { if (flag) { break; } int t = m_adj[j]; int num3 = CornerOf(t, i); int b = P(t, (num3 + 1) % 3); int a = P(t, (num3 + 2) % 3); if (EdgeCount(i, b) > 1 || EdgeCount(a, i) > 1) { flag = true; break; } if (Opposite(i, b) < 0) { num++; } if (Opposite(a, i) < 0) { num2++; } } m_kind[i] = (byte)(flag ? 2 : ((num != 0 || num2 != 0) ? ((num == 1 && num2 == 1) ? 1 : 2) : 0)); if (m_off[i] != m_off[i + 1]) { if (flag) { NonManifold++; } else if (m_kind[i] == 2) { OddBorder++; } else if (m_kind[i] == 1) { Border++; } else { Free++; } } } } private bool Open(int a, int b) { if (Opposite(a, b) >= 0 || EdgeCount(a, b) <= 0) { if (Opposite(b, a) < 0) { return EdgeCount(b, a) > 0; } return false; } return true; } private bool WedgeMap(int u, int v) { m_mapFrom.Clear(); m_mapTo.Clear(); for (int i = m_off[u]; i < m_off[u + 1]; i++) { int num = m_adj[i]; int item = m_tri[num * 3 + CornerOf(num, u)]; int num2 = m_mapFrom.IndexOf(item); if (num2 < 0) { m_mapFrom.Add(item); m_mapTo.Add(-1); num2 = m_mapFrom.Count - 1; } for (int j = 0; j < 3; j++) { if (P(num, j) == v) { int num3 = m_tri[num * 3 + j]; if (m_mapTo[num2] < 0) { m_mapTo[num2] = num3; } else if (m_mapTo[num2] != num3) { return false; } } } } for (int k = 0; k < m_mapTo.Count; k++) { if (m_mapTo[k] < 0) { return false; } } return true; } private bool Flips(int u, int v) { if (KeepParts) { bool flag = false; for (int i = m_off[u]; i < m_off[u + 1]; i++) { if (flag) { break; } int t = m_adj[i]; flag = P(t, 0) != v && P(t, 1) != v && P(t, 2) != v; } if (!flag) { return true; } } for (int j = m_off[u]; j < m_off[u + 1]; j++) { int t2 = m_adj[j]; int num = CornerOf(t2, u); int num2 = P(t2, (num + 1) % 3); int num3 = P(t2, (num + 2) % 3); if (num2 != v && num3 != v) { double bx = m_px[num2]; double num4 = m_py[num2]; double bz = m_pz[num2]; double cx = m_px[num3]; double cy = m_py[num3]; double cz = m_pz[num3]; Cross(m_px[u], m_py[u], m_pz[u], bx, num4, bz, cx, cy, cz, out var nx, out var ny, out var nz); Cross(m_px[v], m_py[v], m_pz[v], bx, num4, bz, cx, cy, cz, out var nx2, out var ny2, out var nz2); if (nx2 * nx2 + ny2 * ny2 + nz2 * nz2 <= 1E-24) { return true; } if (nx * nx2 + ny * ny2 + nz * nz2 <= 0.0) { return true; } } } return false; } private static void Cross(double ax, double ay, double az, double bx, double by, double bz, double cx, double cy, double cz, out double nx, out double ny, out double nz) { double num = bx - ax; double num2 = by - ay; double num3 = bz - az; double num4 = cx - ax; double num5 = cy - ay; double num6 = cz - az; nx = num2 * num6 - num3 * num5; ny = num3 * num4 - num * num6; nz = num * num5 - num2 * num4; } internal void Pass(double bound2) { Passes++; Free = (Border = (NonManifold = (OddBorder = (NoWedge = (Flip = (OverBound = 0L)))))); BuildAdjacency(); Classify(); Grow(ref m_candU, m_np); Grow(ref m_candV, m_np); Grow(ref m_candCost, m_np); int num = 0; for (int i = 0; i < m_np; i++) { if (m_kind[i] == 2 || m_off[i] == m_off[i + 1]) { continue; } double num2 = bound2; int num3 = -1; bool flag = false; bool flag2 = false; for (int j = m_off[i]; j < m_off[i + 1]; j++) { int t = m_adj[j]; for (int k = 0; k < 3; k++) { int num4 = P(t, k); if (num4 == i || (m_kind[i] == 1 && (m_kind[num4] != 1 || !Open(i, num4)))) { continue; } double num5 = Cost(i, num4); if (num5 > bound2) { flag = true; } else if (!(num5 > num2) && (num5 != num2 || num3 < 0)) { if (!WedgeMap(i, num4)) { flag2 = true; continue; } num2 = num5; num3 = num4; } } } if (num3 < 0) { if (flag2) { NoWedge++; } else if (flag) { OverBound++; } } else { m_candU[num] = i; m_candV[num] = num3; m_candCost[num] = num2; num++; } } int[] array = Grow(ref m_order, num); for (int l = 0; l < num; l++) { array[l] = l; } double[] array2 = Grow(ref m_keys, num); Array.Copy(m_candCost, array2, num); Array.Sort(array2, array, 0, num); Array.Clear(m_locked, 0, m_np); for (int m = 0; m < num; m++) { int num6 = array[m]; int num7 = m_candU[num6]; int num8 = m_candV[num6]; if (m_locked[num7] || m_locked[num8]) { continue; } if (Flips(num7, num8)) { Flip++; } else if (WedgeMap(num7, num8)) { for (int n = 0; n < m_mapFrom.Count; n++) { m_remap[m_mapFrom[n]] = m_mapTo[n]; m_moved.Add(m_mapFrom[n]); } for (int num9 = m_off[num7]; num9 < m_off[num7 + 1]; num9++) { int t2 = m_adj[num9]; bool[] locked = m_locked; int num10 = P(t2, 0); bool flag3; m_locked[P(t2, 1)] = (flag3 = (m_locked[P(t2, 2)] = true)); locked[num10] = flag3; } int num11 = num7 * 10; int num12 = num8 * 10; for (int num13 = 0; num13 < 10; num13++) { m_q[num12 + num13] += m_q[num11 + num13]; } m_w[num8] += m_w[num7]; } } int num14 = 0; for (int num15 = 0; num15 < m_tn; num15++) { int num16 = m_remap[m_tri[num15 * 3]]; int num17 = m_remap[m_tri[num15 * 3 + 1]]; int num18 = m_remap[m_tri[num15 * 3 + 2]]; int num19 = m_pt[num16]; int num20 = m_pt[num17]; int num21 = m_pt[num18]; if (num19 != num20 && num20 != num21 && num19 != num21) { m_tri[num14 * 3] = num16; m_tri[num14 * 3 + 1] = num17; m_tri[num14 * 3 + 2] = num18; num14++; } } m_tn = num14; foreach (int item in m_moved) { m_remap[item] = item; } m_moved.Clear(); } } private const double BorderWeight = 10.0; private const double SeamWeight = 1.0; internal static bool KeepParts = true; private const int MaxPassesPerLevel = 64; private static readonly ConcurrentBag<Scratch> s_pool = new ConcurrentBag<Scratch>(); internal static bool Pooled => !s_pool.IsEmpty; internal static int[][] Levels(float[] pos, int vertexCount, int[] tri, float[] bounds, out Stats stats, int[] weld = null, Scratch scratch = null) { Scratch scratch2 = scratch ?? Rent(); Run r = scratch2.R; r.Init(pos, vertexCount, tri, weld); int[][] array = new int[bounds.Length][]; for (int i = 0; i < bounds.Length; i++) { double bound = (double)bounds[i] * (double)bounds[i]; for (int j = 0; j < 64; j++) { int triCount = r.TriCount; r.Pass(bound); if (triCount - r.TriCount < Math.Max(1, triCount / 100)) { break; } } array[i] = r.Faces(); } stats = new Stats { Points = r.PointCount, Passes = r.Passes, Free = r.Free, Border = r.Border, NonManifold = r.NonManifold, OddBorder = r.OddBorder, NoWedge = r.NoWedge, Flip = r.Flip, OverBound = r.OverBound }; if (scratch == null) { Return(scratch2); } return array; } internal static Scratch Rent() { if (!s_pool.TryTake(out var result)) { return new Scratch(); } return result; } internal static void Return(Scratch s) { s_pool.Add(s); } internal static void ReleaseAll() { Scratch result; while (s_pool.TryTake(out result)) { } } internal static int[] WeldExact(float[] attrs, int stride, int n) { int[] array = new int[n]; Dictionary<ulong, int> dictionary = new Dictionary<ulong, int>(n); int[] array2 = new int[n]; for (int i = 0; i < n; i++) { ulong num = 14695981039346656037uL; for (int j = 0; j < stride; j++) { num ^= (uint)(attrs[i * stride + j] + 0f).GetHashCode(); num *= 1099511628211L; } array2[i] = -1; if (!dictionary.TryGetValue(num, out var value)) { dictionary[num] = i; array[i] = i; continue; } int num2 = value; while (value >= 0) { bool flag = true; for (int k = 0; k < stride && flag; k++) { flag = attrs[i * stride + k] + 0f == attrs[value * stride + k] + 0f; } if (flag) { break; } num2 = value; value = array2[value]; } if (value >= 0) { array[i] = value; continue; } array[i] = i; array2[num2] = i; } return array; } internal static int[] WeldSoft(float[] pos, float[] nrm, float[] uv, int n, float cosAngle, float uvTol, int[] rep = null, Scratch scratch = null) { if (rep == null || rep.Length < n) { rep = new int[n]; } Scratch obj = scratch ?? new Scratch(); Dictionary<Key, int> weldHead = obj.WeldHead; weldHead.Clear(); int[] array = Grow(ref obj.WeldNext, n); for (int i = 0; i < n; i++) { Key key = new Key { X = pos[i * 3] + 0f, Y = pos[i * 3 + 1] + 0f, Z = pos[i * 3 + 2] + 0f }; rep[i] = i; array[i] = -1; if (!weldHead.TryGetValue(key, out var value)) { weldHead[key] = i; continue; } int num = value; while (value >= 0) { if (!(nrm[i * 3] * nrm[value * 3] + nrm[i * 3 + 1] * nrm[value * 3 + 1] + nrm[i * 3 + 2] * nrm[value * 3 + 2] < cosAngle) && (uv == null || (!(Math.Abs(uv[i * 2] - uv[value * 2]) > uvTol) && !(Math.Abs(uv[i * 2 + 1] - uv[value * 2 + 1]) > uvTol)))) { rep[i] = value; break; } num = value; value = array[value]; } if (rep[i] == i) { array[num] = i; } } weldHead.Clear(); return rep; } internal static T[] Grow<T>(ref T[] a, int n) { if (a == null || a.Length < n) { long val = 2147483647L; T[] obj = a; a = new T[Math.Max(n, (int)Math.Min(val, (long)((obj != null) ? obj.Length : 0) * 5L / 4))]; } return a; } } internal static class FarTerrain { private class ZoneEdits { public Vector3 Centre; public int Width; public float Scale; public float[] Delta; public Color[] Paint; } private static readonly FieldRef<Heightmap, List<float>> Heights = AccessTools.FieldRefAccess<Heightmap, List<float>>("m_heights"); private static readonly FieldRef<Heightmap, Texture2D> PaintMask = AccessTools.FieldRefAccess<Heightmap, Texture2D>("m_paintMask"); private static readonly FieldRef<ZDOMan, Dictionary<ZDOID, ZDO>> ZdosById = AccessTools.FieldRefAccess<ZDOMan, Dictionary<ZDOID, ZDO>>("m_objectsByID"); private static readonly Dictionary<Vector2s, ZoneEdits> s_zones = new Dictionary<Vector2s, ZoneEdits>(); private static ZDOMan s_loadedFor; private static bool? s_renderHeim; internal static int ZoneCount => s_zones.Count; private static bool On { get { if (Plugin.FarOn != null && Plugin.FarOn.Value && Plugin.FarTerrainOn != null && Plugin.FarTerrainOn.Value && (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && ZDOMan.instance != null) { bool? flag = s_renderHeim; bool num; if (!flag.HasValue) { bool? flag2 = (s_renderHeim = Chainloader.PluginInfos.ContainsKey("com.renderheim")); num = flag2.Value; } else { num = flag == true; } if (!num) { return !FarLandsLink.Drawing; } } return false; } } private static bool OnHere { get { if (!On) { if (Plugin.FarOn != null && Plugin.FarOn.Value && Plugin.FarTerrainOn != null && Plugin.FarTerrainOn.Value && (Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer() && FarNet.RemoteReady) { bool? flag = s_renderHeim; bool num; if (!flag.HasValue) { bool? flag2 = (s_renderHeim = Chainloader.PluginInfos.ContainsKey("com.renderheim")); num = flag2.Value; } else { num = flag == true; } if (!num) { return !FarLandsLink.Drawing; } } return false; } return true; } } internal static bool RemoteWanted { get { if (OnHere && (Object)(object)ZNet.instance != (Object)null) { return !ZNet.instance.IsServer(); } return false; } } internal static void Patch(Harmony h) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown h.Patch((MethodBase)AccessTools.Method(typeof(Heightmap), "ApplyModifiers", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(FarTerrain), "Post", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } internal static void RemoteZone(long id, byte[] data) { //IL_001b: 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_003e: 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_004d: 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) FarManifest.TerrainZone(id, out var zoneX, out var zoneZ); Vector2s val = default(Vector2s); ((Vector2s)(ref val))..ctor(zoneX, zoneZ); if (data == null) { s_zones.Remove(val); return; } try { ZoneEdits zoneEdits = Parse(data); if (zoneEdits == null) { s_zones.Remove(val); return; } zoneEdits.Centre = ZoneSystem.GetZonePos(val); s_zones[val] = zoneEdits; } catch (Exception ex) { Plugin.Log.LogWarning((object)$"far terrain: zone {zoneX},{zoneZ} from the server unreadable: {ex.Message}"); } } internal static void RemoteClear() { if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer()) { s_zones.Clear(); } } private static void Post(Heightmap __instance) { if (!__instance.IsDistantLod || !OnHere) { return; } try { Apply(__instance); } catch (Exception ex) { Plugin.Log.LogWarning((object)("far terrain: " + ex.Message)); } } private static void Load() { //IL_00fa: 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_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_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_0119: Unknown result type (might be due to invalid IL or missing references) if (!ZNet.instance.IsServer() || s_loadedFor == ZDOMan.instance) { return; } s_loadedFor = ZDOMan.instance; s_zones.Clear(); HashSet<int> hashSet = new HashSet<int>(); foreach (GameObject prefab in ZNetScene.instance.m_prefabs) { if ((Object)(object)prefab != (Object)null && (Object)(object)prefab.GetComponent<TerrainComp>() != (Object)null) { hashSet.Add(StringExtensionMethods.GetStableHashCode(((Object)prefab).name)); } } int num = 0; int num2 = 0; foreach (ZDO value in ZdosById.Invoke(ZDOMan.instance).Values) { if (value == null || !hashSet.Contains(value.GetPrefab())) { continue; } byte[] byteArray = value.GetByteArray(ZDOVars.s_TCData, (byte[])null); if (byteArray != null) { ZoneEdits zoneEdits = Parse(byteArray); if (zoneEdits == null) { num2++; continue; } Vector2s zone = ZoneSystem.GetZone(value.GetPosition()); zoneEdits.Centre = ZoneSystem.GetZonePos(zone); s_zones[zone] = zoneEdits; num++; } } Plugin.Log.LogInfo((object)string.Format("far terrain: edits of {0} zones read{1}", num, (num2 > 0) ? $" ({num2} unreadable)" : "")); } private static ZoneEdits Parse(byte[] bytes) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_001b: 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_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) ZPackage val = new ZPackage(Utils.Decompress(bytes)); val.ReadInt(); val.ReadInt(); val.ReadVector3(); val.ReadSingle(); int num = val.ReadInt(); int num2 = Mathf.RoundToInt(Mathf.Sqrt((float)num)); if (num2 * num2 != num || num2 < 2) { return null; } ZoneEdits zoneEdits = new ZoneEdits { Width = num2 - 1, Scale = 64f / (float)(num2 - 1), Delta = new float[num], Paint = (Color[])(object)new Color[num] }; for (int i = 0; i < num; i++) { if (val.ReadBool()) { zoneEdits.Delta[i] = Mathf.Clamp(val.ReadSingle() + val.ReadSingle(), -8f, 8f); } } for (int j = 0; j < num; j++) { zoneEdits.Paint[j] = new Color(0f, 0f, 0f, -1f); } int num3 = val.ReadInt(); if (num3 == num) { for (int k = 0; k < num3; k++) { if (val.ReadBool()) { zoneEdits.Paint[k] = new Color(val.ReadSingle(), val.ReadSingle(), val.ReadSingle(), val.ReadSingle()); } } } return zoneEdits; } private static void Apply(Heightmap hm) { //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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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_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) //IL_00d4: 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) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) Load(); if (s_zones.Count == 0) { return; } List<float> list = Heights.Invoke(hm); Texture2D val = PaintMask.Invoke(hm); int width = hm.m_width; int num = width + 1; float scale = hm.m_scale; Vector3 position = ((Component)hm).transform.position; bool flag = false; Vector2s zone = ZoneSystem.GetZone(position); int num2; if (!((Object)(object)ZNet.instance != (Object)null)) { num2 = 6; } else { SimulationDistance syncedSimulationDistance = ZNet.instance.GetSyncedSimulationDistance(); num2 = ((SimulationDistance)(ref syncedSimulationDistance)).NearSimulationDistance; } int num3 = num2 + 5; for (int i = 0; i < num; i++) { for (int j = 0; j < num; j++) { float num4 = position.x + ((float)j - (float)width * 0.5f) * scale; float num5 = position.z + ((float)i - (float)width * 0.5f) * scale; Vector2s zone2 = ZoneSystem.GetZone(new Vector3(num4, 0f, num5)); if (!s_zones.TryGetValue(zone2, out var value)) { continue; } float num6 = (num4 - value.Centre.x) / value.Scale + (float)value.Width * 0.5f; float num7 = (num5 - value.Centre.z) / value.Scale + (float)value.Width * 0.5f; int num8 = Mathf.Clamp(Mathf.FloorToInt(num6), 0, value.Width - 1); int num9 = Mathf.Clamp(Mathf.FloorToInt(num7), 0, value.Width - 1); float num10 = Mathf.Clamp01(num6 - (float)num8); float num11 = Mathf.Clamp01(num7 - (float)num9); int num12 = value.Width + 1; float num13 = Mathf.Lerp(Mathf.Lerp(value.Delta[num9 * num12 + num8], value.Delta[num9 * num12 + num8 + 1], num10), Mathf.Lerp(value.Delta[(num9 + 1) * num12 + num8], value.Delta[(num9 + 1) * num12 + num8 + 1], num10), num11); int num14 = i * num + j; bool flag2 = Mathf.Abs(zone2.x - zone.x) <= num3 && Mathf.Abs(zone2.y - zone.y) <= num3; if (num13 > 0f && flag2) { num13 = 0f; } if (num13 != 0f && num14 < list.Count) { list[num14] += num13; } if ((Object)(object)val != (Object)null) { Color val2 = value.Paint[Mathf.Clamp(Mathf.RoundToInt(num7), 0, value.Width) * num12 + Mathf.Clamp(Mathf.RoundToInt(num6), 0, value.Width)]; if (val2.a >= 0f && j < ((Texture)val).width && i < ((Texture)val).height) { val.SetPixel(j, i, val2); flag = true; } } } } if (flag) { val.Apply(); } } } internal static class Floaters { private static readonly FieldRef<WaterVolume, List<IWaterInteractable>> InWater = AccessTools.FieldRefAccess<WaterVolume, List<IWaterInteractable>>("m_inWater"); private static readonly FieldRef<WaterVolume, Collider> VCollider = AccessTools.FieldRefAccess<WaterVolume, Collider>("m_collider"); private static readonly FieldRef<WaterVolume, float> OneDepth = AccessTools.FieldRefAccess<WaterVolume, float>("m_oneDepth"); private static readonly FieldRef<WaterVolume, float[]> NormDepth = AccessTools.FieldRefAccess<WaterVolume, float[]>("m_normalizedDepth"); private static readonly FieldRef<float> DayTime = AccessTools.StaticFieldRefAccess<float>(AccessTools.Field(typeof(WaterVolume), "s_wrappedDayTimeSeconds")); private static readonly FieldRef<Vector4> Wind1 = AccessTools.StaticFieldRefAccess<Vector4>(AccessTools.Field(typeof(WaterVolume), "s_globalWind1")); private static readonly FieldRef<Vector4> Wind2 = AccessTools.StaticFieldRefAccess<Vector4>(AccessTools.Field(typeof(WaterVolume), "s_globalWind2")); private static readonly FieldRef<float> WindAlpha = AccessTools.StaticFieldRefAccess<float>(AccessTools.Field(typeof(WaterVolume), "s_globalWindAlpha")); private static readonly FieldRef<Vector2[]> Directions = AccessTools.StaticFieldRefAccess<Vector2[]>(AccessTools.Field(typeof(WaterVolume), "s_createWaveDirections")); private static readonly FieldRef<Vector2[]> Tangents = AccessTools.StaticFieldRefAccess<Vector2[]>(AccessTools.Field(typeof(WaterVolume), "s_createWaveTangents")); private static readonly List<int> s_remove = new List<int>(); private static readonly Vector2[] s_dir = (Vector2[])(object)new Vector2[10]; private static readonly Vector2[] s_tan = (Vector2[])(object)new Vector2[10]; private static Vector2 s_dir1; private static Vector2 s_tan1; private static Vector2 s_dir2; private static Vector2 s_tan2; private static Vector4 s_w1 = new Vector4(float.NaN, 0f, 0f, 0f); private static Vector4 s_w2 = new Vector4(float.NaN, 0f, 0f, 0f); internal static bool Verify; internal static long Checked; internal static long Mismatched; internal static float MaxDiff; internal static void Patch(Harmony h) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown h.Patch((MethodBase)AccessTools.Method(typeof(WaterVolume), "UpdateFloaters", (Type[])null, (Type[])null), new HarmonyMethod(typeof(Floaters), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private static bool Prefix(WaterVolume __instance) { //IL_0056: 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_006a: 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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: 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_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0180: 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_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_022e: 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_03a6: Unknown result type (might be due to invalid IL or missing references) //IL_039f: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_03ab: Unknown result type (might be due to invalid IL or missing references) //IL_03c2: Unknown result type (might be due to invalid IL or missing references) //IL_03bb: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_0270: 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_027b: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_03c7: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.FloatersOn.Value) { return true; } List<IWaterInteractable> list = InWater.Invoke(__instance); int count = list.Count; if (count == 0) { return false; } Vector2[] array = Directions.Invoke(); Vector2[] array2 = Tangents.Invoke(); if (array == null || array2 == null) { return true; } for (int i = 1; i < 10; i++) { s_dir[i] = array[i]; s_tan[i] = array2[i]; } Transform transform = ((Component)__instance).transform; float y = transform.position.y; float surfaceOffset = __instance.m_surfaceOffset; float num = OneDepth.Invoke(__instance); bool useGlobalWind = __instance.m_useGlobalWind; bool flag = __instance.m_forceDepth < 0f; Vector3 size = default(Vector3); float[] nd = NormDepth.Invoke(__instance); if (useGlobalWind && num <= -1f) { Bounds bounds = VCollider.Invoke(__instance).bounds; size = ((Bounds)(ref bounds)).size; } float waterTime = DayTime.Invoke(); float num2 = WindAlpha.Invoke(); Vector4 val = Wind1.Invoke(); Vector4 val2 = Wind2.Invoke(); if (val != s_w1 || float.IsNaN(s_w1.x)) { s_w1 = val; WindDir(val, out s_dir1, out s_tan1); } if (num2 != 0f && (val2 != s_w2 || float.IsNaN(s_w2.x))) { s_w2 = val2; WindDir(val2, out s_dir2, out s_tan2); } bool flag2 = false; s_remove.Clear(); for (int j = 0; j < count; j++) { IWaterInteractable val3 = list[j]; if (val3 == null) { s_remove.Add(j); continue; } Transform transform2 = val3.GetTransform(); if (!Object.op_Implicit((Object)(object)transform2)) { s_remove.Add(j); continue; } Vector3 position = transform2.position; float num3 = 0f; if (useGlobalWind) { float num4 = ((num > -1f) ? num : Depth(transform, position, size, nd)); float big = 1f - (float)WorldGenerator.DeepNorthWaveFade(position.x, position.z); if (num4 != 0f) { flag2 = true; num3 = ((num2 == 0f) ? Wave(position, num4, val.w, s_dir1, s_tan1, waterTime, big) : Mathf.LerpUnclamped(Wave(position, num4, val.w, s_dir1, s_tan1, waterTime, big), Wave(position, num4, val2.w, s_dir2, s_tan2, waterTime, big), num2)); } } float num5 = y + num3 + surfaceOffset; if (flag && Utils.LengthXZ(position) > 10500f) { num5 -= 100f; } if (Verify) { Checked++; float waterSurface = __instance.GetWaterSurface(position, 1f); if (num5 != waterSurface) { Mismatched++; MaxDiff = Mathf.Max(MaxDiff, Mathf.Abs(num5 - waterSurface)); } } val3.SetLiquidLevel(num5, (LiquidType)0, (Component)(object)__instance); } for (int num6 = s_remove.Count - 1; num6 >= 0; num6--) { list.RemoveAt(s_remove[num6]); } if (flag2) { array[0] = ((num2 == 0f) ? s_dir1 : s_dir2); array2[0] = ((num2 == 0f) ? s_tan1 : s_tan2); } return false; } private static void WindDir(Vector4 wind, out Vector2 dir, out Vector2 tan) { //IL_0001: 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) //IL_000d: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) dir = new Vector2(wind.x, wind.z); ((Vector2)(ref dir)).Normalize(); tan = new Vector2(0f - dir.y, dir.x); } private static float Depth(Transform vt, Vector3 point, Vector3 size, float[] nd) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //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) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) Vector3 val = vt.InverseTransformPoint(point); float num = (val.x + size.x / 2f) / size.x; float num2 = (val.z + size.z / 2f) / size.z; float num3 = Mathf.Lerp(nd[3], nd[2], num); float num4 = Mathf.Lerp(nd[0], nd[1], num); return Mathf.Lerp(num3, num4, num2); } private static float Troch(float x, float k) { return Mathf.Sin(x - Mathf.Cos(x) * k) * 0.5f + 0.5f; } private static float One(Vector3 p, float time, float speed, float length, float height, Vector2 dir, Vector2 tan, float sharp) { //IL_0000: 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_0008: 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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_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_0024: 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_0041: Unknown result type (might be due to invalid IL or missing references) Vector2 val = -(p.z * dir + p.x * tan); float num = time * speed; return (Troch(num + val.y * length, sharp) * Troch(num * 0.123f + val.x * 0.13123f * length, sharp) - 0.2f) * height; } private static float Wave(Vector3 p, float depth, float windW, Vector2 d0, Vector2 t0, float waterTime, float big) { //IL_0022: 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_0037: 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_0059: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: 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) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: 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_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0167: 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_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Lerp(0f, windW, depth); float time = waterTime / 20f; Vector2[] array = s_dir; Vector2[] array2 = s_tan; float num2 = One(p, time, 10f, 0.04f, 8f * big, d0, t0, 0.5f); float num3 = One(p, time, 14.123f, 0.08f, 6f * big, array[1], array2[1], 0.5f); float num4 = One(p, time, 22.312f, 0.1f, 4f * big, array[2], array2[2], 0.5f); float num5 = One(p, time, 31.42f, 0.2f, 2f * big, array[3], array2[3], 0.5f); float num6 = One(p, time, 35.42f, 0.4f, 1f * big, array[4], array2[4], 0.5f); float num7 = One(p, time, 38.1223f, 1f, 0.8f * big, array[5], array2[5], 0.7f); float num8 = One(p, time, 41.1223f, 1.2f, 0.6f, array[6], array2[6], 0.8f); float num9 = One(p, time, 51.5123f, 1.3f, 0.4f, array[7], array2[7], 0.9f); float num10 = One(p, time, 54.2f, 1.3f, 0.3f, array[8], array2[8], 0.9f); float num11 = One(p, time, 56.123f, 1.5f, 0.2f, array[9], array2[9], 0.9f); return (num2 + num3 + num4 + num5 + num6 + num7 + num8 + num9 + num10 + num11) * num; } } internal class FpsReadout : MonoBehaviour { internal static bool Shown; internal static bool Big; private const int Size = 4096; private readonly float[] m_ms = new float[4096]; private readonly float[] m_sorted = new float[4096]; private int m_next; private int m_count; private float m_nextText; private string m_text = ""; private GUIStyle m_style; private GUIStyle m_bigStyle; private string m_big = ""; private ProfilerRecorder m_draws; private ProfilerRecorder m_batches; private ProfilerRecorder m_setPass; private ProfilerRecorder m_tris; private bool m_recording; private GUIStyle m_legendStyle; private void Update() { //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) MergeRender.VizTick(); if (Big != m_recording) { Record(Big); } if (!Shown) { m_count = 0; return; } m_ms[m_next] = Time.unscaledDeltaTime * 1000f; m_next = (m_next + 1) % 4096; if (m_count < 4096) { m_count++; } if (Time.unscaledTime < m_nextText) { return; } m_nextText = Time.unscaledTime + 0.5f; float num = 0f; int num2 = 0; for (int i = 1; i <= m_count; i++) { float num3 = m_ms[(m_next - i + 4096) % 4096]; if (num + num3 > 10000f) { break; } m_sorted[num2++] = num3; num += num3; } if (num2 == 0) { return; } Array.Sort(m_sorted, 0, num2); float num4 = num / (float)num2; float num5 = m_sorted[Mathf.Clamp(num2 - 1 - num2 / 100, 0, num2 - 1)]; m_text = $"{1000f / num4:0} fps 1% low {1000f / num5:0} {num4:0.0} ms (last {num / 1000f:0} s)"; if (!Big) { return; } float num6 = 0f; int num7 = 0; for (int j = 1; j <= m_count; j++) { if (!(num6 < 500f)) { break; } num6 += m_ms[(m_next - j + 4096) % 4096]; num7++; } float num8 = num6 / (float)Mathf.Max(num7, 1); bool flag = Plugin.MergeOn.Value && MergeRender.Active; bool flag2 = MergeRender.Viz != MergeRender.VizMode.Off; m_big = (flag2 ? "Frame rate: not meaningful in a colour view\n" : $"{1000f / num8:0} FPS {num8:0.0} ms\n1% low {1000f / num5:0} FPS\n") + "Draw calls " + Stat(m_draws) + "\nBatches " + Stat(m_batches) + " SetPass " + Stat(m_setPass) + "\nTriangles " + Tris(m_tris) + "\n" + (flag ? string.Format("{0}: on, {1:N0} pieces in {2:N0} merged cells", "Valheim Enhanced Edition", MergeRender.PieceCount, MergeRender.CellCount) : "Valheim Enhanced Edition: off (vanilla)") + (Plugin.FarOn.Value ? $"\nFar view: on, {MergeRender.FarCount:N0} far cells" : "") + ((MergeRender.Viz != MergeRender.VizMode.Off) ? ("\nView: " + MergeRender.Viz.ToString().ToLowerInvariant() + ": " + MergeRender.VizLine) : ""); } private static string Stat(ProfilerRecorder r) { if (!((ProfilerRecorder)(ref r)).Valid) { return "n/a"; } return ((ProfilerRecorder)(ref r)).LastValue.ToString("N0"); } private static string Tris(ProfilerRecorder r) { if (((ProfilerRecorder)(ref r)).Valid) { if (((ProfilerRecorder)(ref r)).LastValue < 1000000) { return $"{(double)((ProfilerRecorder)(ref r)).LastValue / 1000.0:0} k"; } return $"{(double)((ProfilerRecorder)(ref r)).LastValue / 1000000.0:0.0} M"; } return "n/a"; } private void Record(bool on) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //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_0023: 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_0035: 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_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_0053: 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_0065: Unknown result type (might be due to invalid IL or missing references) m_recording = on; if (on) { m_draws = ProfilerRecorder.StartNew(ProfilerCategory.Render, "Draw Calls Count", 1, (ProfilerRecorderOptions)24); m_batches = ProfilerRecorder.StartNew(ProfilerCategory.Render, "Batches Count", 1, (ProfilerRecorderOptions)24); m_setPass = ProfilerRecorder.StartNew(ProfilerCategory.Render, "SetPass Calls Count", 1, (ProfilerRecorderOptions)24); m_tris = ProfilerRecorder.StartNew(ProfilerCategory.Render, "Triangles Count", 1, (ProfilerRecorderOptions)24); } else { ((ProfilerRecorder)(ref m_draws)).Dispose(); ((ProfilerRecorder)(ref m_batches)).Dispose(); ((ProfilerRecorder)(ref m_setPass)).Dispose(); ((ProfilerRecorder)(ref m_tris)).Dispose(); } } private void OnDestroy() { if (m_recording) { Record(on: false); } } private void OnGUI() { //IL_0082: 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_00d5: 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_0043: 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_005c: Expected O, but got Unknown if (MergeRender.Viz != MergeRender.VizMode.Off) { DrawLegend(); } if (!Shown || m_text.Length == 0) { return; } if (Big) { DrawBig(); return; } if (m_style == null) { m_style = new GUIStyle(GUI.skin.label) { fontSize = 16, fontStyle = (FontStyle)1 }; } Rect val = default(Rect); ((Rect)(ref val))..ctor(12f, 8f, 600f, 24f); m_style.normal.textColor = Color.black; GUI.Label(new Rect(((Rect)(ref val)).x + 1f, ((Rect)(ref val)).y + 1f, ((Rect)(ref val)).width, ((Rect)(ref val)).height), m_text, m_style); m_style.normal.textColor = Color.yellow; GUI.Label(val, m_text, m_style); } private void DrawLegend() { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown //IL_00aa: 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_002b: 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_003e: Expected O, but got Unknown //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Expected O, but got Unknown //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: 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_0174: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0195: 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_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) List<(Color, string)> list = MergeRender.VizLegend(); float num = (float)Screen.height / 1080f; if (m_legendStyle == null) { m_legendStyle = new GUIStyle(GUI.skin.label) { fontStyle = (FontStyle)1, wordWrap = false }; } m_legendStyle.fontSize = Mathf.RoundToInt(17f * num); float num2 = 24f * num; float num3 = 16f * num; float num4 = 10f * num; string text = "View: " + MergeRender.Viz.ToString().ToLowerInvariant() + " " + MergeRender.VizLine; float num5 = m_legendStyle.CalcSize(new GUIContent(text)).x; foreach (var item in list) { num5 = Mathf.Max(num5, num3 + 8f * num + m_legendStyle.CalcSize(new GUIContent(item.Item2)).x); } float num6 = num2 * (float)(list.Count + 1); Rect val = default(Rect); ((Rect)(ref val))..ctor(num4 * 2f, (float)Screen.height - num6 - num4 * 6f, num5 + num4 * 2f, num6 + num4); Color color = GUI.color; GUI.color = new Color(0f, 0f, 0f, 0.55f); GUI.DrawTexture(val, (Texture)(object)Texture2D.whiteTexture); m_legendStyle.normal.textColor = Color.white; GUI.color = color; GUI.Label(new Rect(((Rect)(ref val)).x + num4, ((Rect)(ref val)).y + num4 * 0.5f, num5, num2), text, m_legendStyle); for (int i = 0; i < list.Count; i++) { float num7 = ((Rect)(ref val)).y + num4 * 0.5f + num2 * (float)(i + 1); GUI.color = list[i].Item1; GUI.DrawTexture(new Rect(((Rect)(ref val)).x + num4, num7 + (num2 - num3) * 0.5f, num3, num3), (Texture)(object)Texture2D.whiteTexture); GUI.color = color; GUI.Label(new Rect(((Rect)(ref val)).x + num4 + num3 + 8f * num, num7, num5, num2), list[i].Item2, m_legendStyle); } } private void DrawBig() { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_0077: 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0099: 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_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0180: 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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown if (m_big.Length != 0) { float num = (float)Screen.height / 1080f; if (m_bigStyle == null) { m_bigStyle = new GUIStyle(GUI.skin.label) { fontStyle = (FontStyle)1, wordWrap = false, richText = false }; } m_bigStyle.fontSize = Mathf.RoundToInt(26f * num); GUIContent val = new GUIContent(m_big); Vector2 val2 = m_bigStyle.CalcSize(val); Rect val3 = default(Rect); ((Rect)(ref val3))..ctor(24f * num, 20f * num, val2.x + 4f, val2.y + 4f); Color color = GUI.color; GUI.color = new Color(0f, 0f, 0f, 0.45f); GUI.DrawTexture(new Rect(((Rect)(ref val3)).x - 12f * num, ((Rect)(ref val3)).y - 8f * num, ((Rect)(ref val3)).width + 24f * num, ((Rect)(ref val3)).height + 16f * num), (Texture)(object)Texture2D.whiteTexture); GUI.color = color; m_bigStyle.normal.textColor = Color.black; GUI.Label(new Rect(((Rect)(ref val3)).x + 2f, ((Rect)(ref val3)).y + 2f, ((Rect)(ref val3)).width, ((Rect)(ref val3)).height), val, m_bigStyle); m_bigStyle.normal.textColor = Color.white; GUI.Label(val3, val, m_bigStyle); } } } internal static class MergeRender { private class FarCell { public long Id; public Vector3 Origin; public GameObject Go; public readonly List<FarGroup> Groups = new List<FarGroup>(); public float MissingSince = -1f; public float SeenSince = -1f; public bool Shown; public bool Foliage;