Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of R2API Core v5.3.0
plugins/R2API.Core/R2API.Core.dll
Decompiled 4 months 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"); } } } }