Decompiled source of ClearDistance v1.0.1

BepInEx/plugins/ClearDistance/ClearDistance.dll

Decompiled a month ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("ClearDistance")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ClearDistance")]
[assembly: AssemblyTitle("ClearDistance")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ClearDistance
{
	[BepInPlugin("com.cleardistance.valheim", "Clear Distance", "1.0.1")]
	public sealed class Plugin : BaseUnityPlugin
	{
		private static Plugin? _instance;

		private static FieldInfo? _clutterDistance;

		private static MethodInfo? _clearClutter;

		private static FieldInfo? _clutterInstance;

		private Harmony? _harmony;

		private ConfigEntry<float> _grassDistance;

		private ConfigEntry<float> _lodBias;

		private ConfigEntry<int> _streamingBudget;

		private void Awake()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Expected O, but got Unknown
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Expected O, but got Unknown
			_instance = this;
			_grassDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Visuals", "Grass distance", 65f, new ConfigDescription("Grass and small vegetation visibility in metres. Larger values cost more CPU and GPU time.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(45f, 120f), Array.Empty<object>()));
			_lodBias = ((BaseUnityPlugin)this).Config.Bind<float>("Visuals", "Minimum object LOD bias", 5f, new ConfigDescription("Keeps detailed object meshes farther away. Valheim's highest preset is usually 5.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>()));
			_streamingBudget = ((BaseUnityPlugin)this).Config.Bind<int>("Visuals", "Minimum texture streaming budget MB", 768, new ConfigDescription("Reduces low resolution texture swaps when Unity's texture streaming is active. Set to 0 to leave the game budget alone.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 2048), Array.Empty<object>()));
			_grassDistance.SettingChanged += delegate
			{
				ApplyClutter();
			};
			_lodBias.SettingChanged += delegate
			{
				ApplyQuality();
			};
			_streamingBudget.SettingChanged += delegate
			{
				ApplyQuality();
			};
			Type type = AccessTools.TypeByName("ClutterSystem");
			if (type != null)
			{
				_clutterDistance = AccessTools.Field(type, "m_distance");
				_clearClutter = AccessTools.Method(type, "ClearAll", (Type[])null, (Type[])null);
				_clutterInstance = AccessTools.Field(type, "instance");
			}
			_harmony = new Harmony("com.cleardistance.valheim");
			Patch(type, "Awake", "ClutterAwake");
			Patch(AccessTools.TypeByName("GraphicsSettingsManager"), "ApplyQualitySettings", "QualityApplied");
			ApplyQuality();
		}

		private void Patch(Type? type, string method, string postfix)
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Expected O, but got Unknown
			MethodInfo methodInfo = ((type == null) ? null : AccessTools.Method(type, method, (Type[])null, (Type[])null));
			if (methodInfo == null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not find " + (type?.Name ?? "game type") + "." + method + "; its setting will be applied only at startup."));
			}
			else
			{
				_harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), postfix, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
		}

		private static void ClutterAwake(object __instance)
		{
			_instance?.SetClutter(__instance);
		}

		private static void QualityApplied()
		{
			_instance?.ApplyQuality();
		}

		private void ApplyClutter()
		{
			object obj = _clutterInstance?.GetValue(null);
			if (obj != null)
			{
				SetClutter(obj);
			}
		}

		private void SetClutter(object instance)
		{
			if (!(_clutterDistance == null))
			{
				float value = _grassDistance.Value;
				if (!(Math.Abs(Convert.ToSingle(_clutterDistance.GetValue(instance)) - value) < 0.1f))
				{
					_clutterDistance.SetValue(instance, value);
					_clearClutter?.Invoke(instance, null);
				}
			}
		}

		private void ApplyQuality()
		{
			if (QualitySettings.lodBias < _lodBias.Value)
			{
				QualitySettings.lodBias = _lodBias.Value;
			}
			int value = _streamingBudget.Value;
			if (value > 0 && QualitySettings.streamingMipmapsMemoryBudget < (float)value)
			{
				QualitySettings.streamingMipmapsMemoryBudget = value;
			}
		}

		private void OnDestroy()
		{
			Harmony? harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			_instance = null;
		}
	}
}