Decompiled source of NoArbitraryIncompatibilityFlag v1.1.1

patchers/NoArbitraryIncompatibilityFlag.dll

Decompiled 2 weeks 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 System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Collections.Generic;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("NoArbitraryIncompatibilityFlag")]
[assembly: AssemblyDescription("Reverses arbitrary incompatibility flags from RtD mods")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("NoArbitraryIncompatibilityFlag")]
[assembly: AssemblyCopyright("Copyright © 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("a1b2c3d4-e5f6-7890-abcd-ef1234567890")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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 NoArbitraryIncompatibilityFlag
{
	public static class Patcher
	{
		private static ManualLogSource Logger = Logger.CreateLogSource("NoArbitraryIncompatibilityFlag");

		private static readonly BepInIncompatibility[] EmptyIncompatibilities = (BepInIncompatibility[])(object)new BepInIncompatibility[0];

		private static readonly HashSet<string> processedRtDMods = new HashSet<string>();

		private static bool summaryLogged = false;

		private static bool insideGetAssemblies = false;

		private static readonly HashSet<string> RtDModGUIDs = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
		{
			"Soloredis.RtDOcean", "Soloredis.RtDVines", "Soloredis.RtDMonsters", "Soloredis.RtDSouls", "Soloredis.RtDBiomes", "Soloredis.RtDMonstrum", "Soloredis.RtDDungeons", "Soloredis.RtDFairyTale", "Soloredis.RtDGardening", "Soloredis.RtDHorrors",
			"Soloredis.RtDItems", "Soloredis.RtDMagic", "Soloredis.RtDSouls_Addon"
		};

		public static IEnumerable<string> TargetDLLs { get; } = new string[13]
		{
			"RtDOcean.dll", "RtDVines.dll", "RtDMonsters.dll", "RtDSouls.dll", "RtDBiomes.dll", "RtDMonstrum.dll", "RtDDungeons.dll", "RtDFairyTale.dll", "RtDGardening.dll", "RtDHorrors.dll",
			"RtDItems.dll", "RtDMagic.dll", "RtDSouls_Addon.dll"
		};


		public static void Patch(AssemblyDefinition assembly)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			string name = ((AssemblyNameReference)assembly.Name).Name;
			Logger.LogInfo((object)("Processing " + name + "..."));
			int num = 0;
			Enumerator<TypeDefinition> enumerator = assembly.MainModule.Types.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					TypeDefinition current = enumerator.Current;
					num += StripIncompatibilityAttributes(current);
					StripStaticConstructorThrows(current);
					NeuterFailMethod(current);
					StripFailCallsFromAwake(current);
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			if (num > 0)
			{
				Logger.LogInfo((object)$"  Stripped {num} incompatibility attribute(s) from {name}");
			}
		}

		private static int StripIncompatibilityAttributes(TypeDefinition type)
		{
			int num = 0;
			for (int num2 = type.CustomAttributes.Count - 1; num2 >= 0; num2--)
			{
				if (((MemberReference)type.CustomAttributes[num2].AttributeType).Name == "BepInIncompatibility")
				{
					type.CustomAttributes.RemoveAt(num2);
					num++;
				}
			}
			return num;
		}

		private static void StripStaticConstructorThrows(TypeDefinition type)
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: 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_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			MethodDefinition val = ((IEnumerable<MethodDefinition>)type.Methods).FirstOrDefault((Func<MethodDefinition, bool>)((MethodDefinition m) => ((MemberReference)m).Name == ".cctor"));
			if (val == null || !val.HasBody || !((IEnumerable<Instruction>)val.Body.Instructions).Any((Instruction i) => i.OpCode == OpCodes.Ldstr && i.Operand is string text && text.IndexOf("integrity", StringComparison.OrdinalIgnoreCase) >= 0))
			{
				return;
			}
			Collection<Instruction> instructions = val.Body.Instructions;
			for (int j = 0; j < instructions.Count; j++)
			{
				if (!(instructions[j].OpCode != OpCodes.Throw))
				{
					instructions[j].OpCode = OpCodes.Nop;
					instructions[j].Operand = null;
					if (j > 0 && instructions[j - 1].OpCode == OpCodes.Newobj)
					{
						instructions[j - 1].OpCode = OpCodes.Nop;
						instructions[j - 1].Operand = null;
					}
					if (j > 1 && instructions[j - 2].OpCode == OpCodes.Ldstr)
					{
						instructions[j - 2].OpCode = OpCodes.Nop;
						instructions[j - 2].Operand = null;
					}
					Logger.LogInfo((object)("  Stripped integrity throw from " + ((MemberReference)type).Name + " static constructor"));
				}
			}
		}

		private static void NeuterFailMethod(TypeDefinition type)
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			MethodDefinition val = ((IEnumerable<MethodDefinition>)type.Methods).FirstOrDefault((Func<MethodDefinition, bool>)((MethodDefinition m) => ((MemberReference)m).Name == "Fail"));
			if (val != null && val.HasBody)
			{
				val.Body.Instructions.Clear();
				val.Body.ExceptionHandlers.Clear();
				val.Body.Variables.Clear();
				ILProcessor iLProcessor = val.Body.GetILProcessor();
				iLProcessor.Append(iLProcessor.Create(OpCodes.Ret));
				Logger.LogInfo((object)("  Neutered " + ((MemberReference)type).Name + ".Fail()"));
			}
		}

		private static void StripFailCallsFromAwake(TypeDefinition type)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			MethodDefinition val = ((IEnumerable<MethodDefinition>)type.Methods).FirstOrDefault((Func<MethodDefinition, bool>)((MethodDefinition m) => ((MemberReference)m).Name == "Awake"));
			if (val == null || !val.HasBody)
			{
				return;
			}
			int num = 0;
			Enumerator<Instruction> enumerator = val.Body.Instructions.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					Instruction current = enumerator.Current;
					if (current.OpCode == OpCodes.Call)
					{
						object operand = current.Operand;
						MethodReference val2 = (MethodReference)((operand is MethodReference) ? operand : null);
						if (val2 != null && ((MemberReference)val2).Name == "Fail")
						{
							current.OpCode = OpCodes.Nop;
							current.Operand = null;
							num++;
						}
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			if (num > 0)
			{
				Logger.LogInfo((object)$"  Removed {num} Fail() call(s) from {((MemberReference)type).Name}.Awake()");
			}
		}

		public static void Initialize()
		{
		}

		public static void Finish()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			try
			{
				Harmony val = new Harmony("NoArbitraryIncompatibilityFlag");
				PropertyInfo property = typeof(PluginInfo).GetProperty("Incompatibilities");
				if (property == null)
				{
					Logger.LogError((object)"Could not find Incompatibilities property");
				}
				else
				{
					MethodInfo getMethod = property.GetGetMethod();
					if (getMethod == null)
					{
						Logger.LogError((object)"Could not find Incompatibilities getter method");
					}
					else
					{
						MethodInfo methodInfo = AccessTools.Method(typeof(Patcher), "Incompatibilities_Getter_Prefix", (Type[])null, (Type[])null);
						val.Patch((MethodBase)getMethod, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						Logger.LogInfo((object)"✓ Ready to bypass incompatibility checks for RtD mods");
					}
				}
				PatchContainsKey(val);
				PatchAssemblyGetName(val);
				PatchGetAssemblies(val);
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("Error during Finish: " + ex.Message));
				Logger.LogError((object)("Stack trace: " + ex.StackTrace));
			}
		}

		private static void PatchContainsKey(Harmony harmony)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			try
			{
				MethodInfo method = typeof(Dictionary<string, PluginInfo>).GetMethod("ContainsKey");
				if (method == null)
				{
					Logger.LogError((object)"Could not find Dictionary.ContainsKey method");
					return;
				}
				MethodInfo methodInfo = AccessTools.Method(typeof(Patcher), "ContainsKey_Prefix", (Type[])null, (Type[])null);
				harmony.Patch((MethodBase)method, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Logger.LogInfo((object)"✓ Ready to hide from RtD mod detection");
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("Error patching ContainsKey: " + ex.Message));
			}
		}

		private static void PatchAssemblyGetName(Harmony harmony)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			try
			{
				MethodInfo method = typeof(Assembly).GetMethod("GetName", Type.EmptyTypes);
				if (method == null)
				{
					Logger.LogError((object)"Could not find Assembly.GetName method");
					return;
				}
				MethodInfo methodInfo = AccessTools.Method(typeof(Patcher), "GetName_Postfix", (Type[])null, (Type[])null);
				harmony.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Logger.LogInfo((object)"✓ Ready to hide assembly name from RtD mod detection");
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("Error patching Assembly.GetName: " + ex.Message));
			}
		}

		private static void PatchGetAssemblies(Harmony harmony)
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			//IL_007e: Expected O, but got Unknown
			try
			{
				MethodInfo method = typeof(AppDomain).GetMethod("GetAssemblies", Type.EmptyTypes);
				if (method == null)
				{
					Logger.LogError((object)"Could not find AppDomain.GetAssemblies method");
					return;
				}
				MethodInfo methodInfo = AccessTools.Method(typeof(Patcher), "GetAssemblies_Prefix", (Type[])null, (Type[])null);
				MethodInfo methodInfo2 = AccessTools.Method(typeof(Patcher), "GetAssemblies_Postfix", (Type[])null, (Type[])null);
				harmony.Patch((MethodBase)method, new HarmonyMethod(methodInfo), new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Logger.LogInfo((object)"✓ Ready to hide assembly from AppDomain.GetAssemblies");
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("Error patching AppDomain.GetAssemblies: " + ex.Message));
			}
		}

		private static void GetAssemblies_Prefix()
		{
			insideGetAssemblies = true;
		}

		private static void GetAssemblies_Postfix(ref Assembly[] __result)
		{
			try
			{
				insideGetAssemblies = false;
				StackTrace stackTrace = new StackTrace();
				for (int i = 0; i < stackTrace.FrameCount; i++)
				{
					try
					{
						MethodBase methodBase = stackTrace.GetFrame(i)?.GetMethod();
						if (!(methodBase?.DeclaringType != null))
						{
							continue;
						}
						Type declaringType = methodBase.DeclaringType;
						while (declaringType != null)
						{
							try
							{
								BepInPlugin customAttribute = ((MemberInfo)declaringType).GetCustomAttribute<BepInPlugin>(inherit: false);
								if (customAttribute != null && RtDModGUIDs.Contains(customAttribute.GUID))
								{
									__result = __result.Where((Assembly a) => a.FullName.IndexOf("NoArbitraryIncompatibilityFlag", StringComparison.OrdinalIgnoreCase) < 0).ToArray();
									return;
								}
							}
							catch
							{
							}
							declaringType = declaringType.DeclaringType;
						}
					}
					catch
					{
					}
				}
			}
			catch
			{
			}
		}

		private static void GetName_Postfix(Assembly __instance, ref AssemblyName __result)
		{
			try
			{
				if (insideGetAssemblies || __result == null || __result.Name == null || !__result.Name.Contains("NoArbitraryIncompatibilityFlag"))
				{
					return;
				}
				StackTrace stackTrace = new StackTrace();
				for (int i = 0; i < stackTrace.FrameCount; i++)
				{
					try
					{
						MethodBase methodBase = stackTrace.GetFrame(i)?.GetMethod();
						if (!(methodBase?.DeclaringType != null))
						{
							continue;
						}
						Type declaringType = methodBase.DeclaringType;
						while (declaringType != null)
						{
							try
							{
								BepInPlugin customAttribute = ((MemberInfo)declaringType).GetCustomAttribute<BepInPlugin>(inherit: false);
								if (customAttribute != null && RtDModGUIDs.Contains(customAttribute.GUID))
								{
									__result = new AssemblyName("HiddenAssembly");
									return;
								}
							}
							catch
							{
							}
							declaringType = declaringType.DeclaringType;
						}
					}
					catch
					{
					}
				}
			}
			catch
			{
			}
		}

		private static bool ContainsKey_Prefix(Dictionary<string, PluginInfo> __instance, string key, ref bool __result)
		{
			try
			{
				if (key == "IAmOnTheInternetAndItIsScary.NoArbitraryIncompatibilityFlag")
				{
					StackTrace stackTrace = new StackTrace();
					for (int i = 0; i < stackTrace.FrameCount; i++)
					{
						try
						{
							MethodBase methodBase = stackTrace.GetFrame(i)?.GetMethod();
							if (!(methodBase?.DeclaringType != null))
							{
								continue;
							}
							Type declaringType = methodBase.DeclaringType;
							while (declaringType != null)
							{
								try
								{
									BepInPlugin customAttribute = ((MemberInfo)declaringType).GetCustomAttribute<BepInPlugin>(inherit: false);
									if (customAttribute != null && RtDModGUIDs.Contains(customAttribute.GUID))
									{
										__result = false;
										return false;
									}
								}
								catch
								{
								}
								declaringType = declaringType.DeclaringType;
							}
						}
						catch
						{
						}
					}
				}
				return true;
			}
			catch
			{
				return true;
			}
		}

		private static bool Incompatibilities_Getter_Prefix(PluginInfo __instance, ref IEnumerable<BepInIncompatibility> __result)
		{
			try
			{
				if (__instance != null)
				{
					BepInPlugin metadata = __instance.Metadata;
					if (((metadata != null) ? metadata.GUID : null) != null && RtDModGUIDs.Contains(__instance.Metadata.GUID))
					{
						if (!processedRtDMods.Contains(__instance.Metadata.GUID))
						{
							processedRtDMods.Add(__instance.Metadata.GUID);
							Logger.LogInfo((object)("✓ Found RtD mod: " + __instance.Metadata.Name));
						}
						__result = EmptyIncompatibilities;
						return false;
					}
				}
				if (!summaryLogged && processedRtDMods.Count > 0)
				{
					summaryLogged = true;
					Logger.LogInfo((object)$"✓ Successfully bypassed incompatibility checks for {processedRtDMods.Count} RtD mod(s)");
				}
				return true;
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("Error in Incompatibilities_Getter_Prefix: " + ex.Message));
				return true;
			}
		}
	}
	[BepInPlugin("IAmOnTheInternetAndItIsScary.NoArbitraryIncompatibilityFlag", "NoArbitraryIncompatibilityFlag", "1.1.0")]
	public class NoArbitraryIncompatibilityFlagPlugin : BaseUnityPlugin
	{
		internal const string ModName = "NoArbitraryIncompatibilityFlag";

		internal const string ModGUID = "IAmOnTheInternetAndItIsScary.NoArbitraryIncompatibilityFlag";

		internal const string ModVersion = "1.1.0";

		public void Awake()
		{
		}
	}
}