using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Cecil.Rocks;
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(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("AdvancedREPO.Patcher")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Better stamina for REPO")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+e0ce9281b74a83533d1745f48a75808927f50012")]
[assembly: AssemblyProduct("AdvancedREPO.Patcher")]
[assembly: AssemblyTitle("AdvancedREPO.Patcher")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.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 AdvancedREPO.Patcher
{
public class Patch : Attribute
{
public string? TypeName = null;
private string _AssemblyName = "Assembly-CSharp.dll";
public string? MethodName { get; set; } = null;
public string AssemblyName
{
get
{
return _AssemblyName;
}
set
{
if (!value.EndsWith(".dll", StringComparison.OrdinalIgnoreCase))
{
value += ".dll";
}
_AssemblyName = value;
}
}
public Patch(string? typeName = null)
{
TypeName = typeName;
}
}
public class Patcher
{
public static ManualLogSource Log;
private static List<string>? AssemblyNames;
private static ConcurrentDictionary<string, ConcurrentBag<Action<AssemblyDefinition>>>? Assemblies;
private static ConcurrentDictionary<string, ConcurrentDictionary<string, ConcurrentBag<Action<TypeDefinition>>>>? Types;
private static ConcurrentDictionary<string, ConcurrentDictionary<string, ConcurrentDictionary<string, ConcurrentBag<Action<MethodDefinition>>>>>? Methods;
private static bool Initialized;
public static IEnumerable<string> TargetDLLs
{
get
{
Log = Logger.CreateLogSource("AdvancedREPO.Patcher");
Assembly callingAssembly = Assembly.GetCallingAssembly();
string name = callingAssembly.GetName().Name;
if (!name.StartsWith("BepInEx", StringComparison.OrdinalIgnoreCase))
{
AssemblyNames = null;
Assemblies = new ConcurrentDictionary<string, ConcurrentBag<Action<AssemblyDefinition>>>();
Types = new ConcurrentDictionary<string, ConcurrentDictionary<string, ConcurrentBag<Action<TypeDefinition>>>>();
Methods = new ConcurrentDictionary<string, ConcurrentDictionary<string, ConcurrentDictionary<string, ConcurrentBag<Action<MethodDefinition>>>>>();
Log.LogInfo((object)("Collecting patches for assembly " + callingAssembly.GetName().Name));
Initialize(callingAssembly);
if (AssemblyNames != null)
{
return AssemblyNames;
}
Log.LogWarning((object)"No targetted dlls found. Skipping patching.");
}
return new string[0];
}
}
public static void Initialize(Assembly assembly)
{
if (!assembly.GetReferencedAssemblies().Any((AssemblyName e) => e.Name == "AdvancedREPO.Patcher"))
{
return;
}
assembly.GetTypes().AsParallel().ForAll(delegate(Type type)
{
type.GetMethods().AsParallel().ForAll(delegate(MethodInfo method)
{
Patch customAttribute = method.GetCustomAttribute<Patch>();
if (customAttribute == null)
{
return;
}
if (customAttribute.TypeName != null)
{
if (customAttribute.MethodName != null)
{
try
{
Methods.GetOrAdd(customAttribute.AssemblyName, (string key) => new ConcurrentDictionary<string, ConcurrentDictionary<string, ConcurrentBag<Action<MethodDefinition>>>>()).GetOrAdd(customAttribute.TypeName, (string key) => new ConcurrentDictionary<string, ConcurrentBag<Action<MethodDefinition>>>()).GetOrAdd(customAttribute.MethodName, (string key) => new ConcurrentBag<Action<MethodDefinition>>())
.Add((Action<MethodDefinition>)method.CreateDelegate(typeof(Action<MethodDefinition>)));
return;
}
catch (Exception)
{
Log.LogWarning((object)("Method patcher found in " + method.DeclaringType.FullName + "::" + method.Name + " has an invalid signature."));
return;
}
}
try
{
Types.GetOrAdd(customAttribute.AssemblyName, (string key) => new ConcurrentDictionary<string, ConcurrentBag<Action<TypeDefinition>>>()).GetOrAdd(customAttribute.TypeName, (string key) => new ConcurrentBag<Action<TypeDefinition>>()).Add((Action<TypeDefinition>)method.CreateDelegate(typeof(Action<TypeDefinition>)));
return;
}
catch (Exception)
{
Log.LogWarning((object)("Type patcher found in " + method.DeclaringType.FullName + "::" + method.Name + " has an invalid signature."));
return;
}
}
try
{
Assemblies.GetOrAdd(customAttribute.AssemblyName, (string key) => new ConcurrentBag<Action<AssemblyDefinition>>()).Add((Action<AssemblyDefinition>)method.CreateDelegate(typeof(Action<AssemblyDefinition>)));
}
catch (Exception)
{
Log.LogWarning((object)("Assembly patcher found in " + method.DeclaringType.FullName + "::" + method.Name + " has an invalid signature."));
}
});
});
HashSet<string> assemblies = new HashSet<string>();
Methods.Keys.ToList().ForEach(delegate(string key)
{
assemblies.Add(key);
});
Types.Keys.ToList().ForEach(delegate(string key)
{
assemblies.Add(key);
});
Assemblies.Keys.ToList().ForEach(delegate(string key)
{
assemblies.Add(key);
});
AssemblyNames = assemblies.ToList();
}
public static void Patch(AssemblyDefinition assembly)
{
AssemblyDefinition assembly2 = assembly;
Log.LogInfo((object)("Patching assembly " + ((AssemblyNameReference)assembly2.Name).Name));
string key = ((AssemblyNameReference)assembly2.Name).Name + ".dll";
if (Assemblies.TryGetValue(key, out ConcurrentBag<Action<AssemblyDefinition>> value))
{
Log.LogInfo((object)("Applying patches for assembly " + ((AssemblyNameReference)assembly2.Name).Name));
value.AsParallel().ForAll(delegate(Action<AssemblyDefinition> p)
{
p(assembly2);
});
}
if (Types.TryGetValue(key, out ConcurrentDictionary<string, ConcurrentBag<Action<TypeDefinition>>> value2))
{
value2.AsParallel().ForAll(delegate(KeyValuePair<string, ConcurrentBag<Action<TypeDefinition>>> t)
{
ModuleDefinition mainModule2 = assembly2.MainModule;
TypeDefinition type2 = ((mainModule2 != null) ? mainModule2.GetType(t.Key) : null) ?? null;
if (type2 != null)
{
Log.LogInfo((object)("Applying patches for type " + ((MemberReference)type2).FullName));
t.Value.AsParallel().ForAll(delegate(Action<TypeDefinition> p)
{
p(type2);
});
}
});
}
if (!Methods.TryGetValue(key, out ConcurrentDictionary<string, ConcurrentDictionary<string, ConcurrentBag<Action<MethodDefinition>>>> value3))
{
return;
}
value3.AsParallel().ForAll(delegate(KeyValuePair<string, ConcurrentDictionary<string, ConcurrentBag<Action<MethodDefinition>>>> t)
{
ModuleDefinition mainModule = assembly2.MainModule;
TypeDefinition type = ((mainModule != null) ? mainModule.GetType(t.Key) : null) ?? null;
if (type != null)
{
t.Value.AsParallel().ForAll(delegate(KeyValuePair<string, ConcurrentBag<Action<MethodDefinition>>> m)
{
IEnumerable<MethodDefinition> methods = TypeDefinitionRocks.GetMethods(type);
methods.AsParallel().ForAll(delegate(MethodDefinition method)
{
if (((MemberReference)method).Name == m.Key)
{
Log.LogInfo((object)("Applying patches for method " + ((MemberReference)method).FullName));
m.Value.AsParallel().ForAll(delegate(Action<MethodDefinition> p)
{
p(method);
});
}
});
});
}
});
}
public static void Finish()
{
Log.Dispose();
}
}
}
namespace AdvancedREPO.Patcher.Extensions
{
public static class Instructions
{
private static Dictionary<OpCode, OpCode> SimplifyDict = new Dictionary<OpCode, OpCode>
{
{
OpCodes.Beq_S,
OpCodes.Beq
},
{
OpCodes.Bge_S,
OpCodes.Bge
},
{
OpCodes.Bge_Un_S,
OpCodes.Bge_Un
},
{
OpCodes.Bgt_S,
OpCodes.Bgt
},
{
OpCodes.Bgt_Un_S,
OpCodes.Bgt_Un
},
{
OpCodes.Ble_S,
OpCodes.Ble
},
{
OpCodes.Ble_Un_S,
OpCodes.Ble_Un
},
{
OpCodes.Blt_S,
OpCodes.Blt
},
{
OpCodes.Blt_Un_S,
OpCodes.Blt_Un
},
{
OpCodes.Bne_Un_S,
OpCodes.Bne_Un
},
{
OpCodes.Brfalse_S,
OpCodes.Brfalse
},
{
OpCodes.Brtrue_S,
OpCodes.Brtrue
},
{
OpCodes.Br_S,
OpCodes.Br
},
{
OpCodes.Ldarg_S,
OpCodes.Ldarg
},
{
OpCodes.Ldarga_S,
OpCodes.Ldarga
},
{
OpCodes.Ldloc_S,
OpCodes.Ldloc
},
{
OpCodes.Ldloca_S,
OpCodes.Ldloca
},
{
OpCodes.Leave_S,
OpCodes.Leave
},
{
OpCodes.Starg_S,
OpCodes.Starg
},
{
OpCodes.Stloc_S,
OpCodes.Stloc
}
};
private static Dictionary<OpCode, OpCode> UltraSimplifyDict = new Dictionary<OpCode, OpCode>
{
{
OpCodes.Beq_S,
OpCodes.Beq
},
{
OpCodes.Bge_S,
OpCodes.Bge
},
{
OpCodes.Bge_Un_S,
OpCodes.Bge_Un
},
{
OpCodes.Bgt_S,
OpCodes.Bgt
},
{
OpCodes.Bgt_Un_S,
OpCodes.Bgt_Un
},
{
OpCodes.Ble_S,
OpCodes.Ble
},
{
OpCodes.Ble_Un_S,
OpCodes.Ble_Un
},
{
OpCodes.Blt_S,
OpCodes.Blt
},
{
OpCodes.Blt_Un_S,
OpCodes.Blt_Un
},
{
OpCodes.Bne_Un_S,
OpCodes.Bne_Un
},
{
OpCodes.Brfalse_S,
OpCodes.Brfalse
},
{
OpCodes.Brtrue_S,
OpCodes.Brtrue
},
{
OpCodes.Br_S,
OpCodes.Br
},
{
OpCodes.Ldarga_S,
OpCodes.Ldarga
},
{
OpCodes.Ldarg_0,
OpCodes.Ldarg
},
{
OpCodes.Ldarg_1,
OpCodes.Ldarg
},
{
OpCodes.Ldarg_2,
OpCodes.Ldarg
},
{
OpCodes.Ldarg_3,
OpCodes.Ldarg
},
{
OpCodes.Ldloca_S,
OpCodes.Ldloca
},
{
OpCodes.Ldloc_S,
OpCodes.Ldloc
},
{
OpCodes.Ldloc_0,
OpCodes.Ldloc
},
{
OpCodes.Ldloc_1,
OpCodes.Ldloc
},
{
OpCodes.Ldloc_2,
OpCodes.Ldloc
},
{
OpCodes.Ldloc_3,
OpCodes.Ldloc
},
{
OpCodes.Leave_S,
OpCodes.Leave
},
{
OpCodes.Starg_S,
OpCodes.Starg
},
{
OpCodes.Stloc_S,
OpCodes.Stloc
},
{
OpCodes.Stloc_0,
OpCodes.Stloc
},
{
OpCodes.Stloc_1,
OpCodes.Stloc
},
{
OpCodes.Stloc_2,
OpCodes.Stloc
},
{
OpCodes.Stloc_3,
OpCodes.Stloc
},
{
OpCodes.Ldc_I4_0,
OpCodes.Ldc_I4
},
{
OpCodes.Ldc_I4_1,
OpCodes.Ldc_I4
},
{
OpCodes.Ldc_I4_2,
OpCodes.Ldc_I4
},
{
OpCodes.Ldc_I4_3,
OpCodes.Ldc_I4
},
{
OpCodes.Ldc_I4_4,
OpCodes.Ldc_I4
},
{
OpCodes.Ldc_I4_5,
OpCodes.Ldc_I4
},
{
OpCodes.Ldc_I4_6,
OpCodes.Ldc_I4
},
{
OpCodes.Ldc_I4_7,
OpCodes.Ldc_I4
},
{
OpCodes.Ldc_I4_8,
OpCodes.Ldc_I4
}
};
private static OpCode Simplify(OpCode op, bool ultra = false)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
if (ultra && UltraSimplifyDict.ContainsKey(op))
{
return UltraSimplifyDict[op];
}
if (SimplifyDict.ContainsKey(op))
{
return SimplifyDict[op];
}
return op;
}
public static bool LooseEquals(this OpCode op1, OpCode op2, bool ultra = false)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
return Simplify(op1, ultra) == Simplify(op2, ultra);
}
public static int SearchFor(this Collection<Instruction> collection, OpCode[] opCodes, int startIndex = 0, bool ultraSimplify = false)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
int num = 0;
for (int i = startIndex; i < collection.Count - opCodes.Length; i++)
{
Instruction val = collection[i];
if (val.OpCode.LooseEquals(opCodes[num]))
{
num++;
if (num == opCodes.Length)
{
return i - opCodes.Length + 1;
}
}
else
{
num = 0;
}
}
return -1;
}
}
}