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 ValheimOptimizer v2.1.0
plugins/ValheimOptimizer.dll
Decompiled 10 months agousing 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 }); } } }