Decompiled source of ValheimOptimizer v2.1.0

plugins/ValheimOptimizer.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn.Managers;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("ValheimOptimizer")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ValheimOptimizer")]
[assembly: AssemblyTitle("ValheimOptimizer")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ValheimOptimizer
{
	[BepInPlugin("com.yourname.valheimoptimizer", "Valheim Optimizer", "1.9.6")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class ValheimOptimizer : BaseUnityPlugin
	{
		[CompilerGenerated]
		private sealed class <DelayedZoneReflection>d__63 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public ValheimOptimizer <>4__this;

			private float <t>5__1;

			private Type <zsType>5__2;

			private object <zsInst>5__3;

			private Type <pType>5__4;

			private Type <cType>5__5;

			private Type <zType>5__6;

			private Type <znsType>5__7;

			private object <znsInst>5__8;

			private MethodInfo <destroyM>5__9;

			private Exception <ex>5__10;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DelayedZoneReflection>d__63(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<zsType>5__2 = null;
				<zsInst>5__3 = null;
				<pType>5__4 = null;
				<cType>5__5 = null;
				<zType>5__6 = null;
				<znsType>5__7 = null;
				<znsInst>5__8 = null;
				<destroyM>5__9 = null;
				<ex>5__10 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_03e5: Unknown result type (might be due to invalid IL or missing references)
				//IL_03ef: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<t>5__1 = 0f;
					break;
				case 1:
					<>1__state = -1;
					<t>5__1 += 0.5f;
					<zsType>5__2 = null;
					<zsInst>5__3 = null;
					break;
				}
				if (<t>5__1 < 10f)
				{
					<zsType>5__2 = AccessTools.TypeByName("ZoneSystem");
					<zsInst>5__3 = <zsType>5__2?.GetField("instance", BindingFlags.Static | BindingFlags.Public)?.GetValue(null);
					if (<zsInst>5__3 != null)
					{
						try
						{
							<>4__this._spawnZoneDel = (Action<int, int>)Delegate.CreateDelegate(typeof(Action<int, int>), <zsInst>5__3, <zsType>5__2.GetMethod("SpawnZone", new Type[2]
							{
								typeof(int),
								typeof(int)
							}));
							<>4__this._zoneCellSize = (float)<zsType>5__2.GetField("m_cellSize", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(<zsInst>5__3);
							<pType>5__4 = AccessTools.TypeByName("Player");
							<>4__this._playerField = <pType>5__4.GetField("m_localPlayer", BindingFlags.Static | BindingFlags.NonPublic);
							<>4__this._transformProp = <pType>5__4.GetProperty("transform", BindingFlags.Instance | BindingFlags.Public);
							<>4__this._characterField = <pType>5__4.GetField("m_character", BindingFlags.Instance | BindingFlags.NonPublic);
							<cType>5__5 = AccessTools.TypeByName("Character");
							<>4__this._velocityField = <cType>5__5.GetField("m_velocity", BindingFlags.Instance | BindingFlags.NonPublic);
							<>4__this._getAllChars = (Func<IEnumerable>)Delegate.CreateDelegate(typeof(Func<IEnumerable>), <cType>5__5.GetMethod("GetAllCharacters", BindingFlags.Static | BindingFlags.Public));
							<>4__this._isAlive = (Func<object, bool>)Delegate.CreateDelegate(typeof(Func<object, bool>), <cType>5__5.GetMethod("IsAlive", BindingFlags.Instance | BindingFlags.Public));
							<>4__this._isBoss = (Func<object, bool>)Delegate.CreateDelegate(typeof(Func<object, bool>), <cType>5__5.GetMethod("IsBoss", BindingFlags.Instance | BindingFlags.Public));
							<>4__this._isPlayer = (Func<object, bool>)Delegate.CreateDelegate(typeof(Func<object, bool>), <cType>5__5.GetMethod("IsPlayer", BindingFlags.Instance | BindingFlags.Public));
							<zType>5__6 = AccessTools.TypeByName("ZNet");
							<>4__this._getZNetInstance = (Func<object>)Delegate.CreateDelegate(typeof(Func<object>), <zType>5__6.GetProperty("instance", BindingFlags.Static | BindingFlags.Public).GetGetMethod());
							<>4__this._isServer = (Func<object, bool>)Delegate.CreateDelegate(typeof(Func<object, bool>), <zType>5__6.GetProperty("IsServer", BindingFlags.Instance | BindingFlags.Public).GetGetMethod());
							<znsType>5__7 = AccessTools.TypeByName("ZNetScene");
							<>4__this._getZNetSceneInstance = (Func<object>)Delegate.CreateDelegate(typeof(Func<object>), <znsType>5__7.GetProperty("instance", BindingFlags.Static | BindingFlags.Public).GetGetMethod());
							<znsInst>5__8 = <>4__this._getZNetSceneInstance();
							<destroyM>5__9 = <znsType>5__7.GetMethod("Destroy", new Type[1] { typeof(GameObject) });
							<>4__this._znetSceneDestroy = (Action<GameObject>)Delegate.CreateDelegate(typeof(Action<GameObject>), <znsInst>5__8, <destroyM>5__9);
							<>4__this._zoneReflectionDone = true;
							((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)"[VO] Reflection complete");
							return false;
						}
						catch (Exception ex)
						{
							<ex>5__10 = ex;
							((BaseUnityPlugin)<>4__this).Logger.LogWarning((object)$"[VO] Reflection error: {<ex>5__10}");
							return false;
						}
					}
					<>2__current = (object)new WaitForSeconds(0.5f);
					<>1__state = 1;
					return true;
				}
				((BaseUnityPlugin)<>4__this).Logger.LogWarning((object)"[VO] Zone reflection timed out; prefetch disabled");
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <MasterLoop>d__62 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public ValheimOptimizer <>4__this;

			private float <lastGC>5__1;

			private float <lastLOD>5__2;

			private bool <jitDone>5__3;

			private float <now>5__4;

			private float <ft>5__5;

			private int <maxBatch>5__6;

			private int <minBatch>5__7;

			private int <batch>5__8;

			private int <toSpawn>5__9;

			private object <netInst>5__10;

			private float <bias>5__11;

			private float <target>5__12;

			private string[] <>s__13;

			private int <>s__14;

			private string <sig>5__15;

			private MethodInfo <mi>5__16;

			private Queue<Vector2Int> <>s__17;

			private bool <>s__18;

			private int <i>5__19;

			private Vector2Int <cell>5__20;

			private object <plObj>5__21;

			private Vector3 <plPos>5__22;

			private int <removed>5__23;

			private int <maxKill>5__24;

			private int <perTick>5__25;

			private IEnumerator <>s__26;

			private object <chr>5__27;

			private Vector3 <cpos>5__28;

			private object <plObj>5__29;

			private Vector3 <plPos>5__30;

			private IEnumerator <>s__31;

			private object <chr>5__32;

			private Component <comp>5__33;

			private float <dist>5__34;

			private bool <show>5__35;

			private Renderer[] <>s__36;

			private int <>s__37;

			private Renderer <rend>5__38;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <MasterLoop>d__62(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<netInst>5__10 = null;
				<>s__13 = null;
				<sig>5__15 = null;
				<mi>5__16 = null;
				<>s__17 = null;
				<plObj>5__21 = null;
				<>s__26 = null;
				<chr>5__27 = null;
				<plObj>5__29 = null;
				<>s__31 = null;
				<chr>5__32 = null;
				<comp>5__33 = null;
				<>s__36 = null;
				<rend>5__38 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_047a: Unknown result type (might be due to invalid IL or missing references)
				//IL_047f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0555: Unknown result type (might be due to invalid IL or missing references)
				//IL_055a: Unknown result type (might be due to invalid IL or missing references)
				//IL_055f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0797: Unknown result type (might be due to invalid IL or missing references)
				//IL_079c: Unknown result type (might be due to invalid IL or missing references)
				//IL_07a1: Unknown result type (might be due to invalid IL or missing references)
				//IL_0667: Unknown result type (might be due to invalid IL or missing references)
				//IL_066c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0671: Unknown result type (might be due to invalid IL or missing references)
				//IL_0677: Unknown result type (might be due to invalid IL or missing references)
				//IL_067d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0857: Unknown result type (might be due to invalid IL or missing references)
				//IL_0867: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<lastGC>5__1 = Time.time;
					<lastLOD>5__2 = Time.time;
					<jitDone>5__3 = false;
					<>4__this._avgFT = Time.unscaledDeltaTime;
					goto IL_0071;
				case 1:
					<>1__state = -1;
					goto IL_0071;
				case 2:
					{
						<>1__state = -1;
						<now>5__4 = Time.time;
						if (<now>5__4 - <lastGC>5__1 >= <>4__this._cleanupInterval.Value && Time.unscaledDeltaTime < <>4__this._maxFrameTime.Value)
						{
							GC.Collect();
							Resources.UnloadUnusedAssets();
							<lastGC>5__1 = <now>5__4;
						}
						<ft>5__5 = Time.unscaledDeltaTime;
						<>4__this._avgFT = <>4__this._lodAdjustStep.Value * <ft>5__5 + (1f - <>4__this._lodAdjustStep.Value) * <>4__this._avgFT;
						if (<now>5__4 - <lastLOD>5__2 >= <>4__this._lodInterval.Value)
						{
							<bias>5__11 = QualitySettings.lodBias;
							<target>5__12 = ((<>4__this._avgFT > <>4__this._lodUpperThresh.Value) ? <>4__this._lodBiasMin.Value : ((<>4__this._avgFT < <>4__this._lodLowerThresh.Value) ? <>4__this._lodBiasMax.Value : <bias>5__11));
							QualitySettings.lodBias = Mathf.MoveTowards(<bias>5__11, <target>5__12, <>4__this._lodAdjustStep.Value * <ft>5__5);
							if (<>4__this._avgFT > <>4__this._lodUpperThresh.Value)
							{
								QualitySettings.masterTextureLimit = Math.Min(<>4__this._texLimitMax.Value, QualitySettings.masterTextureLimit + 1);
							}
							else if (<>4__this._avgFT < <>4__this._lodLowerThresh.Value)
							{
								QualitySettings.masterTextureLimit = Math.Max(<>4__this._texLimitMin.Value, QualitySettings.masterTextureLimit - 1);
							}
							<lastLOD>5__2 = <now>5__4;
						}
						if (!<jitDone>5__3)
						{
							<>s__13 = new string[4] { "BaseAI:FixedUpdate", "ZoneSystem:SpawnZone", "Projectile:OnHit", "Projectile:LateUpdate" };
							for (<>s__14 = 0; <>s__14 < <>s__13.Length; <>s__14++)
							{
								<sig>5__15 = <>s__13[<>s__14];
								<mi>5__16 = AccessTools.Method(<sig>5__15, (Type[])null, (Type[])null);
								if (<mi>5__16 != null)
								{
									RuntimeHelpers.PrepareMethod(<mi>5__16.MethodHandle);
								}
								<mi>5__16 = null;
								<sig>5__15 = null;
							}
							<>s__13 = null;
							<jitDone>5__3 = true;
						}
						<maxBatch>5__6 = <>4__this._zoneBatchSize.Value;
						<minBatch>5__7 = <>4__this._minZoneBatchSize.Value;
						<batch>5__8 = ((<>4__this._avgFT > <>4__this._lodUpperThresh.Value) ? <minBatch>5__7 : <maxBatch>5__6);
						<>s__17 = <>4__this._zoneQ;
						<>s__18 = false;
						try
						{
							Monitor.Enter(<>s__17, ref <>s__18);
							<toSpawn>5__9 = Math.Min(<>4__this._zoneQ.Count, <batch>5__8);
						}
						finally
						{
							if (<>s__18)
							{
								Monitor.Exit(<>s__17);
							}
						}
						<>s__17 = null;
						<i>5__19 = 0;
						while (<i>5__19 < <toSpawn>5__9)
						{
							if (<>4__this._spawnZoneDel != null)
							{
								<cell>5__20 = <>4__this._zoneQ.Dequeue();
								<>4__this._spawnZoneDel(((Vector2Int)(ref <cell>5__20)).x, ((Vector2Int)(ref <cell>5__20)).y);
							}
							<i>5__19++;
						}
						<netInst>5__10 = <>4__this._getZNetInstance();
						if (<netInst>5__10 != null && <>4__this._isServer(<netInst>5__10))
						{
							<plObj>5__21 = <>4__this._playerField.GetValue(null);
							if (<plObj>5__21 != null)
							{
								<plPos>5__22 = ((Transform)<>4__this._transformProp.GetValue(<plObj>5__21)).position;
								<removed>5__23 = 0;
								<maxKill>5__24 = <>4__this._mobDespawnsPerTick.Value;
								<perTick>5__25 = ((<>4__this._avgFT > <>4__this._lodUpperThresh.Value) ? 1 : <maxKill>5__24);
								<>s__26 = <>4__this._getAllChars().GetEnumerator();
								try
								{
									while (<>s__26.MoveNext())
									{
										<chr>5__27 = <>s__26.Current;
										if (<removed>5__23 >= <perTick>5__25)
										{
											break;
										}
										if (!<>4__this._isAlive(<chr>5__27) || <>4__this._isBoss(<chr>5__27) || <>4__this._isPlayer(<chr>5__27))
										{
											continue;
										}
										<cpos>5__28 = ((Transform)<>4__this._transformProp.GetValue(<chr>5__27)).position;
										if (!(Vector3.Distance(<plPos>5__22, <cpos>5__28) <= <>4__this._mobDespawnDistance.Value))
										{
											Action<GameObject> znetSceneDestroy = <>4__this._znetSceneDestroy;
											if (znetSceneDestroy != null)
											{
												object obj = <chr>5__27;
												object obj2 = ((obj is Component) ? obj : null);
												znetSceneDestroy((obj2 != null) ? ((Component)obj2).gameObject : null);
											}
											<removed>5__23++;
											<chr>5__27 = null;
										}
									}
								}
								finally
								{
									if (<>s__26 is IDisposable disposable)
									{
										disposable.Dispose();
									}
								}
								<>s__26 = null;
							}
							<plObj>5__21 = null;
						}
						if (<netInst>5__10 != null && !<>4__this._isServer(<netInst>5__10))
						{
							<plObj>5__29 = <>4__this._playerField.GetValue(null);
							if (<plObj>5__29 != null)
							{
								<plPos>5__30 = ((Transform)<>4__this._transformProp.GetValue(<plObj>5__29)).position;
								<>s__31 = <>4__this._getAllChars().GetEnumerator();
								try
								{
									while (<>s__31.MoveNext())
									{
										<chr>5__32 = <>s__31.Current;
										if (!<>4__this._isAlive(<chr>5__32) || <>4__this._isBoss(<chr>5__32) || <>4__this._isPlayer(<chr>5__32))
										{
											continue;
										}
										ref Component reference = ref <comp>5__33;
										object obj3 = <chr>5__32;
										reference = (Component)((obj3 is Component) ? obj3 : null);
										if (!((Object)(object)<comp>5__33 == (Object)null))
										{
											<dist>5__34 = Vector3.Distance(<plPos>5__30, <comp>5__33.transform.position);
											<show>5__35 = <dist>5__34 <= <>4__this._clientMobHideDistance.Value;
											<>s__36 = <comp>5__33.GetComponentsInChildren<Renderer>(true);
											for (<>s__37 = 0; <>s__37 < <>s__36.Length; <>s__37++)
											{
												<rend>5__38 = <>s__36[<>s__37];
												<rend>5__38.enabled = <show>5__35;
												<rend>5__38 = null;
											}
											<>s__36 = null;
											<comp>5__33 = null;
											<chr>5__32 = null;
										}
									}
								}
								finally
								{
									if (<>s__31 is IDisposable disposable2)
									{
										disposable2.Dispose();
									}
								}
								<>s__31 = null;
							}
							<plObj>5__29 = null;
						}
						<netInst>5__10 = null;
						break;
					}
					IL_0071:
					if (!<>4__this._zoneReflectionDone)
					{
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					break;
				}
				<>2__current = null;
				<>1__state = 2;
				return true;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <PreloadRoutine>d__65 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public ValheimOptimizer <>4__this;

			private bool <spawned>5__1;

			private string[] <>s__2;

			private int <>s__3;

			private string <name>5__4;

			private Shader <s>5__5;

			private Material <m>5__6;

			private Dictionary<string, GameObject>.Enumerator <>s__7;

			private KeyValuePair<string, GameObject> <kv>5__8;

			private Type <zsType>5__9;

			private object <inst>5__10;

			private MethodInfo <mSpawn>5__11;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <PreloadRoutine>d__65(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 2)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>s__2 = null;
				<name>5__4 = null;
				<s>5__5 = null;
				<m>5__6 = null;
				<>s__7 = default(Dictionary<string, GameObject>.Enumerator);
				<kv>5__8 = default(KeyValuePair<string, GameObject>);
				<zsType>5__9 = null;
				<inst>5__10 = null;
				<mSpawn>5__11 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b7: Expected O, but got Unknown
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>s__2 = new string[2] { "Standard", "Unlit/Texture" };
						<>s__3 = 0;
						goto IL_0183;
					case 1:
						<>1__state = -1;
						<m>5__6 = null;
						goto IL_0167;
					case 2:
						<>1__state = -3;
						<kv>5__8.Value.SetActive(false);
						<kv>5__8 = default(KeyValuePair<string, GameObject>);
						goto IL_021e;
					case 3:
						<>1__state = -1;
						goto IL_034f;
					case 4:
						{
							<>1__state = -1;
							return false;
						}
						IL_0183:
						if (<>s__3 < <>s__2.Length)
						{
							<name>5__4 = <>s__2[<>s__3];
							<s>5__5 = Shader.Find(<name>5__4);
							if (<s>5__5 != null)
							{
								<m>5__6 = new Material(<s>5__5);
								GL.PushMatrix();
								GL.LoadOrtho();
								<m>5__6.SetPass(0);
								GL.Begin(7);
								GL.Vertex3(0f, 0f, 0f);
								GL.Vertex3(1f, 0f, 0f);
								GL.Vertex3(1f, 1f, 0f);
								GL.Vertex3(0f, 1f, 0f);
								GL.End();
								GL.PopMatrix();
								Object.Destroy((Object)(object)<m>5__6);
								<>2__current = null;
								<>1__state = 1;
								return true;
							}
							goto IL_0167;
						}
						<>s__2 = null;
						<>s__7 = <>4__this._prefabPool.GetEnumerator();
						<>1__state = -3;
						goto IL_021e;
						IL_021e:
						if (<>s__7.MoveNext())
						{
							<kv>5__8 = <>s__7.Current;
							<kv>5__8.Value.SetActive(true);
							<>2__current = null;
							<>1__state = 2;
							return true;
						}
						<>m__Finally1();
						<>s__7 = default(Dictionary<string, GameObject>.Enumerator);
						<spawned>5__1 = false;
						try
						{
							<zsType>5__9 = AccessTools.TypeByName("ZoneSystem");
							<inst>5__10 = <zsType>5__9?.GetField("instance", BindingFlags.Static | BindingFlags.Public)?.GetValue(null);
							<mSpawn>5__11 = <zsType>5__9?.GetMethod("SpawnZone", new Type[2]
							{
								typeof(int),
								typeof(int)
							});
							if (<inst>5__10 != null && <mSpawn>5__11 != null)
							{
								<mSpawn>5__11.Invoke(<inst>5__10, new object[2] { 0, 0 });
								<spawned>5__1 = true;
							}
							<zsType>5__9 = null;
							<inst>5__10 = null;
							<mSpawn>5__11 = null;
						}
						catch
						{
						}
						if (<spawned>5__1)
						{
							<>2__current = null;
							<>1__state = 3;
							return true;
						}
						goto IL_034f;
						IL_034f:
						GC.Collect();
						<>2__current = Resources.UnloadUnusedAssets();
						<>1__state = 4;
						return true;
						IL_0167:
						<s>5__5 = null;
						<name>5__4 = null;
						<>s__3++;
						goto IL_0183;
					}
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				((IDisposable)<>s__7).Dispose();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private ConfigEntry<float> _cleanupInterval;

		private ConfigEntry<float> _maxFrameTime;

		private ConfigEntry<float> _lodBiasMin;

		private ConfigEntry<float> _lodBiasMax;

		private ConfigEntry<float> _lodAdjustStep;

		private ConfigEntry<float> _lodUpperThresh;

		private ConfigEntry<float> _lodLowerThresh;

		private ConfigEntry<float> _lodInterval;

		private ConfigEntry<int> _lodSamples;

		private ConfigEntry<int> _texLimitMin;

		private ConfigEntry<int> _texLimitMax;

		private ConfigEntry<int> _texAdjustStep;

		private ConfigEntry<float> _texInterval;

		private ConfigEntry<float> _prefetchInterval;

		private ConfigEntry<float> _prefetchSpeed;

		private ConfigEntry<float> _prefetchDistance;

		private ConfigEntry<int> _zoneBatchSize;

		private ConfigEntry<int> _minZoneBatchSize;

		private ConfigEntry<bool> _enableVSync;

		private ConfigEntry<int> _targetFrameRate;

		private ConfigEntry<float> _mobDespawnDistance;

		private ConfigEntry<int> _mobDespawnsPerTick;

		private ConfigEntry<float> _clientMobHideDistance;

		private FileSystemWatcher _configWatcher;

		private DateTime _lastReloadTime;

		private const long RELOAD_DELAY = 10000000L;

		private const string CONFIG_NAME = "com.yourname.valheimoptimizer.cfg";

		private static readonly string[] HeavyPrefabs = new string[5] { "vfx_fireplace", "npc_troll", "piece_workbench", "Arrow_explosive", "Arrow_explosion" };

		private readonly Dictionary<string, GameObject> _prefabPool = new Dictionary<string, GameObject>();

		private Action<int, int> _spawnZoneDel;

		private float _zoneCellSize;

		private FieldInfo _playerField;

		private PropertyInfo _transformProp;

		private FieldInfo _characterField;

		private FieldInfo _velocityField;

		private bool _zoneReflectionDone;

		private Func<IEnumerable> _getAllChars;

		private Func<object, bool> _isAlive;

		private Func<object, bool> _isBoss;

		private Func<object, bool> _isPlayer;

		private Func<object> _getZNetInstance;

		private Func<object, bool> _isServer;

		private Func<object> _getZNetSceneInstance;

		private Action<GameObject> _znetSceneDestroy;

		private Vector3 _latestPos;

		private Vector3 _latestVel;

		private readonly object _movLock = new object();

		private readonly Queue<Vector2Int> _zoneQ = new Queue<Vector2Int>();

		private Thread _zoneThread;

		private bool _zoneThreadRunning;

		private Harmony _harmony;

		private float _avgFT;

		private WaitForSeconds _wsMaster;

		public static ValheimOptimizer Instance { get; private set; }

		private void Awake()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			//IL_03b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bf: Expected O, but got Unknown
			Instance = this;
			_harmony = new Harmony("com.yourname.valheimoptimizer");
			((BaseUnityPlugin)this).Config.SaveOnConfigSet = false;
			_cleanupInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Performance", "MemoryCleanupInterval", 60f, "Secs between GC sweeps");
			_maxFrameTime = ((BaseUnityPlugin)this).Config.Bind<float>("Performance", "MaxFrameTime", 0.033f, "Skip GC if frame > this");
			_enableVSync = ((BaseUnityPlugin)this).Config.Bind<bool>("Performance", "EnableVSync", true, "Enable V‑Sync");
			_targetFrameRate = ((BaseUnityPlugin)this).Config.Bind<int>("Performance", "TargetFrameRate", 60, "Hard FPS cap (0 = uncapped)");
			_mobDespawnDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Performance", "MobDespawnDistance", 100f, "Distance to drip‑despawn mobs");
			_mobDespawnsPerTick = ((BaseUnityPlugin)this).Config.Bind<int>("Performance", "MobDespawnsPerTick", 2, "Max mobs removed per tick");
			_clientMobHideDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Performance", "ClientMobHideDistance", 150f, "Hide mobs beyond this distance on clients");
			_lodBiasMin = ((BaseUnityPlugin)this).Config.Bind<float>("Graphics", "LODBiasMin", 0.5f, "Min LOD bias");
			_lodBiasMax = ((BaseUnityPlugin)this).Config.Bind<float>("Graphics", "LODBiasMax", 2f, "Max LOD bias");
			_lodAdjustStep = ((BaseUnityPlugin)this).Config.Bind<float>("Graphics", "LODBiasStep", 0.1f, "Adjust/sec");
			_lodUpperThresh = ((BaseUnityPlugin)this).Config.Bind<float>("Graphics", "LODUpperFrameThreshold", 0.04f, "Above → drop");
			_lodLowerThresh = ((BaseUnityPlugin)this).Config.Bind<float>("Graphics", "LODLowerFrameThreshold", 0.03f, "Below → raise");
			_lodSamples = ((BaseUnityPlugin)this).Config.Bind<int>("Graphics", "LODNumSamples", 10, "Frames/window");
			_lodInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Graphics", "LODUpdateInterval", 1f, "Secs between adj");
			_texLimitMin = ((BaseUnityPlugin)this).Config.Bind<int>("Graphics", "TextureLimitMin", 0, "Best (0=full)");
			_texLimitMax = ((BaseUnityPlugin)this).Config.Bind<int>("Graphics", "TextureLimitMax", 2, "Worst (2=¼)");
			_texAdjustStep = ((BaseUnityPlugin)this).Config.Bind<int>("Graphics", "TextureLimitStep", 1, "Step size");
			_texInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Graphics", "TextureChangeInterval", 30f, "Secs between changes");
			_prefetchInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Travel", "ZonePrefetchInterval", 0.1f, "Secs per check");
			_prefetchSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Travel", "ZonePrefetchSpeed", 10f, "Speed to prefetch");
			_prefetchDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Travel", "ZonePrefetchDistance", 50f, "Meters ahead");
			_zoneBatchSize = ((BaseUnityPlugin)this).Config.Bind<int>("Travel", "ZoneBatchSize", 8, "Zones/tick (max)");
			_minZoneBatchSize = ((BaseUnityPlugin)this).Config.Bind<int>("Travel", "MinZoneBatchSize", 1, "Zones/tick under load");
			((BaseUnityPlugin)this).Config.Save();
			((BaseUnityPlugin)this).Config.SaveOnConfigSet = true;
			SetupWatcher();
			QualitySettings.vSyncCount = (_enableVSync.Value ? 1 : 0);
			Application.targetFrameRate = ((_targetFrameRate.Value > 0) ? _targetFrameRate.Value : (-1));
			_wsMaster = new WaitForSeconds(0.2f);
			CachePrefabPool();
			((MonoBehaviour)this).StartCoroutine(DelayedZoneReflection());
			_zoneThreadRunning = true;
			_zoneThread = new Thread(ZonePrefetchLoop)
			{
				IsBackground = true
			};
			_zoneThread.Start();
			((MonoBehaviour)this).StartCoroutine(PreloadRoutine());
			((MonoBehaviour)this).StartCoroutine(MasterLoop());
			_harmony.PatchAll();
		}

		private void OnDestroy()
		{
			_configWatcher?.Dispose();
			_zoneThreadRunning = false;
			_zoneThread?.Join(500);
			((BaseUnityPlugin)this).Config.Save();
		}

		private void SetupWatcher()
		{
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, "com.yourname.valheimoptimizer.cfg")
			{
				NotifyFilter = (NotifyFilters.LastWrite | NotifyFilters.CreationTime)
			};
			fileSystemWatcher.Changed += OnConfigChanged;
			fileSystemWatcher.Created += OnConfigChanged;
			fileSystemWatcher.EnableRaisingEvents = true;
			_configWatcher = fileSystemWatcher;
		}

		private void OnConfigChanged(object s, FileSystemEventArgs e)
		{
			if (DateTime.Now.Ticks - _lastReloadTime.Ticks >= 10000000)
			{
				try
				{
					((BaseUnityPlugin)this).Logger.LogDebug((object)"[VO] Reloading config");
					((BaseUnityPlugin)this).Config.Reload();
				}
				catch (Exception arg)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)$"[VO] Config reload failed: {arg}");
				}
				_lastReloadTime = DateTime.Now;
			}
		}

		private void Update()
		{
			//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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			if (_zoneReflectionDone)
			{
				object obj = _playerField?.GetValue(null);
				if (obj != null)
				{
					object value = _characterField.GetValue(obj);
					_latestVel = (Vector3)_velocityField.GetValue(value);
					_latestPos = ((Transform)_transformProp.GetValue(obj)).position;
				}
			}
		}

		[IteratorStateMachine(typeof(<MasterLoop>d__62))]
		private IEnumerator MasterLoop()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <MasterLoop>d__62(0)
			{
				<>4__this = this
			};
		}

		[IteratorStateMachine(typeof(<DelayedZoneReflection>d__63))]
		private IEnumerator DelayedZoneReflection()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DelayedZoneReflection>d__63(0)
			{
				<>4__this = this
			};
		}

		private void ZonePrefetchLoop()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				while (_zoneThreadRunning)
				{
					Vector3 latestPos;
					Vector3 latestVel;
					lock (_movLock)
					{
						latestPos = _latestPos;
						latestVel = _latestVel;
					}
					if (((Vector3)(ref latestVel)).magnitude >= _prefetchSpeed.Value)
					{
						Vector3 val = latestPos + ((Vector3)(ref latestVel)).normalized * _prefetchDistance.Value;
						int num = Mathf.FloorToInt(val.x / _zoneCellSize);
						int num2 = Mathf.FloorToInt(val.z / _zoneCellSize);
						lock (_zoneQ)
						{
							for (int i = -1; i <= 1; i++)
							{
								for (int j = -1; j <= 1; j++)
								{
									_zoneQ.Enqueue(new Vector2Int(num + i, num2 + j));
								}
							}
						}
					}
					Thread.Sleep((int)(_prefetchInterval.Value * 1000f));
				}
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)$"[VO] Zone thread error: {arg}");
			}
		}

		[IteratorStateMachine(typeof(<PreloadRoutine>d__65))]
		private IEnumerator PreloadRoutine()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <PreloadRoutine>d__65(0)
			{
				<>4__this = this
			};
		}

		private void CachePrefabPool()
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			string[] heavyPrefabs = HeavyPrefabs;
			foreach (string text in heavyPrefabs)
			{
				GameObject prefab = PrefabManager.Instance.GetPrefab(text);
				if (!((Object)(object)prefab == (Object)null))
				{
					GameObject val = Object.Instantiate<GameObject>(prefab);
					((Object)val).name = "Pool_" + text;
					val.SetActive(false);
					Object.DontDestroyOnLoad((Object)(object)val);
					_prefabPool[text] = val;
					Renderer[] componentsInChildren = val.GetComponentsInChildren<Renderer>(true);
					LODGroup val2 = val.AddComponent<LODGroup>();
					val2.SetLODs((LOD[])(object)new LOD[2]
					{
						new LOD(0.5f, componentsInChildren),
						new LOD(0f, (Renderer[])(object)new Renderer[0])
					});
					val2.RecalculateBounds();
				}
			}
		}
	}
}
namespace ValheimOptimizer.Patches
{
	public static class ArrowReflectionPatches
	{
		[HarmonyPrefix]
		[HarmonyPatch("Projectile:LateUpdate")]
		public static void LateUpdatePrefix(object __instance)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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_0078: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			Component val = (Component)((__instance is Component) ? __instance : null);
			if (!((Object)(object)val == (Object)null) && ((Object)val.gameObject).name.Contains("Arrow"))
			{
				Type type = __instance.GetType();
				FieldInfo field = type.GetField("m_velocity", BindingFlags.Instance | BindingFlags.NonPublic);
				Vector3 val2 = (Vector3)field.GetValue(__instance);
				Vector3 position = val.transform.position;
				Vector3 val3 = position - val2 * Time.deltaTime;
				Vector3 val4 = position - val3;
				RaycastHit val5 = default(RaycastHit);
				if (!(((Vector3)(ref val4)).sqrMagnitude < 1E-06f) && Physics.Raycast(val3, val4, ref val5, ((Vector3)(ref val4)).magnitude, LayerMask.GetMask(new string[2] { "Default", "character" })))
				{
					MethodInfo method = type.GetMethod("OnHit", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					method.Invoke(__instance, new object[3]
					{
						((RaycastHit)(ref val5)).point,
						((RaycastHit)(ref val5)).normal,
						((RaycastHit)(ref val5)).collider
					});
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("Projectile:Awake")]
		public static void AwakePostfix(object __instance)
		{
			Component val = (Component)((__instance is Component) ? __instance : null);
			CapsuleCollider val2 = default(CapsuleCollider);
			if (!((Object)(object)val == (Object)null) && ((Object)val.gameObject).name.Contains("Arrow") && val.TryGetComponent<CapsuleCollider>(ref val2))
			{
				CapsuleCollider obj = val2;
				obj.radius *= 1.2f;
				CapsuleCollider obj2 = val2;
				obj2.height *= 1.1f;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("Projectile:OnHit")]
		public static void OnHitPostfix(object __instance, object character, object hitData)
		{
			Type type = __instance.GetType();
			FieldInfo field = type.GetField("m_nview", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			object value = field.GetValue(__instance);
			MethodInfo method = value.GetType().GetMethod("InvokeRPC", new Type[2]
			{
				typeof(string),
				typeof(object[])
			});
			method.Invoke(value, new object[5]
			{
				"Hit",
				character.GetType().GetMethod("GetZDOID").Invoke(character, null),
				hitData.GetType().GetField("m_damage", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(hitData),
				hitData.GetType().GetField("m_point", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(hitData),
				hitData.GetType().GetField("m_dir", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(hitData)
			});
			(AccessTools.TypeByName("EpicLoot.Magic.ExplosionHandler")?.GetMethod("TryExplode", BindingFlags.Static | BindingFlags.Public))?.Invoke(null, new object[3] { __instance, character, hitData });
		}
	}
}