Decompiled source of UniversalIncompatibilityPatcher v1.0.0

UniversalIncompatibilityPatcher/patchers/UniversalIncompatibilityPatcher.dll

Decompiled 3 hours ago
using System;
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.Logging;
using Mono.Cecil;
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: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = ".NET Framework 4.6")]
[assembly: AssemblyVersion("0.0.0.0")]
namespace UniversalIncompatibilityPatcher;

public static class Patcher
{
	private static readonly ManualLogSource Logger = Logger.CreateLogSource("UniversalIncompatibilityPatcher");

	private static readonly string ConfigPath = Path.Combine(Paths.BepInExRootPath, "config", "UniversalIncompatibilityPatcher.cfg");

	public static IEnumerable<string> TargetDLLs { get; } = new List<string>();


	public static void Patch(AssemblyDefinition assembly)
	{
	}

	public static void Finish()
	{
	}

	public static void Initialize()
	{
		EnsureConfig();
		string[] array = LoadConfig();
		if (array.Length == 0)
		{
			Logger.LogWarning((object)"No mods configured in UniversalIncompatibilityPatcher.cfg.");
			return;
		}
		string text = Path.Combine(Paths.BepInExRootPath, "plugins");
		if (!Directory.Exists(text))
		{
			Logger.LogWarning((object)("Plugins folder not found: " + text));
			return;
		}
		int num = 0;
		int num2 = 0;
		string[] array2 = array;
		foreach (string text2 in array2)
		{
			string[] files = Directory.GetFiles(text, text2, SearchOption.AllDirectories);
			if (files.Length == 0)
			{
				Logger.LogWarning((object)(text2 + " not found in plugins folder."));
				continue;
			}
			string[] array3 = files;
			foreach (string dllPath in array3)
			{
				try
				{
					int num3 = PatchMod(dllPath);
					if (num3 > 0)
					{
						num += num3;
						num2++;
						Logger.LogInfo((object)$"[{text2}] Removed {num3} incompatibility flag(s).");
					}
					else
					{
						Logger.LogInfo((object)("[" + text2 + "] Already clean, nothing to patch."));
					}
				}
				catch (Exception ex)
				{
					Logger.LogError((object)("Failed to patch " + text2 + ": " + ex.Message));
				}
			}
		}
		if (num2 > 0)
		{
			Logger.LogInfo((object)$"Done! Removed {num} flag(s) from {num2} mod(s).");
		}
		else
		{
			Logger.LogInfo((object)"Done! All configured mods were already clean.");
		}
	}

	private static void EnsureConfig()
	{
		if (!File.Exists(ConfigPath))
		{
			Directory.CreateDirectory(Path.GetDirectoryName(ConfigPath));
			File.WriteAllText(ConfigPath, "# UniversalIncompatibilityPatcher - Target Mods\n#\n# Add one DLL filename per line.\n# The name must match exactly as it appears inside the plugins folder.\n# Lines starting with # are ignored.\n#\n# Example:\n# ServerCharacters.dll\n# AnotherMod.dll\n#\n\nServerCharacters.dll\n");
			Logger.LogInfo((object)"Config file created.");
		}
	}

	private static string[] LoadConfig()
	{
		return (from line in File.ReadAllLines(ConfigPath)
			select line.Trim() into line
			where line.Length > 0 && !line.StartsWith("#")
			select line).ToArray();
	}

	private static int PatchMod(string dllPath)
	{
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Expected O, but got Unknown
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0108: Expected O, but got Unknown
		int num = 0;
		string text = dllPath + ".tmp";
		ReaderParameters val = new ReaderParameters
		{
			ReadSymbols = false
		};
		AssemblyDefinition val2 = AssemblyDefinition.ReadAssembly(dllPath, val);
		try
		{
			Enumerator<TypeDefinition> enumerator = val2.MainModule.Types.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					TypeDefinition current = enumerator.Current;
					if (!current.HasCustomAttributes)
					{
						continue;
					}
					List<CustomAttribute> list = ((IEnumerable<CustomAttribute>)current.CustomAttributes).Where((CustomAttribute a) => ((MemberReference)a.AttributeType).FullName == "BepInEx.BepInIncompatibility").ToList();
					foreach (CustomAttribute item in list)
					{
						current.CustomAttributes.Remove(item);
						num++;
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			if (num > 0)
			{
				WriterParameters val3 = new WriterParameters
				{
					WriteSymbols = false
				};
				val2.Write(text, val3);
			}
		}
		finally
		{
			((IDisposable)val2)?.Dispose();
		}
		if (num > 0)
		{
			File.Delete(dllPath);
			File.Move(text, dllPath);
		}
		return num;
	}
}