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 ValheimOptimized v1.1.1
ValheimOptimized_1.1.1/ValheimOptimized.dll
Decompiled 5 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Threading; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using SoftReferenceableAssets; using Unity.Jobs; using UnityEngine; using UnityEngine.Experimental.Rendering; using UnityEngine.PostProcessing; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("ValheimOptimized")] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: IgnoresAccessChecksTo("assembly_utils")] [assembly: IgnoresAccessChecksTo("assembly_postprocessing")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.1.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; } } [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public string AssemblyName { get; } public IgnoresAccessChecksToAttribute(string assemblyName) { AssemblyName = assemblyName; } } } namespace ValheimOptimized { internal static class AllocTrim { private sealed class ModCache { public SharedData R; public SharedData L; public SharedData C; public SharedData G; public SharedData H; public SharedData S; public SharedData U; public SharedData T; } [HarmonyPatch] internal static class Hooks { [HarmonyTranspiler] [HarmonyPatch(typeof(Player), "Update")] private static IEnumerable<CodeInstruction> Update_Transpiler(IEnumerable<CodeInstruction> instructions) { //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Expected O, but got Unknown List<CodeInstruction> list = instructions.ToList(); MethodInfo methodInfo = AccessTools.Method(typeof(string), "Format", new Type[2] { typeof(string), typeof(object) }, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(AllocTrim), "HotbarName", (Type[])null, (Type[])null); MethodInfo methodInfo3 = AccessTools.Method(typeof(AllocTrim), "HotbarAltName", (Type[])null, (Type[])null); int num = 0; for (int i = 0; i + 3 < list.Count; i++) { if (!(list[i].opcode != OpCodes.Ldstr) && list[i].operand is string text && (!(text != "Hotbar{0}") || !(text != "Hotbar{0}Alt")) && !(list[i + 2].opcode != OpCodes.Box) && CodeInstructionExtensions.Calls(list[i + 3], methodInfo)) { list[i].opcode = OpCodes.Nop; list[i].operand = null; list[i + 2].opcode = OpCodes.Nop; list[i + 2].operand = null; CodeInstruction val = new CodeInstruction(OpCodes.Call, (object)((text == "Hotbar{0}") ? methodInfo2 : methodInfo3)); val.labels.AddRange(list[i + 3].labels); val.blocks.AddRange(list[i + 3].blocks); list[i + 3] = val; num++; } } if (num == 0) { Plugin.Log.LogWarning((object)"AllocTrim: Player.Update hotbar pattern not found (hotbar string cache inactive)"); } return list; } [HarmonyTranspiler] [HarmonyPatch(/*Could not decode attribute arguments.*/)] private static IEnumerable<CodeInstruction> InstanceRenderer_Ctor(IEnumerable<CodeInstruction> instructions) { //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Expected O, but got Unknown List<CodeInstruction> list = instructions.ToList(); MethodInfo methodInfo = AccessTools.Method(typeof(AllocTrim), "RentMatrices", (Type[])null, (Type[])null); int num = 0; for (int i = 0; i + 1 < list.Count; i++) { if (list[i].opcode == OpCodes.Ldc_I4 && list[i].operand is int num2 && num2 == 1024 && list[i + 1].opcode == OpCodes.Newarr && list[i + 1].operand as Type == typeof(Matrix4x4)) { list[i].opcode = OpCodes.Nop; list[i].operand = null; CodeInstruction val = new CodeInstruction(OpCodes.Call, (object)methodInfo); val.labels.AddRange(list[i + 1].labels); list[i + 1] = val; num++; } } if (num == 0) { Plugin.Log.LogWarning((object)"AllocTrim: InstanceRenderer allocation pattern not found (grass matrix pool inactive)"); } return list; } [HarmonyPrefix] [HarmonyPatch(typeof(ClutterSystem), "FreePatch")] private static void FreePatch_Prefix(PatchData patch) { if (patch == null) { return; } List<GameObject> objects = patch.m_objects; for (int i = 0; i < objects.Count; i++) { GameObject val = objects[i]; if ((Object)(object)val == (Object)null) { continue; } InstanceRenderer component = val.GetComponent<InstanceRenderer>(); if ((Object)(object)component == (Object)null) { continue; } Matrix4x4[] instances = component.m_instances; if (instances == null || instances.Length != 1024) { continue; } component.m_instanceCount = 0; component.m_instances = NoMatrices; lock (MatrixPool) { if (MatrixPool.Count < 256) { MatrixPool.Push(instances); PoolReturned++; } } } } [HarmonyPrefix] [HarmonyPatch(typeof(Utils), "ChebyshevDistance", new Type[] { typeof(Vector3), typeof(Vector3) })] private static bool Chebyshev_Prefix(Vector3 a, Vector3 b, ref float __result) { //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_0019: 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_0032: 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) float num = a.x - b.x; if (num < 0f) { num = 0f - num; } float num2 = a.y - b.y; if (num2 < 0f) { num2 = 0f - num2; } float num3 = a.z - b.z; if (num3 < 0f) { num3 = 0f - num3; } float num4 = num; if (num2 > num4) { num4 = num2; } if (num3 > num4) { num4 = num3; } __result = num4; return false; } [HarmonyPrefix] [HarmonyPatch(typeof(Player), "UpdateModifiers")] private static bool UpdateModifiers_Prefix(Player __instance) { ModCache orCreateValue = Cache.GetOrCreateValue(__instance); SharedData val = ((Humanoid)__instance).m_rightItem?.m_shared; SharedData val2 = ((Humanoid)__instance).m_leftItem?.m_shared; SharedData val3 = ((Humanoid)__instance).m_chestItem?.m_shared; SharedData val4 = ((Humanoid)__instance).m_legItem?.m_shared; SharedData val5 = ((Humanoid)__instance).m_helmetItem?.m_shared; SharedData val6 = ((Humanoid)__instance).m_shoulderItem?.m_shared; SharedData val7 = ((Humanoid)__instance).m_utilityItem?.m_shared; SharedData val8 = ((Humanoid)__instance).m_trinketItem?.m_shared; if (orCreateValue.R == val && orCreateValue.L == val2 && orCreateValue.C == val3 && orCreateValue.G == val4 && orCreateValue.H == val5 && orCreateValue.S == val6 && orCreateValue.U == val7 && orCreateValue.T == val8) { return false; } orCreateValue.R = val; orCreateValue.L = val2; orCreateValue.C = val3; orCreateValue.G = val4; orCreateValue.H = val5; orCreateValue.S = val6; orCreateValue.U = val7; orCreateValue.T = val8; return true; } } private static readonly string[] Hotbar; private static readonly string[] HotbarAlt; private static readonly ConditionalWeakTable<Player, ModCache> Cache; private static readonly Stack<Matrix4x4[]> MatrixPool; private static readonly Matrix4x4[] NoMatrices; internal static int PoolHits; internal static int PoolMisses; internal static int PoolReturned; static AllocTrim() { Hotbar = new string[9]; HotbarAlt = new string[9]; Cache = new ConditionalWeakTable<Player, ModCache>(); MatrixPool = new Stack<Matrix4x4[]>(); NoMatrices = (Matrix4x4[])(object)new Matrix4x4[0]; for (int i = 0; i < 9; i++) { Hotbar[i] = "Hotbar" + i; HotbarAlt[i] = "Hotbar" + i + "Alt"; } } public static string HotbarName(int i) { if ((uint)i >= 9u) { return "Hotbar" + i; } return Hotbar[i]; } public static string HotbarAltName(int i) { if ((uint)i >= 9u) { return "Hotbar" + i + "Alt"; } return HotbarAlt[i]; } public static Matrix4x4[] RentMatrices() { lock (MatrixPool) { if (MatrixPool.Count > 0) { PoolHits++; return MatrixPool.Pop(); } } PoolMisses++; return (Matrix4x4[])(object)new Matrix4x4[1024]; } } internal static class DepthNormalsFix { private static Camera _cam; private static bool _strippedLastFrame; private static bool _backedOff; private static bool _wasActive; private static int _readdCount; internal static void Tick() { //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_0055: Invalid comparison between Unknown and I4 //IL_00bb: 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) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) GameCamera instance = GameCamera.instance; if ((Object)(object)instance == (Object)null) { _cam = null; return; } Camera camera = instance.m_camera; if ((Object)(object)camera == (Object)null) { return; } if ((Object)(object)camera != (Object)(object)_cam) { _cam = camera; _strippedLastFrame = false; _backedOff = false; _readdCount = 0; } bool flag = (camera.depthTextureMode & 2) > 0; if (_backedOff) { return; } if (flag && _strippedLastFrame && ++_readdCount >= 3) { _backedOff = true; Plugin.Log.LogWarning((object)"DepthNormals is re-requested by another camera effect; leaving it on."); } else if (flag) { if (!IsSafe(instance, out var why)) { _backedOff = true; Plugin.Log.LogWarning((object)("DepthNormals kept: " + why)); } else { camera.depthTextureMode = (DepthTextureMode)((camera.depthTextureMode & -3) | 1); _strippedLastFrame = true; _wasActive = true; } } else { _strippedLastFrame = false; _wasActive = true; } } private static bool IsSafe(GameCamera gc, out string why) { //IL_0081: 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_0022: Invalid comparison between Unknown and I4 why = null; AmplifyOcclusionEffect component = ((Component)gc).GetComponent<AmplifyOcclusionEffect>(); if ((Object)(object)component != (Object)null && ((Behaviour)component).enabled && (int)component.PerPixelNormals == 1) { why = "Amplify Occlusion uses camera normals"; return false; } PostProcessingBehaviour component2 = ((Component)gc).GetComponent<PostProcessingBehaviour>(); if ((Object)(object)component2 != (Object)null && ((Behaviour)component2).enabled && (Object)(object)component2.profile != (Object)null && component2.profile.ambientOcclusion != null && ((PostProcessingModel)component2.profile.ambientOcclusion).enabled) { why = "PostProcessing ambient occlusion is enabled"; return false; } _ = gc.m_camera.actualRenderingPath; _ = 3; return true; } } internal static class FrameLoad { private static float _avg = 1f / 60f; internal static bool Busy { get { float num = _avg * 1.8f; if (num < 0.009f) { num = 0.009f; } return Time.unscaledDeltaTime > num; } } internal static void Tick() { float unscaledDeltaTime = Time.unscaledDeltaTime; if (unscaledDeltaTime > 0f && unscaledDeltaTime < 0.1f) { _avg += (unscaledDeltaTime - _avg) * 0.02f; } } } internal static class MinimapUpload { [HarmonyPatch] internal static class Hooks { [HarmonyPrefix] [HarmonyPatch(typeof(Minimap), "Explore", new Type[] { typeof(Vector3), typeof(float) })] private static bool Explore_Prefix(Minimap __instance, Vector3 p, float radius) { //IL_0029: 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_007a: Unknown result type (might be due to invalid IL or missing references) Texture2D fogTexture = __instance.m_fogTexture; if ((Object)(object)fogTexture == (Object)null) { return true; } int textureSize = __instance.m_textureSize; int num = (int)Mathf.Ceil(radius / __instance.m_pixelSize); int num2 = default(int); int num3 = default(int); __instance.WorldToPixel(p, ref num2, ref num3); int num4 = int.MaxValue; int num5 = int.MaxValue; int num6 = -1; int num7 = -1; for (int i = num3 - num; i <= num3 + num; i++) { if (i < 0 || i >= textureSize) { continue; } for (int j = num2 - num; j <= num2 + num; j++) { if (j < 0 || j >= textureSize) { continue; } Vector2 val = new Vector2((float)(j - num2), (float)(i - num3)); if (!(((Vector2)(ref val)).magnitude > (float)num) && __instance.Explore(j, i)) { if (j < num4) { num4 = j; } if (j > num6) { num6 = j; } if (i < num5) { num5 = i; } if (i > num7) { num7 = i; } } } } if (num6 >= 0) { try { Upload(fogTexture, num4, num5, num6 - num4 + 1, num7 - num5 + 1); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Minimap partial upload failed, falling back to vanilla: " + ex.Message)); _supported = 0; fogTexture.Apply(); } } return false; } } private const int StageSize = 64; private static Texture2D _stage; private static int _supported = -1; private static bool Supported(Texture2D tex) { //IL_0008: 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_0010: Invalid comparison between Unknown and I4 if (_supported < 0) { _supported = (((SystemInfo.copyTextureSupport & 1) > 0) ? 1 : 0); } if (_supported == 1) { return ((Texture)tex).mipmapCount == 1; } return false; } private static void Upload(Texture2D tex, int x, int y, int w, int h) { //IL_002c: 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_0055: 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_0060: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown if (w > 64 || h > 64 || !Supported(tex)) { tex.Apply(); return; } if ((Object)(object)_stage == (Object)null || ((Texture)_stage).graphicsFormat != ((Texture)tex).graphicsFormat) { if ((Object)(object)_stage != (Object)null) { Object.Destroy((Object)(object)_stage); } _stage = new Texture2D(64, 64, ((Texture)tex).graphicsFormat, (TextureCreationFlags)0) { name = "ValheimOptimized_FogStage", hideFlags = (HideFlags)61, wrapMode = (TextureWrapMode)1, filterMode = (FilterMode)0 }; } Color[] pixels = tex.GetPixels(x, y, w, h); _stage.SetPixels(0, 0, w, h, pixels); _stage.Apply(false, false); Graphics.CopyTexture((Texture)(object)_stage, 0, 0, 0, 0, w, h, (Texture)(object)tex, 0, 0, x, y); } } internal static class ObjectSpawn { [HarmonyPatch] internal static class Hooks { [HarmonyPrefix] [HarmonyPatch(typeof(ZNetScene), "CreateObjects")] private static void CreateObjects_Prefix(ZNetScene __instance, List<ZDO> currentNearObjects) { _t0 = Stopwatch.GetTimestamp(); float num = ((Plugin.CObjectBudget != null) ? Plugin.CObjectBudget.Value : 1f); int count = currentNearObjects.Count; if (count > 1500) { num *= 3f; } else if (count > 500) { num *= 2f; } _budget = (long)((double)num * Tick); } [HarmonyPostfix] [HarmonyPatch(typeof(ZoneSystem), "ShouldDelayProxyLocationSpawning")] private static void DelayLocation_Post(ref bool __result) { if (__result) { return; } ZNetScene instance = ZNetScene.instance; if ((Object)(object)instance == (Object)null || instance.InLoadingScreen()) { return; } if (Stopwatch.GetTimestamp() < _locNextAllowed) { __result = true; return; } int frameCount = Time.frameCount; if (frameCount == _locBusyFrame) { __result = true; } else if (FrameLoad.Busy && _locBusySkips < 6) { _locBusySkips++; _locBusyFrame = frameCount; __result = true; } else { _locBusySkips = 0; } } [HarmonyPrefix] [HarmonyPatch(typeof(ZoneSystem), "SpawnProxyLocation")] private static void SpawnLoc_Pre() { _locStart = Stopwatch.GetTimestamp(); } [HarmonyPostfix] [HarmonyPatch(typeof(ZoneSystem), "SpawnProxyLocation")] private static void SpawnLoc_Post() { long timestamp = Stopwatch.GetTimestamp(); double num = (double)(timestamp - _locStart) / Tick; double num2 = Math.Min(400.0, Math.Max(50.0, num * 2.0)); _locNextAllowed = timestamp + (long)(num2 * Tick); } [HarmonyPrefix] [HarmonyPatch(typeof(ZNetScene), "CreateObjectsSorted")] private static bool CreateObjectsSorted_Prefix(ZNetScene __instance, List<ZDO> currentNearObjects, int maxCreatedPerFrame, ref int created) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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_00d7: 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) if (!Active(__instance)) { return true; } if (!ZoneSystem.instance.IsActiveAreaLoaded()) { return false; } List<ZDO> tempCurrentObjects = __instance.m_tempCurrentObjects2; tempCurrentObjects.Clear(); Vector3 referencePosition = ZNet.instance.GetReferencePosition(); foreach (ZDO currentNearObject in currentNearObjects) { if (!currentNearObject.Created) { currentNearObject.m_tempSortValue = Utils.DistanceSqr(referencePosition, currentNearObject.GetPosition()); tempCurrentObjects.Add(currentNearObject); } } if (tempCurrentObjects.Count == 0) { return false; } int num = Mathf.Max(tempCurrentObjects.Count / 100, maxCreatedPerFrame); tempCurrentObjects.Sort((Comparison<ZDO>)ZNetScene.ZDOCompare); foreach (ZDO item in tempCurrentObjects) { if (!ZoneSystem.instance.IsZoneReadyForType(item.GetSector(), item.Type)) { continue; } if ((Object)(object)__instance.CreateObject(item) != (Object)null) { created++; if (created >= num || OverBudget()) { break; } } else if (ZNet.instance.IsServer()) { item.SetOwner(ZDOMan.GetSessionID()); ZLog.Log((object)("Destroyed invalid prefab ZDO:" + ((object)Unsafe.As<ZDOID, ZDOID>(ref item.m_uid)/*cast due to .constrained prefix*/).ToString())); ZDOMan.instance.DestroyZDO(item); } } return false; } [HarmonyPrefix] [HarmonyPatch(typeof(ZNetScene), "CreateDistantObjects")] private static bool CreateDistantObjects_Prefix(ZNetScene __instance, List<ZDO> objects, int maxCreatedPerFrame, ref int created) { if (!Active(__instance)) { return true; } if (created > maxCreatedPerFrame || OverBudget()) { return false; } foreach (ZDO @object in objects) { if (@object.Created) { continue; } if ((Object)(object)__instance.CreateObject(@object) != (Object)null) { created++; if (created > maxCreatedPerFrame || OverBudget()) { break; } } else if (ZNet.instance.IsServer()) { @object.SetOwner(ZDOMan.GetSessionID()); ZLog.Log((object)("Destroyed invalid predab ZDO:" + ((object)Unsafe.As<ZDOID, ZDOID>(ref @object.m_uid)/*cast due to .constrained prefix*/).ToString() + " prefab hash:" + @object.GetPrefab())); ZDOMan.instance.DestroyZDO(@object); } } return false; } } private static readonly double Tick = (double)Stopwatch.Frequency / 1000.0; private static long _t0; private static long _budget; private static long _locNextAllowed; private static long _locStart; private static int _locBusySkips; private static int _locBusyFrame = -1; private static bool Active(ZNetScene zs) { if (!zs.InLoadingScreen()) { return (Object)(object)ZNet.instance != (Object)null; } return false; } private static bool OverBudget() { return Stopwatch.GetTimestamp() - _t0 > _budget; } } internal static class ShadowCull { private static Light _light; private static bool _dirty = true; private static bool _applied; private static float _next; internal static void MarkDirty() { _dirty = true; } internal static void Tick() { if (Time.unscaledTime < _next && !_dirty) { return; } _next = Time.unscaledTime + 1f; EnvMan instance = EnvMan.instance; Light val = (((Object)(object)instance != (Object)null) ? instance.m_dirLight : null); if ((Object)(object)val == (Object)null) { _light = null; return; } if ((Object)(object)val != (Object)(object)_light || _dirty || !_applied) { val.layerShadowCullDistances = Build(); _light = val; _applied = true; } _dirty = false; } private static float[] Build() { float[] array = new float[32]; Set(array, "piece", Plugin.CShadowPiece.Value); Set(array, "piece_nonsolid", Plugin.CShadowSmall.Value); Set(array, "Default_small", Plugin.CShadowSmall.Value); Set(array, "effect", Plugin.CShadowSmall.Value); Set(array, "item", Plugin.CShadowItem.Value); Set(array, "weapon", Plugin.CShadowItem.Value); Set(array, "character", Plugin.CShadowCharacter.Value); Set(array, "character_net", Plugin.CShadowCharacter.Value); Set(array, "character_noenv", Plugin.CShadowCharacter.Value); Set(array, "character_ghost", Plugin.CShadowCharacter.Value); Set(array, "vehicle", Plugin.CShadowVehicle.Value); return array; } private static void Set(float[] d, string layer, float dist) { int num = LayerMask.NameToLayer(layer); if (num >= 0 && num < 32) { d[num] = Mathf.Max(0f, dist); } } } internal static class SkyAlphaThrottle { [HarmonyPatch] internal static class Hooks { [HarmonyPrefix] [HarmonyPatch(typeof(DepthCamera), "RenderDepth")] private static bool RenderDepth_Prefix(DepthCamera __instance) { //IL_0052: 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_0057: 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_00c3: 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_012c: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) Camera mainCamera = Utils.GetMainCamera(); if ((Object)(object)mainCamera == (Object)null) { return true; } if ((Object)(object)__instance.m_camera != (Object)null) { _mask = __instance.m_camera.cullingMask; } Vector3 val = (Object.op_Implicit((Object)(object)Player.m_localPlayer) ? ((Component)Player.m_localPlayer).transform.position : ((Component)mainCamera).transform.position); float time = Time.time; bool flag = (Object)(object)__instance.m_texture != (Object)null && !__instance.m_texture.IsCreated(); bool flag2 = !_has || _dirty || flag || time - _lastTime >= Plugin.CSkyMaxInterval.Value; if (!flag2) { float num = val.x - _lastCenter.x; float num2 = val.z - _lastCenter.z; float value = Plugin.CSkyMove.Value; if (num * num + num2 * num2 > value * value || Mathf.Abs(val.y - _lastCenter.y) > Plugin.CSkyVertical.Value) { flag2 = true; } } if (!flag2) { return false; } _has = true; _dirty = false; _lastCenter = val; _lastTime = time; return true; } [HarmonyPostfix] [HarmonyPatch(typeof(ZNetView), "Awake")] private static void ZNetView_Awake(ZNetView __instance) { MarkIfRelevant(((Component)__instance).gameObject); } [HarmonyPrefix] [HarmonyPatch(typeof(ZNetView), "OnDestroy")] private static void ZNetView_OnDestroy(ZNetView __instance) { MarkIfRelevant(((Component)__instance).gameObject); } } private static bool _has; private static Vector3 _lastCenter; private static float _lastTime; private static bool _dirty = true; private static int _mask = 33792; private const float DirtyRadius = 60f; private static void MarkIfRelevant(GameObject go) { //IL_001e: 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) if (_has && !_dirty && !((Object)(object)go == (Object)null)) { Vector3 position = go.transform.position; float num = position.x - _lastCenter.x; float num2 = position.z - _lastCenter.z; if (!(num * num + num2 * num2 > 3600f) && ((_mask & (1 << go.layer)) != 0 || !((Object)(object)go.GetComponent<Piece>() == (Object)null))) { _dirty = true; } } } } internal static class SyncCoalesce { [HarmonyPatch] internal static class Hooks { [HarmonyTranspiler] [HarmonyPatch(typeof(ZSyncTransform), "SyncPosition")] private static IEnumerable<CodeInstruction> SyncPosition_Transpiler(IEnumerable<CodeInstruction> instructions) { MethodInfo target = AccessTools.Method(typeof(Physics), "SyncTransforms", (Type[])null, (Type[])null); MethodInfo repl = AccessTools.Method(typeof(SyncCoalesce), "Sync", (Type[])null, (Type[])null); int n = 0; foreach (CodeInstruction instruction in instructions) { if (CodeInstructionExtensions.Calls(instruction, target)) { n++; yield return CodeInstructionExtensions.MoveBlocksFrom(CodeInstructionExtensions.MoveLabelsFrom(new CodeInstruction(OpCodes.Call, (object)repl), instruction), instruction); } else { yield return instruction; } } if (n == 0) { Plugin.Log.LogWarning((object)"SyncCoalesce: no Physics.SyncTransforms call found in ZSyncTransform.SyncPosition (inactive)"); } } [HarmonyPrefix] [HarmonyPatch(typeof(MonoUpdatersExtra), "CustomFixedUpdate")] private static void Loop_Prefix(List<IMonoUpdater> source) { if (source == ZSyncTransform.Instances) { _inLoop = true; _dirty = false; } } [HarmonyFinalizer] [HarmonyPatch(typeof(MonoUpdatersExtra), "CustomFixedUpdate")] private static void Loop_Finalizer() { if (_inLoop) { _inLoop = false; if (_dirty) { _dirty = false; Physics.SyncTransforms(); } } } } private static bool _inLoop; private static bool _dirty; public static void Sync() { if (_inLoop) { _dirty = true; } else { Physics.SyncTransforms(); } } } internal static class TerrainAsync { private struct BakeJob : IJob { public int MeshId; public MeshColliderCookingOptions Options; public void Execute() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) Physics.BakeMesh(MeshId, false, Options); } } private class Pending { public Heightmap Hm; public Mesh Mesh; public JobHandle Handle; public int Frame; } [HarmonyPatch] internal static class Hooks { [HarmonyPrefix] [HarmonyPatch(typeof(Heightmap), "RebuildCollisionMesh")] private static bool RebuildCollisionMesh_Prefix(Heightmap __instance) { //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_0093: Expected O, but got Unknown //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0247: 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_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_0298: 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) //IL_00c7: 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_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: 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_00f2: Unknown result type (might be due to invalid IL or missing references) CompleteOnly(__instance); _deferredThisCall = null; bool num = (Object)(object)ZNetScene.instance != (Object)null && !ZNetScene.instance.InLoadingScreen(); bool flag = (Object)(object)__instance.m_collider != (Object)null && (Object)(object)__instance.m_collider.sharedMesh != (Object)null && (Object)(object)__instance.m_collisionMesh != (Object)null; if (!(num && flag) || WorldGenFix.SpawningZones != 0) { return true; } if ((Object)(object)__instance.m_collisionMesh == (Object)null) { __instance.m_collisionMesh = new Mesh { name = "___Heightmap m_collisionMesh" }; } int num2 = __instance.m_width + 1; float num3 = -999999f; float num4 = 999999f; Heightmap.s_tempVertices.Clear(); for (int i = 0; i < num2; i++) { for (int j = 0; j < num2; j++) { Vector3 val = __instance.CalcVertex(j, i); Heightmap.s_tempVertices.Add(val); if (val.y > num3) { num3 = val.y; } if (val.y < num4) { num4 = val.y; } } } __instance.m_collisionMesh.SetVertices(Heightmap.s_tempVertices); int num5 = (num2 - 1) * (num2 - 1) * 6; if (__instance.m_collisionMesh.GetIndexCount(0) != num5) { Heightmap.s_tempIndices.Clear(); for (int k = 0; k < num2 - 1; k++) { for (int l = 0; l < num2 - 1; l++) { int item = k * num2 + l; int item2 = k * num2 + l + 1; int item3 = (k + 1) * num2 + l + 1; int item4 = (k + 1) * num2 + l; Heightmap.s_tempIndices.Add(item); Heightmap.s_tempIndices.Add(item4); Heightmap.s_tempIndices.Add(item2); Heightmap.s_tempIndices.Add(item2); Heightmap.s_tempIndices.Add(item4); Heightmap.s_tempIndices.Add(item3); } } __instance.m_collisionMesh.SetIndices(Heightmap.s_tempIndices.ToArray(), (MeshTopology)0, 0); } _deferredThisCall = __instance; float num6 = (float)__instance.m_width * __instance.m_scale * 0.5f; ((Bounds)(ref __instance.m_bounds)).SetMinMax(((Component)__instance).transform.position + new Vector3(0f - num6, num4, 0f - num6), ((Component)__instance).transform.position + new Vector3(num6, num3, num6)); __instance.m_boundingSphere.position = ((Bounds)(ref __instance.m_bounds)).center; __instance.m_boundingSphere.radius = Vector3.Distance(__instance.m_boundingSphere.position, ((Bounds)(ref __instance.m_bounds)).max); return false; } [HarmonyPostfix] [HarmonyPatch(typeof(Heightmap), "Regenerate")] private static void Regenerate_Postfix(Heightmap __instance) { //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_005d: 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_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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) if (_deferredThisCall == __instance) { _deferredThisCall = null; if (!((Object)(object)__instance.m_collider == (Object)null) && !((Object)(object)__instance.m_collisionMesh == (Object)null)) { JobHandle handle = IJobExtensions.Schedule<BakeJob>(new BakeJob { MeshId = ((Object)__instance.m_collisionMesh).GetInstanceID(), Options = __instance.m_collider.cookingOptions }, default(JobHandle)); JobHandle.ScheduleBatchedJobs(); _pending.Add(new Pending { Hm = __instance, Mesh = __instance.m_collisionMesh, Handle = handle, Frame = Time.frameCount }); } } } [HarmonyFinalizer] [HarmonyPatch(typeof(Heightmap), "Regenerate")] private static void Regenerate_Finalizer(Heightmap __instance, Exception __exception) { if (__exception != null && _deferredThisCall == __instance) { _deferredThisCall = null; if ((Object)(object)__instance.m_collider != (Object)null && (Object)(object)__instance.m_collisionMesh != (Object)null) { __instance.m_collider.sharedMesh = __instance.m_collisionMesh; } } } [HarmonyPrefix] [HarmonyPatch(typeof(Heightmap), "OnDestroy")] private static void OnDestroy_Prefix(Heightmap __instance) { CompleteOnly(__instance); } [HarmonyPrefix] [HarmonyPatch(typeof(Heightmap), "Clear")] private static void Clear_Prefix(Heightmap __instance) { CompleteOnly(__instance); } [HarmonyPostfix] [HarmonyPatch(typeof(Heightmap), "HaveQueuedRebuild", new Type[] { typeof(Vector3), typeof(float) })] private static void HaveQueuedRebuild_Postfix(Vector3 point, float radius, ref bool __result) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (__result || _pending.Count == 0) { return; } for (int i = 0; i < _pending.Count; i++) { Heightmap hm = _pending[i].Hm; if ((Object)(object)hm != (Object)null && hm.IsPointInside(point, radius)) { __result = true; break; } } } } private static readonly List<Pending> _pending = new List<Pending>(); private static readonly FieldRef<Heightmap, Action> _wntCache = AccessTools.FieldRefAccess<Heightmap, Action>("m_clearConnectedWearNTearCache"); private static Heightmap _deferredThisCall; private static int IndexOf(Heightmap hm) { for (int i = 0; i < _pending.Count; i++) { if (_pending[i].Hm == hm) { return i; } } return -1; } private static void CompleteOnly(Heightmap hm) { int num = IndexOf(hm); if (num >= 0) { ((JobHandle)(ref _pending[num].Handle)).Complete(); _pending.RemoveAt(num); } } private static void Finish(int i) { Pending pending = _pending[i]; ((JobHandle)(ref pending.Handle)).Complete(); _pending.RemoveAt(i); Heightmap hm = pending.Hm; if (!((Object)(object)hm == (Object)null) && !((Object)(object)hm.m_collider == (Object)null) && !((Object)(object)hm.m_collisionMesh == (Object)null) && hm.m_collisionMesh == pending.Mesh) { hm.m_collider.sharedMesh = hm.m_collisionMesh; _wntCache.Invoke(hm)?.Invoke(); } } internal static void Tick() { if (_pending.Count == 0) { return; } int frameCount = Time.frameCount; for (int num = _pending.Count - 1; num >= 0; num--) { Pending pending = _pending[num]; if ((Object)(object)pending.Hm == (Object)null) { ((JobHandle)(ref pending.Handle)).Complete(); _pending.RemoveAt(num); } else if (((JobHandle)(ref pending.Handle)).IsCompleted || frameCount - pending.Frame >= 2) { Finish(num); } } } internal static void CompleteAll() { for (int num = _pending.Count - 1; num >= 0; num--) { Finish(num); } } } internal static class TerrainMeshAsync { private sealed class Buffers { public float[] Heights; public Vector3[] Verts; public Color32[] Colors; public Vector3[] Normals; public Vector4[] Tangents; public Buffers(int n) { Heights = new float[n]; Verts = (Vector3[])(object)new Vector3[n]; Colors = (Color32[])(object)new Color32[n]; Normals = (Vector3[])(object)new Vector3[n]; Tangents = (Vector4[])(object)new Vector4[n]; } } private sealed class Job { public Heightmap Hm; public int Width; public float Scale; public bool DistantLod; public BiomeSector[] Corners; public Buffers Buf; public Vector3 Origin; public WorldGenerator WorldGen; public long Seq; public Vector2[] Uvs; public int[] Indices; public Bounds Bounds; } [HarmonyPatch] internal static class Hooks { [HarmonyPrefix] [HarmonyPatch(typeof(Heightmap), "RebuildRenderMesh")] private static bool RebuildRenderMesh_Prefix(Heightmap __instance) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance.m_renderMesh == (Object)null && MustBeInstant(__instance)) { return true; } if (PendingCount() >= 24) { return true; } Schedule(__instance, __instance.m_width, __instance.m_scale, __instance.IsDistantLod, __instance.m_cornerBiomes, __instance.m_heights, ((Component)__instance).transform.position, WorldGenerator.instance); return false; } [HarmonyPrefix] [HarmonyPatch(typeof(Heightmap), "OnDestroy")] private static void OnDestroy_Prefix(Heightmap __instance) { lock (_lock) { _latestSeq.Remove(__instance); } } } private const int WorkerCount = 2; private const int MaxQueueDepth = 24; private static readonly double TickToMs = 1000.0 / (double)Stopwatch.Frequency; private const double ApplyBudgetMs = 1.5; private static readonly Dictionary<int, Stack<Buffers>> _pool = new Dictionary<int, Stack<Buffers>>(); private static readonly object _lock = new object(); private static readonly Queue<Job> _toBuild = new Queue<Job>(); private static readonly Queue<Job> _ready = new Queue<Job>(); private static readonly Dictionary<Heightmap, long> _latestSeq = new Dictionary<Heightmap, long>(); private static long _seq; private static Thread[] _workers; private static bool _stop; private static readonly Dictionary<int, (Vector2[] uvs, int[] indices)> _gridCache = new Dictionary<int, (Vector2[], int[])>(); private static readonly FieldRef<Heightmap, Action> _wntCache = AccessTools.FieldRefAccess<Heightmap, Action>("m_clearConnectedWearNTearCache"); private static Buffers Rent(int width) { lock (_pool) { if (_pool.TryGetValue(width, out var value) && value.Count > 0) { return value.Pop(); } } int num = width + 1; return new Buffers(num * num); } private static void Return(Job job, int width) { if (job.Buf == null) { return; } lock (_pool) { if (!_pool.TryGetValue(width, out var value)) { value = (_pool[width] = new Stack<Buffers>()); } if (value.Count < 24) { value.Push(job.Buf); } } job.Buf = null; } private static void EnsureStarted() { if (_workers != null) { return; } lock (_lock) { if (_workers == null) { _workers = new Thread[2]; for (int i = 0; i < 2; i++) { Thread thread = new Thread(WorkerLoop) { IsBackground = true, Name = "ValheimOptimized.MeshBuild" + i }; thread.Start(); _workers[i] = thread; } } } } internal static void Shutdown() { lock (_lock) { _stop = true; } if (_workers != null) { Thread[] workers = _workers; foreach (Thread thread in workers) { try { thread.Join(500); } catch { } } } _workers = null; } private static (Vector2[] uvs, int[] indices) GridFor(int width) { //IL_0054: 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) lock (_gridCache) { if (_gridCache.TryGetValue(width, out (Vector2[], int[]) value)) { return value; } int num = width + 1; Vector2[] array = (Vector2[])(object)new Vector2[num * num]; for (int i = 0; i < num; i++) { for (int j = 0; j < num; j++) { array[i * num + j] = new Vector2((float)j / (float)width, (float)i / (float)width); } } int[] array2 = new int[(num - 1) * (num - 1) * 6]; int num2 = 0; for (int k = 0; k < num - 1; k++) { for (int l = 0; l < num - 1; l++) { int num3 = k * num + l; int num4 = k * num + l + 1; int num5 = (k + 1) * num + l + 1; int num6 = (k + 1) * num + l; array2[num2++] = num3; array2[num2++] = num6; array2[num2++] = num4; array2[num2++] = num4; array2[num2++] = num6; array2[num2++] = num5; } } value = (array, array2); _gridCache[width] = value; return value; } } private static int PendingCount() { lock (_lock) { return _toBuild.Count; } } private static void Schedule(Heightmap hm, int width, float scale, bool distantLod, BiomeSector[] corners, List<float> heights, Vector3 origin, WorldGenerator worldGen) { //IL_0045: 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) EnsureStarted(); Job job = new Job { Hm = hm, Width = width, Scale = scale, DistantLod = distantLod, Corners = (BiomeSector[])corners.Clone(), Buf = Rent(width), Origin = origin, WorldGen = worldGen }; heights.CopyTo(job.Buf.Heights); lock (_lock) { job.Seq = ++_seq; _latestSeq[hm] = job.Seq; _toBuild.Enqueue(job); } } private static void WorkerLoop() { while (true) { Job job = null; lock (_lock) { if (_stop) { break; } if (_toBuild.Count > 0) { job = _toBuild.Dequeue(); } } if (job == null) { Thread.Sleep(1); continue; } try { Build(job); } catch (Exception ex) { Plugin.Log.LogWarning((object)("TerrainMeshAsync build failed: " + ex.Message)); continue; } lock (_lock) { _ready.Enqueue(job); } } } private static void Build(Job job) { //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_0094: 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_00a3: 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_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_0118: 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_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_03e7: Unknown result type (might be due to invalid IL or missing references) //IL_03f7: Unknown result type (might be due to invalid IL or missing references) //IL_0402: Unknown result type (might be due to invalid IL or missing references) //IL_041b: Unknown result type (might be due to invalid IL or missing references) //IL_041d: 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_0183: 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_01ad: 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_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: 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_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0211: 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_0217: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Unknown result type (might be due to invalid IL or missing references) //IL_031b: 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_0324: Unknown result type (might be due to invalid IL or missing references) //IL_0333: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_034f: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Unknown result type (might be due to invalid IL or missing references) //IL_035a: Unknown result type (might be due to invalid IL or missing references) //IL_035f: Unknown result type (might be due to invalid IL or missing references) //IL_0364: 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_0374: Unknown result type (might be due to invalid IL or missing references) //IL_0379: Unknown result type (might be due to invalid IL or missing references) //IL_037b: Unknown result type (might be due to invalid IL or missing references) //IL_0380: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_0392: Unknown result type (might be due to invalid IL or missing references) //IL_0398: 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_03a6: Unknown result type (might be due to invalid IL or missing references) //IL_03b2: Unknown result type (might be due to invalid IL or missing references) //IL_03b7: Unknown result type (might be due to invalid IL or missing references) int width = job.Width; int num = width + 1; (Vector2[] uvs, int[] indices) tuple = GridFor(width); Vector2[] item = tuple.uvs; int[] item2 = tuple.indices; float[] heights = job.Buf.Heights; float scale = job.Scale; Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor((float)width * scale * -0.5f, 0f, (float)width * scale * -0.5f); Vector3[] verts = job.Buf.Verts; Color32[] colors = job.Buf.Colors; float num2 = float.MaxValue; float num3 = float.MinValue; Color32 biomeColor = Heightmap.GetBiomeColor(job.Corners[0]); Color32 biomeColor2 = Heightmap.GetBiomeColor(job.Corners[1]); Color32 biomeColor3 = Heightmap.GetBiomeColor(job.Corners[2]); Color32 biomeColor4 = Heightmap.GetBiomeColor(job.Corners[3]); bool flag = job.Corners[0] == job.Corners[1] && job.Corners[0] == job.Corners[2] && job.Corners[0] == job.Corners[3]; for (int i = 0; i < num; i++) { for (int j = 0; j < num; j++) { int num4 = i * num + j; float num5 = heights[num4]; verts[num4] = new Vector3(val.x + (float)j * scale, num5, val.z + (float)i * scale); if (num5 < num2) { num2 = num5; } if (num5 > num3) { num3 = num5; } if (job.DistantLod) { float num6 = job.Origin.x + val.x + (float)j * scale; float num7 = job.Origin.z + val.z + (float)i * scale; colors[num4] = Heightmap.GetBiomeColor(job.WorldGen.GetBiomeSector(num6, num7, false)); } else if (flag) { colors[num4] = biomeColor; } else { float num8 = DUtils.SmoothStep(0f, 1f, (float)j / (float)width); float num9 = DUtils.SmoothStep(0f, 1f, (float)i / (float)width); Color32 val2 = Color32.Lerp(biomeColor, biomeColor2, num8); Color32 val3 = Color32.Lerp(biomeColor3, biomeColor4, num8); colors[num4] = Color32.Lerp(val2, val3, num9); } } } Vector3[] normals = job.Buf.Normals; Vector4[] tangents = job.Buf.Tangents; Vector3 val5 = default(Vector3); for (int k = 0; k < num; k++) { int num10 = Math.Max(k - 1, 0); int num11 = Math.Min(k + 1, num - 1); float num12 = ((num10 == num11) ? 1f : ((float)(num11 - num10) * scale)); for (int l = 0; l < num; l++) { int num13 = Math.Max(l - 1, 0); int num14 = Math.Min(l + 1, num - 1); float num15 = ((num13 == num14) ? 1f : ((float)(num14 - num13) * scale)); float num16 = heights[k * num + num13]; float num17 = heights[k * num + num14]; float num18 = heights[num10 * num + l]; float num19 = heights[num11 * num + l]; float num20 = (num17 - num16) / num15; float num21 = (num19 - num18) / num12; Vector3 val4 = new Vector3(0f - num20, 1f, 0f - num21); Vector3 normalized = ((Vector3)(ref val4)).normalized; int num22 = k * num + l; normals[num22] = normalized; ((Vector3)(ref val5))..ctor(1f, num20, 0f); val5 -= normalized * Vector3.Dot(val5, normalized); Vector3 normalized2; if (!(((Vector3)(ref val5)).sqrMagnitude > 1E-08f)) { val4 = Vector3.Cross(Vector3.up, normalized); normalized2 = ((Vector3)(ref val4)).normalized; } else { normalized2 = ((Vector3)(ref val5)).normalized; } val5 = normalized2; tangents[num22] = new Vector4(val5.x, val5.y, val5.z, -1f); } } float num23 = (float)width * scale * 0.5f; Bounds bounds = default(Bounds); ((Bounds)(ref bounds)).SetMinMax(new Vector3(0f - num23, num2, 0f - num23), new Vector3(num23, num3, num23)); job.Uvs = item; job.Indices = item2; job.Bounds = bounds; } internal static void Tick() { if (_workers == null) { return; } long num = (long)(1.5 / TickToMs); long num2 = 0L; while (true) { Job job; lock (_lock) { if (_ready.Count == 0) { break; } job = _ready.Dequeue(); } bool flag; lock (_lock) { flag = !_latestSeq.TryGetValue(job.Hm, out var value) || value != job.Seq; } if (flag) { Return(job, job.Width); continue; } long timestamp = Stopwatch.GetTimestamp(); Apply(job); Return(job, job.Width); lock (_lock) { _latestSeq.Remove(job.Hm); } num2 += Stopwatch.GetTimestamp() - timestamp; if (num2 <= num) { continue; } break; } } private static void Apply(Job job) { //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown Heightmap hm = job.Hm; if (!((Object)(object)hm == (Object)null) && !((Object)(object)hm.m_meshFilter == (Object)null)) { Mesh val = hm.m_renderMesh; if ((Object)(object)val == (Object)null) { val = (hm.m_renderMesh = new Mesh { name = "___Heightmap m_renderMesh" }); } val.Clear(); int num = (job.Width + 1) * (job.Width + 1); val.SetVertices(job.Buf.Verts, 0, num); val.SetColors(job.Buf.Colors, 0, num); val.SetUVs(0, job.Uvs); val.SetIndices(job.Indices, (MeshTopology)0, 0); val.SetNormals(job.Buf.Normals, 0, num); val.SetTangents(job.Buf.Tangents, 0, num); val.bounds = job.Bounds; hm.m_meshFilter.mesh = val; _wntCache.Invoke(hm)?.Invoke(); } } internal static bool MustBeInstant(Heightmap hm) { //IL_0032: 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_0047: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZNetScene.instance == (Object)null || ZNetScene.instance.InLoadingScreen()) { return true; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return true; } Vector3 val = ((Component)hm).transform.position - ((Component)localPlayer).transform.position; val.y = 0f; if (!hm.IsDistantLod) { return ((Vector3)(ref val)).sqrMagnitude < 5184f; } return false; } } internal static class TerrainStream { [HarmonyPatch] internal static class Hooks { [HarmonyTranspiler] [HarmonyPatch(typeof(HeightmapBuilder), "BuildThread")] private static IEnumerable<CodeInstruction> BuildThread_Transpiler(IEnumerable<CodeInstruction> instructions) { MethodInfo sleep = AccessTools.Method(typeof(Thread), "Sleep", new Type[1] { typeof(int) }, (Type[])null); MethodInfo repl = AccessTools.Method(typeof(TerrainStream), "BuilderSleep", (Type[])null, (Type[])null); int n = 0; foreach (CodeInstruction instruction in instructions) { if (CodeInstructionExtensions.Calls(instruction, sleep)) { n++; yield return CodeInstructionExtensions.MoveBlocksFrom(CodeInstructionExtensions.MoveLabelsFrom(new CodeInstruction(OpCodes.Call, (object)repl), instruction), instruction); } else if ((instruction.opcode == OpCodes.Ldc_I4_S || instruction.opcode == OpCodes.Ldc_I4) && Convert.ToInt32(instruction.operand) == 16) { n++; yield return CodeInstructionExtensions.MoveBlocksFrom(CodeInstructionExtensions.MoveLabelsFrom(new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(TerrainStream), "ReadyCap", (Type[])null, (Type[])null)), instruction), instruction); } else { yield return instruction; } } if (n != 2) { Plugin.Log.LogWarning((object)$"TerrainStream: BuildThread patched {n} site(s), expected 2 (terrain streaming priority may be inactive)"); } } [HarmonyPrefix] [HarmonyPatch(typeof(HeightmapBuilder), "RequestTerrainSync")] private static void RequestTerrainSync_Prefix(HeightmapBuilder __instance, Vector3 center, int width, float scale, bool distantLod, WorldGenerator worldGen) { //IL_002b: 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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Expected O, but got Unknown object obj = __instance.m_lock; if (obj == null) { return; } lock (obj) { List<HMBuildData> ready = __instance.m_ready; for (int i = 0; i < ready.Count; i++) { if (ready[i].IsEqual(center, width, scale, distantLod, worldGen)) { return; } } List<HMBuildData> toBuild = __instance.m_toBuild; int num = -1; for (int j = 0; j < toBuild.Count; j++) { if (toBuild[j].IsEqual(center, width, scale, distantLod, worldGen)) { num = j; break; } } if (num > 1) { HMBuildData item = toBuild[num]; toBuild.RemoveAt(num); toBuild.Insert(1, item); } else if (num < 0) { toBuild.Insert(Mathf.Min(1, toBuild.Count), new HMBuildData(center, width, scale, distantLod, worldGen)); } } } [HarmonyPrefix] [HarmonyPatch(typeof(TerrainLod), "RebuildAllHeightmaps")] private static bool RebuildAll_Prefix(TerrainLod __instance) { //IL_004a: 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_0094: Unknown result type (might be due to invalid IL or missing references) if (!_lodDone.TryGetValue(__instance, out var value)) { value = (_lodDone[__instance] = new HashSet<int>()); } List<HeightmapWithOffset> heightmaps = __instance.m_heightmaps; for (int i = 0; i < heightmaps.Count; i++) { if (!value.Contains(i)) { __instance.RebuildHeightmap(heightmaps[i]); heightmaps[i].m_state = (HeightmapState)1; value.Add(i); if (value.Count >= heightmaps.Count) { break; } return false; } } for (int j = 0; j < heightmaps.Count; j++) { heightmaps[j].m_state = (HeightmapState)2; } __instance.m_heightmapState = (HeightmapState)2; value.Clear(); return false; } [HarmonyPrefix] [HarmonyPatch(typeof(Heightmap), "LateUpdate")] private static bool HmLateUpdate_Prefix(Heightmap __instance) { if (__instance.m_doLateUpdate != 1) { return true; } return AllowDeferred(); } [HarmonyPrefix] [HarmonyPatch(typeof(Heightmap), "CustomLateUpdate")] private static bool HmCustomLateUpdate_Prefix(Heightmap __instance) { if (__instance.m_doLateUpdate != 2) { return true; } return AllowDeferred(); } [HarmonyPrefix] [HarmonyPriority(600)] [HarmonyPatch(typeof(Heightmap), "Regenerate")] private static void Regen_Pre(out long __state) { __state = Stopwatch.GetTimestamp(); } [HarmonyPostfix] [HarmonyPriority(200)] [HarmonyPatch(typeof(Heightmap), "Regenerate")] private static void Regen_Post(long __state) { RollFrame(); _frameRegenTicks += Stopwatch.GetTimestamp() - __state; } [HarmonyPrefix] [HarmonyPatch(typeof(TerrainLod), "ResetMeshes")] private static void ResetMeshes_Prefix(TerrainLod __instance) { _lodDone.Remove(__instance); } } private static readonly Dictionary<TerrainLod, HashSet<int>> _lodDone = new Dictionary<TerrainLod, HashSet<int>>(); private const double RegenBudgetMs = 3.0; private const int MaxDeferredPerFrame = 4; private static readonly double TickToMs = 1000.0 / (double)Stopwatch.Frequency; private static int _frame = -1; private static long _frameRegenTicks; private static int _frameDeferredRuns; public static int ReadyCap() { return 64; } public static void BuilderSleep(int ms) { HeightmapBuilder instance = HeightmapBuilder.m_instance; object obj = instance?.m_lock; if (obj != null) { bool flag; lock (obj) { flag = instance.m_toBuild.Count > 0; } if (flag) { Thread.Sleep(0); return; } } Thread.Sleep(ms); } private static void RollFrame() { int frameCount = Time.frameCount; if (frameCount != _frame) { _frame = frameCount; _frameRegenTicks = 0L; _frameDeferredRuns = 0; } } private static bool AllowDeferred() { RollFrame(); if (_frameDeferredRuns == 0 || ((double)_frameRegenTicks * TickToMs < 3.0 && _frameDeferredRuns < 4)) { _frameDeferredRuns++; return true; } return false; } } internal static class WorldGenFix { [HarmonyPatch] internal static class Hooks { [HarmonyPrefix] [HarmonyPatch(typeof(ZoneSystem), "SpawnZone")] private static void SpawnZone_Prefix() { SpawningZones++; } [HarmonyFinalizer] [HarmonyPatch(typeof(ZoneSystem), "SpawnZone")] private static void SpawnZone_Finalizer() { if (SpawningZones > 0) { SpawningZones--; } } } internal static int SpawningZones; } internal static class ZoneSmooth { private sealed class Job { public DungeonGenerator Gen; public int Next; public long Born; } private sealed class Tear { public GameObject Root; public List<GameObject> Parts = new List<GameObject>(); public List<int> Cost = new List<int>(); public int Next; } [HarmonyPatch] internal static class Hooks { private static float _ttlPending; private static int _ttlSkips; [HarmonyPrefix] [HarmonyPatch(typeof(ZNetScene), "RemoveObjects")] private static bool RemoveObjects_Prefix(ZNetScene __instance, List<ZDO> currentNearObjects, List<ZDO> currentDistantObjects) { if (InLoading()) { return true; } byte b = (byte)(Time.frameCount & 0xFF); foreach (ZDO currentNearObject in currentNearObjects) { currentNearObject.TempRemoveEarmark = b; } foreach (ZDO currentDistantObject in currentDistantObjects) { currentDistantObject.TempRemoveEarmark = b; } List<ZNetView> tempRemoved = __instance.m_tempRemoved; tempRemoved.Clear(); foreach (ZNetView value in __instance.m_instances.Values) { if (value.GetZDO().TempRemoveEarmark != b) { tempRemoved.Add(value); } } int count = tempRemoved.Count; if (count == 0) { return false; } int num = Math.Min(Math.Max(48, count / 10), count); int num2 = 0; for (int i = 0; i < num; i++) { ZNetView val = tempRemoved[i]; ZDO zDO = val.GetZDO(); val.ResetZDO(); if ((Object)(object)val != (Object)null) { GameObject gameObject = ((Component)val).gameObject; if (!TryDeferDestroy(gameObject)) { num2 += gameObject.transform.hierarchyCount; Object.Destroy((Object)(object)gameObject); } } if (!zDO.Persistent && zDO.IsOwner()) { ZDOMan.instance.DestroyZDO(zDO); } __instance.m_instances.Remove(zDO); if (num2 >= 900) { break; } } return false; } [HarmonyPrefix] [HarmonyPatch(typeof(DungeonGenerator), "OnRoomLoaded")] private static bool OnRoomLoaded_Prefix(DungeonGenerator __instance, LoadResult result, ref int ___m_roomsToLoad) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (InLoading()) { return true; } if ((int)result == 0 && !((Object)(object)__instance == (Object)null) && !((Object)(object)((Component)__instance).gameObject == (Object)null)) { ___m_roomsToLoad--; if (___m_roomsToLoad <= 0) { Jobs.Add(new Job { Gen = __instance, Next = 0, Born = Stopwatch.GetTimestamp() }); } } return false; } [HarmonyPrefix] [HarmonyPatch(typeof(ZoneSystem), "UpdateTTL")] private static bool UpdateTTL_Prefix(ref float dt) { if (!InLoading() && FrameLoad.Busy && _ttlSkips < 4) { _ttlPending += dt; _ttlSkips++; return false; } dt += _ttlPending; _ttlPending = 0f; _ttlSkips = 0; return true; } } private static readonly double TicksPerMs = (double)Stopwatch.Frequency / 1000.0; private static readonly List<Job> Jobs = new List<Job>(); private static long _nextRoomAllowed; private static int _roomDeferrals; private static readonly List<Tear> Tears = new List<Tear>(); private static int _tearDeferrals; private const int BigLocation = 400; private const int MaxPart = 250; private const int TearBudget = 500; private static bool InLoading() { ZNetScene instance = ZNetScene.instance; if (!((Object)(object)instance == (Object)null) && !instance.InLoadingScreen()) { return (Object)(object)ZNet.instance == (Object)null; } return true; } internal static void Update_() { try { if (Tears.Count > 0) { UpdateTears(); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("ZoneSmooth teardown failed, finishing at once: " + ex.Message)); FlushTears(); } if (Jobs.Count > 0) { UpdateRooms(); } } private static void UpdateRooms() { //IL_00c8: 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_00d8: 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_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) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) long timestamp = Stopwatch.GetTimestamp(); bool flag = InLoading(); if (!flag && timestamp - Jobs[0].Born <= (long)(800.0 * TicksPerMs)) { if (timestamp < _nextRoomAllowed) { return; } if (FrameLoad.Busy && _roomDeferrals < 4) { _roomDeferrals++; return; } } _roomDeferrals = 0; for (int i = 0; i < Jobs.Count; i++) { Job job = Jobs[i]; DungeonGenerator gen = job.Gen; if ((Object)(object)gen == (Object)null) { Jobs.RemoveAt(i--); continue; } try { RoomPlacementData[] loadedRooms = gen.m_loadedRooms; int num = ((loadedRooms != null) ? loadedRooms.Length : 0); while (job.Next < num) { RoomPlacementData val = loadedRooms[job.Next++]; long timestamp2 = Stopwatch.GetTimestamp(); gen.PlaceRoom(val.m_roomData, val.m_position, val.m_rotation, (RoomConnection)null, (SpawnMode)1); if (!flag) { long timestamp3 = Stopwatch.GetTimestamp(); _nextRoomAllowed = timestamp3 + Math.Max((timestamp3 - timestamp2) * 2, (long)(5.0 * TicksPerMs)); break; } } if (job.Next >= num) { SnapToGround.SnappAll(); gen.m_loadedRooms = null; gen.ReleaseHeldReferences(); Jobs.RemoveAt(i--); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("ZoneSmooth dungeon job failed: " + ex.Message)); try { gen.ReleaseHeldReferences(); } catch { } Jobs.RemoveAt(i--); } if (!flag) { break; } } } private static void Partition(Transform t, Tear tear) { for (int i = 0; i < t.childCount; i++) { Transform child = t.GetChild(i); int hierarchyCount = child.hierarchyCount; if (hierarchyCount > 250 && child.childCount > 0) { Partition(child, tear); } tear.Parts.Add(((Component)child).gameObject); tear.Cost.Add((hierarchyCount > 250) ? 1 : hierarchyCount); } } private static bool TryDeferDestroy(GameObject go) { try { if ((Object)(object)go.GetComponent<LocationProxy>() == (Object)null) { return false; } if (go.transform.hierarchyCount < 400) { return false; } Tear tear = new Tear { Root = go }; Partition(go.transform, tear); if (tear.Parts.Count < 2) { return false; } Tears.Add(tear); return true; } catch { return false; } } private static void UpdateTears() { bool flag = InLoading(); if (!flag && FrameLoad.Busy && _tearDeferrals < 3) { _tearDeferrals++; return; } _tearDeferrals = 0; for (int i = 0; i < Tears.Count; i++) { Tear tear = Tears[i]; if ((Object)(object)tear.Root == (Object)null) { Tears.RemoveAt(i--); continue; } int num = 0; while (tear.Next < tear.Parts.Count && (flag || num < 500)) { GameObject val = tear.Parts[tear.Next]; num += tear.Cost[tear.Next]; tear.Next++; if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } } if (tear.Next >= tear.Parts.Count) { Object.Destroy((Object)(object)tear.Root); Tears.RemoveAt(i--); } if (!flag) { break; } } } private static void FlushTears() { Tear[] array = Tears.ToArray(); foreach (Tear tear in array) { try { if ((Object)(object)tear.Root != (Object)null) { Object.Destroy((Object)(object)tear.Root); } } catch { } } Tears.Clear(); } internal static void Shutdown() { Job[] array = Jobs.ToArray(); foreach (Job job in array) { try { if ((Object)(object)job.Gen != (Object)null) { job.Gen.ReleaseHeldReferences(); } } catch { } } Jobs.Clear(); FlushTears(); } } internal sealed class Fixed<T> { public readonly T Value; public Fixed(T v) { Value = v; } } internal static class Feat { public const bool DepthNormals = true; public const bool ShadowCull = true; public const bool SkyAlpha = true; public const bool Minimap = true; public const bool Terrain = true; public const bool Sync = true; public const bool TerrainStream = true; public const bool ObjectSpawn = true; public const bool AllocTrim = true; public const bool ZoneSmooth = true; } [BepInPlugin("dow.valheim.optimized", "ValheimOptimized", "1.1.1")] public class Plugin : BaseUnityPlugin { public const string Guid = "dow.valheim.optimized"; public const string Name = "ValheimOptimized"; public const string Version = "1.1.1"; internal static Plugin Instance; internal static ManualLogSource Log; private Harmony _harmony; internal static readonly Fixed<float> CShadowPiece = new Fixed<float>(80f); internal static readonly Fixed<float> CShadowSmall = new Fixed<float>(35f); internal static readonly Fixed<float> CShadowCharacter = new Fixed<float>(50f); internal static readonly Fixed<float> CShadowItem = new Fixed<float>(25f); internal static readonly Fixed<float> CShadowVehicle = new Fixed<float>(80f); internal static readonly Fixed<float> CSkyMove = new Fixed<float>(12f); internal static readonly Fixed<float> CSkyVertical = new Fixed<float>(10f); internal static readonly Fixed<float> CSkyMaxInterval = new Fixed<float>(10f); internal static readonly Fixed<float> CObjectBudget = new Fixed<float>(1f); private void Awake() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; _harmony = new Harmony("dow.valheim.optimized"); PatchGroup(typeof(SkyAlphaThrottle.Hooks)); PatchGroup(typeof(MinimapUpload.Hooks)); PatchGroup(typeof(TerrainAsync.Hooks)); PatchGroup(typeof(SyncCoalesce.Hooks)); PatchGroup(typeof(TerrainStream.Hooks)); PatchGroup(typeof(TerrainMeshAsync.Hooks)); PatchGroup(typeof(ObjectSpawn.Hooks)); PatchGroup(typeof(AllocTrim.Hooks)); PatchGroup(typeof(ZoneSmooth.Hooks)); PatchGroup(typeof(WorldGenFix.Hooks)); Log.LogInfo((object)"ValheimOptimized 1.1.1 loaded."); } private void PatchGroup(Type t) { try { _harmony.PatchAll(t); } catch (Exception arg) { Log.LogError((object)$"Patch group {t.FullName} FAILED (that optimization is inactive): {arg}"); } } private void LateUpdate() { FrameLoad.Tick(); DepthNormalsFix.Tick(); ShadowCull.Tick(); TerrainAsync.Tick(); TerrainMeshAsync.Tick(); ZoneSmooth.Update_(); } private void OnDestroy() { TerrainAsync.CompleteAll(); TerrainMeshAsync.Shutdown(); ZoneSmooth.Shutdown(); } } }