Decompiled source of HowToFish Comprehensive Optimization v1.5.4

BepInEx\plugins\HowToFish.ComprehensivePerformanceOptimization.dll

Decompiled 2 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
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(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("HowToFish.ComprehensivePerformanceOptimization")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("HowToFish.ComprehensivePerformanceOptimization")]
[assembly: AssemblyTitle("HowToFish.ComprehensivePerformanceOptimization")]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Optimize
{
	[BepInPlugin("HowToFish.ComprehensivePerformanceOptimization", "HowToFish Comprehensive Performance Optimization", "1.5.4")]
	[BepInProcess("How to Fish.exe")]
	public class OptimizePlugin : BaseUnityPlugin
	{
		private ConfigEntry<bool> _logTrim;

		private ConfigEntry<bool> _gentleGc;

		private ConfigEntry<float> _gcInterval;

		private ConfigEntry<bool> _jitWarmup;

		private ConfigEntry<bool> _earlyRange;

		private ConfigEntry<float> _rangeMul;

		internal static float IslandRangeMultiplier = 1f;

		internal int BatchPerFrame = 256;

		internal bool WarmStarted;

		internal bool WarmDone;

		internal IEnumerator WarmCoroutine;

		private float _gcTimer;

		private static readonly BindingFlags[] Groups = new BindingFlags[4]
		{
			BindingFlags.Static | BindingFlags.Public,
			BindingFlags.Static | BindingFlags.NonPublic,
			BindingFlags.Instance | BindingFlags.Public,
			BindingFlags.Instance | BindingFlags.NonPublic
		};

		private void Awake()
		{
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Expected O, but got Unknown
			_logTrim = ((BaseUnityPlugin)this).Config.Bind<bool>("Logging", "ReduceLogSpam", true, "削减每帧日志栈生成,降低GC与CPU占用");
			_gentleGc = ((BaseUnityPlugin)this).Config.Bind<bool>("GC", "IdleCollect", true, "低负载时定期清理垃圾,平滑GC停顿");
			_gcInterval = ((BaseUnityPlugin)this).Config.Bind<float>("GC", "CollectIntervalSeconds", 20f, "垃圾清理间隔(秒)");
			_jitWarmup = ((BaseUnityPlugin)this).Config.Bind<bool>("Warmup", "EnableJitWarmup", true, "启动时预编译模组方法,消除首次使用卡顿");
			_earlyRange = ((BaseUnityPlugin)this).Config.Bind<bool>("IslandEarlyLoad", "EnableEarlyLoadRange", true, "加大岛屿预加载触发距离,降低跨岛卡顿");
			_rangeMul = ((BaseUnityPlugin)this).Config.Bind<float>("IslandEarlyLoad", "RangeMultiplier", 2f, "触发距离放大倍数");
			if (_logTrim.Value)
			{
				try
				{
					Application.SetStackTraceLogType((LogType)3, (StackTraceLogType)0);
					Application.SetStackTraceLogType((LogType)2, (StackTraceLogType)0);
					Application.SetStackTraceLogType((LogType)0, (StackTraceLogType)0);
					Log("log trim enabled");
				}
				catch
				{
				}
			}
			if (_jitWarmup.Value)
			{
				WarmupHost warmupHost = new GameObject("HowToFishOptimize.Warmup").AddComponent<WarmupHost>();
				Object.DontDestroyOnLoad((Object)(object)((Component)warmupHost).gameObject);
				warmupHost.Init(this);
			}
			if (_earlyRange.Value)
			{
				float num = (IslandRangeMultiplier = Mathf.Max(1f, _rangeMul.Value));
				try
				{
					MethodInfo methodInfo = AccessTools.Method("IslandManager:get_NearPlayerRange", (Type[])null, (Type[])null);
					if (methodInfo == null)
					{
						LogWarn("IslandManager.get_NearPlayerRange missing");
					}
					else
					{
						new Harmony("HowToFish.ComprehensivePerformanceOptimization.island").Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(IslandRangePatches), "NearRangePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						Log("early-load range x" + num);
					}
				}
				catch (Exception ex)
				{
					LogWarn("island patch: " + ex.Message);
				}
			}
			Log("loaded");
		}

		private void Update()
		{
			if (!_gentleGc.Value)
			{
				return;
			}
			_gcTimer += Time.unscaledDeltaTime;
			if (!(_gcTimer >= _gcInterval.Value))
			{
				return;
			}
			_gcTimer = 0f;
			try
			{
				GC.Collect(GC.MaxGeneration, GCCollectionMode.Optimized, blocking: false);
			}
			catch
			{
			}
		}

		internal IEnumerator WarmAll()
		{
			string pluginPath = Paths.PluginPath;
			List<MethodBase> targets = new List<MethodBase>();
			HashSet<string> hashSet = new HashSet<string>();
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				if (!assembly.IsDynamic)
				{
					string location;
					try
					{
						location = assembly.Location;
					}
					catch
					{
						continue;
					}
					if (!string.IsNullOrEmpty(location) && location.StartsWith(pluginPath, StringComparison.OrdinalIgnoreCase))
					{
						hashSet.Add(Path.GetFileName(location));
						Collect(assembly, targets);
					}
				}
			}
			Log("warming " + targets.Count + " across " + hashSet.Count);
			int prepared = 0;
			int skipped = 0;
			int idx = 0;
			while (idx < targets.Count)
			{
				for (int j = 0; j < BatchPerFrame; j++)
				{
					if (idx >= targets.Count)
					{
						break;
					}
					if (TryPrepare(targets[idx++]))
					{
						prepared++;
					}
					else
					{
						skipped++;
					}
				}
				yield return null;
			}
			WarmDone = true;
			Log("warmup prepared=" + prepared + " skipped=" + skipped);
		}

		private static void Collect(Assembly asm, List<MethodBase> outList)
		{
			Type[] array;
			try
			{
				array = asm.GetTypes();
			}
			catch (ReflectionTypeLoadException ex)
			{
				IEnumerable<Type> types = ex.Types;
				array = (types ?? Enumerable.Empty<Type>()).Where((Type t) => t != null).ToArray();
			}
			catch
			{
				return;
			}
			Type[] array2 = array;
			foreach (Type type in array2)
			{
				if (type == null)
				{
					continue;
				}
				BindingFlags[] groups = Groups;
				foreach (BindingFlags bindingAttr in groups)
				{
					MethodInfo[] methods;
					try
					{
						methods = type.GetMethods(bindingAttr);
					}
					catch
					{
						continue;
					}
					MethodInfo[] array3 = methods;
					foreach (MethodInfo methodInfo in array3)
					{
						if (!(methodInfo.DeclaringType != type) && !methodInfo.IsGenericMethodDefinition && !methodInfo.ContainsGenericParameters && !methodInfo.IsAbstract && methodInfo.GetMethodBody() != null && !(methodInfo.DeclaringType?.FullName == "<Module>"))
						{
							outList.Add(methodInfo);
						}
					}
				}
			}
		}

		private static bool TryPrepare(MethodBase m)
		{
			try
			{
				RuntimeHelpers.PrepareMethod(m.MethodHandle);
				return true;
			}
			catch
			{
				return false;
			}
		}

		internal void Log(string s)
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Optimize: " + s));
		}

		internal void LogWarn(string s)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("Optimize: " + s));
		}
	}
	internal static class IslandRangePatches
	{
		public static void NearRangePostfix(ref float __result)
		{
			float islandRangeMultiplier = OptimizePlugin.IslandRangeMultiplier;
			if (islandRangeMultiplier > 1f)
			{
				__result *= islandRangeMultiplier;
			}
		}
	}
	internal class WarmupHost : MonoBehaviour
	{
		private OptimizePlugin _owner;

		private int _frames;

		public void Init(OptimizePlugin owner)
		{
			_owner = owner;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
		}

		private void Update()
		{
			if (_owner.WarmDone)
			{
				return;
			}
			if (!_owner.WarmStarted)
			{
				if (_frames++ >= 30)
				{
					_owner.WarmStarted = true;
					_owner.WarmCoroutine = _owner.WarmAll();
				}
			}
			else if (_owner.WarmCoroutine != null && !_owner.WarmCoroutine.MoveNext())
			{
				_owner.WarmDone = true;
			}
		}
	}
}