Decompiled source of ValheimFPSOptimizer v1.5.0

BepInEx/plugins/ValheimFPSOptimizer2.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
using UnityEngine;
using ValheimFPSOptimizer.CPU;
using ValheimFPSOptimizer.GPU;
using ValheimFPSOptimizer.Monitoring;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ValheimFPSOptimizer")]
[assembly: AssemblyDescription("Adaptive FPS & Frametime Optimizer for Valheim")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ValheimFPSOptimizer")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("BE52F8E6-343B-4FAF-85C3-7047DE1AB2E4")]
[assembly: AssemblyFileVersion("3.2.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("3.2.0.0")]
namespace ValheimFPSOptimizer.Monitoring
{
	public class FrametimeMonitor
	{
		private readonly Queue<float> samples = new Queue<float>();

		private const int MaxSamples = 120;

		public float AvgMs { get; private set; }

		public float OnePercentLowMs { get; private set; }

		public void Update()
		{
			float item = Time.unscaledDeltaTime * 1000f;
			samples.Enqueue(item);
			if (samples.Count > 120)
			{
				samples.Dequeue();
			}
			if (samples.Count >= 30)
			{
				float[] array = samples.ToArray();
				AvgMs = array.Average();
				Array.Sort(array);
				int value = Mathf.Max(1, array.Length / 100);
				OnePercentLowMs = array[^value];
			}
		}
	}
}
namespace ValheimFPSOptimizer.Harmony
{
	[HarmonyPatch(typeof(Character), "CustomFixedUpdate")]
	public static class Character_CustomFixedUpdate_Patch
	{
		private static bool Prefix(Character __instance)
		{
			if (__instance.IsPlayer())
			{
				return true;
			}
			return (Time.frameCount & 1) == 0;
		}
	}
}
namespace ValheimFPSOptimizer.GPU
{
	public class GpuEfficiencyController
	{
		private int lastQueue = -1;

		public void Apply(FrametimeMonitor ft)
		{
			int num = ((!(ft.OnePercentLowMs > ft.AvgMs * 1.4f)) ? 3 : 2);
			if (num != lastQueue)
			{
				QualitySettings.maxQueuedFrames = num;
				lastQueue = num;
			}
			QualitySettings.asyncUploadTimeSlice = 2;
			QualitySettings.asyncUploadBufferSize = 64;
		}
	}
}
namespace ValheimFPSOptimizer.CPU
{
	public class AdaptiveRendererOptimizer
	{
		private readonly List<Renderer> renderers = new List<Renderer>();

		private int index;

		private float nextTick;

		private Vector3 lastCamPos;

		private Quaternion lastCamRot;

		private const int batchSize = 40;

		public void Init()
		{
			renderers.AddRange(Object.FindObjectsByType<Renderer>((FindObjectsSortMode)0));
		}

		public void Tick(Camera cam, float interval)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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)
			if ((Object)(object)cam == (Object)null || Time.unscaledTime < nextTick || (Vector3.Distance(((Component)cam).transform.position, lastCamPos) < 0.3f && Quaternion.Angle(((Component)cam).transform.rotation, lastCamRot) < 2f))
			{
				return;
			}
			lastCamPos = ((Component)cam).transform.position;
			lastCamRot = ((Component)cam).transform.rotation;
			nextTick = Time.unscaledTime + interval;
			Plane[] array = GeometryUtility.CalculateFrustumPlanes(cam);
			int num = 0;
			while (num < 40 && index < renderers.Count)
			{
				Renderer val = renderers[index];
				if (Object.op_Implicit((Object)(object)val))
				{
					bool flag = GeometryUtility.TestPlanesAABB(array, val.bounds);
					if (val.enabled != flag)
					{
						val.enabled = flag;
					}
				}
				num++;
				index++;
			}
			if (index >= renderers.Count)
			{
				index = 0;
			}
		}
	}
	public class FrameBudgetGuard
	{
		private float lastTarget = -1f;

		public void Apply(FrametimeMonitor ft)
		{
			float num = ((ft.OnePercentLowMs > 28f) ? 0.045f : ((!(ft.OnePercentLowMs > 22f)) ? 0.07f : 0.055f));
			if (!Mathf.Approximately(lastTarget, num))
			{
				Time.maximumDeltaTime = num;
				lastTarget = num;
			}
		}
	}
}
namespace ValheimFPSOptimizer.Core
{
	public static class HardwareDetector
	{
		public static HardwareClass Detect()
		{
			int processorCount = SystemInfo.processorCount;
			int graphicsMemorySize = SystemInfo.graphicsMemorySize;
			if (processorCount >= 8 && graphicsMemorySize >= 6000)
			{
				return HardwareClass.Strong;
			}
			if (processorCount >= 4 && graphicsMemorySize >= 3000)
			{
				return HardwareClass.Medium;
			}
			return HardwareClass.Weak;
		}
	}
	[BepInPlugin("dev.fpsoptimizer.valheim", "Valheim FPS Optimizer", "3.2.1")]
	public class PerformanceOptimizer : BaseUnityPlugin
	{
		private FrametimeMonitor frametime;

		private FrameBudgetGuard budget;

		private AdaptiveRendererOptimizer rendererOpt;

		private GpuEfficiencyController gpuOpt;

		private Camera cam;

		private HardwareClass hw;

		private void Awake()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			hw = HardwareDetector.Detect();
			cam = Camera.main;
			frametime = new FrametimeMonitor();
			budget = new FrameBudgetGuard();
			rendererOpt = new AdaptiveRendererOptimizer();
			gpuOpt = new GpuEfficiencyController();
			rendererOpt.Init();
			new Harmony("dev.fpsoptimizer.valheim").PatchAll();
			Physics.autoSyncTransforms = false;
			Application.targetFrameRate = 60;
			QualitySettings.vSyncCount = 0;
		}

		private void Update()
		{
			frametime.Update();
			float interval = ((hw == HardwareClass.Strong) ? 0.35f : ((hw == HardwareClass.Medium) ? 0.3f : 0.25f));
			rendererOpt.Tick(cam, interval);
			budget.Apply(frametime);
			gpuOpt.Apply(frametime);
		}
	}
	public enum HardwareClass
	{
		Weak,
		Medium,
		Strong
	}
}