using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Cecil.Cil; [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("SkulOnlineCoopV1.Preloader")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("SkulOnlineCoopV1.Preloader")] [assembly: AssemblyTitle("SkulOnlineCoopV1.Preloader")] [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.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; } } [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 SkulOnlineCoopV1.Preloader { public static class PlayerContextPreloader { public static IEnumerable TargetDLLs => new string[1] { "Assembly-CSharp.dll" }; public static void Patch(ref AssemblyDefinition assembly) { //IL_0178: Unknown result type (might be due to invalid IL or missing references) ModuleDefinition mainModule = assembly.MainModule; TypeDefinition val = mainModule.GetType("Level.LevelManager") ?? throw new InvalidOperationException("Skul Level.LevelManager was not found."); TypeDefinition val2 = mainModule.GetType("Characters.Character") ?? throw new InvalidOperationException("Skul Characters.Character was not found."); MethodDefinition val3 = ((IEnumerable)val.Methods).Single((MethodDefinition method) => ((MemberReference)method).Name == "get_player" && ((MethodReference)method).Parameters.Count == 0); MethodDefinition val4 = AddResolver(mainModule, val, val2, val3); int num = 0; foreach (MethodDefinition item in from method in AllTypes((IEnumerable)mainModule.Types).SelectMany((TypeDefinition type) => (IEnumerable)type.Methods) where method.HasBody select method) { if (item.DeclaringType == val4.DeclaringType) { continue; } Instruction[] array = item.Body.Instructions.ToArray(); foreach (Instruction val5 in array) { object operand = val5.Operand; MethodReference val6 = (MethodReference)((operand is MethodReference) ? operand : null); if (val6 != null && !(((MemberReference)((MemberReference)val6).DeclaringType).FullName != ((MemberReference)val).FullName) && !(((MemberReference)val6).Name != ((MemberReference)val3).Name) && val6.Parameters.Count == 0 && !(((MemberReference)val6.ReturnType).FullName != ((MemberReference)val2).FullName)) { val5.OpCode = OpCodes.Call; val5.Operand = val4; num++; } } } Console.WriteLine($"[SkulOnlineCoopV1] Rewrote {num} LevelManager.player reads to PlayerExecutionContext.Resolve."); } private static MethodDefinition AddResolver(ModuleDefinition module, TypeDefinition levelManager, TypeDefinition character, MethodDefinition getter) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Expected O, but got Unknown //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Expected O, but got Unknown //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Expected O, but got Unknown //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Expected O, but got Unknown //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Unknown result type (might be due to invalid IL or missing references) TypeDefinition type = module.GetType("SkulOnlineCoopV1.Runtime.PlayerExecutionContext"); if (type != null) { return ((IEnumerable)type.Methods).Single((MethodDefinition method) => ((MemberReference)method).Name == "Resolve"); } TypeDefinition val = new TypeDefinition("SkulOnlineCoopV1.Runtime", "PlayerExecutionContext", (TypeAttributes)1048961, module.TypeSystem.Object); module.Types.Add(val); FieldDefinition val2 = new FieldDefinition("_activeCharacter", (FieldAttributes)17, (TypeReference)(object)character); val.Fields.Add(val2); MethodDefinition val3 = new MethodDefinition("SetCurrent", (MethodAttributes)22, module.TypeSystem.Void); ((MethodReference)val3).Parameters.Add(new ParameterDefinition("player", (ParameterAttributes)0, (TypeReference)(object)character)); val3.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_0)); val3.Body.Instructions.Add(Instruction.Create(OpCodes.Stsfld, (FieldReference)(object)val2)); val3.Body.Instructions.Add(Instruction.Create(OpCodes.Ret)); val.Methods.Add(val3); MethodDefinition val4 = new MethodDefinition("ClearCurrent", (MethodAttributes)22, module.TypeSystem.Void); val4.Body.Instructions.Add(Instruction.Create(OpCodes.Ldnull)); val4.Body.Instructions.Add(Instruction.Create(OpCodes.Stsfld, (FieldReference)(object)val2)); val4.Body.Instructions.Add(Instruction.Create(OpCodes.Ret)); val.Methods.Add(val4); MethodDefinition val5 = new MethodDefinition("GetCurrent", (MethodAttributes)22, (TypeReference)(object)character); val5.Body.Instructions.Add(Instruction.Create(OpCodes.Ldsfld, (FieldReference)(object)val2)); val5.Body.Instructions.Add(Instruction.Create(OpCodes.Ret)); val.Methods.Add(val5); MethodDefinition val6 = new MethodDefinition("Resolve", (MethodAttributes)22, (TypeReference)(object)character); ((MethodReference)val6).Parameters.Add(new ParameterDefinition("manager", (ParameterAttributes)0, (TypeReference)(object)levelManager)); Instruction val7 = Instruction.Create(OpCodes.Pop); val6.Body.Instructions.Add(Instruction.Create(OpCodes.Ldsfld, (FieldReference)(object)val2)); val6.Body.Instructions.Add(Instruction.Create(OpCodes.Dup)); val6.Body.Instructions.Add(Instruction.Create(OpCodes.Brfalse_S, val7)); val6.Body.Instructions.Add(Instruction.Create(OpCodes.Ret)); val6.Body.Instructions.Add(val7); val6.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_0)); val6.Body.Instructions.Add(Instruction.Create(OpCodes.Callvirt, (MethodReference)(object)getter)); val6.Body.Instructions.Add(Instruction.Create(OpCodes.Ret)); val.Methods.Add(val6); return val6; } private static IEnumerable AllTypes(IEnumerable roots) { foreach (TypeDefinition type in roots) { yield return type; foreach (TypeDefinition item in AllTypes((IEnumerable)type.NestedTypes)) { yield return item; } } } } }