Some mods may be broken due to the recent Alloyed Collective update.
Decompiled source of R2API Core v5.3.0
plugins/R2API.Core/R2API.Core.dll
Decompiled 2 weeks agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Logging; using HG.Reflection; using HarmonyLib; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Cecil.Cil; using MonoMod.Cil; using MonoMod.RuntimeDetour; using MonoMod.Utils; using On.RoR2; using R2API.AutoVersionGen; using R2API.Utils; using RoR2; using RoR2.Networking; using RoR2.UI; using UnityEngine; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: InternalsVisibleTo("R2API.Items")] [assembly: InternalsVisibleTo("R2API.ContentManagement")] [assembly: InternalsVisibleTo("R2API.ArtifactCode")] [assembly: InternalsVisibleTo("R2API.Difficulty")] [assembly: InternalsVisibleTo("R2API.Elites")] [assembly: InternalsVisibleTo("R2API.RecalculateStats")] [assembly: InternalsVisibleTo("R2API.Prefab")] [assembly: InternalsVisibleTo("R2API.Language")] [assembly: InternalsVisibleTo("R2API.Unlockable")] [assembly: InternalsVisibleTo("R2API.TempVisualEffect")] [assembly: InternalsVisibleTo("R2API.SceneAsset")] [assembly: InternalsVisibleTo("R2API.Orb")] [assembly: InternalsVisibleTo("R2API.Loadout")] [assembly: InternalsVisibleTo("R2API.Dot")] [assembly: InternalsVisibleTo("R2API.DamageType")] [assembly: InternalsVisibleTo("R2API.Sound")] [assembly: InternalsVisibleTo("R2API.Director")] [assembly: InternalsVisibleTo("R2API.Deployable")] [assembly: InternalsVisibleTo("R2API.LobbyConfig")] [assembly: InternalsVisibleTo("R2API.Networking")] [assembly: InternalsVisibleTo("R2API.CommandHelper")] [assembly: InternalsVisibleTo("R2API.Colors")] [assembly: InternalsVisibleTo("R2API.Rules")] [assembly: InternalsVisibleTo("R2API.Skins")] [assembly: InternalsVisibleTo("R2API.StringSerializerExtensions")] [assembly: InternalsVisibleTo("R2API.CharacterBody")] [assembly: InternalsVisibleTo("R2API.Teams")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("R2API.Core")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("5.3.0.0")] [assembly: AssemblyInformationalVersion("5.3.0+2598e052d6bdcbb09d1c362d7c32ff182e556924")] [assembly: AssemblyProduct("R2API.Core")] [assembly: AssemblyTitle("R2API.Core")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("5.3.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [module: UnverifiableCode] 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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NativeIntegerAttribute : Attribute { public readonly bool[] TransformFlags; public NativeIntegerAttribute() { TransformFlags = new bool[1] { true }; } public NativeIntegerAttribute(bool[] P_0) { TransformFlags = 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 System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] [ExcludeFromCodeCoverage] [DebuggerNonUserCode] internal sealed class MemberNotNullAttribute : Attribute { public string[] Members { get; } public MemberNotNullAttribute(string member) { Members = new string[1] { member }; } public MemberNotNullAttribute(params string[] members) { Members = members; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] [ExcludeFromCodeCoverage] [DebuggerNonUserCode] internal sealed class MemberNotNullWhenAttribute : Attribute { public bool ReturnValue { get; } public string[] Members { get; } public MemberNotNullWhenAttribute(bool returnValue, string member) { ReturnValue = returnValue; Members = new string[1] { member }; } public MemberNotNullWhenAttribute(bool returnValue, params string[] members) { ReturnValue = returnValue; Members = members; } } } namespace R2API { public class Notification : MonoBehaviour { public GameObject? RootObject { get; set; } public GenericNotification? GenericNotification { get; set; } public Func<string>? GetTitle { get; set; } public Func<string>? GetDescription { get; set; } public Transform? Parent { get; set; } private void Awake() { Parent = ((Component)RoR2Application.instance.mainCanvas).transform; RootObject = Object.Instantiate<GameObject>(Resources.Load<GameObject>("Prefabs/NotificationPanel2")); GenericNotification = RootObject.GetComponent<GenericNotification>(); ((Component)GenericNotification).transform.SetParent(Parent); ((Behaviour)GenericNotification.iconImage).enabled = false; } private void Update() { if ((Object)(object)GenericNotification == (Object)null) { Object.Destroy((Object)(object)this); return; } GenericNotification.titleText.SetFieldValue("resolvedString", GetTitle()); GenericNotification.titleText.InvokeMethod("UpdateLabel"); GenericNotification.descriptionText.SetFieldValue("resolvedString", GetDescription()); GenericNotification.descriptionText.InvokeMethod("UpdateLabel"); } private void OnDestroy() { Object.Destroy((Object)(object)GenericNotification); Object.Destroy((Object)(object)RootObject); } public void SetIcon(Texture? texture) { ((Behaviour)GenericNotification.iconImage).enabled = true; GenericNotification.iconImage.texture = texture; } public void SetPosition(Vector3 position) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) RootObject.transform.position = position; } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("com.bepis.r2api", "R2API", "5.3.0")] [AutoVersion] public class R2API : BaseUnityPlugin { public const string PluginGUID = "com.bepis.r2api"; public const string PluginName = "R2API"; private const string GameBuildId = "1.4.1"; internal static HashSet<string> LoadedSubmodules; private NetworkCompatibilityHandler _networkCompatibilityHandler; public const string PluginVersion = "5.3.0"; internal static ManualLogSource Logger { get; set; } public static bool DebugMode { get; private set; } internal static R2API Instance { get; private set; } internal static event EventHandler R2APIStart; private void Awake() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown Instance = this; Logger = ((BaseUnityPlugin)this).Logger; _networkCompatibilityHandler = new NetworkCompatibilityHandler(); _networkCompatibilityHandler.BuildModList(); RoR2Application.Awake += new hook_Awake(CheckIfUsedOnRightGameVersion); } private void Start() { R2API.R2APIStart?.Invoke(this, null); } private void OnDestroy() { _networkCompatibilityHandler.CleanupModList(); EnumPatcher.UnsetHooks(); } private static void DebugUpdate() { } public static void LogDebug(object debugText, [CallerMemberName] string caller = "") { Logger.LogDebug((object)(caller + " : " + debugText.ToString())); } private void CheckIfUsedOnRightGameVersion(orig_Awake orig, RoR2Application self) { orig.Invoke(self); string version = Application.version; if (!("1.4.1" == version)) { Logger.LogWarning((object)("This version of R2API was built for build id \"1.4.1\", you are running \"" + version + "\".")); Logger.LogWarning((object)"Should any problems arise, please check for a new version before reporting issues."); } } public static bool IsLoaded(string submodule) { if (LoadedSubmodules == null) { Logger.LogWarning((object)"IsLoaded called before submodules were loaded, result may not reflect actual load status."); return false; } return LoadedSubmodules.Contains(submodule); } public static bool SupportsVersion(string? version) { Version version2 = Version.Parse("5.3.0"); Version version3 = Version.Parse(version); if (version2.Major == version3.Major) { return version2.Minor <= version3.Minor; } return false; } } } namespace R2API.AutoVersionGen { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] internal class AutoVersionAttribute : Attribute { } } namespace R2API.MiscHelpers { internal static class ILCursorExtensions { public static ILCursor EmitDel<TDel>(this ILCursor cursor, TDel func) where TDel : Delegate { cursor.EmitDelegate<TDel>(func); return cursor; } } public static class KeyValuePairExtensions { public static void Deconstruct<TKey, TValue>(this KeyValuePair<TKey, TValue> kvp, out TKey key, out TValue value) { key = kvp.Key; value = kvp.Value; } } public delegate T Modifier<T>(T input); internal static class MulticastDelegateExtensions { public static T InvokeSequential<T>(this Modifier<T> func, T initialValue, bool skipErrors = false) { Delegate[] invocationList = func.GetInvocationList(); if (invocationList == null || invocationList.Length <= 1) { return func(initialValue); } foreach (Modifier<T> item in invocationList.Where((Delegate a) => a is Modifier<T>).Cast<Modifier<T>>()) { try { initialValue = item(initialValue); } catch (Exception ex) { if (!skipErrors) { throw ex; } R2API.Logger.LogError((object)ex); } } return initialValue; } public static TOut InvokeSequential<TIn, TOut>(this Func<TIn, TOut> func, TIn initialValue, Func<TOut, TIn> inBetween, bool skipErrors = false) { Delegate[] invocationList = func.GetInvocationList(); if (invocationList == null || invocationList.Length <= 1) { return func(initialValue); } TOut val = default(TOut); bool flag = true; foreach (Func<TIn, TOut> item in invocationList.Where((Delegate a) => a is Func<TIn, TOut>).Cast<Func<TIn, TOut>>()) { if (flag) { try { val = item(initialValue); flag = false; } catch (Exception ex) { if (!skipErrors) { throw ex; } R2API.Logger.LogError((object)ex); } } else { val = item(inBetween(val)); } } return val; } } } namespace R2API.Utils { public static class EnumerableExtensions { public static void ForEachTry<T>(this IEnumerable<T>? list, Action<T>? action, IDictionary<T, Exception?>? exceptions = null) { Action<T> action2 = action; IDictionary<T, Exception?> exceptions2 = exceptions; list.ToList().ForEach(delegate(T element) { try { action2(element); } catch (Exception value) { exceptions2?.Add(element, value); } }); } } [AttributeUsage(AttributeTargets.All, AllowMultiple = true)] [Obsolete("All submodules are automatically loaded and this attribute is now unused.", false)] public class R2APISubmoduleDependency : Attribute { public const string AttributeObsolete = "All submodules are automatically loaded and this attribute is now unused."; public const string PropertyObsolete = "All submodules are automatically loaded and this property is now unused"; public string?[]? SubmoduleNames { get; } public R2APISubmoduleDependency(params string[] submoduleName) { SubmoduleNames = submoduleName; } } public static class CecilUtil { internal static bool IsSubTypeOf(this TypeDefinition typeDefinition, string typeFullName) { if (((MemberReference)typeDefinition).FullName == typeFullName) { return true; } TypeReference baseType = typeDefinition.BaseType; TypeDefinition val = ((baseType != null) ? baseType.Resolve() : null); while (val != null) { if (((MemberReference)val).FullName == typeFullName) { return true; } TypeReference baseType2 = val.BaseType; val = ((baseType2 != null) ? baseType2.Resolve() : null); } return false; } } public static class ChatMessage { public static void Send(string? message) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown SimpleChatMessage val = new SimpleChatMessage(); val.baseToken = "{0}"; val.paramTokens = new string[1] { message }; Chat.SendBroadcastChat((ChatMessageBase)(object)val); } public static void Send(string? message, string? messageFrom) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown SimpleChatMessage val = new SimpleChatMessage(); val.baseToken = "{0}: {1}"; val.paramTokens = new string[2] { messageFrom, message }; Chat.SendBroadcastChat((ChatMessageBase)(object)val); } public static void SendColored(string? message, string? colorHex) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown SimpleChatMessage val = new SimpleChatMessage(); val.baseToken = "<color=" + colorHex + ">{0}</color>"; val.paramTokens = new string[1] { message }; Chat.SendBroadcastChat((ChatMessageBase)(object)val); } public static void SendColored(string? message, ColorIndex color) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) SendColored(message, ColorCatalog.GetColorHexString(color)); } public static void SendColored(string? message, Color color) { SendColored(message, ColorToHexString(color)); } public static void SendColored(string? message, Color color) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) SendColored(message, ColorToHexString(color)); } public static void SendColored(string? message, string? colorHex, string? messageFrom) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown SimpleChatMessage val = new SimpleChatMessage(); val.baseToken = "<color=" + colorHex + ">{0}: {1}</color>"; val.paramTokens = new string[2] { messageFrom, message }; Chat.SendBroadcastChat((ChatMessageBase)(object)val); } public static void SendColored(string? message, ColorIndex color, string? messageFrom) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) SendColored(message, ColorCatalog.GetColorHexString(color), messageFrom); } public static void SendColored(string? message, Color color, string? messageFrom) { SendColored(message, ColorToHexString(color), messageFrom); } public static void SendColored(string? message, Color color, string? messageFrom) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) SendColored(message, ColorToHexString(color), messageFrom); } private static string ColorToHexString(Color c) { return "#" + c.R.ToString("X2") + c.G.ToString("X2") + c.B.ToString("X2"); } private static string ColorToHexString(Color c) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) return "#" + ColorUtility.ToHtmlStringRGB(c); } } internal static class CompressedFlagArrayUtilities { [StructLayout(LayoutKind.Explicit)] [DebuggerDisplay("{ToString()}")] private ref struct FullBlockMask { [FieldOffset(3)] private byte byte0; [FieldOffset(2)] private byte byte1; [FieldOffset(1)] private byte byte2; [FieldOffset(0)] private byte byte3; [FieldOffset(0)] public uint integer; public byte this[int i] { get { if (BitConverter.IsLittleEndian) { return i switch { 0 => byte0, 1 => byte1, 2 => byte2, 3 => byte3, _ => throw new IndexOutOfRangeException(), }; } return i switch { 0 => byte3, 1 => byte2, 2 => byte1, 3 => byte0, _ => throw new IndexOutOfRangeException(), }; } set { if (BitConverter.IsLittleEndian) { switch (i) { case 0: byte0 = value; break; case 1: byte1 = value; break; case 2: byte2 = value; break; case 3: byte3 = value; break; default: throw new IndexOutOfRangeException(); } } else { switch (i) { case 0: byte3 = value; break; case 1: byte2 = value; break; case 2: byte1 = value; break; case 3: byte0 = value; break; default: throw new IndexOutOfRangeException(); } } } } public override string ToString() { return Convert.ToString(integer, 2).PadLeft(32, '0'); } } private static readonly byte[] tempBlockValues = new byte[18]; private static readonly int[] tempBlockPartValuesCounts = new int[4]; public const byte flagsPerValue = 8; public const byte valuesPerBlock = 18; public const byte flagsPerSection = 144; public const byte sectionsCount = 8; public const byte blockPartsCount = 4; private const uint fullBlockHeader = 4218992u; private const uint block1HeaderMask = 64u; private const uint block2HeaderMask = 96u; private const uint block3HeaderMask = 112u; private const uint block4HeaderMask = 120u; private const uint block1HeaderXor = 0u; private const uint block2HeaderXor = 64u; private const uint block3HeaderXor = 96u; private const uint block4HeaderXor = 112u; private const int block1HeaderSkip = 2; private const int block2HeaderSkip = 3; private const int block3HeaderSkip = 4; private const int block4HeaderSkip = 5; private const int block1HeaderValuesCount = 6; private const int block2HeaderValuesCount = 5; private const int block3HeaderValuesCount = 4; private const int block4HeaderValuesCount = 3; private const int block1HeaderOffset = -2; private const int block2HeaderOffset = 3; private const int block3HeaderOffset = 7; private const int block4HeaderOffset = 10; private const uint highestBitInByte = 128u; public static void Add(ref byte[] values, int index) { if (index < 0) { throw new ArgumentOutOfRangeException("index"); } int num = index / 8; int num2 = index - num * 8; ResizeIfNeeded(ref values, num); values[num] = (byte)(values[num] | (128u >> num2)); } public static void AddImmutable(ref byte[] values, int index) { if (index < 0) { throw new ArgumentOutOfRangeException("index"); } int num = index / 8; int num2 = index - num * 8; if (!ResizeIfNeeded(ref values, num)) { byte b = (byte)(values[num] | (128u >> num2)); if (values[num] != b) { byte[] obj = values; values = new byte[values.Length]; obj.CopyTo(values, 0); values[num] = b; } } else { byte b2 = (byte)(128u >> num2); values[num] = b2; } } public static void Add(ref byte[] values, byte[] operand) { ResizeIfNeeded(ref values, operand.Length); for (int i = 0; i < operand.Length; i++) { values[i] |= operand[i]; } } public static bool Remove(ref byte[] values, int index) { if (index < 0) { return false; } int num = index / 8; if (num >= values.Length) { return false; } int num2 = index - num * 8; values[num] = (byte)(values[num] & ~(128 >>> num2)); DownsizeIfNeeded(ref values); return true; } public static bool RemoveImmutable(ref byte[] values, int index) { if (index < 0 || values == null) { return false; } int num = index / 8; if (num >= values.Length) { return false; } int num2 = index - num * 8; byte b = (byte)(values[num] & ~(128 >>> num2)); if (values[num] == b) { return true; } if (b == 0) { DownsizeIgnoreLast(ref values); if (values.Length == 0) { values = null; } } else { byte[] obj = values; values = new byte[values.Length]; obj.CopyTo(values, 0); values[num] = b; } return true; } public static bool Remove(ref byte[] values, byte[] operand) { bool flag = false; int num = Math.Min(values.Length, operand.Length); for (int i = 0; i < num; i++) { flag |= (values[i] & operand[i]) != 0; values[i] &= (byte)(~operand[i]); } DownsizeIfNeeded(ref values); return flag; } public static bool Has(byte[] values, int index) { if (index < 0 || values == null) { return false; } int num = index / 8; if (num >= values.Length) { return false; } int num2 = index - num * 8; return (values[num] & (128 >>> num2)) != 0; } public static byte[] ReadFromNetworkReader(NetworkReader reader, int maxValue) { byte[] values = Array.Empty<byte>(); byte b = reader.ReadByte(); if (b == 0) { return values; } if (maxValue <= 8) { return new byte[1] { b }; } if (maxValue <= 64) { int num = 0; for (int i = 0; i < 8; i++) { if ((b & (1 << i)) != 0) { num = i; tempBlockValues[i] = reader.ReadByte(); } else { tempBlockValues[i] = 0; } } values = new byte[num + 1]; Array.Copy(tempBlockValues, 0, values, 0, num + 1); return values; } for (int j = 0; j < 8; j++) { if ((b & (1 << j)) != 0) { ReadBlock(ref values, reader, j); } } return values; } public static void WriteToNetworkWriter(byte[] values, NetworkWriter writer, int maxValue) { int num = 0; if (maxValue <= 8) { writer.Write((byte)((values.Length != 0) ? values[0] : 0)); return; } if (maxValue <= 64) { int num2 = 0; for (int num3 = Math.Min(8, values.Length) - 1; num3 >= 0; num3--) { num <<= 1; if (values[num3] != 0) { tempBlockValues[num2++] = values[num3]; num |= 1; } } writer.Write((byte)num); for (int num4 = num2 - 1; num4 >= 0; num4--) { writer.Write(tempBlockValues[num4]); } return; } for (int i = 0; i < 8; i++) { if (!IsBlockEmpty(values, i, out var end)) { num |= 1 << i; } if (end) { break; } } writer.Write((byte)num); for (int j = 0; j < 8; j++) { if ((num & (1 << j)) > 0) { WriteBlock(values, writer, j); } } } private static void ReadBlock(ref byte[] values, NetworkReader reader, int blockIndex) { Array.Clear(tempBlockValues, 0, 18); int num = 0; int lastValueIndex = 0; byte b; do { b = reader.ReadByte(); var (num2, num3, fromIndex, valueBitesOffset) = GetMaskValues(num); while (((b & num2) ^ num3) != 0) { (num2, num3, fromIndex, valueBitesOffset) = GetMaskValues(++num); } ReadBlockValues(ref lastValueIndex, valueBitesOffset, fromIndex, 8, reader, b); } while ((b & 0x80) == 0); ResizeIfNeeded(ref values, blockIndex * 18 + lastValueIndex); Array.Copy(tempBlockValues, 0, values, blockIndex * 18, lastValueIndex + 1); } private static void ReadBlockValues(ref int lastValueIndex, int valueBitesOffset, int fromIndex, int toIndex, NetworkReader reader, byte blockByte) { for (int i = fromIndex; i < toIndex; i++) { if ((blockByte & (128u >> i)) != 0) { lastValueIndex = i + valueBitesOffset; tempBlockValues[lastValueIndex] = reader.ReadByte(); } } } private static bool ResizeIfNeeded(ref byte[] values, int valueIndex) { if (values == null) { values = new byte[valueIndex + 1]; return true; } if (valueIndex >= values.Length) { Array.Resize(ref values, valueIndex + 1); return true; } return false; } private static void DownsizeIfNeeded(ref byte[] value) { if (value.Length != 0 && value[value.Length - 1] == 0) { DownsizeIgnoreLast(ref value); } } private static void DownsizeIgnoreLast(ref byte[] value) { for (int num = value.Length - 2; num >= 0; num--) { if (value[num] != 0) { Array.Resize(ref value, num + 1); return; } } value = Array.Empty<byte>(); } private static void WriteBlock(byte[] values, NetworkWriter writer, int blockIndex) { int blockValuesCount = 0; FullBlockMask fullBlockMask = default(FullBlockMask); PrepareBlockValues(values, blockIndex, 0, 6, ref blockValuesCount, ref fullBlockMask); tempBlockPartValuesCounts[0] = blockValuesCount; fullBlockMask.integer <<= 3; PrepareBlockValues(values, blockIndex, 6, 11, ref blockValuesCount, ref fullBlockMask); tempBlockPartValuesCounts[1] = blockValuesCount; fullBlockMask.integer <<= 4; PrepareBlockValues(values, blockIndex, 11, 15, ref blockValuesCount, ref fullBlockMask); tempBlockPartValuesCounts[2] = blockValuesCount; fullBlockMask.integer <<= 5; PrepareBlockValues(values, blockIndex, 15, 18, ref blockValuesCount, ref fullBlockMask); tempBlockPartValuesCounts[3] = blockValuesCount; int num = 0; for (int num2 = 3; num2 > 0; num2--) { if (fullBlockMask[num2] != 0) { num = num2; break; } } fullBlockMask.integer |= 4218992u; fullBlockMask[num] |= 128; int i = 0; for (int j = 0; j <= num; j++) { if (i != tempBlockPartValuesCounts[j]) { writer.Write(fullBlockMask[j]); for (; i < tempBlockPartValuesCounts[j]; i++) { writer.Write(tempBlockValues[i]); } } } } private static void PrepareBlockValues(byte[] values, int blockIndex, int fromIndex, int toIndex, ref int blockValuesCount, ref FullBlockMask fullBlockMask) { for (int i = fromIndex; i < toIndex; i++) { fullBlockMask.integer <<= 1; int num = blockIndex * 18 + i; if (num < values.Length && values[num] != 0) { fullBlockMask.integer |= 1u; tempBlockValues[blockValuesCount++] = values[num]; } } } private static bool IsBlockEmpty(byte[] values, int blockIndex, out bool end) { if (values.Length == 0 || values.Length / 18 < blockIndex) { end = true; return true; } end = false; int num = Math.Min((blockIndex + 1) * 18, values.Length); for (int i = blockIndex * 18; i < num; i++) { if (values[i] != 0) { return false; } } return true; } private static (uint mask, uint xor, int skip, int offset) GetMaskValues(int i) { return i switch { 0 => (64u, 0u, 2, -2), 1 => (96u, 64u, 3, 3), 2 => (112u, 96u, 4, 7), 3 => (120u, 112u, 5, 10), _ => throw new IndexOutOfRangeException(), }; } } public static class DirectMessage { private static NetworkUser[] GetConnectionNetworkUsers(NetworkConnection conn) { List<PlayerController> playerControllers = conn.playerControllers; NetworkUser[] array = (NetworkUser[])(object)new NetworkUser[playerControllers.Count]; for (int i = 0; i < playerControllers.Count; i++) { array[i] = playerControllers[i].gameObject.GetComponent<NetworkUser>(); } return array; } private static NetworkConnection ResolveUserToConnection(NetworkUser user) { foreach (NetworkConnection connection in NetworkServer.connections) { if (connection == null) { continue; } NetworkUser[] connectionNetworkUsers = GetConnectionNetworkUsers(connection); foreach (NetworkUser obj in connectionNetworkUsers) { if (((object)user).Equals((object?)obj)) { return connection; } } } return null; } public static void SendDirectMessage(string? message, NetworkConnection? connection) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown SimpleChatMessage val = new SimpleChatMessage(); val.baseToken = "{0}"; val.paramTokens = new string[1] { message }; SendDirectMessage((ChatMessageBase)(object)val, connection); } public static void SendDirectMessage(string? message, NetworkUser? user) { SendDirectMessage(message, ResolveUserToConnection(user)); } public static void SendDirectMessage(ChatMessageBase message, NetworkConnection? connection) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown NetworkWriter val = new NetworkWriter(); val.StartMessage((short)59); val.Write(message.GetTypeIndex()); val.Write((MessageBase)(object)message); val.FinishMessage(); connection.SendWriter(val, QosChannelIndex.chat.intVal); } } internal static class DirectoryUtilities { private static bool _alreadyPrintedFolderStructure; private static bool _bepinexFolderPrinted; private static readonly HashSet<string> BannedFolders = new HashSet<string> { "MonoBleedingEdge", "Risk of Rain 2_Data" }; internal static void LogFolderStructureAsTree(string directory) { if (!_alreadyPrintedFolderStructure) { WriteFolderStructure(directory); if (!_bepinexFolderPrinted) { WriteFolderStructure(Paths.BepInExRootPath); } _alreadyPrintedFolderStructure = true; } } private static void WriteFolderStructure(string directory) { R2API.Logger.LogDebug((object)""); R2API.Logger.LogDebug((object)("+ " + new DirectoryInfo(directory).Name)); string[] directories = Directory.GetDirectories(directory); for (int i = 0; i < directories.Length; i++) { WriteFolderStructureRecursively(directories[i]); } string[] files = Directory.GetFiles(directory); for (int j = 1; j <= files.Length; j++) { FileInfo fileInfo = new FileInfo(files[j - 1]); R2API.Logger.LogDebug((object)(GenerateSpaces(0) + ((j != files.Length) ? "|" : "`") + "---- " + fileInfo.Name + " (" + ParseSize(fileInfo.Length) + ")")); } } private static void WriteFolderStructureRecursively(string directory, int spaces = 0) { DirectoryInfo directoryInfo = new DirectoryInfo(directory); R2API.Logger.LogDebug((object)(GenerateSpaces(spaces) + "|---+ " + directoryInfo.Name)); if (!_bepinexFolderPrinted && Paths.BepInExRootPath == directory) { _bepinexFolderPrinted = true; } if (directoryInfo.Parent != null && (BannedFolders.Contains(directoryInfo.Name) || BannedFolders.Contains(directoryInfo.Parent.Name + "/" + directoryInfo.Name))) { R2API.Logger.LogDebug((object)(GenerateSpaces(spaces + 4) + "`---- (Folder content not shown)")); return; } string[] directories = Directory.GetDirectories(directory); for (int i = 0; i < directories.Length; i++) { WriteFolderStructureRecursively(directories[i], spaces + 4); } string[] files = Directory.GetFiles(directory); for (int j = 1; j <= files.Length; j++) { FileInfo fileInfo = new FileInfo(files[j - 1]); R2API.Logger.LogDebug((object)(GenerateSpaces(spaces + 4) + ((j != files.Length) ? "|" : "`") + "---- " + fileInfo.Name + " (" + ParseSize(fileInfo.Length) + ")")); } } private static string ParseSize(long lSize) { string[] array = new string[4] { "B", "KB", "MB", "GB" }; float num = lSize; int num2 = 0; while (num > 1024f) { num2++; num /= 1024f; } return num.ToString("F2") + array[num2]; } private static string GenerateSpaces(int spaces) { string text = ""; for (int i = 1; i <= spaces; i += 4) { text += "| "; } return text; } } public static class EmbeddedResources { private unsafe static readonly delegate*<Assembly, string, out int, out Module, nint> GetManifestResourceInternal = (delegate*<Assembly, string, out int, out Module, nint>)(void*)typeof(R2API).Assembly.GetType().GetMethod("GetManifestResourceInternal", (BindingFlags)(-1)).MethodHandle.GetFunctionPointer(); [MethodImpl(MethodImplOptions.NoInlining)] public unsafe static (nint ptr, int size) GetEmbeddedResource(string resourceName, Assembly? owningAssembly = null) { if ((object)owningAssembly == null) { owningAssembly = Assembly.GetCallingAssembly(); } int item = default(int); Module module = default(Module); return (GetManifestResourceInternal(owningAssembly, resourceName, out item, out module), item); } } internal static class EnumPatcher { private class EnumData { private readonly struct EnumValueEntry { public readonly string Name; public readonly ulong Value; public readonly EnumValueHandle Handle; internal EnumValueEntry(string name, ulong value, EnumValueHandle handle) { Name = name; Value = value; Handle = handle; } } private const int EntriesCapacityIncrement = 4; private readonly Type _underlyingType; private readonly bool _isUnderlyingTypeUnsigned; private ulong _nextEntryHandle = 1uL; private string[] _baseNames; private ulong[] _baseValues; private int _entriesCount; private EnumValueEntry[] _entries = new EnumValueEntry[4]; private bool _combinedValuesDirty; private string[] _cachedCombinedNames; private ulong[] _cachedCombinedValues; public Type Type { get; } public int EntryCount => _entriesCount; internal EnumData(Type type) { Type = type; _underlyingType = Type.GetEnumUnderlyingType(); bool isUnderlyingTypeUnsigned; switch (System.Type.GetTypeCode(_underlyingType)) { case TypeCode.Byte: case TypeCode.UInt16: case TypeCode.UInt32: case TypeCode.UInt64: isUnderlyingTypeUnsigned = true; break; default: isUnderlyingTypeUnsigned = false; break; } _isUnderlyingTypeUnsigned = isUnderlyingTypeUnsigned; } private void EnsureDesiredEntriesCapacity() { int num = (_entriesCount / 4 + 1) * 4; if (_entries.Length != num) { Array.Resize(ref _entries, num); } } internal ulong ToUInt64(object value) { if (_isUnderlyingTypeUnsigned) { return Convert.ToUInt64(value); } return (ulong)Convert.ToInt64(value); } internal object ToEnumValue(ulong value) { if (_isUnderlyingTypeUnsigned) { return Convert.ChangeType(value, _underlyingType); } return Convert.ChangeType((long)value, _underlyingType); } internal EnumValueHandle AddEntry(string name, object value) { EnsureDesiredEntriesCapacity(); EnumValueHandle enumValueHandle = new EnumValueHandle(Type, _nextEntryHandle++); _entries[_entriesCount++] = new EnumValueEntry(name, ToUInt64(value), enumValueHandle); _combinedValuesDirty = true; return enumValueHandle; } private void RemoveEntryAt(int entryIndex) { Array.Copy(_entries, entryIndex + 1, _entries, entryIndex, _entriesCount - entryIndex - 1); _entriesCount--; } internal void RemoveEntry(in EnumValueHandle handle) { for (int i = 0; i < _entriesCount; i++) { if (_entries[i].Handle.Value == handle.Value) { RemoveEntryAt(i); break; } } EnsureDesiredEntriesCapacity(); } internal bool IsHandleValid(in EnumValueHandle handle) { for (int i = 0; i < _entriesCount; i++) { if (_entries[i].Handle.Value == handle.Value) { return true; } } return false; } internal void ModifyEnumValues(ref string[] names, ref ulong[] values) { if (_entriesCount > 0) { if (_baseNames == null || _baseValues == null) { _baseNames = names; _baseValues = values; _combinedValuesDirty = true; } if (_combinedValuesDirty) { _combinedValuesDirty = false; RecalculateCombinedValues(); } names = _cachedCombinedNames; values = _cachedCombinedValues; } } private void RecalculateCombinedValues() { int num = _baseValues.Length; for (int i = 0; i < _entriesCount; i++) { if (Array.BinarySearch(_baseValues, _entries[i].Value) < 0) { num++; } } if (_cachedCombinedNames == null || _cachedCombinedNames.Length != num) { _cachedCombinedNames = new string[num]; _cachedCombinedValues = new ulong[num]; } Array.Copy(_baseValues, _cachedCombinedValues, _baseValues.Length); Array.Copy(_baseNames, _cachedCombinedNames, _baseNames.Length); int num2 = _baseValues.Length; for (int j = 0; j < _entriesCount; j++) { int num3 = Array.BinarySearch(_baseValues, _entries[j].Value); if (num3 >= 0) { _cachedCombinedValues[num3] = _entries[j].Value; _cachedCombinedNames[num3] = _entries[j].Name; } else { _cachedCombinedValues[num2] = _entries[j].Value; _cachedCombinedNames[num2] = _entries[j].Name; num2++; } } Array.Sort(_cachedCombinedValues, _cachedCombinedNames); } } public readonly struct EnumValueHandle { internal readonly Type EnumType; internal readonly ulong Value; internal EnumValueHandle(Type enumType, ulong value) { EnumType = enumType; Value = value; } } [CompilerGenerated] private static class <>O { public static Manipulator <0>__AppendEnumValuesAndNamesHook; public static <>A{00000048}<Type, ulong[], string[]> <1>__modifyEnumValues; } private static readonly Dictionary<Type, EnumData> _enumDataByType = new Dictionary<Type, EnumData>(); private static readonly List<IDetour> _hookInstances = new List<IDetour>(); private static bool _hooksEnabled; internal static void SetHooks() { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown if (_hooksEnabled) { return; } MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(Enum), "GetCachedValuesAndNames", (Type[])null, (Type[])null); if (methodInfo != null) { List<IDetour> hookInstances = _hookInstances; object obj = <>O.<0>__AppendEnumValuesAndNamesHook; if (obj == null) { Manipulator val = AppendEnumValuesAndNamesHook; <>O.<0>__AppendEnumValuesAndNamesHook = val; obj = (object)val; } hookInstances.Add((IDetour)new ILHook((MethodBase)methodInfo, (Manipulator)obj)); } _hooksEnabled = true; } internal static void UnsetHooks() { if (!_hooksEnabled) { return; } foreach (IDetour hookInstance in _hookInstances) { ((IDisposable)hookInstance)?.Dispose(); } _hookInstances.Clear(); _hooksEnabled = false; } private static void AppendEnumValuesAndNamesHook(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: 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_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); TypeReference returnType = ((MethodReference)il.Method).ReturnType; TypeDefinition val2 = Extensions.SafeResolve(returnType); if (val2 == null) { R2API.Logger.LogError((object)("EnumPatcher.AppendEnumValuesAndNamesHook: Failed to resolve return type of " + ((MemberReference)il.Method).FullName)); return; } FieldDefinition val3 = Extensions.FindField(val2, "Values"); if (val3 == null) { R2API.Logger.LogError((object)("EnumPatcher.AppendEnumValuesAndNamesHook (" + ((MemberReference)il.Method).FullName + "): Failed to find Values field")); return; } FieldDefinition val4 = Extensions.FindField(val2, "Names"); if (val4 == null) { R2API.Logger.LogError((object)("EnumPatcher.AppendEnumValuesAndNamesHook (" + ((MemberReference)il.Method).FullName + "): Failed to find Names field")); return; } VariableDefinition val5 = new VariableDefinition(returnType); il.Method.Body.Variables.Add(val5); while (val.TryGotoNext((MoveType)1, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchRet(x) })) { ILLabel val6 = val.DefineLabel(); val.Emit(OpCodes.Stloc, val5); val.Emit(OpCodes.Ldloc, val5); val.Emit(OpCodes.Brfalse, (object)val6); val.Emit(OpCodes.Ldarg_0); val.Emit(OpCodes.Ldloc, val5); val.Emit(OpCodes.Ldflda, (FieldReference)(object)val3); val.Emit(OpCodes.Ldloc, val5); val.Emit(OpCodes.Ldflda, (FieldReference)(object)val4); val.EmitDelegate<<>A{00000048}<Type, ulong[], string[]>>((<>A{00000048}<Type, ulong[], string[]>)modifyEnumValues); val.MarkLabel(val6); val.Emit(OpCodes.Ldloc, val5); val.SearchTarget = (SearchTarget)1; } static void modifyEnumValues(Type enumType, ref ulong[] values, ref string[] names) { if (_enumDataByType.TryGetValue(enumType, out EnumData value)) { value.ModifyEnumValues(ref names, ref values); } } } public static EnumValueHandle SetEnumValue<TEnum>(string name, TEnum value) where TEnum : Enum { return SetEnumValue(typeof(TEnum), name, value); } public static EnumValueHandle SetEnumValue(Type enumType, string name, object enumValue) { if ((object)enumType == null) { throw new ArgumentNullException("enumType"); } if (string.IsNullOrEmpty(name)) { throw new ArgumentException("'name' cannot be null or empty.", "name"); } if (enumValue == null) { throw new ArgumentNullException("enumValue"); } if (!enumType.IsEnum) { throw new ArgumentException("'enumType' must be an enum type", "enumType"); } if (!enumType.IsAssignableFrom(enumValue.GetType())) { throw new ArgumentException("'enumValue' must be of type 'enumType'"); } SetHooks(); if (!_enumDataByType.TryGetValue(enumType, out EnumData value)) { value = new EnumData(enumType); _enumDataByType.Add(enumType, value); } return value.AddEntry(name, enumValue); } public static void RemoveEnumValueEntry(in EnumValueHandle handle) { if (IsValid(in handle) && _enumDataByType.TryGetValue(handle.EnumType, out EnumData value)) { value.RemoveEntry(in handle); if (value.EntryCount <= 0) { _enumDataByType.Remove(handle.EnumType); } } } public static bool IsValid(in EnumValueHandle handle) { if (handle.EnumType == null || handle.Value == 0L) { return false; } if (_enumDataByType.TryGetValue(handle.EnumType, out EnumData value)) { return value.IsHandleValid(in handle); } return false; } } public static class ManualLogSourceExtension { public static void LogBlockError(this ManualLogSource? logger, IEnumerable<string?>? lines, int width = 70) { logger.LogBlock((LogLevel)2, "ERROR", lines, width); } public static void LogBlockWarning(this ManualLogSource? logger, IEnumerable<string?>? lines, int width = 70) { logger.LogBlock((LogLevel)4, "WARNING", lines, width); } public static void LogBlock(this ManualLogSource? logger, LogLevel level, string? header, IEnumerable<string?>? lines, int width = 70) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) ManualLogSource logger2 = logger; string text = new string('*', width + 2); string text2 = CenterText("", width); logger2.Log(level, (object)text); logger2.Log(level, (object)text2); logger2.Log(level, (object)CenterText("!" + header + "!", width)); lines.ToList().ForEach(delegate(string x) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) logger2.Log(level, (object)CenterText(x, width)); }); logger2.Log(level, (object)text2); logger2.Log(level, (object)text); } public static string CenterText(string? text = "", int width = 70) { return string.Format("*{0," + (width / 2 + text.Length / 2) + "}{1," + (width / 2 - text.Length / 2) + "}*", text, " "); } } public enum CompatibilityLevel { NoNeedForSync, EveryoneMustHaveMod } public enum VersionStrictness { DifferentModVersionsAreOk, EveryoneNeedSameModVersion } [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class)] public class NetworkCompatibility : Attribute { public CompatibilityLevel CompatibilityLevel { get; internal set; } public VersionStrictness VersionStrictness { get; internal set; } public NetworkCompatibility(CompatibilityLevel compatibility = CompatibilityLevel.EveryoneMustHaveMod, VersionStrictness versionStrictness = VersionStrictness.EveryoneNeedSameModVersion) { CompatibilityLevel = compatibility; VersionStrictness = versionStrictness; } } internal class NetworkCompatibilityHandler { internal const char ModGuidAndModVersionSeparator = ';'; internal readonly HashSet<string> ModList = new HashSet<string>(); internal void BuildModList() { R2API.R2APIStart += ScanPluginsForNetworkCompat; } internal void CleanupModList() { if (NetworkModCompatibilityHelper.networkModList != null && NetworkModCompatibilityHelper.networkModList.Count() > 0) { List<string> list = NetworkModCompatibilityHelper.networkModList.ToList(); list.RemoveAll(ModList.Contains); NetworkModCompatibilityHelper.networkModList = list; } } private void ScanPluginsForNetworkCompat(object? _, EventArgs __) { foreach (var (_, val2) in Chainloader.PluginInfos) { try { string gUID = val2.Metadata.GUID; Version version = val2.Metadata.Version; if (!gUID.StartsWith("com.bepis.r2api") && !val2.Dependencies.All((BepInDependency dependency) => !dependency.DependencyGUID.StartsWith("com.bepis.r2api") || (int)dependency.Flags == 2)) { TryGetNetworkCompatibility(((object)val2.Instance).GetType(), out NetworkCompatibility networkCompatibility); if (networkCompatibility.CompatibilityLevel == CompatibilityLevel.EveryoneMustHaveMod) { ModList.Add((networkCompatibility.VersionStrictness == VersionStrictness.EveryoneNeedSameModVersion) ? (gUID + ";" + version) : gUID); } } } catch (Exception ex) { R2API.Logger.LogError((object)("Exception in ScanPluginsForNetworkCompat while scanning plugin " + val2.Metadata.GUID)); R2API.Logger.LogError((object)("R2API Failed to properly scan the assembly." + Environment.NewLine + "Please make sure you are compiling against net standard 2.0 and not anything else when making a plugin for Risk of Rain 2 !" + Environment.NewLine + ex)); } } AddToNetworkModList(); R2API.R2APIStart -= ScanPluginsForNetworkCompat; } private static void TryGetNetworkCompatibility(Type baseUnityPluginType, out NetworkCompatibility networkCompatibility) { networkCompatibility = new NetworkCompatibility(); foreach (CustomAttributeData customAttribute in baseUnityPluginType.Assembly.CustomAttributes) { if (customAttribute.AttributeType == typeof(NetworkCompatibility)) { networkCompatibility.CompatibilityLevel = (CompatibilityLevel)customAttribute.ConstructorArguments[0].Value; networkCompatibility.VersionStrictness = (VersionStrictness)customAttribute.ConstructorArguments[1].Value; return; } } foreach (CustomAttributeData customAttribute2 in baseUnityPluginType.CustomAttributes) { if (customAttribute2.AttributeType == typeof(NetworkCompatibility)) { networkCompatibility.CompatibilityLevel = (CompatibilityLevel)customAttribute2.ConstructorArguments[0].Value; networkCompatibility.VersionStrictness = (VersionStrictness)customAttribute2.ConstructorArguments[1].Value; break; } } } private void AddToNetworkModList() { if (ModList.Count == 0) { return; } List<string> list = ModList.ToList(); list.Sort(StringComparer.InvariantCulture); R2API.Logger.LogInfo((object)"[NetworkCompatibility] Adding to the networkModList : "); foreach (string item in list) { R2API.Logger.LogInfo((object)item); NetworkModCompatibilityHelper.networkModList = NetworkModCompatibilityHelper.networkModList.Append(item); } } } public static class Reflection { public delegate T GetDelegate<out T>(object? instance); public delegate void SetDelegate<in T>(object? instance, T value); public delegate void SetDelegateRef<TInstance, in TValue>(ref TInstance instance, TValue value) where TInstance : struct; public delegate T GetDelegateRef<TInstance, out T>(ref TInstance instance) where TInstance : struct; private const BindingFlags AllFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; private static readonly Dictionary<(Type T, string name), FieldInfo> FieldCache = new Dictionary<(Type, string), FieldInfo>(); private static readonly Dictionary<(Type T, string name, Type TReturn), Delegate> FieldGetDelegateCache = new Dictionary<(Type, string, Type), Delegate>(); private static readonly Dictionary<(Type T, string name, Type TValue), Delegate> FieldSetDelegateCache = new Dictionary<(Type, string, Type), Delegate>(); private static readonly Dictionary<(Type T, string name), PropertyInfo> PropertyCache = new Dictionary<(Type, string), PropertyInfo>(); private static readonly Dictionary<(Type T, string name, Type TInstance, Type TReturn), Delegate> PropertyGetDelegateCache = new Dictionary<(Type, string, Type, Type), Delegate>(); private static readonly Dictionary<(Type T, string name, Type TInstance, Type TValue), Delegate> PropertySetDelegateCache = new Dictionary<(Type, string, Type, Type), Delegate>(); private static readonly Dictionary<(Type T, string name), MethodInfo> MethodCache = new Dictionary<(Type, string), MethodInfo>(); private static readonly Dictionary<(Type T, string name, long argumentTypesHashCode), MethodInfo> OverloadedMethodCache = new Dictionary<(Type, string, long), MethodInfo>(); private static readonly Dictionary<(Type T, string name), FastReflectionDelegate> MethodDelegateCache = new Dictionary<(Type, string), FastReflectionDelegate>(); private static readonly Dictionary<(Type T, string name, long argumentTypesHashCode), FastReflectionDelegate> OverloadedMethodDelegateCache = new Dictionary<(Type, string, long), FastReflectionDelegate>(); private static readonly Dictionary<(Type T, long argumentTypesHashCode), ConstructorInfo> ConstructorCache = new Dictionary<(Type, long), ConstructorInfo>(); private static readonly Dictionary<(Type T, string name), Type> NestedTypeCache = new Dictionary<(Type, string), Type>(); public static long CombineHashCode<T>(IEnumerable<T> enumerable) { long num = 0L; foreach (T item in enumerable) { num = num * 486187739 + EqualityComparer<T>.Default.GetHashCode(item); } return num; } public static FieldInfo GetFieldCached<T>(string? name) { return typeof(T).GetFieldCached(name); } public static FieldInfo GetFieldCached(this Type? T, string? name) { if (FieldCache.TryGetValue((T, name), out FieldInfo value)) { return value; } return FieldCache[(T, name)] = T.GetFieldFull(name); } public static TReturn GetFieldValue<TReturn>(this object? instance, string? fieldName) { return instance.GetType().GetFieldGetDelegate<TReturn>(fieldName)(instance); } public static TReturn GetFieldValue<TReturn>(this Type? staticType, string? fieldName) { return staticType.GetFieldGetDelegate<TReturn>(fieldName)(null); } public static void SetFieldValue<TValue>(this object? instance, string? fieldName, TValue value) { instance.GetType().GetFieldSetDelegate<TValue>(fieldName)(instance, value); } public static void SetFieldValue<TValue>(this Type? staticType, string? fieldName, TValue value) { staticType.GetFieldSetDelegate<TValue>(fieldName)(null, value); } public static void SetStructFieldValue<TInstance, TValue>(this ref TInstance instance, string? fieldName, TValue value) where TInstance : struct { typeof(TInstance).GetFieldSetDelegateRef<TInstance, TValue>(fieldName)(ref instance, value); } private static FieldInfo GetFieldFull(this Type T, string name) { while (T != null) { FieldInfo field = T.GetField(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { return field; } T = T.BaseType; } return null; } public static GetDelegate<TReturn> GetFieldGetDelegate<TReturn>(this Type type, string? fieldName) { if (FieldGetDelegateCache.TryGetValue((type, fieldName, typeof(TReturn)), out Delegate value)) { return (GetDelegate<TReturn>)value; } Delegate delegate2 = (FieldGetDelegateCache[(type, fieldName, typeof(TReturn))] = type.GetFieldCached(fieldName).CreateGetDelegate<TReturn>()); return (GetDelegate<TReturn>)delegate2; } public static SetDelegate<TValue> GetFieldSetDelegate<TValue>(this Type type, string? fieldName) { if (FieldSetDelegateCache.TryGetValue((type, fieldName, typeof(TValue)), out Delegate value)) { return (SetDelegate<TValue>)value; } Delegate delegate2 = (FieldSetDelegateCache[(type, fieldName, typeof(TValue))] = type.GetFieldCached(fieldName).CreateSetDelegate<TValue>()); return (SetDelegate<TValue>)delegate2; } public static SetDelegateRef<TInstance, TValue> GetFieldSetDelegateRef<TInstance, TValue>(this Type type, string? fieldName) where TInstance : struct { if (FieldSetDelegateCache.TryGetValue((type, fieldName, typeof(TValue)), out Delegate value)) { return (SetDelegateRef<TInstance, TValue>)value; } Delegate delegate2 = (FieldSetDelegateCache[(type, fieldName, typeof(TValue))] = type.GetFieldCached(fieldName).CreateSetDelegateRef<TInstance, TValue>()); return (SetDelegateRef<TInstance, TValue>)delegate2; } public static PropertyInfo GetPropertyCached<T>(string? name) { return typeof(T).GetPropertyCached(name); } public static PropertyInfo GetPropertyCached(this Type? T, string? name) { if (PropertyCache.TryGetValue((T, name), out PropertyInfo value)) { return value; } return PropertyCache[(T, name)] = T.GetProperty(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); } public static TReturn GetPropertyValue<TReturn>(this object? instance, string? propName) { return instance.GetType().GetPropertyGetDelegate<TReturn>(propName)(instance); } public static TReturn GetPropertyValue<TReturn>(this Type? staticType, string? propName) { return staticType.GetPropertyGetDelegate<TReturn>(propName)(null); } public static void SetPropertyValue<TValue>(this object? instance, string? propName, TValue value) { instance.GetType().GetPropertySetDelegate<TValue>(propName)(instance, value); } public static void SetPropertyValue<TValue>(this Type? staticType, string? propName, TValue value) { staticType.GetPropertySetDelegate<TValue>(propName)(null, value); } public static void SetStructPropertyValue<TInstance, TValue>(this ref TInstance instance, string? propName, TValue value) where TInstance : struct { typeof(TInstance).GetPropertySetDelegateRef<TInstance, TValue>(propName)(ref instance, value); } public static TValue GetStructPropertyValue<TInstance, TValue>(this ref TInstance instance, string? propName) where TInstance : struct { return typeof(TInstance).GetPropertyGetDelegateRef<TInstance, TValue>(propName)(ref instance); } public static MethodInfo GetPropertyGetter(this Type type, string propName) { return type.GetProperty(propName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).GetGetMethod(nonPublic: true); } public static MethodInfo GetPropertySetter(this Type type, string propName) { return type.GetProperty(propName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).GetSetMethod(nonPublic: true); } public static GetDelegate<TReturn> GetPropertyGetDelegate<TReturn>(this Type type, string? propName) { if (PropertyGetDelegateCache.TryGetValue((type, propName, typeof(object), typeof(TReturn)), out Delegate value)) { return (GetDelegate<TReturn>)value; } Delegate delegate2 = (PropertyGetDelegateCache[(type, propName, typeof(object), typeof(TReturn))] = type.GetPropertyCached(propName).CreateGetDelegate<TReturn>()); return (GetDelegate<TReturn>)delegate2; } public static GetDelegateRef<TInstance, TReturn> GetPropertyGetDelegateRef<TInstance, TReturn>(this Type type, string? propName) where TInstance : struct { if (PropertyGetDelegateCache.TryGetValue((type, propName, typeof(TInstance), typeof(TReturn)), out Delegate value)) { return (GetDelegateRef<TInstance, TReturn>)value; } Delegate delegate2 = (PropertyGetDelegateCache[(type, propName, typeof(TInstance), typeof(TReturn))] = type.GetPropertyCached(propName).CreateGetDelegate<TInstance, TReturn>()); return (GetDelegateRef<TInstance, TReturn>)delegate2; } public static SetDelegate<TValue> GetPropertySetDelegate<TValue>(this Type type, string? propName) { if (PropertySetDelegateCache.TryGetValue((type, propName, typeof(object), typeof(TValue)), out Delegate value)) { return (SetDelegate<TValue>)value; } Delegate delegate2 = (PropertySetDelegateCache[(type, propName, typeof(object), typeof(TValue))] = type.GetPropertyCached(propName).CreateSetDelegate<TValue>()); return (SetDelegate<TValue>)delegate2; } private static SetDelegateRef<TInstance, TValue> GetPropertySetDelegateRef<TInstance, TValue>(this Type type, string? propName) where TInstance : struct { if (PropertySetDelegateCache.TryGetValue((type, propName, typeof(TInstance), typeof(TValue)), out Delegate value)) { return (SetDelegateRef<TInstance, TValue>)value; } Delegate delegate2 = (PropertySetDelegateCache[(type, propName, typeof(TInstance), typeof(TValue))] = type.GetPropertyCached(propName).CreateSetDelegateRef<TInstance, TValue>()); return (SetDelegateRef<TInstance, TValue>)delegate2; } public static MethodInfo GetMethodCached<T>(string? name) { return typeof(T).GetMethodCached(name); } public static MethodInfo GetMethodCached(this Type? T, string? name) { if (MethodCache.TryGetValue((T, name), out MethodInfo value)) { return value; } return MethodCache[(T, name)] = T.GetMethod(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); } public static MethodInfo GetMethodWithConstructedGenericParameter(this Type? T, string? name, Type? genericTypeDefinition) { string name2 = name; Type genericTypeDefinition2 = genericTypeDefinition; return T.GetMethods().First(delegate(MethodInfo method) { if (method.Name != name2) { return false; } Type parameterType = method.GetParameters().First().ParameterType; if (!parameterType.IsConstructedGenericType) { return false; } Type type = parameterType.GetGenericArguments().First(); return parameterType == genericTypeDefinition2.MakeGenericType(type); }); } public static MethodInfo GetMethodCached<T>(string? name, Type?[]? argumentTypes) { return typeof(T).GetMethodCached(name, argumentTypes); } public static MethodInfo GetMethodCached(this Type? T, string? name, Type?[]? argumentTypes) { (Type, string, long) key = (T, name, CombineHashCode(argumentTypes)); if (OverloadedMethodCache.TryGetValue(key, out MethodInfo value)) { return value; } return OverloadedMethodCache[key] = T.GetMethod(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, argumentTypes, null); } public static TReturn InvokeMethod<TReturn>(this object? instance, string? methodName) { return instance.InvokeMethod<TReturn>(methodName, null); } public static TReturn InvokeMethod<TReturn>(this Type? staticType, string? methodName) { return staticType.InvokeMethod<TReturn>(methodName, null); } public static void InvokeMethod(this object? instance, string? methodName) { instance.InvokeMethod<object>(methodName); } public static void InvokeMethod(this Type? staticType, string? methodName) { staticType.InvokeMethod<object>(methodName); } public static TReturn InvokeMethod<TReturn>(this object? instance, string? methodName, params object?[]? methodParams) { if (methodParams == null) { return (TReturn)instance.GetType().GetMethodDelegateCached(methodName).Invoke(instance, methodParams); } return (TReturn)instance.GetType().GetMethodDelegateCached(methodName, methodParams.Select((object x) => x.GetType()).ToArray()).Invoke(instance, methodParams); } public static TReturn InvokeMethod<TReturn>(this Type? staticType, string? methodName, params object?[]? methodParams) { if (methodParams == null) { return (TReturn)staticType.GetMethodDelegateCached(methodName).Invoke((object)null, methodParams); } return (TReturn)staticType.GetMethodDelegateCached(methodName, methodParams.Select((object x) => x.GetType()).ToArray()).Invoke((object)null, methodParams); } public static void InvokeMethod(this object? instance, string? methodName, params object?[]? methodParams) { instance.InvokeMethod<object>(methodName, methodParams); } public static void InvokeMethod(this Type? staticType, string? methodName, params object?[]? methodParams) { staticType.InvokeMethod<object>(methodName, methodParams); } public static FastReflectionDelegate GetMethodDelegateCached(this Type type, string? methodName) { if (MethodDelegateCache.TryGetValue((type, methodName), out FastReflectionDelegate value)) { return value; } return MethodDelegateCache[(type, methodName)] = type.GetMethodCached(methodName).GenerateCallDelegate(); } public static FastReflectionDelegate GetMethodDelegateCached(this Type type, string? methodName, Type[] argumentTypes) { (Type, string, long) key = (type, methodName, CombineHashCode(argumentTypes)); if (OverloadedMethodDelegateCache.TryGetValue(key, out FastReflectionDelegate value)) { return value; } return OverloadedMethodDelegateCache[key] = type.GetMethodCached(methodName, argumentTypes).GenerateCallDelegate(); } public static ConstructorInfo GetConstructorCached<T>(Type?[]? argumentTypes) { return typeof(T).GetConstructorCached(argumentTypes); } public static ConstructorInfo GetConstructorCached(this Type? T, Type?[]? argumentTypes) { (Type, long) key = (T, CombineHashCode(argumentTypes)); if (ConstructorCache.TryGetValue(key, out ConstructorInfo value)) { return value; } return ConstructorCache[key] = T.GetConstructor(argumentTypes); } public static Type GetNestedType<T>(string? name) { return typeof(T).GetNestedTypeCached(name); } public static Type GetNestedTypeCached<T>(string? name) { return typeof(T).GetNestedTypeCached(name); } public static Type GetNestedTypeCached(this Type? T, string? name) { if (NestedTypeCache.TryGetValue((T, name), out Type value)) { return value; } return NestedTypeCache[(T, name)] = T.GetNestedType(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); } public static object Instantiate(this Type? type) { return Activator.CreateInstance(type, nonPublic: true); } public static object Instantiate(this Type? type, params object?[]? constructorArguments) { return type.GetConstructorCached(constructorArguments.Select((object x) => x.GetType()).ToArray()).Invoke(constructorArguments); } public static object InstantiateGeneric<TClass>(this Type? typeArgument) { return typeof(TClass).MakeGenericType(typeArgument).Instantiate(); } public static object InstantiateGeneric<TClass>(this Type?[]? typeArgument) { return typeof(TClass).MakeGenericType(typeArgument).Instantiate(); } public static IList InstantiateList(this Type? type) { return (IList)typeof(List<>).MakeGenericType(type).Instantiate(); } private static FieldInfo ThrowIfFieldTypeCannotBeAssignedTo<T>(this FieldInfo fieldInfo) { if (!typeof(T).IsAssignableFrom(fieldInfo.FieldType)) { throw new InvalidCastException($"{fieldInfo.Name} is of type {fieldInfo.FieldType}, it cannot be assigned to the type {typeof(T)}."); } return fieldInfo; } private static PropertyInfo ThrowIfPropertyTypeCannotBeAssignedTo<T>(this PropertyInfo propertyInfo) { if (!typeof(T).IsAssignableFrom(propertyInfo.PropertyType)) { throw new InvalidCastException($"{propertyInfo.Name} is of type {propertyInfo.PropertyType}, it cannot be assigned to the type {typeof(T)}."); } return propertyInfo; } private static FieldInfo ThrowIfTCannotBeAssignedToField<T>(this FieldInfo fieldInfo) { if (!fieldInfo.FieldType.IsAssignableFrom(typeof(T))) { throw new InvalidCastException($"{fieldInfo.Name} is of type {fieldInfo.FieldType}. An instance of {typeof(T)} cannot be assigned to it."); } return fieldInfo; } private static FieldInfo ThrowIfFieldIsConst(this FieldInfo fieldInfo) { if (fieldInfo.IsLiteral && !fieldInfo.IsInitOnly) { throw new FieldAccessException("Unable to set constant field " + fieldInfo.Name + " of type " + fieldInfo.DeclaringType.FullName + "."); } return fieldInfo; } private static PropertyInfo ThrowIfTCannotBeAssignedToProperty<T>(this PropertyInfo propertyInfo) { if (!propertyInfo.PropertyType.IsAssignableFrom(typeof(T))) { throw new InvalidCastException($"{propertyInfo.Name} is of type {propertyInfo.PropertyType}. An instance of {typeof(T)} cannot be assigned to it."); } return propertyInfo; } private static PropertyInfo ThrowIfTNotEqualToPropertyType<T>(this PropertyInfo propertyInfo) { if (propertyInfo.PropertyType != typeof(T)) { throw new InvalidCastException($"{propertyInfo.Name} is of type {propertyInfo.PropertyType}. {typeof(T)} is a different type."); } return propertyInfo; } private static GetDelegate<TReturn> CreateGetDelegate<TReturn>(this FieldInfo field) { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) if (field == null) { throw new ArgumentException("Field cannot be null.", "field"); } field.ThrowIfFieldTypeCannotBeAssignedTo<TReturn>(); if (field.IsLiteral && !field.IsInitOnly) { object value = field.GetValue(null); TReturn returnValue = ((value == null) ? default(TReturn) : ((TReturn)value)); return Extensions.CastDelegate<GetDelegate<TReturn>>((Delegate)(Func<object, TReturn>)((object _) => returnValue)); } DynamicMethodDefinition val = new DynamicMethodDefinition($"{field} Getter", typeof(TReturn), new Type[1] { typeof(object) }); try { ILProcessor iLProcessor = val.GetILProcessor(); if (!field.IsStatic) { iLProcessor.Emit(OpCodes.Ldarg_0); if (field.DeclaringType.GetTypeInfo().IsValueType) { Extensions.Emit(iLProcessor, OpCodes.Unbox_Any, field.DeclaringType); } } Extensions.Emit(iLProcessor, (!field.IsStatic) ? OpCodes.Ldfld : OpCodes.Ldsfld, field); if (field.FieldType.IsValueType && !typeof(TReturn).IsValueType) { Extensions.Emit(iLProcessor, OpCodes.Box, field.FieldType); } iLProcessor.Emit(OpCodes.Ret); return (GetDelegate<TReturn>)val.Generate().CreateDelegate(typeof(GetDelegate<TReturn>)); } finally { ((IDisposable)val)?.Dispose(); } } private static SetDelegate<TValue> CreateSetDelegate<TValue>(this FieldInfo field) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) if (field == null) { throw new ArgumentException("Field cannot be null.", "field"); } field.ThrowIfTCannotBeAssignedToField<TValue>(); field.ThrowIfFieldIsConst(); DynamicMethodDefinition val = new DynamicMethodDefinition($"{field} Setter", typeof(void), new Type[2] { typeof(object), typeof(TValue) }); try { ILProcessor iLProcessor = val.GetILProcessor(); if (!field.IsStatic) { iLProcessor.Emit(OpCodes.Ldarg_0); } iLProcessor.Emit(OpCodes.Ldarg_1); if (!field.FieldType.IsValueType && typeof(TValue).IsValueType) { Extensions.Emit(iLProcessor, OpCodes.Box, typeof(TValue)); } Extensions.Emit(iLProcessor, (!field.IsStatic) ? OpCodes.Stfld : OpCodes.Stsfld, field); iLProcessor.Emit(OpCodes.Ret); return (SetDelegate<TValue>)val.Generate().CreateDelegate(typeof(SetDelegate<TValue>)); } finally { ((IDisposable)val)?.Dispose(); } } private static SetDelegateRef<TInstance, TValue> CreateSetDelegateRef<TInstance, TValue>(this FieldInfo field) where TInstance : struct { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) if (field == null) { throw new ArgumentException("Field cannot be null.", "field"); } field.ThrowIfTCannotBeAssignedToField<TValue>(); field.ThrowIfFieldIsConst(); DynamicMethodDefinition val = new DynamicMethodDefinition($"{field} SetterByRef", typeof(void), new Type[2] { typeof(TInstance).MakeByRefType(), typeof(TValue) }); try { ILProcessor iLProcessor = val.GetILProcessor(); if (!field.IsStatic) { iLProcessor.Emit(OpCodes.Ldarg_0); } iLProcessor.Emit(OpCodes.Ldarg_1); if (!field.FieldType.IsValueType && typeof(TValue).IsValueType) { Extensions.Emit(iLProcessor, OpCodes.Box, typeof(TValue)); } Extensions.Emit(iLProcessor, (!field.IsStatic) ? OpCodes.Stfld : OpCodes.Stsfld, field); iLProcessor.Emit(OpCodes.Ret); return (SetDelegateRef<TInstance, TValue>)val.Generate().CreateDelegate(typeof(SetDelegateRef<TInstance, TValue>)); } finally { ((IDisposable)val)?.Dispose(); } } private static GetDelegate<TReturn> CreateGetDelegate<TReturn>(this PropertyInfo property) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) if (property == null) { throw new ArgumentException("Property cannot be null.", "property"); } property.ThrowIfPropertyTypeCannotBeAssignedTo<TReturn>(); DynamicMethodDefinition val = new DynamicMethodDefinition($"{property} Getter", typeof(TReturn), new Type[1] { typeof(object) }); try { ILProcessor iLProcessor = val.GetILProcessor(); MethodInfo getMethod = property.GetGetMethod(nonPublic: true); if (!getMethod.IsStatic) { iLProcessor.Emit(OpCodes.Ldarg_0); } Extensions.Emit(iLProcessor, OpCodes.Call, (MethodBase)getMethod); if (property.PropertyType.IsValueType && !typeof(TReturn).IsValueType) { Extensions.Emit(iLProcessor, OpCodes.Box, property.PropertyType); } iLProcessor.Emit(OpCodes.Ret); return (GetDelegate<TReturn>)val.Generate().CreateDelegate(typeof(GetDelegate<TReturn>)); } finally { ((IDisposable)val)?.Dispose(); } } private static GetDelegateRef<TInstance, TReturn> CreateGetDelegate<TInstance, TReturn>(this PropertyInfo property) where TInstance : struct { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) if (property == null) { throw new ArgumentException("Property cannot be null.", "property"); } property.ThrowIfPropertyTypeCannotBeAssignedTo<TReturn>(); DynamicMethodDefinition val = new DynamicMethodDefinition($"{property} Getter", typeof(TReturn), new Type[1] { typeof(TInstance).MakeByRefType() }); try { ILProcessor iLProcessor = val.GetILProcessor(); MethodInfo getMethod = property.GetGetMethod(nonPublic: true); if (!getMethod.IsStatic) { iLProcessor.Emit(OpCodes.Ldarg_0); } Extensions.Emit(iLProcessor, OpCodes.Call, (MethodBase)getMethod); if (property.PropertyType.IsValueType && !typeof(TReturn).IsValueType) { Extensions.Emit(iLProcessor, OpCodes.Box, property.PropertyType); } iLProcessor.Emit(OpCodes.Ret); return (GetDelegateRef<TInstance, TReturn>)val.Generate().CreateDelegate(typeof(GetDelegateRef<TInstance, TReturn>)); } finally { ((IDisposable)val)?.Dispose(); } } private static SetDelegate<TValue> CreateSetDelegate<TValue>(this PropertyInfo property) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) if (property == null) { throw new ArgumentException("Property cannot be null.", "property"); } property.ThrowIfTCannotBeAssignedToProperty<TValue>(); DynamicMethodDefinition val = new DynamicMethodDefinition($"{property} Setter", typeof(void), new Type[2] { typeof(object), typeof(TValue) }); try { ILProcessor iLProcessor = val.GetILProcessor(); MethodInfo setMethod = property.GetSetMethod(nonPublic: true); if (!setMethod.IsStatic) { iLProcessor.Emit(OpCodes.Ldarg_0); } iLProcessor.Emit(OpCodes.Ldarg_1); if (!property.PropertyType.IsValueType && typeof(TValue).IsValueType) { Extensions.Emit(iLProcessor, OpCodes.Box, typeof(TValue)); } Extensions.Emit(iLProcessor, OpCodes.Call, (MethodBase)setMethod); iLProcessor.Emit(OpCodes.Ret); return (SetDelegate<TValue>)val.Generate().CreateDelegate(typeof(SetDelegate<TValue>)); } finally { ((IDisposable)val)?.Dispose(); } } private static SetDelegateRef<TInstance, TValue> CreateSetDelegateRef<TInstance, TValue>(this PropertyInfo property) where TInstance : struct { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) if (property == null) { throw new ArgumentException("Property cannot be null.", "property"); } property.ThrowIfTCannotBeAssignedToProperty<TValue>(); DynamicMethodDefinition val = new DynamicMethodDefinition($"{property} SetterByRef", typeof(void), new Type[2] { typeof(TInstance).MakeByRefType(), typeof(TValue) }); try { ILProcessor iLProcessor = val.GetILProcessor(); MethodInfo setMethod = property.GetSetMethod(nonPublic: true); if (!setMethod.IsStatic) { iLProcessor.Emit(OpCodes.Ldarg_0); } iLProcessor.Emit(OpCodes.Ldarg_1); if (!property.PropertyType.IsValueType && typeof(TValue).IsValueType) { Extensions.Emit(iLProcessor, OpCodes.Box, typeof(TValue)); } Extensions.Emit(iLProcessor, OpCodes.Call, (MethodBase)setMethod); iLProcessor.Emit(OpCodes.Ret); return (SetDelegateRef<TInstance, TValue>)val.Generate().CreateDelegate(typeof(SetDelegateRef<TInstance, TValue>)); } finally { ((IDisposable)val)?.Dispose(); } } private static FastReflectionDelegate GenerateCallDelegate(this MethodInfo method) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Expected O, but got Unknown //IL_01bd: Unknown result type (might be due to invalid IL or missing references) if (method == null) { throw new ArgumentException("Method cannot be null.", "method"); } DynamicMethodDefinition val = new DynamicMethodDefinition("CallDelegate<" + method.Name + ">", typeof(object), new Type[2] { typeof(object), typeof(object[]) }); try { ILProcessor iLProcessor = val.GetILProcessor(); ParameterInfo[] parameters = method.GetParameters(); if (!method.IsStatic) { iLProcessor.Emit(OpCodes.Ldarg_0); if (method.DeclaringType.GetTypeInfo().IsValueType) { Extensions.Emit(iLProcessor, OpCodes.Unbox_Any, method.DeclaringType); } } for (int i = 0; i < parameters.Length; i++) { Type type = parameters[i].ParameterType; bool isByRef = type.IsByRef; if (isByRef) { type = type.GetElementType(); } bool isValueType = type.GetTypeInfo().IsValueType; if (isByRef && isValueType) { iLProcessor.Emit(OpCodes.Ldarg_1); iLProcessor.EmitFast_Ldc_I4(i); } iLProcessor.Emit(OpCodes.Ldarg_1); iLProcessor.EmitFast_Ldc_I4(i); if (isByRef && !isValueType) { Extensions.Emit(iLProcessor, OpCodes.Ldelema, typeof(object)); continue; } iLProcessor.Emit(OpCodes.Ldelem_Ref); if (isValueType) { Extensions.Emit(iLProcessor, (!isByRef) ? OpCodes.Unbox_Any : OpCodes.Unbox, type); } } if (method.IsFinal || !method.IsVirtual) { Extensions.Emit(iLProcessor, OpCodes.Call, (MethodBase)method); } else { Extensions.Emit(iLProcessor, OpCodes.Callvirt, (MethodBase)method); } Type type2 = (method.IsConstructor ? method.DeclaringType : method.ReturnType); if (type2 != typeof(void)) { if (type2.GetTypeInfo().IsValueType) { Extensions.Emit(iLProcessor, OpCodes.Box, type2); } } else { iLProcessor.Emit(OpCodes.Ldnull); } iLProcessor.Emit(OpCodes.Ret); return (FastReflectionDelegate)val.Generate().CreateDelegate(typeof(FastReflectionDelegate)); } finally { ((IDisposable)val)?.Dispose(); } } public static void EmitFast_Ldc_I4(this ILProcessor? il, int value) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) switch (value) { case -1: il.Emit(OpCodes.Ldc_I4_M1); return; case 0: il.Emit(OpCodes.Ldc_I4_0); return; case 1: il.Emit(OpCodes.Ldc_I4_1); return; case 2: il.Emit(OpCodes.Ldc_I4_2); return; case 3: il.Emit(OpCodes.Ldc_I4_3); return; case 4: il.Emit(OpCodes.Ldc_I4_4); return; case 5: il.Emit(OpCodes.Ldc_I4_5); return; case 6: il.Emit(OpCodes.Ldc_I4_6); return; case 7: il.Emit(OpCodes.Ldc_I4_7); return; case 8: il.Emit(OpCodes.Ldc_I4_8); return; } if (value > -129 && value < 128) { il.Emit(OpCodes.Ldc_I4_S, (sbyte)value); } else { il.Emit(OpCodes.Ldc_I4, value); } } public static byte ReadLocalIndex(OpCode opCode, object? operand) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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_001d: 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_002a: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) if (opCode == OpCodes.Ldloc_0 || opCode == OpCodes.Stloc_0) { return 0; } if (opCode == OpCodes.Ldloc_1 || opCode == OpCodes.Stloc_1) { return 1; } if (opCode == OpCodes.Ldloc_2 || opCode == OpCodes.Stloc_2) { return 2; } if (opCode == OpCodes.Ldloc_3 || opCode == OpCodes.Stloc_3) { return 3; } if (opCode == OpCodes.Ldloc_S || opCode == OpCodes.Stloc_S) { return (byte)operand; } throw new Exception($"Could not read index for opcode and operand: {opCode} - {operand}"); } public static bool GetTypesSafe(Assembly assembly, out Type[] assemblyTypes) { try { assemblyTypes = assembly.GetTypes(); } catch (ReflectionTypeLoadException ex) { assemblyTypes = ex.Types.Where((Type t) => t != null).ToArray(); return false; } return true; } public static FieldInfo GetNestedField(Type type, string fieldName) { Type[] nestedTypes = type.GetNestedTypes(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); for (int i = 0; i < nestedTypes.Length; i++) { FieldInfo field = nestedTypes[i].GetField(fieldName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { return field; } } return null; } public static MethodInfo GetNestedMethod(Type type, string methodName) { Type[] nestedTypes = type.GetNestedTypes(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); for (int i = 0; i < nestedTypes.Length; i++) { MethodInfo method = nestedTypes[i].GetMethod(methodName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (method != null) { return method; } } return null; } public static void LogCursorOpcodes(ILCursor cursor) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) int index = cursor.Index; cursor.Goto(0, (MoveType)0, false); while (cursor.Next != null) { Debug.Log((object)cursor.Next.OpCode); int index2 = cursor.Index; cursor.Index = index2 + 1; cursor.Goto(cursor.Index, (MoveType)0, false); } cursor.Index = index; } public static MethodInfo GetGenericMethod(Type type, string name, Type[] parameters) { MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (!(methodInfo.Name == name)) { continue; } ParameterInfo[] parameters2 = methodInfo.GetParameters(); if (parameters2.Length != parameters.Length) { continue; } bool flag = true; for (int j = 0; j < parameters.Length; j++) { if (parameters2[j].ParameterType.Name != parameters[j].Name) { flag = false; break; } } if (flag) { return methodInfo; } } return null; } public static bool IsSameOrSubclassOf<OtherType>(this Type type) { if (!(type == typeof(OtherType))) { return type.IsSubclassOf(typeof(OtherType)); } return true; } } internal class StringUtils { internal static void ThrowIfStringIsNullOrWhiteSpace(string stringToCheck, string paramName) { if (string.IsNullOrWhiteSpace(stringToCheck)) { throw new ArgumentNullException(paramName); } } } public static class SystemInitializerInjector { [CompilerGenerated] private static class <>O { public static hook_ExecuteStatic <0>__SystemInitializerInjectDependencies; } private static readonly Dictionary<MethodInfo, HashSet<Type>> _dependenciesToInject = new Dictionary<MethodInfo, HashSet<Type>>(); private static bool _appliedHooks = false; private static void applyHooksIfNeeded() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown if (!_appliedHooks) { _appliedHooks = true; object obj = <>O.<0>__SystemInitializerInjectDependencies; if (obj == null) { hook_ExecuteStatic val = SystemInitializerInjectDependencies; <>O.<0>__SystemInitializerInjectDependencies = val; obj = (object)val; } SystemInitializerAttribute.ExecuteStatic += (hook_ExecuteStatic)obj; } } private static void SystemInitializerInjectDependencies(orig_ExecuteStatic orig) { orig.Invoke(); foreach (SystemInitializerAttribute initializerAttribute in SystemInitializerAttribute.initializerAttributes) { injectDependencies(initializerAttribute); } } private static void injectDependencies(SystemInitializerAttribute attribute) { SystemInitializerAttribute attribute2 = attribute; if (((SearchableAttribute)attribute2).target is MethodInfo key && _dependenciesToInject.TryGetValue(key, out HashSet<Type> value)) { value.RemoveWhere((Type t) => attribute2.dependencies.Contains(t)); if (value.Count != 0) { int num = attribute2.dependencies.Length; Array.Resize(ref attribute2.dependencies, num + value.Count); value.CopyTo(attribute2.dependencies, num); } } } public static void InjectDependencies<T>(params Type[] dependenciesToInject) { ThrowIfSystemInitializerExecuted(); Type typeFromHandle = typeof(T); foreach (Type dependency in dependenciesToInject) { InjectDependencyInternal(typeFromHandle, dependency); } } public static void InjectDependency<T>(Type dependencyToInject) { ThrowIfSystemInitializerExecuted(); InjectDependencyInternal(typeof(T), dependencyToInject); } public static void InjectDependencies(Type typeToInject, params Type[] dependenciesToInject) { ThrowIfSystemInitializerExecuted(); foreach (Type dependency in dependenciesToInject) { InjectDependencyInternal(typeToInject, dependency); } } public static void InjectDependency(Type typeToInject, Type dependencyToInject) { ThrowIfSystemInitializerExecuted(); InjectDependencyInternal(typeToInject, dependencyToInject); } private static void InjectDependencyInternal(Type typeToInject, Type dependency) { if ((object)typeToInject == null) { throw new ArgumentNullException("typeToInject"); } if ((object)dependency == null) { throw new ArgumentNullException("dependency"); } foreach (MethodInfo allSystemInitializerMethod in GetAllSystemInitializerMethods(typeToInject)) { InjectDependencyInternal(allSystemInitializerMethod, dependency); } } private static IEnumerable<MethodInfo> GetAllSystemInitializerMethods(Type type) { return from m in type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) where ((MemberInfo)m).GetCustomAttribute<SystemInitializerAttribute>() != null select m; } public static void InjectDependency(MethodInfo initializerMethod, Type dependency) { ThrowIfSystemInitializerExecuted(); InjectDependencyInternal(initializerMethod, dependency); } public static void InjectDependencies(MethodInfo initializerMethod, params Type[] dependencies) { ThrowIfSystemInitializerExecuted(); foreach (Type dependency in dependencies) { InjectDependencyInternal(initializerMethod, dependency); } } private static void InjectDependencyInternal(MethodInfo initializerMethod, Type dependency) { if ((object)dependency == null) { throw new ArgumentNullException("dependency"); } if ((object)initializerMethod == null) { throw new ArgumentNullException("initializerMethod"); } if (((MemberInfo)initializerMethod).GetCustomAttribute<SystemInitializerAttribute>() == null) { R2API.Logger.LogWarning((object)("Not injecting SystemInitializer dependency " + dependency.FullName + " into " + initializerMethod.DeclaringType.FullName + "." + initializerMethod.Name + ": Method is missing SystemInitializerAttribute")); return; } if (!_dependenciesToInject.TryGetValue(initializerMethod, out HashSet<Type> value)) { _dependenciesToInject.Add(initializerMethod, value = new HashSet<Type>()); } if (value.Add(dependency)) { applyHooksIfNeeded(); R2API.Logger.LogDebug((object)("Injecting SystemInitializer dependency " + dependency.FullName + " into " + initializerMethod.DeclaringType.FullName + "." + initializerMethod.Name)); } } private static void ThrowIfSystemInitializerExecuted() { if (SystemInitializerAttribute.hasExecuted) { throw new InvalidOperationException("Cannot inject dependencies when SystemInitializer has already been executed"); } } } }