Decompiled source of AzuAutoStorePerformance v1.0.8

BepInEx/plugins/AzuAutoStorePerformance/AzuAutoStorePerformance.dll

Decompiled 20 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using BepInEx;
using BepInEx.Bootstrap;
using HarmonyLib;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("AzuAutoStore Performance")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[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 AzuAutoStorePerformance
{
	[BepInPlugin("com.l4zershark.azuautostoreperformance", "AzuAutoStore Performance", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string Id = "com.l4zershark.azuautostoreperformance";

		private static readonly Harmony Patches = new Harmony("com.l4zershark.azuautostoreperformance");

		private static MethodInfo target;

		private static MethodInfo getItems;

		private static bool active;

		private void Awake()
		{
			try
			{
				Assembly assembly = ((object)Chainloader.PluginInfos["Azumatt.AzuAutoStore"].Instance).GetType().Assembly;
				string text;
				using (SHA256 sHA = SHA256.Create())
				{
					text = BitConverter.ToString(sHA.ComputeHash(File.ReadAllBytes(assembly.Location))).Replace("-", "");
				}
				if (text != "0FB9116FF316D47575E1DE809AE4B1A41A3D6DE12B7165A5E71B10B64AA126DF" && text != "106876C65EEF3C9B50CA2F9123EE166BE3D64E5E6798DCA1592A4FFC60378021")
				{
					throw new NotSupportedException("Unrecognized AzuAutoStore DLL. Supported builds: official 3.1.4 and 3.1.6.");
				}
				target = AccessTools.Method(assembly.GetType("AzuAutoStore.Util.Boxes", throwOnError: true), "CanItemBeStored", new Type[2]
				{
					typeof(string),
					typeof(string)
				}, (Type[])null);
				getItems = AccessTools.Method(assembly.GetType("AzuAutoStore.Util.GroupUtils", throwOnError: true), "GetItemsInGroup", new Type[1] { typeof(string) }, (Type[])null);
				FieldInfo fieldInfo = AccessTools.Field(assembly.GetType("AzuAutoStore.AzuAutoStorePlugin", throwOnError: true), "groups");
				if (target == null || getItems == null || fieldInfo == null || !fieldInfo.IsStatic || fieldInfo.FieldType != typeof(Dictionary<string, HashSet<string>>))
				{
					throw new InvalidOperationException("AzuAutoStore group lookup contract changed.");
				}
				DynamicMethod dynamicMethod = new DynamicMethod("ReadAutoStoreGroups", fieldInfo.FieldType, Type.EmptyTypes, typeof(Plugin), skipVisibility: true);
				dynamicMethod.GetILGenerator().Emit(OpCodes.Ldsfld, fieldInfo);
				dynamicMethod.GetILGenerator().Emit(OpCodes.Ret);
				GroupLookup.ReadGroups = (Func<Dictionary<string, HashSet<string>>>)dynamicMethod.CreateDelegate(typeof(Func<Dictionary<string, HashSet<string>>>));
				SetOptimizationEnabled(enabled: true);
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Optimized group membership checks for AzuAutoStore " + assembly.GetName().Version?.ToString() + ". Storage rules and transfer handling are unchanged."));
			}
			catch (Exception ex)
			{
				if (target != null)
				{
					Patches.Unpatch((MethodBase)target, (HarmonyPatchType)3, "com.l4zershark.azuautostoreperformance");
				}
				active = false;
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Performance addon inactive; original AzuAutoStore remains in control. " + ex.Message));
			}
		}

		internal static void SetOptimizationEnabled(bool enabled)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			if (active != enabled)
			{
				if (target == null)
				{
					throw new InvalidOperationException("Addon did not initialize.");
				}
				if (enabled)
				{
					Patches.Patch((MethodBase)target, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "Transpiler", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
				}
				else
				{
					Patches.Unpatch((MethodBase)target, (HarmonyPatchType)3, "com.l4zershark.azuautostoreperformance");
				}
				active = enabled;
			}
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> input)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(input);
			MethodInfo methodInfo = AccessTools.Method(typeof(List<string>), "Contains", new Type[1] { typeof(string) }, (Type[])null);
			int num = -1;
			for (int i = 0; i + 2 < list.Count; i++)
			{
				if (CodeInstructionExtensions.Calls(list[i], getItems) && list[i + 1].opcode == OpCodes.Ldarg_1 && CodeInstructionExtensions.Calls(list[i + 2], methodInfo))
				{
					if (num >= 0)
					{
						throw new InvalidOperationException("Ambiguous group membership call.");
					}
					num = i;
				}
			}
			if (num < 0)
			{
				throw new InvalidOperationException("Reviewed group membership call was not found.");
			}
			list[num].opcode = OpCodes.Nop;
			list[num].operand = null;
			list[num + 2].opcode = OpCodes.Call;
			list[num + 2].operand = AccessTools.Method(typeof(GroupLookup), "Contains", (Type[])null, (Type[])null);
			return list;
		}

		private void OnDestroy()
		{
			if (active)
			{
				SetOptimizationEnabled(enabled: false);
			}
		}
	}
	internal static class GroupLookup
	{
		internal static Func<Dictionary<string, HashSet<string>>> ReadGroups;

		internal static bool Contains(string group, string prefab)
		{
			if (!ReadGroups().TryGetValue(group, out var value))
			{
				return false;
			}
			if (value == null)
			{
				throw new ArgumentNullException("source");
			}
			if (value.Comparer == EqualityComparer<string>.Default || value.Comparer == StringComparer.Ordinal)
			{
				return value.Contains(prefab);
			}
			foreach (string item in value)
			{
				if (EqualityComparer<string>.Default.Equals(item, prefab))
				{
					return true;
				}
			}
			return false;
		}
	}
}