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.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Preloader.Core.Patching; using Microsoft.CodeAnalysis; using dnlib.DotNet; using dnlib.DotNet.Writer; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("InfernoProtocol.InteropFix")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+477d00f8c6e6102e4d9ad948d3169f90685e9781")] [assembly: AssemblyProduct("InfernoProtocol.InteropFix")] [assembly: AssemblyTitle("InfernoProtocol.InteropFix")] [assembly: AssemblyVersion("1.0.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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; } } } namespace InfernoProtocol.InteropFix { [PatcherPluginInfo("com.holden.infernoprotocol.interopfix", "Inferno Protocol Unity 6 Interop Fix", "1.0.0")] public sealed class Unity6InteropPatcher : BasePatcher { private static readonly string[] AffectedAssemblies = new string[2] { "UnityEngine.CoreModule.dll", "Unity.Collections.dll" }; public override void Initialize() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Expected O, but got Unknown //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown string[] affectedAssemblies = AffectedAssemblies; bool flag = default(bool); foreach (string text in affectedAssemblies) { if (!((BasePatcher)this).Context.AvailableAssembliesPaths.TryGetValue(text, out var value)) { ManualLogSource log = ((BasePatcher)this).Log; BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(17, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Skipped missing "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogDebug(val); continue; } if (((BasePatcher)this).Context.AvailableAssemblies.TryGetValue(text, out var value2)) { value2.Dispose(); } int num = RepairAssembly(value); if (num == 0) { ManualLogSource log2 = ((BasePatcher)this).Log; BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(29, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("No duplicate types found in "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log2.LogDebug(val); continue; } ManualLogSource log3 = ((BasePatcher)this).Log; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(40, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Removed "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" duplicate helper type(s) from "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("."); } log3.LogInfo(val2); } } private static int RepairAssembly(string assemblyPath) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown ModuleDefMD val = ModuleDefMD.Load(File.ReadAllBytes(assemblyPath), new ModuleCreationOptions { TryToLoadPdbFromDisk = false }); try { int num = RemoveDuplicateTopLevelTypes(val); foreach (TypeDef item in ((ModuleDef)val).GetTypes().ToList()) { num += RemoveDuplicateNestedTypes(item); } if (num == 0) { return 0; } string text = assemblyPath + ".infernoprotocol-backup"; if (!File.Exists(text)) { File.Copy(assemblyPath, text); } string text2 = assemblyPath + ".infernoprotocol-tmp"; ModuleWriterOptions val2 = new ModuleWriterOptions((ModuleDef)(object)val) { Logger = (ILogger)(object)DummyLogger.NoThrowInstance }; ((ModuleDef)val).Write(text2, val2); File.Move(text2, assemblyPath, overwrite: true); return num; } finally { ((IDisposable)val)?.Dispose(); } } private static int RemoveDuplicateTopLevelTypes(ModuleDefMD module) { HashSet hashSet = new HashSet(StringComparer.Ordinal); List list = new List(); foreach (TypeDef type in ((ModuleDef)module).Types) { if (!hashSet.Add(type.FullName)) { list.Add(type); } } foreach (TypeDef item in list) { ((ModuleDef)module).Types.Remove(item); } return list.Count; } private static int RemoveDuplicateNestedTypes(TypeDef type) { if (type.NestedTypes.Count < 2) { return 0; } HashSet hashSet = new HashSet(StringComparer.Ordinal); List list = new List(); foreach (TypeDef nestedType in type.NestedTypes) { if (!hashSet.Add(nestedType.Name.String)) { list.Add(nestedType); } } foreach (TypeDef item in list) { type.NestedTypes.Remove(item); } return list.Count; } } }