using System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Preloader.Core.Patching; 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.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("SlipSkid.StripFix")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("SlipSkid.StripFix")] [assembly: AssemblyTitle("SlipSkid.StripFix")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [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 SlipSkid.StripFix { [PatcherPluginInfo("slipskid.stripfix", "Slip & Skid - Strip Fix", "1.0.0")] public class StripFixPatcher : BasePatcher { private const string UnityVersion = "2022.3.62f2"; [TargetAssembly("UnityEngine.CoreModule.dll")] public void PatchCoreModule(AssemblyDefinition assembly) { TypeDefinition type = assembly.MainModule.GetType("UnityEngine.Application"); if (type == null) { ((BasePatcher)this).Log.LogWarning((object)"UnityEngine.Application not found; skipping strip fix."); return; } RestoreUnityVersion(assembly, type); RestoreLogMessageReceived(assembly, type); } private void RestoreUnityVersion(AssemblyDefinition assembly, TypeDefinition application) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Expected O, but got Unknown //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Expected O, but got Unknown if (application.Methods.Any((MethodDefinition m) => ((MemberReference)m).Name == "get_unityVersion")) { ((BasePatcher)this).Log.LogInfo((object)"Application.get_unityVersion already present."); return; } TypeReference val = assembly.MainModule.TypeSystem.String; MethodDefinition val2 = new MethodDefinition("get_unityVersion", (MethodAttributes)2198, val); ILProcessor iLProcessor = val2.Body.GetILProcessor(); iLProcessor.Append(iLProcessor.Create(OpCodes.Ldstr, "2022.3.62f2")); iLProcessor.Append(iLProcessor.Create(OpCodes.Ret)); application.Methods.Add(val2); application.Properties.Add(new PropertyDefinition("unityVersion", (PropertyAttributes)0, val) { GetMethod = val2 }); ManualLogSource log = ((BasePatcher)this).Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(40, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Restored Application.unityVersion => \""); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted("2022.3.62f2"); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("\"."); } log.LogInfo(val3); } private void RestoreLogMessageReceived(AssemblyDefinition assembly, TypeDefinition application) { //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Expected O, but got Unknown if (application.Events.Any((EventDefinition e) => ((MemberReference)e).Name == "logMessageReceived")) { ((BasePatcher)this).Log.LogInfo((object)"Application.logMessageReceived already present."); return; } FieldDefinition val = application.Fields.FirstOrDefault((FieldDefinition f) => ((MemberReference)f).Name == "s_LogCallbackHandler"); TypeDefinition val2 = application.NestedTypes.FirstOrDefault((TypeDefinition t) => ((MemberReference)t).Name == "LogCallback"); if (val == null || val2 == null) { ((BasePatcher)this).Log.LogWarning((object)"s_LogCallbackHandler or LogCallback missing — cannot restore logMessageReceived. Game log forwarding will stay disabled."); return; } ModuleDefinition mainModule = assembly.MainModule; MethodReference combineOrRemove = mainModule.ImportReference((MethodBase)typeof(Delegate).GetMethod("Combine", new Type[2] { typeof(Delegate), typeof(Delegate) })); MethodReference combineOrRemove2 = mainModule.ImportReference((MethodBase)typeof(Delegate).GetMethod("Remove", new Type[2] { typeof(Delegate), typeof(Delegate) })); MethodDefinition val3 = BuildAccessor("add_logMessageReceived", (TypeReference)(object)val2, val, combineOrRemove, mainModule); MethodDefinition val4 = BuildAccessor("remove_logMessageReceived", (TypeReference)(object)val2, val, combineOrRemove2, mainModule); application.Methods.Add(val3); application.Methods.Add(val4); application.Events.Add(new EventDefinition("logMessageReceived", (EventAttributes)0, (TypeReference)(object)val2) { AddMethod = val3, RemoveMethod = val4 }); ((BasePatcher)this).Log.LogInfo((object)"Restored Application.logMessageReceived — game Debug.Log will reach BepInEx."); } private static MethodDefinition BuildAccessor(string name, TypeReference callbackType, FieldDefinition handlerField, MethodReference combineOrRemove, ModuleDefinition module) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_002e: 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) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown MethodDefinition val = new MethodDefinition(name, (MethodAttributes)2198, module.TypeSystem.Void); ((MethodReference)val).Parameters.Add(new ParameterDefinition("value", (ParameterAttributes)0, callbackType)); ILProcessor iLProcessor = val.Body.GetILProcessor(); iLProcessor.Append(iLProcessor.Create(OpCodes.Ldsfld, (FieldReference)(object)handlerField)); iLProcessor.Append(iLProcessor.Create(OpCodes.Ldarg_0)); iLProcessor.Append(iLProcessor.Create(OpCodes.Call, combineOrRemove)); iLProcessor.Append(iLProcessor.Create(OpCodes.Castclass, callbackType)); iLProcessor.Append(iLProcessor.Create(OpCodes.Stsfld, (FieldReference)(object)handlerField)); iLProcessor.Append(iLProcessor.Create(OpCodes.Ret)); return val; } } internal static class CecilExtensions { public static bool Any(this Collection collection, Func predicate) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) Enumerator enumerator = collection.GetEnumerator(); try { while (enumerator.MoveNext()) { T current = enumerator.Current; if (predicate(current)) { return true; } } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } return false; } public static T FirstOrDefault(this Collection collection, Func predicate) where T : class { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) Enumerator enumerator = collection.GetEnumerator(); try { while (enumerator.MoveNext()) { T current = enumerator.Current; if (predicate(current)) { return current; } } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } return null; } } }