Decompiled source of Batter v1.0.0
plugins/Batteritems/batteritems.dll
Decompiled 8 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; using Gungeon; using ItemAPI; using MonoMod.RuntimeDetour; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("Mod")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Mod")] [assembly: AssemblyCopyright("Copyright © 2020")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("d6d7a494-722e-4763-959b-c2d6b6a42b01")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyVersion("1.0.0.0")] namespace batteritems { public class StripedJersey : PassiveItem { public static void Init() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) string name = "Striped Jersey"; string resourcePath = "batteritems/Resources/striped_jersey"; GameObject val = new GameObject(); StripedJersey stripedJersey = val.AddComponent<StripedJersey>(); ItemBuilder.AddSpriteToObject(name, resourcePath, val); string shortDesc = "It's red & white!"; string longDesc = "Negates contact damage and increases movement speed\n\nYour very own protective gear that you're used to sprinting around in.\n"; ((PickupObject)(object)stripedJersey).SetupItem(shortDesc, longDesc, "batteritems"); ((PickupObject)(object)stripedJersey).AddPassiveStatModifier((StatType)0, 1f, (ModifyMethod)0); ((PickupObject)stripedJersey).quality = (ItemQuality)2; } public override void Pickup(PlayerController player) { player.ReceivesTouchDamage = false; ((PassiveItem)this).Pickup(player); Tools.Print("Player picked up " + ((PickupObject)this).DisplayName); } public override DebrisObject Drop(PlayerController player) { Tools.Print("Player dropped " + ((PickupObject)this).DisplayName); return ((PassiveItem)this).Drop(player); } } public class TradingCard : PassiveItem { public static void Init() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) string name = "Old Trading Card"; string resourcePath = "batteritems/Resources/trading_card"; GameObject val = new GameObject(); TradingCard tradingCard = val.AddComponent<TradingCard>(); ItemBuilder.AddSpriteToObject(name, resourcePath, val); string shortDesc = "Hey! That's you!"; string longDesc = "Increases Coolness by 3\n\nWow, this trading card of you is pretty cool.\n"; ((PickupObject)(object)tradingCard).SetupItem(shortDesc, longDesc, "batteritems"); ((PickupObject)(object)tradingCard).AddPassiveStatModifier((StatType)4, 3f, (ModifyMethod)0); ((PickupObject)tradingCard).quality = (ItemQuality)2; } } public class BatterItemsModule : ETGModule { public bool setup; private static string version = "0.0.1"; private string[] itemList = new string[2] { "Trading Card", "Striped Jersey" }; public override void Init() { } public override void Start() { Setup(); } public void Setup() { if (setup) { return; } try { Tools.Init(); ItemBuilder.Init(); TradingCard.Init(); StripedJersey.Init(); setup = true; } catch (Exception e2) { Tools.PrintException(e2); } ETGModConsole.Commands.AddUnit("batteritems", (Action<string[]>)delegate { ETGModConsole.Log("Batter Items: ", false); string[] array = itemList; foreach (string text in array) { ETGModConsole.Log(" " + text, false); } }); ETGModConsole.Log("Batter Items " + version + " Initialized", false); } public override void Exit() { } } } namespace ItemAPI { public static class CompanionBuilder { public enum AnimationType { Move, Idle, Fidget, Flight, Hit, Talk, Other } private static GameObject behaviorSpeculatorPrefab; public static Dictionary<string, GameObject> companionDictionary = new Dictionary<string, GameObject>(); public static void Init() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Expected O, but got Unknown string companionGuid = ((Component)Game.Items["dog"]).GetComponent<CompanionItem>().CompanionGuid; AIActor orLoadByGuid = EnemyDatabase.GetOrLoadByGuid(companionGuid); behaviorSpeculatorPrefab = Object.Instantiate<GameObject>(((Component)orLoadByGuid).gameObject); foreach (Transform item in behaviorSpeculatorPrefab.transform) { Transform val = item; if ((Object)(object)val != (Object)(object)behaviorSpeculatorPrefab.transform) { Object.DestroyImmediate((Object)(object)val); } } Component[] components = behaviorSpeculatorPrefab.GetComponents<Component>(); foreach (Component val2 in components) { if ((object)((object)val2).GetType() != typeof(BehaviorSpeculator)) { Object.DestroyImmediate((Object)(object)val2); } } Object.DontDestroyOnLoad((Object)(object)behaviorSpeculatorPrefab); FakePrefab.MarkAsFakePrefab(behaviorSpeculatorPrefab); behaviorSpeculatorPrefab.SetActive(false); Hook val3 = new Hook((MethodBase)typeof(EnemyDatabase).GetMethod("GetOrLoadByGuid", BindingFlags.Static | BindingFlags.Public), typeof(CompanionBuilder).GetMethod("GetOrLoadByGuid")); } public static AIActor GetOrLoadByGuid(Func<string, AIActor> orig, string guid) { foreach (string key in companionDictionary.Keys) { if (key == guid) { return companionDictionary[key].GetComponent<AIActor>(); } } return orig(guid); } public static GameObject BuildPrefab(string name, string guid, string defaultSpritePath, IntVector2 hitboxOffset, IntVector2 hitBoxSize) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Expected O, but got Unknown if (companionDictionary.ContainsKey(guid)) { Tools.PrintError("CompanionBuilder: Tried to create two companion prefabs with the same GUID!"); return null; } GameObject val = Object.Instantiate<GameObject>(behaviorSpeculatorPrefab); ((Object)val).name = name; tk2dSprite component = SpriteBuilder.SpriteFromResource(defaultSpritePath, val).GetComponent<tk2dSprite>(); component.SetUpSpeculativeRigidbody(hitboxOffset, hitBoxSize).CollideWithOthers = false; val.AddComponent<tk2dSpriteAnimator>(); val.AddComponent<AIAnimator>(); HealthHaver val2 = val.AddComponent<HealthHaver>(); val2.RegisterBodySprite((tk2dBaseSprite)(object)component, false, 0); val2.PreventAllDamage = true; val2.SetHealthMaximum(15000f, (float?)null, false); val2.FullHeal(); AIActor val3 = val.AddComponent<AIActor>(); val3.State = (ActorState)2; val3.EnemyGuid = guid; BehaviorSpeculator component2 = val.GetComponent<BehaviorSpeculator>(); component2.MovementBehaviors = new List<MovementBehaviorBase>(); component2.AttackBehaviors = new List<AttackBehaviorBase>(); component2.TargetBehaviors = new List<TargetBehaviorBase>(); component2.OverrideBehaviors = new List<OverrideBehaviorBase>(); component2.OtherBehaviors = new List<BehaviorBase>(); EnemyDatabaseEntry item = new EnemyDatabaseEntry { myGuid = guid, placeableWidth = 2, placeableHeight = 2, isNormalEnemy = false }; ((AssetBundleDatabase<AIActor, EnemyDatabaseEntry>)(object)EnemyDatabase.Instance).Entries.Add(item); companionDictionary.Add(guid, val); Object.DontDestroyOnLoad((Object)(object)val); FakePrefab.MarkAsFakePrefab(val); val.SetActive(false); return val; } public static tk2dSpriteAnimationClip AddAnimation(this GameObject obj, string name, string spriteDirectory, int fps, AnimationType type, DirectionType directionType = 0, FlipType flipType = 0) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected I4, but got Unknown //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) AIAnimator orAddComponent = GameObjectExtensions.GetOrAddComponent<AIAnimator>(obj); DirectionalAnimation val = orAddComponent.GetDirectionalAnimation(name, directionType, type); if (val == null) { DirectionalAnimation val2 = new DirectionalAnimation(); val2.AnimNames = new string[0]; val2.Flipped = (FlipType[])(object)new FlipType[0]; val2.Type = directionType; val2.Prefix = string.Empty; val = val2; } val.AnimNames = val.AnimNames.Concat(new string[1] { name }).ToArray(); val.Flipped = val.Flipped.Concat((IEnumerable<FlipType>)(object)new FlipType[1] { (FlipType)(int)flipType }).ToArray(); orAddComponent.AssignDirectionalAnimation(name, val, type); return BuildAnimation(orAddComponent, name, spriteDirectory, fps); } public static tk2dSpriteAnimationClip BuildAnimation(AIAnimator aiAnimator, string name, string spriteDirectory, int fps) { tk2dSpriteCollectionData val = ((Component)aiAnimator).GetComponent<tk2dSpriteCollectionData>(); if (!Object.op_Implicit((Object)(object)val)) { val = SpriteBuilder.ConstructCollection(((Component)aiAnimator).gameObject, ((Object)aiAnimator).name + "_collection"); } string[] resourceNames = ResourceExtractor.GetResourceNames(); List<int> list = new List<int>(); for (int i = 0; i < resourceNames.Length; i++) { if (resourceNames[i].StartsWith(spriteDirectory.Replace('/', '.'), StringComparison.OrdinalIgnoreCase)) { list.Add(SpriteBuilder.AddSpriteToCollection(resourceNames[i], val)); } } tk2dSpriteAnimationClip val2 = SpriteBuilder.AddAnimation(((BraveBehaviour)aiAnimator).spriteAnimator, val, list, name, (WrapMode)0); val2.fps = fps; return val2; } public static DirectionalAnimation GetDirectionalAnimation(this AIAnimator aiAnimator, string name, DirectionType directionType, AnimationType type) { DirectionalAnimation val = null; switch (type) { case AnimationType.Idle: val = aiAnimator.IdleAnimation; break; case AnimationType.Move: val = aiAnimator.MoveAnimation; break; case AnimationType.Flight: val = aiAnimator.FlightAnimation; break; case AnimationType.Hit: val = aiAnimator.HitAnimation; break; case AnimationType.Talk: val = aiAnimator.TalkAnimation; break; } if (val != null) { return val; } return null; } public static void AssignDirectionalAnimation(this AIAnimator aiAnimator, string name, DirectionalAnimation animation, AnimationType type) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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_007f: Expected O, but got Unknown switch (type) { case AnimationType.Idle: aiAnimator.IdleAnimation = animation; return; case AnimationType.Move: aiAnimator.MoveAnimation = animation; return; case AnimationType.Flight: aiAnimator.FlightAnimation = animation; return; case AnimationType.Hit: aiAnimator.HitAnimation = animation; return; case AnimationType.Talk: aiAnimator.TalkAnimation = animation; return; case AnimationType.Fidget: aiAnimator.IdleFidgetAnimations.Add(animation); return; } aiAnimator.OtherAnimations.Add(new NamedDirectionalAnimation { anim = animation, name = name }); } } public static class CustomSynergies { public static Hook synergyHook = new Hook((MethodBase)typeof(StringTableManager).GetMethod("GetSynergyString", BindingFlags.Static | BindingFlags.Public), typeof(CustomSynergies).GetMethod("SynergyStringHook")); public static AdvancedSynergyEntry Add(string name, List<string> mandatoryConsoleIDs, List<string> optionalConsoleIDs = null, bool ignoreLichEyeBullets = true) { //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: 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_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Expected O, but got Unknown if (mandatoryConsoleIDs == null || mandatoryConsoleIDs.Count == 0) { Tools.PrintError("Synergy " + name + " has no mandatory items/guns."); return null; } List<int> list = new List<int>(); List<int> list2 = new List<int>(); List<int> list3 = new List<int>(); List<int> list4 = new List<int>(); foreach (string mandatoryConsoleID in mandatoryConsoleIDs) { PickupObject val = Game.Items[mandatoryConsoleID]; if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)((Component)val).GetComponent<Gun>())) { list2.Add(val.PickupObjectId); } else if (Object.op_Implicit((Object)(object)val) && (Object.op_Implicit((Object)(object)((Component)val).GetComponent<PlayerItem>()) || Object.op_Implicit((Object)(object)((Component)val).GetComponent<PassiveItem>()))) { list.Add(val.PickupObjectId); } } if (optionalConsoleIDs != null) { foreach (string optionalConsoleID in optionalConsoleIDs) { PickupObject val = Game.Items[optionalConsoleID]; if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)((Component)val).GetComponent<Gun>())) { list4.Add(val.PickupObjectId); } else if (Object.op_Implicit((Object)(object)val) && (Object.op_Implicit((Object)(object)((Component)val).GetComponent<PlayerItem>()) || Object.op_Implicit((Object)(object)((Component)val).GetComponent<PassiveItem>()))) { list3.Add(val.PickupObjectId); } } } AdvancedSynergyEntry val2 = new AdvancedSynergyEntry { NameKey = name, MandatoryItemIDs = list, MandatoryGunIDs = list2, OptionalItemIDs = list3, OptionalGunIDs = list4, bonusSynergies = new List<CustomSynergyType>(), statModifiers = new List<StatModifier>() }; Add(val2); return val2; } public static void Add(AdvancedSynergyEntry synergyEntry) { AdvancedSynergyEntry[] second = (AdvancedSynergyEntry[])(object)new AdvancedSynergyEntry[1] { synergyEntry }; GameManager.Instance.SynergyManager.synergies = GameManager.Instance.SynergyManager.synergies.Concat(second).ToArray(); } public static string SynergyStringHook(Func<string, int, string> orig, string key, int index = -1) { string text = orig(key, index); if (string.IsNullOrEmpty(text)) { text = key; } return text; } public static bool HasMTGConsoleID(this PlayerController player, string consoleID) { if (!Game.Items.ContainsID(consoleID)) { return false; } return player.HasPickupID(Game.Items[consoleID].PickupObjectId); } } public class FakePrefab : Component { internal static HashSet<GameObject> ExistingFakePrefabs = new HashSet<GameObject>(); public static bool IsFakePrefab(Object o) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) if (o is GameObject) { return ExistingFakePrefabs.Contains((GameObject)o); } if (o is Component) { return ExistingFakePrefabs.Contains(((Component)o).gameObject); } return false; } public static void MarkAsFakePrefab(GameObject obj) { ExistingFakePrefabs.Add(obj); Object.DontDestroyOnLoad((Object)(object)obj); } public static GameObject Clone(GameObject obj) { bool flag = IsFakePrefab((Object)(object)obj); bool activeSelf = obj.activeSelf; if (activeSelf) { obj.SetActive(false); } GameObject val = Object.Instantiate<GameObject>(obj); if (activeSelf) { obj.SetActive(true); } ExistingFakePrefabs.Add(val); Object.DontDestroyOnLoad((Object)(object)val); return val; } public static Object Instantiate(Object o, Object new_o) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_0022: 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_0057: Unknown result type (might be due to invalid IL or missing references) if (o is GameObject && ExistingFakePrefabs.Contains((GameObject)o)) { ((GameObject)new_o).SetActive(true); } else if (o is Component && ExistingFakePrefabs.Contains(((Component)o).gameObject)) { ((Component)new_o).gameObject.SetActive(true); } return new_o; } } public static class FakePrefabHooks { public delegate TResult Func<T1, T2, T3, T4, T5, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5); public static void Init() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Expected O, but got Unknown //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Expected O, but got Unknown //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Expected O, but got Unknown //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Expected O, but got Unknown Hook val = new Hook((MethodBase)typeof(PlayerController).GetMethod("AcquirePassiveItemPrefabDirectly"), typeof(FakePrefabHooks).GetMethod("AcquirePassiveItemPrefabDirectly")); Hook val2 = new Hook((MethodBase)typeof(PlayerItem).GetMethod("Pickup"), typeof(FakePrefabHooks).GetMethod("ActivePickup")); Hook val3 = new Hook((MethodBase)typeof(Object).GetMethod("Instantiate", new Type[3] { typeof(Object), typeof(Transform), typeof(bool) }), typeof(FakePrefabHooks).GetMethod("InstantiateOPI")); Hook val4 = new Hook((MethodBase)typeof(Object).GetMethod("Instantiate", new Type[2] { typeof(Object), typeof(Transform) }), typeof(FakePrefabHooks).GetMethod("InstantiateOP")); Hook val5 = new Hook((MethodBase)typeof(Object).GetMethod("Instantiate", new Type[1] { typeof(Object) }), typeof(FakePrefabHooks).GetMethod("InstantiateO")); Hook val6 = new Hook((MethodBase)typeof(Object).GetMethod("Instantiate", new Type[3] { typeof(Object), typeof(Vector3), typeof(Quaternion) }), typeof(FakePrefabHooks).GetMethod("InstantiateOPR")); Hook val7 = new Hook((MethodBase)typeof(Object).GetMethod("Instantiate", new Type[4] { typeof(Object), typeof(Vector3), typeof(Quaternion), typeof(Transform) }), typeof(FakePrefabHooks).GetMethod("InstantiateOPRP")); } public static void AcquirePassiveItemPrefabDirectly(Action<PlayerController, PassiveItem> orig, PlayerController self, PassiveItem item) { bool flag = FakePrefab.IsFakePrefab((Object)(object)((Component)item).gameObject); if (flag) { ((Component)item).gameObject.SetActive(true); } orig(self, item); if (flag) { ((Component)item).gameObject.SetActive(false); } } public static void ActivePickup(Action<PlayerItem, PlayerController> orig, PlayerItem self, PlayerController player) { bool flag = FakePrefab.IsFakePrefab((Object)(object)((Component)self).gameObject); if (flag) { ((Component)self).gameObject.SetActive(true); } orig(self, player); if (flag) { ((Component)self).gameObject.SetActive(false); } } public static Object InstantiateOPI(Func<Object, Transform, bool, Object> orig, Object original, Transform parent, bool instantiateInWorldSpace) { return FakePrefab.Instantiate(original, orig(original, parent, instantiateInWorldSpace)); } public static Object InstantiateOP(Func<Object, Transform, Object> orig, Object original, Transform parent) { return FakePrefab.Instantiate(original, orig(original, parent)); } public static Object InstantiateO(Func<Object, Object> orig, Object original) { return FakePrefab.Instantiate(original, orig(original)); } public static Object InstantiateOPR(Func<Object, Vector3, Quaternion, Object> orig, Object original, Vector3 position, Quaternion rotation) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) return FakePrefab.Instantiate(original, orig(original, position, rotation)); } public static Object InstantiateOPRP(Func<Object, Vector3, Quaternion, Transform, Object> orig, Object original, Vector3 position, Quaternion rotation, Transform parent) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) return FakePrefab.Instantiate(original, orig(original, position, rotation, parent)); } } public static class ItemBuilder { public enum CooldownType { Timed, Damage, PerRoom, None } public enum ShopType { Goopton, Flynt, Cursula, Trorc, OldRed } public static Dictionary<ShopType, GenericLootTable> shopInventories; public static void Init() { FakePrefabHooks.Init(); CompanionBuilder.Init(); Tools.Init(); LoadShopTables(); } private static void LoadShopTables() { shopInventories = new Dictionary<ShopType, GenericLootTable>(); shopInventories.Add(ShopType.Flynt, LoadShopTable("Shop_Key_Items_01")); shopInventories.Add(ShopType.Trorc, LoadShopTable("Shop_Truck_Items_01")); shopInventories.Add(ShopType.Cursula, LoadShopTable("Shop_Curse_Items_01")); shopInventories.Add(ShopType.Goopton, LoadShopTable("Shop_Goop_Items_01")); shopInventories.Add(ShopType.OldRed, LoadShopTable("Shop_Blank_Items_01")); } public static GenericLootTable LoadShopTable(string assetName) { return Tools.sharedAuto1.LoadAsset<GenericLootTable>(assetName); } public static GameObject AddSpriteToObject(string name, string resourcePath, GameObject obj = null) { GameObject val = SpriteBuilder.SpriteFromResource(resourcePath, obj); ((Object)val).name = name; return val; } public static void SetupItem(this PickupObject item, string shortDesc, string longDesc, string idPool = "customItems") { try { ((BraveBehaviour)item).encounterTrackable = null; Databases.Items.SetupItem(item, ((Object)item).name); SpriteBuilder.AddToAmmonomicon(((BraveBehaviour)item).sprite.GetCurrentSpriteDef()); ((BraveBehaviour)item).encounterTrackable.journalData.AmmonomiconSprite = ((BraveBehaviour)item).sprite.GetCurrentSpriteDef().name; GunExt.SetName(item, ((Object)item).name); GunExt.SetShortDescription(item, shortDesc); GunExt.SetLongDescription(item, longDesc); if (item is PlayerItem) { ((PlayerItem)((item is PlayerItem) ? item : null)).consumable = false; } Game.Items.Add(idPool + ":" + ((Object)item).name.ToLower().Replace(" ", "_"), item); Databases.Items.Add(item, false, "ANY"); FakePrefab.MarkAsFakePrefab(((Component)item).gameObject); ((Component)item).gameObject.SetActive(false); } catch (Exception ex) { ETGModConsole.Log(ex.Message, false); ETGModConsole.Log(ex.StackTrace, false); } } public static void AddToSubShop(this PickupObject po, ShopType type, float weight) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown WeightedGameObjectCollection defaultItemDrops = shopInventories[type].defaultItemDrops; WeightedGameObject val = new WeightedGameObject(); val.pickupId = po.PickupObjectId; val.weight = weight; val.rawGameObject = ((Component)po).gameObject; val.forceDuplicatesPossible = false; val.additionalPrerequisites = (DungeonPrerequisite[])(object)new DungeonPrerequisite[0]; defaultItemDrops.Add(val); } public static void SetCooldownType(this PlayerItem item, CooldownType cooldownType, float value) { item.damageCooldown = -1f; item.roomCooldown = -1; item.timeCooldown = -1f; switch (cooldownType) { case CooldownType.Timed: item.timeCooldown = value; break; case CooldownType.Damage: item.damageCooldown = value; break; case CooldownType.PerRoom: item.roomCooldown = (int)value; break; } } public static StatModifier AddPassiveStatModifier(this PickupObject po, StatType statType, float amount, ModifyMethod method = 0) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) StatModifier val = new StatModifier(); val.amount = amount; val.statToBoost = statType; val.modifyType = method; po.AddPassiveStatModifier(val); return val; } public static void AddPassiveStatModifier(this PickupObject po, StatModifier modifier) { if (po is PlayerItem) { PlayerItem val = (PlayerItem)(object)((po is PlayerItem) ? po : null); if (val.passiveStatModifiers == null) { val.passiveStatModifiers = (StatModifier[])(object)new StatModifier[1] { modifier }; } else { val.passiveStatModifiers = val.passiveStatModifiers.Concat((IEnumerable<StatModifier>)(object)new StatModifier[1] { modifier }).ToArray(); } return; } if (po is PassiveItem) { PassiveItem val2 = (PassiveItem)(object)((po is PassiveItem) ? po : null); if (val2.passiveStatModifiers == null) { val2.passiveStatModifiers = (StatModifier[])(object)new StatModifier[1] { modifier }; } else { val2.passiveStatModifiers = val2.passiveStatModifiers.Concat((IEnumerable<StatModifier>)(object)new StatModifier[1] { modifier }).ToArray(); } return; } throw new NotSupportedException("Object must be of type PlayerItem or PassiveItem"); } public static bool RemovePassiveStatModifier(this PickupObject po, StatModifier modifier) { bool flag = false; if (po is PlayerItem) { PlayerItem val = (PlayerItem)(object)((po is PlayerItem) ? po : null); if (val.passiveStatModifiers == null) { return false; } List<StatModifier> list = val.passiveStatModifiers.ToList(); flag = list.Remove(modifier); val.passiveStatModifiers = list.ToArray(); } else { if (!(po is PassiveItem)) { throw new NotSupportedException("Object must be of type PlayerItem or PassiveItem"); } PassiveItem val2 = (PassiveItem)(object)((po is PassiveItem) ? po : null); if (val2.passiveStatModifiers == null) { return false; } List<StatModifier> list2 = val2.passiveStatModifiers.ToList(); flag = list2.Remove(modifier); val2.passiveStatModifiers = list2.ToArray(); } return flag; } public static IEnumerator HandleDuration(PlayerItem item, float duration, PlayerController user, Action<PlayerController> OnFinish) { if (!item.IsCurrentlyActive) { SetPrivateType<PlayerItem>(item, "m_isCurrentlyActive", value: true); SetPrivateType<PlayerItem>(item, "m_activeElapsed", 0f); SetPrivateType<PlayerItem>(item, "m_activeDuration", duration); item.OnActivationStatusChanged?.Invoke(item); GetPrivateType<PlayerItem, float>(item, "m_activeElapsed"); GetPrivateType<PlayerItem, float>(item, "m_activeDuration"); while (GetPrivateType<PlayerItem, float>(item, "m_activeElapsed") < GetPrivateType<PlayerItem, float>(item, "m_activeDuration") && item.IsCurrentlyActive) { yield return null; } SetPrivateType<PlayerItem>(item, "m_isCurrentlyActive", value: false); item.OnActivationStatusChanged?.Invoke(item); OnFinish?.Invoke(user); } } private static void SetPrivateType<T>(T obj, string field, bool value) { FieldInfo field2 = typeof(T).GetField(field, BindingFlags.Instance | BindingFlags.NonPublic); field2.SetValue(obj, value); } private static void SetPrivateType<T>(T obj, string field, float value) { FieldInfo field2 = typeof(T).GetField(field, BindingFlags.Instance | BindingFlags.NonPublic); field2.SetValue(obj, value); } private static T2 GetPrivateType<T, T2>(T obj, string field) { FieldInfo field2 = typeof(T).GetField(field, BindingFlags.Instance | BindingFlags.NonPublic); return (T2)field2.GetValue(obj); } } public static class Tools { public static bool verbose = false; private static string defaultLog = Path.Combine(ETGMod.ResourcesDirectory, "exampleMod.txt"); public static string modID = "EX"; public static AssetBundle sharedAuto1 = ResourceManager.LoadAssetBundle("shared_auto_001"); public static AssetBundle sharedAuto2 = ResourceManager.LoadAssetBundle("shared_auto_002"); public static void Init() { if (File.Exists(defaultLog)) { File.Delete(defaultLog); } } public static void Print<T>(T obj, string color = "FFFFFF", bool force = false) { if (verbose || force) { ETGModConsole.Log("<color=#" + color + ">" + modID + ": " + obj.ToString() + "</color>", false); } Log(obj.ToString()); } public static void PrintRaw<T>(T obj, bool force = false) { if (verbose || force) { ETGModConsole.Log(obj.ToString(), false); } Log(obj.ToString()); } public static void PrintError<T>(T obj, string color = "FF0000") { ETGModConsole.Log("<color=#" + color + ">" + modID + ": " + obj.ToString() + "</color>", false); Log(obj.ToString()); } public static void PrintException(Exception e, string color = "FF0000") { ETGModConsole.Log("<color=#" + color + ">" + modID + ": " + e.Message + "</color>", false); ETGModConsole.Log(e.StackTrace, false); Log(e.Message); Log("\t" + e.StackTrace); } public static void Log<T>(T obj) { using StreamWriter streamWriter = new StreamWriter(Path.Combine(ETGMod.ResourcesDirectory, defaultLog), append: true); streamWriter.WriteLine(obj.ToString()); } public static void Log<T>(T obj, string fileName) { if (!verbose) { return; } using StreamWriter streamWriter = new StreamWriter(Path.Combine(ETGMod.ResourcesDirectory, fileName), append: true); streamWriter.WriteLine(obj.ToString()); } public static void Dissect(this GameObject obj) { Print(((Object)obj).name + " Components:"); Component[] components = obj.GetComponents<Component>(); foreach (Component val in components) { Print(" " + ((object)val).GetType()); } } public static void ShowHitBox(this SpeculativeRigidbody body) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00af: 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) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) PixelCollider hitboxPixelCollider = body.HitboxPixelCollider; GameObject val = GameObject.CreatePrimitive((PrimitiveType)3); ((Object)val).name = "HitboxDisplay"; val.transform.SetParent(((BraveBehaviour)body).transform); Print(((Object)body).name ?? ""); Print($" Offset: {hitboxPixelCollider.Offset}, Dimesions: {hitboxPixelCollider.Dimensions}"); val.transform.localScale = new Vector3((float)hitboxPixelCollider.Dimensions.x / 16f, (float)hitboxPixelCollider.Dimensions.y / 16f, 1f); Vector3 localPosition = new Vector3((float)hitboxPixelCollider.Offset.x + (float)hitboxPixelCollider.Dimensions.x * 0.5f, (float)hitboxPixelCollider.Offset.y + (float)hitboxPixelCollider.Dimensions.y * 0.5f, -16f) / 16f; val.transform.localPosition = localPosition; } public static void HideHitBox(this SpeculativeRigidbody body) { Transform val = ((BraveBehaviour)body).transform.Find("HitboxDisplay"); if (Object.op_Implicit((Object)(object)val)) { Object.Destroy((Object)(object)val); } } public static void ExportTexture(Texture texture) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown File.WriteAllBytes(Path.Combine(ETGMod.ResourcesDirectory, ((Object)texture).name + ".png"), ImageConversion.EncodeToPNG((Texture2D)texture)); } public static void LogPropertiesAndFields<T>(this T obj, string header = "") { Log(header); Log("======================="); if (obj == null) { Log("LogPropertiesAndFields: Null object"); return; } Type type = obj.GetType(); Log($"Type: {type}"); PropertyInfo[] properties = type.GetProperties(); Log($"{typeof(T)} Properties: "); PropertyInfo[] array = properties; foreach (PropertyInfo propertyInfo in array) { try { object value = propertyInfo.GetValue(obj, null); string text = value.ToString(); if ((object)obj?.GetType().GetGenericTypeDefinition() == typeof(List<>)) { List<object> list = value as List<object>; text = $"List[{list.Count}]"; foreach (object item in list) { text = text + "\n\t\t" + item.ToString(); } } Log("\t" + propertyInfo.Name + ": " + text); } catch { } } Log($"{typeof(T)} Fields: "); FieldInfo[] fields = type.GetFields(); FieldInfo[] array2 = fields; foreach (FieldInfo fieldInfo in array2) { Log($"\t{fieldInfo.Name}: {fieldInfo.GetValue(obj)}"); } } } public static class ResourceExtractor { private static string spritesDirectory = Path.Combine(ETGMod.ResourcesDirectory, "sprites"); public static List<Texture2D> GetTexturesFromDirectory(string directoryPath) { if (!Directory.Exists(directoryPath)) { Tools.PrintError(directoryPath + " not found."); return null; } List<Texture2D> list = new List<Texture2D>(); string[] files = Directory.GetFiles(directoryPath); foreach (string text in files) { if (text.EndsWith(".png")) { Texture2D item = BytesToTexture(File.ReadAllBytes(text), Path.GetFileName(text).Replace(".png", "")); list.Add(item); } } return list; } public static Texture2D GetTextureFromFile(string fileName, string extension = ".png") { fileName = fileName.Replace(extension, ""); string text = Path.Combine(spritesDirectory, fileName + extension); if (!File.Exists(text)) { Tools.PrintError(text + " not found."); return null; } return BytesToTexture(File.ReadAllBytes(text), fileName); } public static List<string> GetCollectionFiles() { List<string> list = new List<string>(); string[] files = Directory.GetFiles(spritesDirectory); foreach (string text in files) { if (text.EndsWith(".png")) { list.Add(Path.GetFileName(text).Replace(".png", "")); } } return list; } public static Texture2D BytesToTexture(byte[] bytes, string resourceName) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false); ImageConversion.LoadImage(val, bytes); ((Texture)val).filterMode = (FilterMode)0; ((Object)val).name = resourceName; return val; } public static string[] GetLinesFromEmbeddedResource(string filePath) { string text = BytesToString(ExtractEmbeddedResource(filePath)); return text.Split(new char[1] { '\n' }); } public static string[] GetLinesFromFile(string filePath) { string text = BytesToString(File.ReadAllBytes(filePath)); return text.Split(new char[1] { '\n' }); } public static string BytesToString(byte[] bytes) { return Encoding.UTF8.GetString(bytes, 0, bytes.Length); } public static List<string> GetResourceFolders() { List<string> list = new List<string>(); string path = Path.Combine(ETGMod.ResourcesDirectory, "sprites"); if (Directory.Exists(path)) { string[] directories = Directory.GetDirectories(path); foreach (string path2 in directories) { list.Add(Path.GetFileName(path2)); } } return list; } public static byte[] ExtractEmbeddedResource(string filePath) { filePath = filePath.Replace("/", "."); filePath = filePath.Replace("\\", "."); Assembly callingAssembly = Assembly.GetCallingAssembly(); using Stream stream = callingAssembly.GetManifestResourceStream(filePath); if (stream == null) { return null; } byte[] array = new byte[stream.Length]; stream.Read(array, 0, array.Length); return array; } public static Texture2D GetTextureFromResource(string resourceName) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown byte[] array = ExtractEmbeddedResource(resourceName); if (array == null) { Tools.PrintError("No bytes found in " + resourceName); return null; } Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false); ImageConversion.LoadImage(val, array); ((Texture)val).filterMode = (FilterMode)0; string text = resourceName.Substring(0, resourceName.LastIndexOf('.')); if (text.LastIndexOf('.') >= 0) { text = text.Substring(text.LastIndexOf('.') + 1); } ((Object)val).name = text; return val; } public static string[] GetResourceNames() { Assembly callingAssembly = Assembly.GetCallingAssembly(); string[] manifestResourceNames = callingAssembly.GetManifestResourceNames(); if (manifestResourceNames == null) { ETGModConsole.Log("No manifest resources found.", false); return null; } return manifestResourceNames; } } public static class SpriteBuilder { private static tk2dSpriteCollectionData itemCollection = ((BraveBehaviour)PickupObjectDatabase.GetByEncounterName("singularity")).sprite.Collection; private static tk2dSpriteCollectionData ammonomiconCollection = AmmonomiconController.ForceInstance.EncounterIconCollection; private static tk2dSprite baseSprite = ((Component)PickupObjectDatabase.GetByEncounterName("singularity")).GetComponent<tk2dSprite>(); public static GameObject SpriteFromFile(string spriteName, GameObject obj = null) { string fileName = spriteName.Replace(".png", ""); Texture2D textureFromFile = ResourceExtractor.GetTextureFromFile(fileName); if ((Object)(object)textureFromFile == (Object)null) { return null; } return SpriteFromTexture(textureFromFile, spriteName, obj); } public static GameObject SpriteFromResource(string spriteName, GameObject obj = null) { string text = ((!spriteName.EndsWith(".png")) ? ".png" : ""); string text2 = spriteName + text; Texture2D textureFromResource = ResourceExtractor.GetTextureFromResource(text2); if ((Object)(object)textureFromResource == (Object)null) { return null; } return SpriteFromTexture(textureFromResource, text2, obj); } public static GameObject SpriteFromTexture(Texture2D texture, string spriteName, GameObject obj = null) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown if ((Object)(object)obj == (Object)null) { obj = new GameObject(); } tk2dSprite val = obj.AddComponent<tk2dSprite>(); int num = AddSpriteToCollection(spriteName, itemCollection); ((tk2dBaseSprite)val).SetSprite(itemCollection, num); ((tk2dBaseSprite)val).SortingOrder = 0; ((tk2dBaseSprite)val).IsPerpendicular = true; obj.GetComponent<BraveBehaviour>().sprite = (tk2dBaseSprite)(object)val; return obj; } public static int AddSpriteToCollection(string resourcePath, tk2dSpriteCollectionData collection) { string text = ((!resourcePath.EndsWith(".png")) ? ".png" : ""); resourcePath += text; Texture2D textureFromResource = ResourceExtractor.GetTextureFromResource(resourcePath); tk2dSpriteDefinition val = ConstructDefinition(textureFromResource); val.name = ((Object)textureFromResource).name; return AddSpriteToCollection(val, collection); } public static int AddSpriteToCollection(tk2dSpriteDefinition spriteDefinition, tk2dSpriteCollectionData collection) { tk2dSpriteDefinition[] spriteDefinitions = collection.spriteDefinitions; tk2dSpriteDefinition[] array = (collection.spriteDefinitions = spriteDefinitions.Concat((IEnumerable<tk2dSpriteDefinition>)(object)new tk2dSpriteDefinition[1] { spriteDefinition }).ToArray()); FieldInfo field = typeof(tk2dSpriteCollectionData).GetField("spriteNameLookupDict", BindingFlags.Instance | BindingFlags.NonPublic); field.SetValue(collection, null); collection.InitDictionary(); return array.Length - 1; } public static int AddToAmmonomicon(tk2dSpriteDefinition spriteDefinition) { return AddSpriteToCollection(spriteDefinition, ammonomiconCollection); } public static tk2dSpriteAnimationClip AddAnimation(tk2dSpriteAnimator animator, tk2dSpriteCollectionData collection, List<int> spriteIDs, string clipName, WrapMode wrapMode = 0) { //IL_00a1: 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_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: 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) //IL_00c1: Expected O, but got Unknown //IL_006d: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown if ((Object)(object)animator.Library == (Object)null) { animator.Library = ((Component)animator).gameObject.AddComponent<tk2dSpriteAnimation>(); animator.Library.clips = (tk2dSpriteAnimationClip[])(object)new tk2dSpriteAnimationClip[0]; ((Behaviour)animator.Library).enabled = true; } List<tk2dSpriteAnimationFrame> list = new List<tk2dSpriteAnimationFrame>(); for (int i = 0; i < spriteIDs.Count; i++) { tk2dSpriteDefinition val = collection.spriteDefinitions[spriteIDs[i]]; if (val.Valid) { list.Add(new tk2dSpriteAnimationFrame { spriteCollection = collection, spriteId = spriteIDs[i] }); } } tk2dSpriteAnimationClip val2 = new tk2dSpriteAnimationClip { name = clipName, fps = 15f, wrapMode = wrapMode }; Array.Resize(ref animator.Library.clips, animator.Library.clips.Length + 1); animator.Library.clips[animator.Library.clips.Length - 1] = val2; val2.frames = list.ToArray(); return val2; } public static SpeculativeRigidbody SetUpSpeculativeRigidbody(this tk2dSprite sprite, IntVector2 offset, IntVector2 dimensions) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_0015: 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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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) SpeculativeRigidbody orAddComponent = GameObjectExtensions.GetOrAddComponent<SpeculativeRigidbody>(((Component)sprite).gameObject); PixelCollider val = new PixelCollider(); val.ColliderGenerationMode = (PixelColliderGeneration)0; val.CollisionLayer = (CollisionLayer)3; val.ManualWidth = dimensions.x; val.ManualHeight = dimensions.y; val.ManualOffsetX = offset.x; val.ManualOffsetY = offset.y; orAddComponent.PixelColliders = new List<PixelCollider> { val }; return orAddComponent; } public static tk2dSpriteDefinition ConstructDefinition(Texture2D texture) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: 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) //IL_009b: 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_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0176: 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_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: 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_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) RuntimeAtlasSegment val = Assets.Packer.Pack(texture, false); Material val2 = new Material(ShaderCache.Acquire(PlayerController.DefaultShaderName)); val2.mainTexture = (Texture)(object)val.texture; int width = ((Texture)texture).width; int height = ((Texture)texture).height; float num = 0f; float num2 = 0f; float num3 = (float)width / 16f; float num4 = (float)height / 16f; tk2dSpriteDefinition val3 = new tk2dSpriteDefinition(); val3.normals = (Vector3[])(object)new Vector3[4] { new Vector3(0f, 0f, -1f), new Vector3(0f, 0f, -1f), new Vector3(0f, 0f, -1f), new Vector3(0f, 0f, -1f) }; val3.tangents = (Vector4[])(object)new Vector4[4] { new Vector4(1f, 0f, 0f, 1f), new Vector4(1f, 0f, 0f, 1f), new Vector4(1f, 0f, 0f, 1f), new Vector4(1f, 0f, 0f, 1f) }; val3.texelSize = new Vector2(0.0625f, 0.0625f); val3.extractRegion = false; val3.regionX = 0; val3.regionY = 0; val3.regionW = 0; val3.regionH = 0; val3.flipped = (FlipMode)0; val3.complexGeometry = false; val3.physicsEngine = (PhysicsEngine)0; val3.colliderType = (ColliderType)1; val3.collisionLayer = (CollisionLayer)6; val3.position0 = new Vector3(num, num2, 0f); val3.position1 = new Vector3(num + num3, num2, 0f); val3.position2 = new Vector3(num, num2 + num4, 0f); val3.position3 = new Vector3(num + num3, num2 + num4, 0f); val3.material = val2; val3.materialInst = val2; val3.materialId = 0; val3.uvs = val.uvs; val3.boundsDataCenter = new Vector3(num3 / 2f, num4 / 2f, 0f); val3.boundsDataExtents = new Vector3(num3, num4, 0f); val3.untrimmedBoundsDataCenter = new Vector3(num3 / 2f, num4 / 2f, 0f); val3.untrimmedBoundsDataExtents = new Vector3(num3, num4, 0f); tk2dSpriteDefinition val4 = val3; val4.name = ((Object)texture).name; return val4; } public static tk2dSpriteCollectionData ConstructCollection(GameObject obj, string name) { tk2dSpriteCollectionData val = obj.AddComponent<tk2dSpriteCollectionData>(); Object.DontDestroyOnLoad((Object)(object)val); val.assetName = name; val.spriteCollectionGUID = name; val.spriteCollectionName = name; val.spriteDefinitions = (tk2dSpriteDefinition[])(object)new tk2dSpriteDefinition[0]; return val; } public static T CopyFrom<T>(this Component comp, T other) where T : Component { Type type = ((object)comp).GetType(); if ((object)type != ((object)other).GetType()) { return default(T); } PropertyInfo[] properties = type.GetProperties(); PropertyInfo[] array = properties; foreach (PropertyInfo propertyInfo in array) { if (propertyInfo.CanWrite) { try { propertyInfo.SetValue(comp, propertyInfo.GetValue(other, null), null); } catch { } } } FieldInfo[] fields = type.GetFields(); FieldInfo[] array2 = fields; foreach (FieldInfo fieldInfo in array2) { fieldInfo.SetValue(comp, fieldInfo.GetValue(other)); } return (T)(object)((comp is T) ? comp : null); } public static void SetColor(this tk2dSprite sprite, Color color) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) ((BraveBehaviour)sprite).renderer.material.SetColor("_OverrideColor", color); } public static T AddComponent<T>(this GameObject go, T toAdd) where T : Component { return ((Component)(object)go.AddComponent<T>()).CopyFrom(toAdd); } } }
plugins/Batteritems/MonoMod.RuntimeDetour.dll
Decompiled 8 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using System.Text; using Harmony.ILCopying; using Mono.Cecil; using Mono.Cecil.Cil; using Mono.Collections.Generic; using MonoMod.Utils; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyTitle("MonoMod.RuntimeDetour")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("MonoMod.RuntimeDetour")] [assembly: AssemblyCopyright("Copyright © 2018")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("d0c584c0-81d7-486e-b70e-d7f9256e0909")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("18.9.0.42435")] [module: UnverifiableCode] namespace Harmony.ILCopying { internal enum ExceptionBlockType { BeginExceptionBlock, BeginCatchBlock, BeginExceptFilterBlock, BeginFaultBlock, BeginFinallyBlock, EndExceptionBlock } internal class ExceptionBlock { public ExceptionBlockType blockType; public Type catchType; public ExceptionBlock(ExceptionBlockType blockType, Type catchType) { this.blockType = blockType; this.catchType = catchType; } } internal class ILInstruction { public int offset; public OpCode opcode; public object operand; public object argument; public List<Label> labels = new List<Label>(); public List<ExceptionBlock> blocks = new List<ExceptionBlock>(); public ILInstruction(OpCode opcode, object operand = null) { this.opcode = opcode; this.operand = operand; argument = operand; } public int GetSize() { int num = opcode.Size; switch (opcode.OperandType) { case OperandType.InlineSwitch: num += (1 + ((int[])operand).Length) * 4; break; case OperandType.InlineI8: case OperandType.InlineR: num += 8; break; case OperandType.InlineBrTarget: case OperandType.InlineField: case OperandType.InlineI: case OperandType.InlineMethod: case OperandType.InlineString: case OperandType.InlineTok: case OperandType.InlineType: case OperandType.ShortInlineR: num += 4; break; case OperandType.InlineVar: num += 2; break; case OperandType.ShortInlineBrTarget: case OperandType.ShortInlineI: case OperandType.ShortInlineVar: num++; break; } return num; } public override string ToString() { string str = ""; AppendLabel(ref str, this); str = str + ": " + opcode.Name; if (operand == null) { return str; } str += " "; switch (opcode.OperandType) { case OperandType.InlineBrTarget: case OperandType.ShortInlineBrTarget: AppendLabel(ref str, operand); break; case OperandType.InlineSwitch: { ILInstruction[] array = (ILInstruction[])operand; for (int i = 0; i < array.Length; i++) { if (i > 0) { str += ","; } AppendLabel(ref str, array[i]); } break; } case OperandType.InlineString: str = string.Concat(str, "\"", operand, "\""); break; default: str += operand; break; } return str; } private static void AppendLabel(ref string str, object argument) { if (argument is ILInstruction iLInstruction) { str = str + "IL_" + iLInstruction.offset.ToString("X4"); } else { str = str + "IL_" + argument; } } } internal class MethodCopier : IDisposable { private class ThisParameter : ParameterInfo { public ThisParameter(MethodBase method) { MemberImpl = method; ClassImpl = method.DeclaringType; NameImpl = "this"; PositionImpl = -1; } } private readonly ILGenerator generator; private readonly MethodBase method; private readonly Module module; private readonly Type[] typeArguments; private readonly Type[] methodArguments; private readonly BinaryReader ilBytes; private readonly ParameterInfo this_parameter; private readonly ParameterInfo[] parameters; private readonly IList<LocalVariableInfo> locals; private readonly IList<ExceptionHandlingClause> exceptions; private List<ILInstruction> ilInstructions; private LocalBuilder[] variables; private static Dictionary<short, OpCode> shortJumps; private static readonly OpCode[] one_byte_opcodes; private static readonly OpCode[] two_bytes_opcodes; private static readonly Dictionary<Type, MethodInfo> emitMethods; public MethodCopier(MethodBase method, ILGenerator generator) { this.generator = generator ?? throw new ArgumentNullException("Generator cannot be null"); this.method = method ?? throw new ArgumentNullException("Method cannot be null"); module = method.Module; MethodBody methodBody = method.GetMethodBody(); if (methodBody == null) { throw new ArgumentException("Method " + method.Name + " has no body"); } byte[] iLAsByteArray = methodBody.GetILAsByteArray(); if (iLAsByteArray == null) { throw new ArgumentException("Can not get IL bytes of method " + method.Name); } ilBytes = new BinaryReader(new MemoryStream(iLAsByteArray)); ilInstructions = new List<ILInstruction>((iLAsByteArray.Length + 1) / 2); Type declaringType = method.DeclaringType; if (declaringType.IsGenericType) { typeArguments = declaringType.GetGenericArguments(); } if (method.IsGenericMethod) { methodArguments = method.GetGenericArguments(); } if (!method.IsStatic) { this_parameter = new ThisParameter(method); } parameters = method.GetParameters(); locals = methodBody.LocalVariables; exceptions = methodBody.ExceptionHandlingClauses; DeclareVariables(); ReadInstructions(); } public void DeclareVariables() { variables = locals.Select((LocalVariableInfo lvi) => generator.DeclareLocal(lvi.LocalType, lvi.IsPinned)).ToArray(); } public void ReadInstructions() { while (ilBytes.BaseStream.Position < ilBytes.BaseStream.Length) { int offset = (int)ilBytes.BaseStream.Position; ILInstruction iLInstruction = new ILInstruction(ReadOpCode()) { offset = offset }; ReadOperand(iLInstruction); ilInstructions.Add(iLInstruction); } ResolveBranches(); ParseExceptions(); } private void ResolveBranches() { foreach (ILInstruction ilInstruction in ilInstructions) { switch (ilInstruction.opcode.OperandType) { case OperandType.InlineBrTarget: case OperandType.ShortInlineBrTarget: ilInstruction.operand = GetInstruction((int)ilInstruction.operand, isEndOfInstruction: false); break; case OperandType.InlineSwitch: { int[] array = (int[])ilInstruction.operand; ILInstruction[] array2 = new ILInstruction[array.Length]; for (int i = 0; i < array.Length; i++) { array2[i] = GetInstruction(array[i], isEndOfInstruction: false); } ilInstruction.operand = array2; break; } } } } private void ParseExceptions() { foreach (ExceptionHandlingClause exception in exceptions) { int tryOffset = exception.TryOffset; int num = exception.TryOffset + exception.TryLength - 1; int handlerOffset = exception.HandlerOffset; int offset = exception.HandlerOffset + exception.HandlerLength - 1; string text = ((exception.Flags == ExceptionHandlingClauseOptions.Clause) ? "catch" : exception.Flags.ToString().ToLower()); ILInstruction instruction = GetInstruction(tryOffset, isEndOfInstruction: false); instruction.blocks.Add(new ExceptionBlock(ExceptionBlockType.BeginExceptionBlock, null)); ILInstruction instruction2 = GetInstruction(offset, isEndOfInstruction: true); instruction2.blocks.Add(new ExceptionBlock(ExceptionBlockType.EndExceptionBlock, null)); switch (exception.Flags) { case ExceptionHandlingClauseOptions.Filter: { ILInstruction instruction3 = GetInstruction(exception.FilterOffset, isEndOfInstruction: false); instruction3.blocks.Add(new ExceptionBlock(ExceptionBlockType.BeginExceptFilterBlock, null)); break; } case ExceptionHandlingClauseOptions.Finally: { ILInstruction instruction3 = GetInstruction(handlerOffset, isEndOfInstruction: false); instruction3.blocks.Add(new ExceptionBlock(ExceptionBlockType.BeginFinallyBlock, null)); break; } case ExceptionHandlingClauseOptions.Clause: { ILInstruction instruction3 = GetInstruction(handlerOffset, isEndOfInstruction: false); instruction3.blocks.Add(new ExceptionBlock(ExceptionBlockType.BeginCatchBlock, exception.CatchType)); break; } case ExceptionHandlingClauseOptions.Fault: { ILInstruction instruction3 = GetInstruction(handlerOffset, isEndOfInstruction: false); instruction3.blocks.Add(new ExceptionBlock(ExceptionBlockType.BeginFaultBlock, null)); break; } } } } public void Copy() { if (generator == null) { return; } foreach (ILInstruction ilInstruction in ilInstructions) { switch (ilInstruction.opcode.OperandType) { case OperandType.InlineSwitch: if (ilInstruction.operand is ILInstruction[] array) { List<Label> list = new List<Label>(); ILInstruction[] array2 = array; foreach (ILInstruction iLInstruction2 in array2) { Label item = generator.DefineLabel(); iLInstruction2.labels.Add(item); list.Add(item); } ilInstruction.argument = list.ToArray(); } break; case OperandType.InlineBrTarget: case OperandType.ShortInlineBrTarget: if (ilInstruction.operand is ILInstruction iLInstruction) { Label label = generator.DefineLabel(); iLInstruction.labels.Add(label); ilInstruction.argument = label; } break; } } int num = 0; foreach (ILInstruction ilInstruction2 in ilInstructions) { foreach (Label label3 in ilInstruction2.labels) { generator.MarkLabel(label3); } foreach (ExceptionBlock block in ilInstruction2.blocks) { switch (block.blockType) { case ExceptionBlockType.BeginExceptionBlock: { Label label2 = generator.BeginExceptionBlock(); break; } case ExceptionBlockType.BeginCatchBlock: generator.BeginCatchBlock(block.catchType); break; case ExceptionBlockType.BeginExceptFilterBlock: generator.BeginExceptFilterBlock(); break; case ExceptionBlockType.BeginFaultBlock: generator.BeginFaultBlock(); break; case ExceptionBlockType.BeginFinallyBlock: generator.BeginFinallyBlock(); break; } } OpCode opCode = ilInstruction2.opcode; object argument = ilInstruction2.argument; if (shortJumps.TryGetValue(opCode.Value, out var value)) { opCode = value; } if (opCode.OperandType == OperandType.InlineNone) { generator.Emit(opCode); } else { if (argument == null) { throw new Exception("Wrong null argument: " + ilInstruction2); } MethodInfo methodInfo = EmitMethodForType(argument.GetType()); if ((object)methodInfo == null) { throw new Exception(string.Concat("Unknown Emit argument type ", argument.GetType(), " in ", ilInstruction2)); } methodInfo.Invoke(generator, new object[2] { opCode, argument }); } foreach (ExceptionBlock block2 in ilInstruction2.blocks) { if (block2.blockType == ExceptionBlockType.EndExceptionBlock) { generator.EndExceptionBlock(); } } num++; } } private static void GetMemberInfoValue(MemberInfo info, out object result) { result = null; switch (info.MemberType) { case MemberTypes.Constructor: result = (ConstructorInfo)info; break; case MemberTypes.Event: result = (EventInfo)info; break; case MemberTypes.Field: result = (FieldInfo)info; break; case MemberTypes.Method: result = (MethodInfo)info; break; case MemberTypes.TypeInfo: case MemberTypes.NestedType: result = (Type)info; break; case MemberTypes.Property: result = (PropertyInfo)info; break; } } private void ReadOperand(ILInstruction instruction) { switch (instruction.opcode.OperandType) { case OperandType.InlineNone: instruction.argument = null; break; case OperandType.InlineSwitch: { int num6 = ilBytes.ReadInt32(); int num7 = (int)ilBytes.BaseStream.Position + 4 * num6; int[] array = new int[num6]; for (int i = 0; i < num6; i++) { array[i] = ilBytes.ReadInt32() + num7; } instruction.operand = array; break; } case OperandType.ShortInlineBrTarget: { sbyte b4 = (sbyte)ilBytes.ReadByte(); instruction.operand = b4 + (int)ilBytes.BaseStream.Position; break; } case OperandType.InlineBrTarget: { int num8 = ilBytes.ReadInt32(); instruction.operand = num8 + (int)ilBytes.BaseStream.Position; break; } case OperandType.ShortInlineI: if (instruction.opcode == OpCodes.Ldc_I4_S) { sbyte b2 = (sbyte)ilBytes.ReadByte(); instruction.operand = b2; instruction.argument = (sbyte)instruction.operand; } else { byte b3 = ilBytes.ReadByte(); instruction.operand = b3; instruction.argument = (byte)instruction.operand; } break; case OperandType.InlineI: { int num5 = ilBytes.ReadInt32(); instruction.operand = num5; instruction.argument = (int)instruction.operand; break; } case OperandType.ShortInlineR: { float num3 = ilBytes.ReadSingle(); instruction.operand = num3; instruction.argument = (float)instruction.operand; break; } case OperandType.InlineR: { double num2 = ilBytes.ReadDouble(); instruction.operand = num2; instruction.argument = (double)instruction.operand; break; } case OperandType.InlineI8: { long num4 = ilBytes.ReadInt64(); instruction.operand = num4; instruction.argument = (long)instruction.operand; break; } case OperandType.InlineSig: { int metadataToken = ilBytes.ReadInt32(); instruction.operand = module.ResolveSignature(metadataToken); instruction.argument = (SignatureHelper)instruction.operand; break; } case OperandType.InlineString: { int metadataToken6 = ilBytes.ReadInt32(); instruction.operand = module.ResolveString(metadataToken6); instruction.argument = (string)instruction.operand; break; } case OperandType.InlineTok: { int metadataToken5 = ilBytes.ReadInt32(); instruction.operand = module.ResolveMember(metadataToken5, typeArguments, methodArguments); GetMemberInfoValue((MemberInfo)instruction.operand, out instruction.argument); break; } case OperandType.InlineType: { int metadataToken4 = ilBytes.ReadInt32(); instruction.operand = module.ResolveType(metadataToken4, typeArguments, methodArguments); instruction.argument = (Type)instruction.operand; break; } case OperandType.InlineMethod: { int metadataToken3 = ilBytes.ReadInt32(); instruction.operand = module.ResolveMethod(metadataToken3, typeArguments, methodArguments); if (instruction.operand is ConstructorInfo) { instruction.argument = (ConstructorInfo)instruction.operand; } else { instruction.argument = (MethodInfo)instruction.operand; } break; } case OperandType.InlineField: { int metadataToken2 = ilBytes.ReadInt32(); instruction.operand = module.ResolveField(metadataToken2, typeArguments, methodArguments); instruction.argument = (FieldInfo)instruction.operand; break; } case OperandType.ShortInlineVar: { byte b = ilBytes.ReadByte(); if (TargetsLocalVariable(instruction.opcode)) { LocalVariableInfo localVariable2 = GetLocalVariable(b); if (localVariable2 == null) { instruction.argument = b; break; } instruction.operand = localVariable2; instruction.argument = variables[localVariable2.LocalIndex]; } else { instruction.operand = GetParameter(b); instruction.argument = b; } break; } case OperandType.InlineVar: { short num = ilBytes.ReadInt16(); if (TargetsLocalVariable(instruction.opcode)) { LocalVariableInfo localVariable = GetLocalVariable(num); if (localVariable == null) { instruction.argument = num; break; } instruction.operand = localVariable; instruction.argument = variables[localVariable.LocalIndex]; } else { instruction.operand = GetParameter(num); instruction.argument = num; } break; } default: throw new NotSupportedException(); } } private ILInstruction GetInstruction(int offset, bool isEndOfInstruction) { int num = ilInstructions.Count - 1; if (offset < 0 || offset > ilInstructions[num].offset) { throw new Exception("Instruction offset " + offset + " is outside valid range 0 - " + ilInstructions[num].offset); } int num2 = 0; int num3 = num; while (num2 <= num3) { int num4 = num2 + (num3 - num2) / 2; ILInstruction iLInstruction = ilInstructions[num4]; if (isEndOfInstruction) { if (offset == iLInstruction.offset + iLInstruction.GetSize() - 1) { return iLInstruction; } } else if (offset == iLInstruction.offset) { return iLInstruction; } if (offset < iLInstruction.offset) { num3 = num4 - 1; } else { num2 = num4 + 1; } } throw new Exception("Cannot find instruction for " + offset.ToString("X4")); } private static bool TargetsLocalVariable(OpCode opcode) { return opcode.Name.Contains("loc"); } private LocalVariableInfo GetLocalVariable(int index) { return locals?[index]; } private ParameterInfo GetParameter(int index) { if (this_parameter != null) { if (index == 0) { return this_parameter; } return parameters[index - 1]; } return parameters[index]; } private OpCode ReadOpCode() { byte b = ilBytes.ReadByte(); return (b != 254) ? one_byte_opcodes[b] : two_bytes_opcodes[ilBytes.ReadByte()]; } private MethodInfo EmitMethodForType(Type type) { foreach (KeyValuePair<Type, MethodInfo> emitMethod in emitMethods) { if ((object)emitMethod.Key == type) { return emitMethod.Value; } } foreach (KeyValuePair<Type, MethodInfo> emitMethod2 in emitMethods) { if (emitMethod2.Key.IsAssignableFrom(type)) { return emitMethod2.Value; } } return null; } public void Dispose() { ((IDisposable)ilBytes).Dispose(); } [MethodImpl(MethodImplOptions.Synchronized)] static MethodCopier() { Dictionary<short, OpCode> dictionary = new Dictionary<short, OpCode>(); OpCode leave_S = OpCodes.Leave_S; dictionary.Add(leave_S.Value, OpCodes.Leave); leave_S = OpCodes.Brfalse_S; dictionary.Add(leave_S.Value, OpCodes.Brfalse); leave_S = OpCodes.Brtrue_S; dictionary.Add(leave_S.Value, OpCodes.Brtrue); leave_S = OpCodes.Beq_S; dictionary.Add(leave_S.Value, OpCodes.Beq); leave_S = OpCodes.Bge_S; dictionary.Add(leave_S.Value, OpCodes.Bge); leave_S = OpCodes.Bgt_S; dictionary.Add(leave_S.Value, OpCodes.Bgt); leave_S = OpCodes.Ble_S; dictionary.Add(leave_S.Value, OpCodes.Ble); leave_S = OpCodes.Blt_S; dictionary.Add(leave_S.Value, OpCodes.Blt); leave_S = OpCodes.Bne_Un_S; dictionary.Add(leave_S.Value, OpCodes.Bne_Un); leave_S = OpCodes.Bge_Un_S; dictionary.Add(leave_S.Value, OpCodes.Bge_Un); leave_S = OpCodes.Bgt_Un_S; dictionary.Add(leave_S.Value, OpCodes.Bgt_Un); leave_S = OpCodes.Ble_Un_S; dictionary.Add(leave_S.Value, OpCodes.Ble_Un); leave_S = OpCodes.Br_S; dictionary.Add(leave_S.Value, OpCodes.Br); leave_S = OpCodes.Blt_Un_S; dictionary.Add(leave_S.Value, OpCodes.Blt_Un); shortJumps = dictionary; one_byte_opcodes = new OpCode[225]; two_bytes_opcodes = new OpCode[31]; FieldInfo[] fields = typeof(OpCodes).GetFields(BindingFlags.Static | BindingFlags.Public); FieldInfo[] array = fields; foreach (FieldInfo fieldInfo in array) { OpCode opCode = (OpCode)fieldInfo.GetValue(null); if (opCode.OpCodeType != OpCodeType.Nternal) { if (opCode.Size == 1) { one_byte_opcodes[opCode.Value] = opCode; } else { two_bytes_opcodes[opCode.Value & 0xFF] = opCode; } } } emitMethods = new Dictionary<Type, MethodInfo>(); foreach (MethodInfo item in typeof(ILGenerator).GetMethods().ToList()) { if (item.Name != "Emit") { continue; } ParameterInfo[] array2 = item.GetParameters(); if (array2.Length == 2) { Type[] array3 = array2.Select((ParameterInfo p) => p.ParameterType).ToArray(); if ((object)array3[0] == typeof(OpCode)) { emitMethods[array3[1]] = item; } } } } } } namespace MonoMod.RuntimeDetour { public class Detour : IDetour, IDisposable { private static Dictionary<MethodBase, List<Detour>> _DetourMap = new Dictionary<MethodBase, List<Detour>>(); private static Dictionary<MethodBase, DynamicMethod> _BackupMethods = new Dictionary<MethodBase, DynamicMethod>(); public static Func<object, MethodBase, MethodBase, bool> OnDetour; public static Func<object, bool> OnUndo; public static Func<object, MethodBase, MethodBase> OnGenerateTrampoline; public readonly MethodBase Method; public readonly MethodBase Target; private NativeDetour _TopDetour; private DynamicMethod _ChainedTrampoline; public bool IsValid => _DetourMap[Method].Contains(this); public int Index { get { return _DetourMap[Method].IndexOf(this); } set { List<Detour> list = _DetourMap[Method]; lock (list) { int num = list.IndexOf(this); if (num == -1) { throw new InvalidOperationException("This detour has been undone."); } list.RemoveAt(num); if (value > num) { value--; } try { list.Insert(value, this); } catch { list.Insert(num, this); throw; } Detour detour = list[list.Count - 1]; if (detour != this) { _TopUndo(); } detour._TopApply(); _UpdateChainedTrampolines(Method); } } } public Detour(MethodBase from, MethodBase to) { Method = from; Target = to; Func<object, MethodBase, MethodBase, bool> onDetour = OnDetour; if (onDetour != null && !Extensions.InvokeWhileTrue((MulticastDelegate)onDetour, new object[3] { this, from, to })) { return; } if (!_BackupMethods.ContainsKey(Method)) { _BackupMethods[Method] = Method.CreateILCopy(); } ParameterInfo[] parameters = Method.GetParameters(); Type[] array; if (!Method.IsStatic) { array = new Type[parameters.Length + 1]; array[0] = Method.DeclaringType; for (int i = 0; i < parameters.Length; i++) { array[i + 1] = parameters[i].ParameterType; } } else { array = new Type[parameters.Length]; for (int j = 0; j < parameters.Length; j++) { array[j] = parameters[j].ParameterType; } } _ChainedTrampoline = new DynamicMethod($"chain_{Method.Name}_{GetHashCode()}", (Method as MethodInfo)?.ReturnType ?? typeof(void), array, Method.DeclaringType, skipVisibility: false).StubCriticalDetour().Pin(); List<Detour> value; lock (_DetourMap) { if (!_DetourMap.TryGetValue(Method, out value)) { value = (_DetourMap[Method] = new List<Detour>()); } } lock (value) { if (value.Count > 0) { value[value.Count - 1]._TopUndo(); } _TopApply(); NativeDetourData detour = ((value.Count <= 0) ? DetourManager.Native.Create(_ChainedTrampoline.GetNativeStart(), _BackupMethods[Method].GetNativeStart()) : DetourManager.Native.Create(_ChainedTrampoline.GetNativeStart(), value[value.Count - 1].Target.GetNativeStart())); DetourManager.Native.MakeWritable(detour); DetourManager.Native.Apply(detour); DetourManager.Native.MakeExecutable(detour); DetourManager.Native.Free(detour); value.Add(this); } } public Detour(MethodBase method, IntPtr to) : this(method, DetourManager.GenerateNativeProxy(to, method)) { } public Detour(Delegate from, IntPtr to) : this(from.Method, to) { } public Detour(Delegate from, Delegate to) : this(from.Method, to.Method) { } public Detour(Expression from, IntPtr to) : this(((MethodCallExpression)from).Method, to) { } public Detour(Expression from, Expression to) : this(((MethodCallExpression)from).Method, ((MethodCallExpression)to).Method) { } public Detour(Expression<Action> from, IntPtr to) : this(from.Body, to) { } public Detour(Expression<Action> from, Expression<Action> to) : this(from.Body, to.Body) { } public void Apply() { if (!IsValid) { throw new InvalidOperationException("This detour has been undone."); } } public void Undo() { Func<object, bool> onUndo = OnUndo; if ((onUndo != null && !Extensions.InvokeWhileTrue((MulticastDelegate)onUndo, new object[1] { this })) || !IsValid) { return; } List<Detour> list = _DetourMap[Method]; lock (list) { list.Remove(this); _TopUndo(); if (list.Count > 0) { list[list.Count - 1]._TopApply(); } _UpdateChainedTrampolines(Method); } } public void Free() { if (IsValid) { Undo(); } } public void Dispose() { Undo(); Free(); } public MethodBase GenerateTrampoline(MethodBase signature = null) { Func<object, MethodBase, MethodBase> onGenerateTrampoline = OnGenerateTrampoline; MethodBase methodBase = ((onGenerateTrampoline != null) ? Extensions.InvokeWhileNull<MethodBase>((MulticastDelegate)onGenerateTrampoline, new object[2] { this, signature }) : null); if ((object)methodBase != null) { return methodBase; } if ((object)signature == null) { signature = Target; } Type returnType = (signature as MethodInfo)?.ReturnType ?? typeof(void); ParameterInfo[] parameters = signature.GetParameters(); Type[] array = new Type[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { array[i] = parameters[i].ParameterType; } DynamicMethod dynamicMethod = new DynamicMethod($"trampoline_{Method.Name}_{GetHashCode()}", returnType, array, Method.DeclaringType, skipVisibility: true); ILGenerator iLGenerator = dynamicMethod.GetILGenerator(); for (int j = 0; j < 10; j++) { iLGenerator.Emit(OpCodes.Nop); } iLGenerator.Emit(OpCodes.Jmp, _ChainedTrampoline); return dynamicMethod.Pin(); } public T GenerateTrampoline<T>() where T : Delegate { if (!typeof(Delegate).IsAssignableFrom(typeof(T))) { throw new InvalidOperationException($"Type {typeof(T)} not a delegate type."); } return Extensions.CreateDelegate(GenerateTrampoline(typeof(T).GetMethod("Invoke")), typeof(T)) as T; } private void _TopUndo() { if (_TopDetour != null) { _TopDetour.Undo(); _TopDetour.Free(); _TopDetour = null; } } private void _TopApply() { if (_TopDetour == null) { _TopDetour = new NativeDetour(Method.GetNativeStart(), Target.GetNativeStart()); } } private static void _UpdateChainedTrampolines(MethodBase method) { List<Detour> list = _DetourMap[method]; lock (list) { if (list.Count != 0) { NativeDetourData detour; for (int i = 1; i < list.Count; i++) { detour = DetourManager.Native.Create(list[i]._ChainedTrampoline.GetNativeStart(), list[i - 1].Target.GetNativeStart()); DetourManager.Native.MakeWritable(detour); DetourManager.Native.Apply(detour); DetourManager.Native.MakeExecutable(detour); DetourManager.Native.Free(detour); } detour = DetourManager.Native.Create(list[0]._ChainedTrampoline.GetNativeStart(), _BackupMethods[method].GetNativeStart()); DetourManager.Native.MakeWritable(detour); DetourManager.Native.Apply(detour); DetourManager.Native.MakeExecutable(detour); DetourManager.Native.Free(detour); } } } } public class Detour<T> : Detour where T : Delegate { public Detour(T from, IntPtr to) : base(from, to) { } public Detour(T from, T to) : base(from, to) { } } public static class DetourManager { public static IDetourRuntimePlatform Runtime; public static IDetourNativePlatform Native; private static readonly FieldInfo _Native; private static readonly MethodInfo _ToNativeDetourData; private static readonly MethodInfo _Copy; private static readonly MethodInfo _Apply; private static readonly ConstructorInfo _ctor_Exception; static DetourManager() { //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Invalid comparison between Unknown and I4 _Native = typeof(DetourManager).GetField("Native"); _ToNativeDetourData = typeof(DetourManager).GetMethod("ToNativeDetourData", BindingFlags.Static | BindingFlags.NonPublic); _Copy = typeof(IDetourNativePlatform).GetMethod("Copy"); _Apply = typeof(IDetourNativePlatform).GetMethod("Apply"); _ctor_Exception = typeof(Exception).GetConstructor(new Type[1] { typeof(string) }); if ((object)Type.GetType("Mono.Runtime") != null) { Runtime = new DetourRuntimeMonoPlatform(); } else { Runtime = new DetourRuntimeNETPlatform(); } typeof(object).Module.GetPEKind(out var _, out var machine); if (machine == ImageFileMachine.ARM) { Native = new DetourNativeARMPlatform(); } else { Native = new DetourNativeX86Platform(); } if ((PlatformHelper.Current & 0x25) == 37) { Native = new DetourNativeWindowsPlatform(Native); } } public unsafe static void Write(this IntPtr to, ref int offs, byte value) { *(byte*)((long)to + offs) = value; offs++; } public unsafe static void Write(this IntPtr to, ref int offs, ushort value) { *(ushort*)((long)to + offs) = value; offs += 2; } public unsafe static void Write(this IntPtr to, ref int offs, uint value) { *(uint*)((long)to + offs) = value; offs += 4; } public unsafe static void Write(this IntPtr to, ref int offs, ulong value) { *(ulong*)((long)to + offs) = value; offs += 8; } public static IntPtr GetNativeStart(this MethodBase method) { return Runtime.GetNativeStart(method.Pin()); } public static IntPtr GetNativeStart(this Delegate method) { return method.Method.GetNativeStart(); } public static IntPtr GetNativeStart(this Expression method) { return ((MethodCallExpression)method).Method.GetNativeStart(); } public static DynamicMethod CreateILCopy(this MethodBase method) { return Runtime.CreateCopy(method); } public static T Pin<T>(this T method) where T : MethodBase { Runtime.Pin(method); return method; } public static DynamicMethod GenerateNativeProxy(IntPtr target, MethodBase signature) { Type returnType = (signature as MethodInfo)?.ReturnType ?? typeof(void); ParameterInfo[] parameters = signature.GetParameters(); Type[] array = new Type[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { array[i] = parameters[i].ParameterType; } DynamicMethod method = new DynamicMethod(string.Format("native_{0}", ((long)target).ToString("X16")), returnType, array, restrictedSkipVisibility: true).StubCriticalDetour(); NativeDetourData detour = Native.Create(method.GetNativeStart(), target); Native.MakeWritable(detour); Native.Apply(detour); Native.MakeExecutable(detour); Native.Free(detour); return method.Pin(); } private static NativeDetourData ToNativeDetourData(IntPtr method, IntPtr target, int size, IntPtr extra) { NativeDetourData result = default(NativeDetourData); result.Method = method; result.Target = target; result.Size = size; result.Extra = extra; return result; } public static DynamicMethod StubCriticalDetour(this DynamicMethod dm) { ILGenerator iLGenerator = dm.GetILGenerator(); for (int i = 0; i < 10; i++) { iLGenerator.Emit(OpCodes.Nop); } iLGenerator.Emit(OpCodes.Ldstr, $"{dm.Name} should've been detoured!"); iLGenerator.Emit(OpCodes.Newobj, _ctor_Exception); iLGenerator.Emit(OpCodes.Throw); return dm; } public static void EmitDetourCopy(this ILGenerator il, IntPtr src, IntPtr dst, int size) { il.Emit(OpCodes.Ldsfld, _Native); il.Emit(OpCodes.Ldc_I8, (long)src); il.Emit(OpCodes.Conv_I); il.Emit(OpCodes.Ldc_I8, (long)dst); il.Emit(OpCodes.Conv_I); il.Emit(OpCodes.Ldc_I4, size); il.Emit(OpCodes.Callvirt, _Copy); } public static void EmitDetourApply(this ILGenerator il, NativeDetourData data) { il.Emit(OpCodes.Ldsfld, _Native); il.Emit(OpCodes.Ldc_I8, (long)data.Method); il.Emit(OpCodes.Conv_I); il.Emit(OpCodes.Ldc_I8, (long)data.Target); il.Emit(OpCodes.Conv_I); il.Emit(OpCodes.Ldc_I4, data.Size); il.Emit(OpCodes.Ldc_I8, (long)data.Extra); il.Emit(OpCodes.Conv_I); il.Emit(OpCodes.Call, _ToNativeDetourData); il.Emit(OpCodes.Callvirt, _Apply); } } public interface IDetourNativePlatform { NativeDetourData Create(IntPtr from, IntPtr to); void Free(NativeDetourData detour); void Apply(NativeDetourData detour); void Copy(IntPtr src, IntPtr dst, int size); void MakeWritable(NativeDetourData detour); void MakeExecutable(NativeDetourData detour); IntPtr MemAlloc(int size); void MemFree(IntPtr ptr); } public sealed class DetourNativeX86Platform : IDetourNativePlatform { private enum DetourSize { Rel32 = 5, Abs32 = 6, Abs64 = 14 } private static bool Is64Bit(long to) { return (to & 0xFFFFFFFFu) != to; } private static DetourSize GetDetourSize(IntPtr from, IntPtr to) { long to2 = (long)to - ((long)from + 5); if (!Is64Bit(to2)) { return DetourSize.Rel32; } if (!Is64Bit((long)to)) { return DetourSize.Abs32; } return DetourSize.Abs64; } public NativeDetourData Create(IntPtr from, IntPtr to) { NativeDetourData nativeDetourData = default(NativeDetourData); nativeDetourData.Method = from; nativeDetourData.Target = to; NativeDetourData result = nativeDetourData; result.Size = (int)GetDetourSize(from, to); return result; } public void Free(NativeDetourData detour) { } public void Apply(NativeDetourData detour) { int offs = 0; switch ((DetourSize)detour.Size) { case DetourSize.Rel32: detour.Method.Write(ref offs, 233); detour.Method.Write(ref offs, (uint)((long)detour.Target - ((long)detour.Method + offs + 4))); break; case DetourSize.Abs32: detour.Method.Write(ref offs, 104); detour.Method.Write(ref offs, (uint)(int)detour.Target); detour.Method.Write(ref offs, 195); break; case DetourSize.Abs64: detour.Method.Write(ref offs, byte.MaxValue); detour.Method.Write(ref offs, 37); detour.Method.Write(ref offs, 0u); detour.Method.Write(ref offs, (ulong)(long)detour.Target); break; default: throw new NotSupportedException($"Unknown X86 detour size {detour.Size}"); } } public unsafe void Copy(IntPtr src, IntPtr dst, int size) { switch ((DetourSize)size) { case DetourSize.Rel32: *(int*)(long)dst = *(int*)(long)src; *(sbyte*)((nint)(long)dst + 4) = *(sbyte*)((nint)(long)src + 4); break; case DetourSize.Abs32: *(int*)(long)dst = *(int*)(long)src; *(short*)((long)dst + 4) = *(short*)((long)src + 4); break; case DetourSize.Abs64: *(long*)(long)dst = *(long*)(long)src; *(int*)((long)dst + 8) = *(int*)((long)src + 8); *(short*)((long)dst + 12) = *(short*)((long)src + 12); break; default: throw new NotSupportedException($"Unknown X86 detour size {size}"); } } public void MakeWritable(NativeDetourData detour) { } public void MakeExecutable(NativeDetourData detour) { } public IntPtr MemAlloc(int size) { return Marshal.AllocHGlobal(size); } public void MemFree(IntPtr ptr) { Marshal.FreeHGlobal(ptr); } } public sealed class DetourNativeARMPlatform : IDetourNativePlatform { private enum DetourSize { Arm32 = 8, Arm64 = 12 } public NativeDetourData Create(IntPtr from, IntPtr to) { NativeDetourData nativeDetourData = default(NativeDetourData); nativeDetourData.Method = from; nativeDetourData.Target = to; NativeDetourData result = nativeDetourData; result.Size = ((IntPtr.Size == 4) ? 8 : 12); return result; } public void Free(NativeDetourData detour) { } public void Apply(NativeDetourData detour) { int offs = 0; switch ((DetourSize)detour.Size) { case DetourSize.Arm32: detour.Method.Write(ref offs, 4); detour.Method.Write(ref offs, 240); detour.Method.Write(ref offs, 31); detour.Method.Write(ref offs, 229); detour.Method.Write(ref offs, (uint)(int)detour.Target); break; case DetourSize.Arm64: detour.Method.Write(ref offs, 4); detour.Method.Write(ref offs, 240); detour.Method.Write(ref offs, 31); detour.Method.Write(ref offs, 229); detour.Method.Write(ref offs, (ulong)(long)detour.Target); break; default: throw new NotSupportedException($"Unknown ARM detour size {detour.Size}"); } } public unsafe void Copy(IntPtr src, IntPtr dst, int size) { switch ((DetourSize)size) { case DetourSize.Arm32: *(int*)(long)dst = *(int*)(long)src; *(int*)((long)dst + 4) = *(int*)((nint)(long)src + (nint)4 * (nint)4); break; case DetourSize.Arm64: *(int*)(long)dst = *(int*)(long)src; *(long*)((long)dst + 4) = *(long*)((nint)(long)src + (nint)4 * (nint)8); break; default: throw new NotSupportedException($"Unknown ARM detour size {size}"); } } public void MakeWritable(NativeDetourData detour) { } public void MakeExecutable(NativeDetourData detour) { } public IntPtr MemAlloc(int size) { return Marshal.AllocHGlobal(size); } public void MemFree(IntPtr ptr) { Marshal.FreeHGlobal(ptr); } } public sealed class DetourNativeWindowsPlatform : IDetourNativePlatform { [Flags] private enum Protection { PAGE_NOACCESS = 1, PAGE_READONLY = 2, PAGE_READWRITE = 4, PAGE_WRITECOPY = 8, PAGE_EXECUTE = 0x10, PAGE_EXECUTE_READ = 0x20, PAGE_EXECUTE_READWRITE = 0x40, PAGE_EXECUTE_WRITECOPY = 0x80, PAGE_GUARD = 0x100, PAGE_NOCACHE = 0x200, PAGE_WRITECOMBINE = 0x400 } private IDetourNativePlatform Inner; public DetourNativeWindowsPlatform(IDetourNativePlatform inner) { Inner = inner; } [DllImport("kernel32.dll")] private static extern bool VirtualProtect(IntPtr lpAddress, IntPtr dwSize, Protection flNewProtect, out Protection lpflOldProtect); public void MakeWritable(NativeDetourData detour) { if (!VirtualProtect(detour.Method, (IntPtr)detour.Size, Protection.PAGE_EXECUTE_READWRITE, out var _)) { throw new Win32Exception(); } Inner.MakeWritable(detour); } public void MakeExecutable(NativeDetourData detour) { if (!VirtualProtect(detour.Method, (IntPtr)detour.Size, Protection.PAGE_EXECUTE_READWRITE, out var _)) { throw new Win32Exception(); } Inner.MakeExecutable(detour); } public NativeDetourData Create(IntPtr from, IntPtr to) { return Inner.Create(from, to); } public void Free(NativeDetourData detour) { Inner.Free(detour); } public void Apply(NativeDetourData detour) { Inner.Apply(detour); } public void Copy(IntPtr src, IntPtr dst, int size) { Inner.Copy(src, dst, size); } public IntPtr MemAlloc(int size) { return Inner.MemAlloc(size); } public void MemFree(IntPtr ptr) { Inner.MemFree(ptr); } } public interface IDetourRuntimePlatform { IntPtr GetNativeStart(MethodBase method); DynamicMethod CreateCopy(MethodBase method); void Pin(MethodBase method); } public abstract class DetourRuntimeILPlatform : IDetourRuntimePlatform { protected HashSet<DynamicMethod> PinnedDynamicMethods = new HashSet<DynamicMethod>(); protected abstract RuntimeMethodHandle GetMethodHandle(MethodBase method); public IntPtr GetNativeStart(MethodBase method) { return GetMethodHandle(method).GetFunctionPointer(); } public void Pin(MethodBase method) { RuntimeMethodHandle methodHandle = GetMethodHandle(method); if (method is DynamicMethod) { DynamicMethod item = (DynamicMethod)method; PinnedDynamicMethods.Add(item); } RuntimeHelpers.PrepareMethod(methodHandle); } public DynamicMethod CreateCopy(MethodBase method) { MethodBody methodBody; try { methodBody = method.GetMethodBody(); } catch (InvalidOperationException) { methodBody = null; } if (methodBody == null) { throw new InvalidOperationException("P/Invoke methods cannot be copied!"); } ParameterInfo[] parameters = method.GetParameters(); Type[] array; if (!method.IsStatic) { array = new Type[parameters.Length + 1]; array[0] = method.DeclaringType; for (int i = 0; i < parameters.Length; i++) { array[i + 1] = parameters[i].ParameterType; } } else { array = new Type[parameters.Length]; for (int j = 0; j < parameters.Length; j++) { array[j] = parameters[j].ParameterType; } } DynamicMethod dynamicMethod = new DynamicMethod($"orig_{method.Name}", (method as MethodInfo)?.ReturnType ?? typeof(void), array, method.DeclaringType, skipVisibility: false); ILGenerator iLGenerator = dynamicMethod.GetILGenerator(); using (MethodCopier methodCopier = new MethodCopier(method, iLGenerator)) { methodCopier.Copy(); } return dynamicMethod.Pin(); } } public sealed class DetourRuntimeNETPlatform : DetourRuntimeILPlatform { private static readonly FieldInfo f_DynamicMethod_m_method = typeof(DynamicMethod).GetField("m_method", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly MethodInfo m_DynamicMethod_GetMethodDescriptor = typeof(DynamicMethod).GetMethod("GetMethodDescriptor", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FastReflectionDelegate dmd_DynamicMethod_GetMethodDescriptor; private static readonly MethodInfo m_RuntimeHelpers__CompileMethod; private static readonly FastReflectionDelegate dmd_RuntimeHelpers__CompileMethod; private static readonly bool m_RuntimeHelpers__CompileMethod_TakesIntPtr; private static readonly bool m_RuntimeHelpers__CompileMethod_TakesIRuntimeMethodInfo; private static readonly MethodInfo m_RuntimeMethodHandle_GetMethodInfo; private static readonly FastReflectionDelegate dmd_RuntimeMethodHandle_GetMethodInfo; protected override RuntimeMethodHandle GetMethodHandle(MethodBase method) { if (method is DynamicMethod) { DynamicMethod dynamicMethod = (DynamicMethod)method; try { dynamicMethod.CreateDelegate(typeof(MulticastDelegate)); } catch { } if ((object)f_DynamicMethod_m_method != null) { return (RuntimeMethodHandle)f_DynamicMethod_m_method.GetValue(method); } if (dmd_DynamicMethod_GetMethodDescriptor != null) { return (RuntimeMethodHandle)dmd_DynamicMethod_GetMethodDescriptor.Invoke((object)method, new object[0]); } } return method.MethodHandle; } static DetourRuntimeNETPlatform() { MethodInfo dynamicMethod_GetMethodDescriptor = m_DynamicMethod_GetMethodDescriptor; dmd_DynamicMethod_GetMethodDescriptor = (((object)dynamicMethod_GetMethodDescriptor != null) ? FastReflectionHelper.CreateFastDelegate((MethodBase)dynamicMethod_GetMethodDescriptor, true) : null); m_RuntimeHelpers__CompileMethod = typeof(RuntimeHelpers).GetMethod("_CompileMethod", BindingFlags.Static | BindingFlags.NonPublic); MethodInfo runtimeHelpers__CompileMethod = m_RuntimeHelpers__CompileMethod; dmd_RuntimeHelpers__CompileMethod = (((object)runtimeHelpers__CompileMethod != null) ? FastReflectionHelper.CreateFastDelegate((MethodBase)runtimeHelpers__CompileMethod, true) : null); m_RuntimeHelpers__CompileMethod_TakesIntPtr = (object)m_RuntimeHelpers__CompileMethod != null && m_RuntimeHelpers__CompileMethod.GetParameters()[0].ParameterType.FullName == "System.IntPtr"; m_RuntimeHelpers__CompileMethod_TakesIRuntimeMethodInfo = (object)m_RuntimeHelpers__CompileMethod != null && m_RuntimeHelpers__CompileMethod.GetParameters()[0].ParameterType.FullName == "System.IRuntimeMethodInfo"; m_RuntimeMethodHandle_GetMethodInfo = typeof(RuntimeMethodHandle).GetMethod("GetMethodInfo", BindingFlags.Instance | BindingFlags.NonPublic); MethodInfo runtimeMethodHandle_GetMethodInfo = m_RuntimeMethodHandle_GetMethodInfo; dmd_RuntimeMethodHandle_GetMethodInfo = (((object)runtimeMethodHandle_GetMethodInfo != null) ? FastReflectionHelper.CreateFastDelegate((MethodBase)runtimeMethodHandle_GetMethodInfo, true) : null); } } public sealed class DetourRuntimeMonoPlatform : DetourRuntimeILPlatform { private static readonly MethodInfo m_DynamicMethod_CreateDynMethod = typeof(DynamicMethod).GetMethod("CreateDynMethod", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FastReflectionDelegate dmd_DynamicMethod_CreateDynMethod; private static readonly FieldInfo f_DynamicMethod_mhandle; protected override RuntimeMethodHandle GetMethodHandle(MethodBase method) { if (method is DynamicMethod) { FastReflectionDelegate obj = dmd_DynamicMethod_CreateDynMethod; if (obj != null) { obj.Invoke((object)method, new object[0]); } if ((object)f_DynamicMethod_mhandle != null) { return (RuntimeMethodHandle)f_DynamicMethod_mhandle.GetValue(method); } } return method.MethodHandle; } static DetourRuntimeMonoPlatform() { MethodInfo dynamicMethod_CreateDynMethod = m_DynamicMethod_CreateDynMethod; dmd_DynamicMethod_CreateDynMethod = (((object)dynamicMethod_CreateDynMethod != null) ? FastReflectionHelper.CreateFastDelegate((MethodBase)dynamicMethod_CreateDynMethod, true) : null); f_DynamicMethod_mhandle = typeof(DynamicMethod).GetField("mhandle", BindingFlags.Instance | BindingFlags.NonPublic); } } public class Hook : IDetour, IDisposable { public readonly MethodBase Method; public readonly MethodBase Target; private MethodInfo _Hook; private Detour _Detour; private int? _RefTarget; private int? _RefTrampoline; public bool IsValid => _Detour.IsValid; public Hook(MethodBase from, MethodInfo to, object target) { Method = from; _Hook = to; Type type = (from as MethodInfo)?.ReturnType ?? typeof(void); if ((object)_Hook.ReturnType != type && !_Hook.ReturnType.IsAssignableFrom(type)) { throw new InvalidOperationException($"Return type of hook for {from} doesn't match, must be {((from as MethodInfo)?.ReturnType ?? typeof(void)).FullName}"); } if (target == null && !to.IsStatic) { throw new InvalidOperationException($"Hook for method {from} must be static, or you must pass a target instance."); } ParameterInfo[] parameters = _Hook.GetParameters(); ParameterInfo[] parameters2 = Method.GetParameters(); Type[] array; if (!Method.IsStatic) { array = new Type[parameters2.Length + 1]; array[0] = Method.DeclaringType; for (int i = 0; i < parameters2.Length; i++) { array[i + 1] = parameters2[i].ParameterType; } } else { array = new Type[parameters2.Length]; for (int j = 0; j < parameters2.Length; j++) { array[j] = parameters2[j].ParameterType; } } Type type2 = null; if (parameters.Length == array.Length + 1 && typeof(Delegate).IsAssignableFrom(parameters[0].ParameterType)) { type2 = parameters[0].ParameterType; } else if (parameters.Length != array.Length) { throw new InvalidOperationException($"Parameter count of hook for {from} doesn't match, must be {array.Length}"); } for (int k = 0; k < array.Length; k++) { Type type3 = array[k]; Type parameterType = parameters[k + (((object)type2 != null) ? 1 : 0)].ParameterType; if (!type3.IsAssignableFrom(parameterType) && !parameterType.IsAssignableFrom(type3)) { throw new InvalidOperationException($"Parameter #{k} of hook for {from} doesn't match, must be {type3.FullName} or related"); } } MethodInfo signature = type2?.GetMethod("Invoke"); DynamicMethod dynamicMethod = new DynamicMethod($"hook_{Method.Name}_{GetHashCode()}", (Method as MethodInfo)?.ReturnType ?? typeof(void), array, Method.DeclaringType, skipVisibility: true); ILGenerator iLGenerator = dynamicMethod.GetILGenerator(); if (target != null) { _RefTarget = DynamicMethodHelper.EmitReference<object>(iLGenerator, target); } if ((object)type2 != null) { _RefTrampoline = DynamicMethodHelper.EmitReference<Delegate>(iLGenerator, (Delegate)null); } for (int l = 0; l < array.Length; l++) { iLGenerator.Emit(OpCodes.Ldarg, l); } iLGenerator.Emit(OpCodes.Call, _Hook); iLGenerator.Emit(OpCodes.Ret); Target = dynamicMethod.Pin(); _Detour = new Detour(Method, Target); if ((object)type2 != null) { DynamicMethodHelper.SetReference(_RefTrampoline.Value, (object)Extensions.CreateDelegate(GenerateTrampoline(signature), type2)); } } public Hook(MethodBase from, MethodInfo to) : this(from, to, null) { } public Hook(MethodBase method, IntPtr to) : this(method, DetourManager.GenerateNativeProxy(to, method), null) { } public Hook(MethodBase method, Delegate to) : this(method, to.Method, to.Target) { } public Hook(Delegate from, IntPtr to) : this(from.Method, to) { } public Hook(Delegate from, Delegate to) : this(from.Method, to) { } public Hook(Expression from, IntPtr to) : this(((MethodCallExpression)from).Method, to) { } public Hook(Expression from, Delegate to) : this(((MethodCallExpression)from).Method, to) { } public Hook(Expression<Action> from, IntPtr to) : this(from.Body, to) { } public Hook(Expression<Action> from, Delegate to) : this(from.Body, to) { } public void Apply() { _Detour.Apply(); } public void Undo() { _Detour.Undo(); if (!IsValid) { _Free(); } } public void Free() { if (IsValid) { _Detour.Free(); _Free(); } } public void Dispose() { Undo(); Free(); } private void _Free() { if (_RefTarget.HasValue) { DynamicMethodHelper.FreeReference(_RefTarget.Value); } if (_RefTrampoline.HasValue) { DynamicMethodHelper.FreeReference(_RefTrampoline.Value); } } public MethodBase GenerateTrampoline(MethodBase signature = null) { return _Detour.GenerateTrampoline(signature); } public T GenerateTrampoline<T>() where T : Delegate { return _Detour.GenerateTrampoline<T>(); } } public class Hook<T> : Hook { public Hook(Expression<Action> from, T to) : base(from.Body, to as Delegate) { } public Hook(Expression<Func<T>> from, IntPtr to) : base(from.Body, to) { } public Hook(Expression<Func<T>> from, Delegate to) : base(from.Body, to) { } public Hook(T from, IntPtr to) : base(from as Delegate, to) { } public Hook(T from, T to) : base(from as Delegate, to as Delegate) { } } public class Hook<TFrom, TTo> : Hook { public Hook(Expression<Func<TFrom>> from, TTo to) : base(from.Body, to as Delegate) { } public Hook(TFrom from, TTo to) : base(from as Delegate, to as Delegate) { } } public interface IDetour : IDisposable { bool IsValid { get; } void Apply(); void Undo(); void Free(); MethodBase GenerateTrampoline(MethodBase signature = null); T GenerateTrampoline<T>() where T : Delegate; } public struct NativeDetourData { public IntPtr Method; public IntPtr Target; public int Size; public IntPtr Extra; } public class NativeDetour : IDetour, IDisposable { public static Func<object, MethodBase, IntPtr, IntPtr, bool> OnDetour; public static Func<object, bool> OnUndo; public static Func<object, MethodBase, MethodBase> OnGenerateTrampoline; public readonly NativeDetourData Data; public readonly MethodBase Method; private DynamicMethod _BackupMethod; private IntPtr _BackupNative; private bool _IsFree; public bool IsValid => !_IsFree; public NativeDetour(MethodBase method, IntPtr from, IntPtr to) { Func<object, MethodBase, IntPtr, IntPtr, bool> onDetour = OnDetour; if (onDetour == null || Extensions.InvokeWhileTrue((MulticastDelegate)onDetour, new object[4] { this, method, from, to })) { Data = DetourManager.Native.Create(from, to); Method = method; MethodBody methodBody; try { methodBody = Method?.GetMethodBody(); } catch (InvalidOperationException) { methodBody = null; } if (methodBody != null) { _BackupMethod = method.CreateILCopy(); } _BackupNative = DetourManager.Native.MemAlloc(Data.Size); DetourManager.Native.Copy(Data.Method, _BackupNative, Data.Size); Apply(); } } public NativeDetour(IntPtr from, IntPtr to) : this(null, from, to) { } public NativeDetour(MethodBase from, IntPtr to) : this(from, from.GetNativeStart(), to) { } public NativeDetour(IntPtr from, MethodBase to) : this(from, to.GetNativeStart()) { } public NativeDetour(MethodBase from, MethodBase to) : this(from, to.GetNativeStart()) { } public NativeDetour(Delegate from, IntPtr to) : this(from.Method, to) { } public NativeDetour(IntPtr from, Delegate to) : this(from, to.Method) { } public NativeDetour(Delegate from, Delegate to) : this(from.Method, to.Method) { } public void Apply() { if (_IsFree) { throw new InvalidOperationException("Free() has been called on this detour."); } DetourManager.Native.MakeWritable(Data); DetourManager.Native.Apply(Data); DetourManager.Native.MakeExecutable(Data); } public void Undo() { Func<object, bool> onUndo = OnUndo; if ((onUndo == null || Extensions.InvokeWhileTrue((MulticastDelegate)onUndo, new object[1] { this })) && !_IsFree) { DetourManager.Native.Copy(_BackupNative, Data.Method, Data.Size); } } public void Free() { if (!_IsFree) { _IsFree = true; DetourManager.Native.MemFree(_BackupNative); DetourManager.Native.Free(Data); } } public void Dispose() { Undo(); Free(); } public MethodBase GenerateTrampoline(MethodBase signature = null) { Func<object, MethodBase, MethodBase> onGenerateTrampoline = OnGenerateTrampoline; MethodBase methodBase = ((onGenerateTrampoline != null) ? Extensions.InvokeWhileNull<MethodBase>((MulticastDelegate)onGenerateTrampoline, new object[2] { this, signature }) : null); if ((object)methodBase != null) { return methodBase; } if (_IsFree) { throw new InvalidOperationException("Free() has been called on this detour."); } if ((object)_BackupMethod != null) { return _BackupMethod; } if ((object)signature == null) { signature = _BackupMethod; } if ((object)signature == null) { throw new ArgumentNullException("A signature must be given if the NativeDetour doesn't hold a reference to a managed method."); } MethodBase methodBase2 = Method; if ((object)methodBase2 == null) { methodBase2 = DetourManager.GenerateNativeProxy(Data.Method, signature); } Type type = (signature as MethodInfo)?.ReturnType ?? typeof(void); ParameterInfo[] parameters = signature.GetParameters(); Type[] array = new Type[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { array[i] = parameters[i].ParameterType; } string name = string.Format("trampoline_native_{0}_{1}", Method?.Name.ToString() ?? ((long)Data.Method).ToString("X16"), GetHashCode()); DynamicMethod dynamicMethod = (((object)Method == null) ? new DynamicMethod(name, type, array, restrictedSkipVisibility: true) : new DynamicMethod(name, type, array, Method.DeclaringType, skipVisibility: true)); ILGenerator iLGenerator = dynamicMethod.GetILGenerator(); iLGenerator.EmitDetourCopy(_BackupNative, Data.Method, Data.Size); LocalBuilder localBuilder = null; if ((object)type != typeof(void)) { localBuilder = iLGenerator.DeclareLocal(type); } Label label = iLGenerator.BeginExceptionBlock(); for (int j = 0; j < array.Length; j++) { iLGenerator.Emit(OpCodes.Ldarg, j); } if (methodBase2 is MethodInfo) { iLGenerator.Emit(OpCodes.Call, (MethodInfo)methodBase2); } else { if (!(methodBase2 is ConstructorInfo)) { throw new NotSupportedException($"Method type {methodBase2.GetType().FullName} not supported."); } iLGenerator.Emit(OpCodes.Call, (ConstructorInfo)methodBase2); } if (localBuilder != null) { iLGenerator.Emit(OpCodes.Stloc_0); } iLGenerator.BeginFinallyBlock(); iLGenerator.EmitDetourApply(Data); iLGenerator.EndExceptionBlock(); if (localBuilder != null) { iLGenerator.Emit(OpCodes.Ldloc_0); } iLGenerator.Emit(OpCodes.Ret); return dynamicMethod.Pin(); } public T GenerateTrampoline<T>() where T : Delegate { if (!typeof(Delegate).IsAssignableFrom(typeof(T))) { throw new InvalidOperationException($"Type {typeof(T)} not a delegate type."); } return Extensions.CreateDelegate(GenerateTrampoline(typeof(T).GetMethod("Invoke")), typeof(T)) as T; } } } namespace MonoMod.RuntimeDetour.HookGen { public static class HookExtensions { public delegate void ILManipulatorMini(MethodBody body, ILProcessor il); public static bool Match(this Instruction instr, OpCode opcode) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) return instr.OpCode == opcode; } public static bool Match<T>(this Instruction instr, OpCode opcode, T value) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) T value2; return instr.Match<T>(opcode, out value2) && (value2?.Equals(value) ?? (value == null)); } public static bool Match<T>(this Instruction instr, OpCode opcode, out T value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == opcode) { value = (T)instr.Operand; return false; } value = default(T); return false; } public static bool MatchNop(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Nop) { return true; } return false; } public static bool MatchBreak(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Break) { return true; } return false; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use MatchLdarg instead.", true)] public static bool MatchLdarg0(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Ldarg_0) { return true; } return false; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use MatchLdarg instead.", true)] public static bool MatchLdarg1(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Ldarg_1) { return true; } return false; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use MatchLdarg instead.", true)] public static bool MatchLdarg2(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Ldarg_2) { return true; } return false; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use MatchLdarg instead.", true)] public static bool MatchLdarg3(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Ldarg_3) { return true; } return false; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use MatchLdloc instead.", true)] public static bool MatchLdloc0(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Ldloc_0) { return true; } return false; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use MatchLdloc instead.", true)] public static bool MatchLdloc1(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Ldloc_1) { return true; } return false; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use MatchLdloc instead.", true)] public static bool MatchLdloc2(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Ldloc_2) { return true; } return false; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use MatchLdloc instead.", true)] public static bool MatchLdloc3(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Ldloc_3) { return true; } return false; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use MatchStloc instead.", true)] public static bool MatchStloc0(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Stloc_0) { return true; } return false; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use MatchStloc instead.", true)] public static bool MatchStloc1(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Stloc_1) { return true; } return false; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use MatchStloc instead.", true)] public static bool MatchStloc2(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Stloc_2) { return true; } return false; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use MatchStloc instead.", true)] public static bool MatchStloc3(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Stloc_3) { return true; } return false; } public static bool MatchLdnull(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Ldnull) { return true; } return false; } public static bool MatchLdcI4(this Instruction instr, int value) { int value2; return instr.MatchLdcI4(out value2) && value2 == value; } public static bool MatchLdcI4(this Instruction instr, out int value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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_0059: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: 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) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: 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_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Ldc_I4) { value = (int)instr.Operand; return true; } if (instr.OpCode == OpCodes.Ldc_I4_S) { value = (sbyte)instr.Operand; return true; } if (instr.OpCode == OpCodes.Ldc_I4_M1) { value = -1; return true; } if (instr.OpCode == OpCodes.Ldc_I4_0) { value = 0; return true; } if (instr.OpCode == OpCodes.Ldc_I4_1) { value = 1; return true; } if (instr.OpCode == OpCodes.Ldc_I4_2) { value = 2; return true; } if (instr.OpCode == OpCodes.Ldc_I4_3) { value = 3; return true; } if (instr.OpCode == OpCodes.Ldc_I4_4) { value = 4; return true; } if (instr.OpCode == OpCodes.Ldc_I4_5) { value = 5; return true; } if (instr.OpCode == OpCodes.Ldc_I4_6) { value = 6; return true; } if (instr.OpCode == OpCodes.Ldc_I4_7) { value = 7; return true; } if (instr.OpCode == OpCodes.Ldc_I4_8) { value = 8; return true; } value = 0; return false; } public static bool MatchLdcI8(this Instruction instr, long value) { long value2; return instr.MatchLdcI8(out value2) && value2 == value; } public static bool MatchLdcI8(this Instruction instr, out long value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Ldc_I8) { value = (long)instr.Operand; return true; } value = 0L; return false; } public static bool MatchLdcR4(this Instruction instr, float value) { float value2; return instr.MatchLdcR4(out value2) && value2 == value; } public static bool MatchLdcR4(this Instruction instr, out float value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Ldc_R4) { value = (float)instr.Operand; return true; } value = 0f; return false; } public static bool MatchLdcR8(this Instruction instr, double value) { double value2; return instr.MatchLdcR8(out value2) && value2 == value; } public static bool MatchLdcR8(this Instruction instr, out double value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Ldc_R8) { value = (double)instr.Operand; return true; } value = 0.0; return false; } public static bool MatchDup(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Dup) { return true; } return false; } public static bool MatchPop(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Pop) { return true; } return false; } public static bool MatchJmp(this Instruction instr, string typeFullName, string name) { MethodReference value; return instr.MatchJmp(out value) && ((MemberReference)(object)value).Is(typeFullName, name); } public static bool MatchJmp<T>(this Instruction instr, string name) { MethodReference value; return instr.MatchJmp(out value) && ((MemberReference)(object)value).Is(typeof(T), name); } public static bool MatchJmp(this Instruction instr, Type type, string name) { MethodReference value; return instr.MatchJmp(out value) && ((MemberReference)(object)value).Is(type, name); } public static bool MatchJmp(this Instruction instr, MethodBase value) { MethodReference value2; return instr.MatchJmp(out value2) && ((MemberReference)(object)value2).Is(value); } public static bool MatchJmp(this Instruction instr, MethodReference value) { MethodReference value2; return instr.MatchJmp(out value2) && value2 == value; } public static bool MatchJmp(this Instruction instr, out MethodReference value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Jmp) { object operand = instr.Operand; value = (MethodReference)((operand is MethodReference) ? operand : null); return true; } value = null; return false; } public static bool MatchCall(this Instruction instr, string typeFullName, string name) { MethodReference value; return instr.MatchCall(out value) && ((MemberReference)(object)value).Is(typeFullName, name); } public static bool MatchCall<T>(this Instruction instr, string name) { MethodReference value; return instr.MatchCall(out value) && ((MemberReference)(object)value).Is(typeof(T), name); } public static bool MatchCall(this Instruction instr, Type type, string name) { MethodReference value; return instr.MatchCall(out value) && ((MemberReference)(object)value).Is(type, name); } public static bool MatchCall(this Instruction instr, MethodBase value) { MethodReference value2; return instr.MatchCall(out value2) && ((MemberReference)(object)value2).Is(value); } public static bool MatchCall(this Instruction instr, MethodReference value) { MethodReference value2; return instr.MatchCall(out value2) && value2 == value; } public static bool MatchCall(this Instruction instr, out MethodReference value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Call) { object operand = instr.Operand; value = (MethodReference)((operand is MethodReference) ? operand : null); return true; } value = null; return false; } public static bool MatchCalli(this Instruction instr, IMethodSignature value) { IMethodSignature value2; return instr.MatchCalli(out value2) && value2 == value; } public static bool MatchCalli(this Instruction instr, out IMethodSignature value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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_0023: Expected O, but got Unknown if (instr.OpCode == OpCodes.Calli) { value = (IMethodSignature)instr.Operand; return true; } value = null; return false; } public static bool MatchRet(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Ret) { return true; } return false; } public static bool MatchBr(this Instruction instr, Instruction value) { Instruction value2; return instr.MatchBr(out value2) && value2 == value; } public static bool MatchBr(this Instruction instr, out Instruction value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown if (instr.OpCode == OpCodes.Br || instr.OpCode == OpCodes.Br_S) { value = (Instruction)instr.Operand; return true; } value = null; return false; } public static bool MatchBrfalse(this Instruction instr, Instruction value) { Instruction value2; return instr.MatchBrfalse(out value2) && value2 == value; } public static bool MatchBrfalse(this Instruction instr, out Instruction value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown if (instr.OpCode == OpCodes.Brfalse || instr.OpCode == OpCodes.Brfalse_S) { value = (Instruction)instr.Operand; return true; } value = null; return false; } public static bool MatchBrtrue(this Instruction instr, Instruction value) { Instruction value2; return instr.MatchBrtrue(out value2) && value2 == value; } public static bool MatchBrtrue(this Instruction instr, out Instruction value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown if (instr.OpCode == OpCodes.Brtrue || instr.OpCode == OpCodes.Brtrue_S) { value = (Instruction)instr.Operand; return true; } value = null; return false; } public static bool MatchBeq(this Instruction instr, Instruction value) { Instruction value2; return instr.MatchBeq(out value2) && value2 == value; } public static bool MatchBeq(this Instruction instr, out Instruction value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown if (instr.OpCode == OpCodes.Beq || instr.OpCode == OpCodes.Beq_S) { value = (Instruction)instr.Operand; return true; } value = null; return false; } public static bool MatchBge(this Instruction instr, Instruction value) { Instruction value2; return instr.MatchBge(out value2) && value2 == value; } public static bool MatchBge(this Instruction instr, out Instruction value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown if (instr.OpCode == OpCodes.Bge || instr.OpCode == OpCodes.Bge_S) { value = (Instruction)instr.Operand; return true; } value = null; return false; } public static bool MatchBgt(this Instruction instr, Instruction value) { Instruction value2; return instr.MatchBgt(out value2) && value2 == value; } public static bool MatchBgt(this Instruction instr, out Instruction value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown if (instr.OpCode == OpCodes.Bgt || instr.OpCode == OpCodes.Bgt_S) { value = (Instruction)instr.Operand; return true; } value = null; return false; } public static bool MatchBle(this Instruction instr, Instruction value) { Instruction value2; return instr.MatchBle(out value2) && value2 == value; } public static bool MatchBle(this Instruction instr, out Instruction value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown if (instr.OpCode == OpCodes.Ble || instr.OpCode == OpCodes.Ble_S) { value = (Instruction)instr.Operand; return true; } value = null; return false; } public static bool MatchBlt(this Instruction instr, Instruction value) { Instruction value2; return instr.MatchBlt(out value2) && value2 == value; } public static bool MatchBlt(this Instruction instr, out Instruction value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown if (instr.OpCode == OpCodes.Blt || instr.OpCode == OpCodes.Blt_S) { value = (Instruction)instr.Operand; return true; } value = null; return false; } public static bool MatchBneUn(this Instruction instr, Instruction value) { Instruction value2; return instr.MatchBneUn(out value2) && value2 == value; } public static bool MatchBneUn(this Instruction instr, out Instruction value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown if (instr.OpCode == OpCodes.Bne_Un || instr.OpCode == OpCodes.Bne_Un_S) { value = (Instruction)instr.Operand; return true; } value = null; return false; } public static bool MatchBgeUn(this Instruction instr, Instruction value) { Instruction value2; return instr.MatchBgeUn(out value2) && value2 == value; } public static bool MatchBgeUn(this Instruction instr, out Instruction value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown if (instr.OpCode == OpCodes.Bge_Un || instr.OpCode == OpCodes.Bge_Un_S) { value = (Instruction)instr.Operand; return true; } value = null; return false; } public static bool MatchBgtUn(this Instruction instr, Instruction value) { Instruction value2; return instr.MatchBgtUn(out value2) && value2 == value; } public static bool MatchBgtUn(this Instruction instr, out Instruction value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown if (instr.OpCode == OpCodes.Bgt_Un || instr.OpCode == OpCodes.Bgt_Un_S) { value = (Instruction)instr.Operand; return true; } value = null; return false; } public static bool MatchBleUn(this Instruction instr, Instruction value) { Instruction value2; return instr.MatchBleUn(out value2) && value2 == value; } public static bool MatchBleUn(this Instruction instr, out Instruction value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown if (instr.OpCode == OpCodes.Ble_Un || instr.OpCode == OpCodes.Ble_Un_S) { value = (Instruction)instr.Operand; return true; } value = null; return false; } public static bool MatchBltUn(this Instruction instr, Instruction value) { Instruction value2; return instr.MatchBltUn(out value2) && value2 == value; } public static bool MatchBltUn(this Instruction instr, out Instruction value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown if (instr.OpCode == OpCodes.Blt_Un || instr.OpCode == OpCodes.Blt_Un_S) { value = (Instruction)instr.Operand; return true; } value = null; return false; } public static bool MatchSwitch(this Instruction instr, Instruction[] value) { Instruction[] value2; return instr.MatchSwitch(out value2) && value2 == value; } public static bool MatchSwitch(this Instruction instr, out Instruction[] value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Switch) { value = (Instruction[])instr.Operand; return true; } value = null; return false; } public static bool MatchLdindI1(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Ldind_I1) { return true; } return false; } public static bool MatchLdindU1(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Ldind_U1) { return true; } return false; } public static bool MatchLdindI2(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Ldind_I2) { return true; } return false; } public static bool MatchLdindU2(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Ldind_U2) { return true; } return false; } public static bool MatchLdindI4(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Ldind_I4) { return true; } return false; } public static bool MatchLdindU4(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Ldind_U4) { return true; } return false; } public static bool MatchLdindI8(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Ldind_I8) { return true; } return false; } public static bool MatchLdindI(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Ldind_I) { return true; } return false; } public static bool MatchLdindR4(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Ldind_R4) { return true; } return false; } public static bool MatchLdindR8(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Ldind_R8) { return true; } return false; } public static bool MatchLdindRef(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Ldind_Ref) { return true; } return false; } public static bool MatchStindRef(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Stind_Ref) { return true; } return false; } public static bool MatchStindI1(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Stind_I1) { return true; } return false; } public static bool MatchStindI2(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Stind_I2) { return true; } return false; } public static bool MatchStindI4(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Stind_I4) { return true; } return false; } public static bool MatchStindI8(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Stind_I8) { return true; } return false; } public static bool MatchStindR4(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Stind_R4) { return true; } return false; } public static bool MatchStindR8(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Stind_R8) { return true; } return false; } public static bool MatchAdd(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Add) { return true; } return false; } public static bool MatchSub(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Sub) { return true; } return false; } public static bool MatchMul(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Mul) { return true; } return false; } public static bool MatchDiv(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Div) { return true; } return false; } public static bool MatchDivUn(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Div_Un) { return true; } return false; } public static bool MatchRem(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Rem) { return true; } return false; } public static bool MatchRemUn(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Rem_Un) { return true; } return false; } public static bool MatchAnd(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.And) { return true; } return false; } public static bool MatchOr(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Or) { return true; } return false; } public static bool MatchXor(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Xor) { return true; } return false; } public static bool MatchShl(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Shl) { return true; } return false; } public static bool MatchShr(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Shr) { return true; } return false; } public static bool MatchShrUn(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Shr_Un) { return true; } return false; } public static bool MatchNeg(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Neg) { return true; } return false; } public static bool MatchNot(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Not) { return true; } return false; } public static bool MatchConvI1(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Conv_I1) { return true; } return false; } public static bool MatchConvI2(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Conv_I2) { return true; } return false; } public static bool MatchConvI4(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Conv_I4) { return true; } return false; } public static bool MatchConvI8(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Conv_I8) { return true; } return false; } public static bool MatchConvR4(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Conv_R4) { return true; } return false; } public static bool MatchConvR8(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Conv_R8) { return true; } return false; } public static bool MatchConvU4(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Conv_U4) { return true; } return false; } public static bool MatchConvU8(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Conv_U8) { return true; } return false; } public static bool MatchCallvirt(this Instruction instr, string typeFullName, string name) { MethodReference value; return instr.MatchCallvirt(out value) && ((MemberReference)(object)value).Is(typeFullName, name); } public static bool MatchCallvirt<T>(this Instruction instr, string name) { MethodReference value; return instr.MatchCallvirt(out value) && ((MemberReference)(object)value).Is(typeof(T), name); } public static bool MatchCallvirt(this Instruction instr, Type type, string name) { MethodReference value; return instr.MatchCallvirt(out value) && ((MemberReference)(object)value).Is(type, name); } public static bool MatchCallvirt(this Instruction instr, MethodBase value) { MethodReference value2; return instr.MatchCallvirt(out value2) && ((MemberReference)(object)value2).Is(value); } public static bool MatchCallvirt(this Instruction instr, MethodReference value) { MethodReference value2; return instr.MatchCallvirt(out value2) && value2 == value; } public static bool MatchCallvirt(this Instruction instr, out MethodReference value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (instr.OpCode == OpCodes.Callvirt) { object operand = instr.Operand; value = (MethodReference)((operand is MethodReference) ? operand : null); return true; } value = null; return false; } public static bool MatchCpobj(this Instruction instr, string fullName) { TypeReference value; return instr.MatchCpobj(out value) && ((MemberReference)(object)value).Is(fullName); } public static bool MatchCpobj<T>(this Instruction instr) { TypeReference value; return instr.MatchCpobj(out value) && ((MemberReference)(object)value).Is(typeof(T)); } public static bool MatchCpobj(this Instruction instr, Type valu
plugins/Batteritems/MonoMod.Utils.dll
Decompiled 8 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; using System.Text.RegularExpressions; using Mono.Cecil; using Mono.Cecil.Cil; using Mono.Collections.Generic; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyTitle("MonoMod.Utils")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("MonoMod.Utils")] [assembly: AssemblyCopyright("Copyright © 2018")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("1839cfe2-3db0-45a8-b03d-9aa797479a3a")] [assembly: AssemblyVersion("18.9.0.42433")] namespace MonoMod { internal class MonoMod__OldName__ : Attribute { public MonoMod__OldName__(string findableID) { } } } namespace MonoMod.ModInterop { [AttributeUsage(AttributeTargets.Class)] public sealed class ModExportNameAttribute : Attribute { public string Name; public ModExportNameAttribute(string name) { Name = name; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Field)] public sealed class ModImportNameAttribute : Attribute { public string Name; public ModImportNameAttribute(string name) { Name = name; } } public static class ModInteropManager { private static HashSet<Type> Registered = new HashSet<Type>(); private static Dictionary<string, List<MethodInfo>> Methods = new Dictionary<string, List<MethodInfo>>(); private static List<FieldInfo> Fields = new List<FieldInfo>(); public static void ModInterop(this Type type) { if (Registered.Contains(type)) { return; } Registered.Add(type); string name = type.Assembly.GetName().Name; object[] customAttributes = type.GetCustomAttributes(typeof(ModExportNameAttribute), inherit: false); for (int i = 0; i < customAttributes.Length; i++) { ModExportNameAttribute modExportNameAttribute = (ModExportNameAttribute)customAttributes[i]; name = modExportNameAttribute.Name; } FieldInfo[] fields = type.GetFields(BindingFlags.Static | BindingFlags.Public); foreach (FieldInfo fieldInfo in fields) { if (typeof(Delegate).IsAssignableFrom(fieldInfo.FieldType)) { Fields.Add(fieldInfo); } } MethodInfo[] methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public); foreach (MethodInfo method in methods) { method.RegisterModExport(); method.RegisterModExport(name); } foreach (FieldInfo field in Fields) { if (!Methods.TryGetValue(field.GetModImportName(), out var value)) { field.SetValue(null, null); continue; } bool flag = false; foreach (MethodInfo item in value) { try { field.SetValue(null, Delegate.CreateDelegate(field.FieldType, item)); flag = true; } catch { continue; } break; } if (!flag) { field.SetValue(null, null); } } } public static void RegisterModExport(this MethodInfo method, string prefix = null) { if (!method.IsPublic || !method.IsStatic) { throw new MemberAccessException("Utility must be public static"); } string text = method.Name; if (!string.IsNullOrEmpty(prefix)) { text = prefix + "." + text; } if (!Methods.TryGetValue(text, out var value)) { value = (Methods[text] = new List<MethodInfo>()); } if (!value.Contains(method)) { value.Add(method); } } private static string GetModImportName(this FieldInfo field) { object[] customAttributes = field.GetCustomAttributes(typeof(ModImportNameAttribute), inherit: false); int num = 0; if (num < customAttributes.Length) { ModImportNameAttribute modImportNameAttribute = (ModImportNameAttribute)customAttributes[num]; return modImportNameAttribute.Name; } object[] customAttributes2 = field.DeclaringType.GetCustomAttributes(typeof(ModImportNameAttribute), inherit: false); int num2 = 0; if (num2 < customAttributes2.Length) { ModImportNameAttribute modImportNameAttribute2 = (ModImportNameAttribute)customAttributes2[num2]; return modImportNameAttribute2.Name + "." + field.Name; } return field.Name; } } } namespace MonoMod.Utils { public sealed class DynamicMethodDefinition : IDisposable { private class AssemblyCecilDefinitionResolver : IAssemblyResolver, IDisposable { private readonly Func<AssemblyName, ModuleDefinition> Gen; private readonly IAssemblyResolver Fallback; private readonly Dictionary<string, AssemblyDefinition> Cache = new Dictionary<string, AssemblyDefinition>(); public AssemblyCecilDefinitionResolver(Func<AssemblyName, ModuleDefinition> moduleGen, IAssemblyResolver fallback) { Gen = moduleGen; Fallback = fallback; } public AssemblyDefinition Resolve(AssemblyNameReference name) { if (Cache.TryGetValue(name.FullName, out var value)) { return value; } Dictionary<string, AssemblyDefinition> cache = Cache; string fullName = name.FullName; ModuleDefinition obj = Gen(new AssemblyName(name.FullName)); return cache[fullName] = ((obj != null) ? obj.Assembly : null) ?? Fallback.Resolve(name); } public AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters) { if (Cache.TryGetValue(name.FullName, out var value)) { return value; } return Cache[name.FullName] = Gen(new AssemblyName(name.FullName)).Assembly ?? Fallback.Resolve(name, parameters); } public void Dispose() { foreach (AssemblyDefinition value in Cache.Values) { value.Dispose(); } Cache.Clear(); } } private static readonly Dictionary<short, OpCode> _ReflOpCodes; private static readonly Dictionary<short, OpCode> _CecilOpCodes; private static readonly Dictionary<Type, MethodInfo> _Emitters; public static readonly Dictionary<string, Assembly> AssemblyCache; public static readonly Dictionary<MemberReference, MemberInfo> ResolveCache; private static readonly Dictionary<Module, ModuleDefinition> _Modules; private static readonly Dictionary<Module, int> _ModuleRefs; private Func<AssemblyName, ModuleDefinition> _ModuleGen; private ModuleDefinition _Module { get { if (_Modules.TryGetValue(Method.Module, out var value)) { return value; } return null; } set { _Modules[Method.Module] = value; } } private int _ModuleRef { get { if (_ModuleRefs.TryGetValue(Method.Module, out var value)) { return value; } return 0; } set { _ModuleRefs[Method.Module] = value; } } public MethodBase Method { get; private set; } public MethodDefinition Definition { get { IMetadataTokenProvider obj = _Module.LookupToken(Method.MetadataToken); IMetadataTokenProvider obj2 = ((obj is MethodReference) ? obj : null); return ((obj2 != null) ? ((MethodReference)obj2).Resolve() : null) ?? throw new InvalidOperationException("Method definition not found"); } } static DynamicMethodDefinition() { //IL_00b7: 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_00ca: Unknown result type (might be due to invalid IL or missing references) _ReflOpCodes = new Dictionary<short, OpCode>(); _CecilOpCodes = new Dictionary<short, OpCode>(); _Emitters = new Dictionary<Type, MethodInfo>(); AssemblyCache = new Dictionary<string, Assembly>(); ResolveCache = new Dictionary<MemberReference, MemberInfo>(); _Modules = new Dictionary<Module, ModuleDefinition>(); _ModuleRefs = new Dictionary<Module, int>(); FieldInfo[] fields = typeof(OpCodes).GetFields(BindingFlags.Static | BindingFlags.Public); foreach (FieldInfo fieldInfo in fields) { OpCode value = (OpCode)fieldInfo.GetValue(null); _ReflOpCodes[value.Value] = value; } FieldInfo[] fields2 = typeof(OpCodes).GetFields(BindingFlags.Static | BindingFlags.Public); foreach (FieldInfo fieldInfo2 in fields2) { OpCode value2 = (OpCode)fieldInfo2.GetValue(null); _CecilOpCodes[((OpCode)(ref value2)).Value] = value2; } MethodInfo[] methods = typeof(ILGenerator).GetMethods(); foreach (MethodInfo methodInfo in methods) { if (!(methodInfo.Name != "Emit")) { ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length == 2 && (object)parameters[0].ParameterType == typeof(OpCode)) { _Emitters[parameters[1].ParameterType] = methodInfo; } } } } public DynamicMethodDefinition(MethodBase method, Func<AssemblyName, ModuleDefinition> moduleGen = null) { Method = method ?? throw new ArgumentNullException("method"); Reload(moduleGen); } public void Reload(Func<AssemblyName, ModuleDefinition> moduleGen = null, bool force = false) { //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown //IL_00bf: Unknown result type (might be due to invalid IL or missing references) ModuleDefinition moduleTmp = null; if (moduleGen != null) { _ModuleGen = moduleGen; } try { ModuleDefinition val = (moduleGen ?? _ModuleGen)?.Invoke(Method.Module.Assembly.GetName()); if (val == null) { if (_Module != null && !force) { val = _Module; } else { ModuleDefinition module = _Module; if (module != null) { module.Dispose(); } _Module = null; ReaderParameters val2 = new ReaderParameters(); if (_ModuleGen != null) { val2.AssemblyResolver = (IAssemblyResolver)(object)new AssemblyCecilDefinitionResolver(_ModuleGen, (IAssemblyResolver)(((object)val2.AssemblyResolver) ?? ((object)new DefaultAssemblyResolver()))); } val = (moduleTmp = ModuleDefinition.ReadModule(Method.DeclaringType.Assembly.Location, val2)); } } _Module = val; _ModuleRef++; } catch when (_DisposeEarly()) { } bool _DisposeEarly() { if (moduleTmp != null) { moduleTmp.Dispose(); _Module = null; _ModuleRef = 0; } return false; } } public DynamicMethod Generate() { //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_03e8: Unknown result type (might be due to invalid IL or missing references) //IL_03ed: Unknown result type (might be due to invalid IL or missing references) //IL_03f1: Unknown result type (might be due to invalid IL or missing references) //IL_03f7: Invalid comparison between Unknown and I4 //IL_040c: Unknown result type (might be due to invalid IL or missing references) //IL_0411: Unknown result type (might be due to invalid IL or missing references) //IL_0359: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_0360: Unknown result type (might be due to invalid IL or missing references) //IL_037b: Expected I4, but got Unknown //IL_0601: Unknown result type (might be due to invalid IL or missing references) //IL_0606: Unknown result type (might be due to invalid IL or missing references) //IL_05c5: Unknown result type (might be due to invalid IL or missing references) //IL_05ca: Unknown result type (might be due to invalid IL or missing references) MethodDefinition definition = Definition; Type[] genericArgsType = (Method.DeclaringType.IsGenericType ? Method.DeclaringType.GetGenericArguments() : null); Type[] genericArgsMethod = (Method.IsGenericMethod ? Method.GetGenericArguments() : null); ParameterInfo[] parameters = Method.GetParameters(); Type[] array; if (!Method.IsStatic) { array = new Type[parameters.Length + 1]; array[0] = Method.DeclaringType; for (int i = 0; i < parameters.Length; i++) { array[i + 1] = parameters[i].ParameterType; } } else { array = new Type[parameters.Length]; for (int j = 0; j < parameters.Length; j++) { array[j] = parameters[j].ParameterType; } } DynamicMethod dynamicMethod = new DynamicMethod("DynamicMethodDefinition:" + ((MemberReference)definition.DeclaringType).FullName + "::" + ((MemberReference)definition).Name, (Method as MethodInfo)?.ReturnType ?? typeof(void), array, Method.DeclaringType, skipVisibility: true); ILGenerator il = dynamicMethod.GetILGenerator(); LocalBuilder[] array2 = ((IEnumerable<VariableDefinition>)definition.Body.Variables).Select((VariableDefinition var) => il.DeclareLocal(ResolveMember((MemberReference)(object)((VariableReference)var).VariableType, genericArgsType, genericArgsMethod) as Type, var.IsPinned)).ToArray(); Dictionary<int, Label> labelMap = new Dictionary<int, Label>(); Enumerator<Instruction> enumerator = definition.Body.Instructions.GetEnumerator(); try { while (enumerator.MoveNext()) { Instruction current = enumerator.Current; if (current.Operand is Instruction[] array3) { Instruction[] array4 = array3; foreach (Instruction val in array4) { if (!labelMap.ContainsKey(val.Offset)) { labelMap[val.Offset] = il.DefineLabel(); } } } else { object operand = current.Operand; Instruction val2; if ((val2 = (Instruction)((operand is Instruction) ? operand : null)) != null && !labelMap.ContainsKey(val2.Offset)) { labelMap[val2.Offset] = il.DefineLabel(); } } } } finally { ((IDisposable)enumerator).Dispose(); } object[] array5 = new object[2]; Enumerator<Instruction> enumerator2 = definition.Body.Instructions.GetEnumerator(); try { while (enumerator2.MoveNext()) { Instruction current2 = enumerator2.Current; if (labelMap.TryGetValue(current2.Offset, out var value)) { il.MarkLabel(value); } Enumerator<ExceptionHandler> enumerator3 = definition.Body.ExceptionHandlers.GetEnumerator(); try { while (enumerator3.MoveNext()) { ExceptionHandler current3 = enumerator3.Current; if (current3.TryStart == current2) { il.BeginExceptionBlock(); } else if (current3.FilterStart == current2) { il.BeginExceptFilterBlock(); } else if (current3.HandlerStart == current2) { ExceptionHandlerType handlerType = current3.HandlerType; switch ((int)handlerType) { case 0: il.BeginCatchBlock(ResolveMember((MemberReference)(object)current3.CatchType, genericArgsType, genericArgsMethod) as Type); break; case 2: il.BeginFinallyBlock(); break; case 4: il.BeginFaultBlock(); break; } } } } finally { ((IDisposable)enumerator3).Dispose(); } OpCode opCode = current2.OpCode; if ((int)((OpCode)(ref opCode)).OperandType == 5) { ILGenerator iLGenerator = il; Dictionary<short, OpCode> reflOpCodes = _ReflOpCodes; opCode = current2.OpCode; iLGenerator.Emit(reflOpCodes[((OpCode)(ref opCode)).Value]); } else { object obj = current2.Operand; Instruction val3; VariableDefinition val4; ParameterDefinition val5; MemberReference mref; if (obj is Instruction[] source) { obj = source.Select((Instruction target) => labelMap[target.Offset]).ToArray(); } else if ((val3 = (Instruction)((obj is Instruction) ? obj : null)) != null) { obj = labelMap[val3.Offset]; } else if ((val4 = (VariableDefinition)((obj is VariableDefinition) ? obj : null)) != null) { obj = array2[((VariableReference)val4).Index]; } else if ((val5 = (ParameterDefinition)((obj is ParameterDefinition) ? obj : null)) != null) { obj = ((ParameterReference)val5).Index; } else if ((mref = (MemberReference)((obj is MemberReference) ? obj : null)) != null) { obj = ResolveMember(mref, genericArgsType, genericArgsMethod); } if (obj == null) { throw new NullReferenceException($"Unexpected null in {definition} @ {current2}"); } Type operandType = obj.GetType(); if (!_Emitters.TryGetValue(operandType, out var value2)) { value2 = _Emitters.FirstOrDefault((KeyValuePair<Type, MethodInfo> kvp) => kvp.Key.IsAssignableFrom(operandType)).Value; } if ((object)value2 == null) { throw new InvalidOperationException($"Unexpected unemittable {obj.GetType().FullName} in {definition} @ {current2}"); } Dictionary<short, OpCode> reflOpCodes2 = _ReflOpCodes; opCode = current2.OpCode; array5[0] = reflOpCodes2[((OpCode)(ref opCode)).Value]; array5[1] = obj; value2.Invoke(il, array5); } Enumerator<ExceptionHandler> enumerator4 = definition.Body.ExceptionHandlers.GetEnumerator(); try { while (enumerator4.MoveNext()) { ExceptionHandler current4 = enumerator4.Current; if (current4.HandlerEnd == current2.Next) { il.EndExceptionBlock(); } } } finally { ((IDisposable)enumerator4).Dispose(); } } } finally { ((IDisposable)enumerator2).Dispose(); } return dynamicMethod; } private static MemberInfo ResolveMember(MemberReference mref, Type[] genericTypeArguments, Type[] genericMethodArguments, Module module = null) { if (ResolveCache.TryGetValue(mref, out var value) && (object)value != null) { return value; } MemberReference obj = mref; MethodReference method; Type type; if ((method = (MethodReference)(object)((obj is MethodReference) ? obj : null)) != null && mref.DeclaringType is ArrayType) { type = ResolveMember((MemberReference)(object)mref.DeclaringType, genericTypeArguments, genericMethodArguments, module) as Type; string methodID = method.GetFindableID(null, null, withType: false); MethodInfo methodInfo = type.GetMethods().First((MethodInfo m) => m.GetFindableID(null, null, withType: false, proxyMethod: false, simple: false) == methodID); if ((object)methodInfo != null) { return ResolveCache[mref] = methodInfo; } } TypeReference val = (TypeReference)(((object)mref.DeclaringType) ?? ((object)(((mref is TypeReference) ? mref : null) ?? throw new NotSupportedException("MemberReference hasn't got a DeclaringType / isn't a TypeReference in itself")))); if ((object)module == null) { IMetadataScope scope = val.Scope; IMetadataScope val2 = scope; if (val2 == null) { goto IL_01c8; } AssemblyNameReference val3; string fullName; string text; if ((val3 = (AssemblyNameReference)(object)((val2 is AssemblyNameReference) ? val2 : null)) == null) { ModuleDefinition val4; if ((val4 = (ModuleDefinition)(object)((val2 is ModuleDefinition) ? val2 : null)) == null) { ModuleReference val5; if ((val5 = (ModuleReference)(object)((val2 is ModuleReference) ? val2 : null)) == null) { goto IL_01c8; } ModuleReference val6 = val5; fullName = ((MemberReference)val).Module.Assembly.FullName; text = ((ModuleReference)((MemberReference)val).Module).Name; } else { ModuleDefinition val7 = val4; fullName = val7.Assembly.FullName; text = ((ModuleReference)val7).Name; } } else { AssemblyNameReference val8 = val3; fullName = val8.FullName; text = null; } if (!AssemblyCache.TryGetValue(fullName, out var value2)) { value2 = (AssemblyCache[fullName] = Assembly.Load(fullName)); } module = (string.IsNullOrEmpty(text) ? value2.GetModules()[0] : value2.GetModule(text)); } MemberReference obj2 = mref; TypeReference val9; if ((val9 = (TypeReference)(object)((obj2 is TypeReference) ? obj2 : null)) != null) { MemberReference obj3 = mref; TypeSpecification val10; if ((val10 = (TypeSpecification)(object)((obj3 is TypeSpecification) ? obj3 : null)) != null) { type = ResolveMember((MemberReference)(object)val10.ElementType, genericTypeArguments, genericMethodArguments, module) as Type; if (((TypeReference)val10).IsByReference) { return ResolveCache[mref] = type.MakeByRefType(); } if (((TypeReference)val10).IsPointer) { return ResolveCache[mref] = type.MakePointerType(); } if (((TypeReference)val10).IsArray) { return ResolveCache[mref] = type.MakeArrayType(((ArrayType)((val10 is ArrayType) ? val10 : null)).Dimensions.Count); } if (((TypeReference)val10).IsGenericInstance) { return ResolveCache[mref] = type.MakeGenericType(((IEnumerable<TypeReference>)((GenericInstanceType)((val10 is GenericInstanceType) ? val10 : null)).GenericArguments).Select((TypeReference arg) => ResolveMember((MemberReference)(object)arg, genericTypeArguments, genericMethodArguments) as Type).ToArray()); } } else { type = module.GetType(mref.FullName.Replace("/", "+")); } return ResolveCache[mref] = type; } type = ResolveMember((MemberReference)(object)mref.DeclaringType, genericTypeArguments, genericMethodArguments, module) as Type; MemberReference obj4 = mref; GenericInstanceMethod val11; MemberInfo memberInfo7; if ((val11 = (GenericInstanceMethod)(object)((obj4 is GenericInstanceMethod) ? obj4 : null)) != null) { memberInfo7 = ResolveMember((MemberReference)(object)((MethodSpecification)val11).ElementMethod, genericTypeArguments, genericMethodArguments, module); memberInfo7 = (memberInfo7 as MethodInfo).MakeGenericMethod(((IEnumerable<TypeReference>)val11.GenericArguments).Select((TypeReference arg) => ResolveMember((MemberReference)(object)arg, genericTypeArguments, genericMethodArguments) as Type).ToArray()); } else { memberInfo7 = type.GetMembers((BindingFlags)2147483647).FirstOrDefault((MemberInfo m) => mref.Is(m)); } return ResolveCache[mref] = memberInfo7; IL_01c8: throw new NotSupportedException($"Unsupported scope type {((object)val.Scope).GetType().FullName}"); } public void Dispose() { if (_Module != null && --_ModuleRef == 0) { _Module.Dispose(); _Module = null; } } } public static class DynamicMethodHelper { private static List<object> References = new List<object>(); private static readonly MethodInfo _GetMethodFromHandle = typeof(MethodBase).GetMethod("GetMethodFromHandle", new Type[1] { typeof(RuntimeMethodHandle) }); private static readonly MethodInfo _GetReference = typeof(DynamicMethodHelper).GetMethod("GetReference"); public static object GetReference(int id) { return References[id]; } public static void SetReference(int id, object obj) { References[id] = obj; } private static int AddReference(object obj) { lock (References) { References.Add(obj); return References.Count - 1; } } public static void FreeReference(int id) { References[id] = null; } public static DynamicMethod Stub(this DynamicMethod dm) { ILGenerator iLGenerator = dm.GetILGenerator(); for (int i = 0; i < 10; i++) { iLGenerator.Emit(OpCodes.Nop); } if ((object)dm.ReturnType != typeof(void)) { iLGenerator.DeclareLocal(dm.ReturnType); iLGenerator.Emit(OpCodes.Ldloca_S, (sbyte)0); iLGenerator.Emit(OpCodes.Initobj, dm.ReturnType); iLGenerator.Emit(OpCodes.Ldloc_0); } iLGenerator.Emit(OpCodes.Ret); return dm; } public static void EmitMethodOf(this ILGenerator il, MethodBase method) { if (method is MethodInfo) { il.Emit(OpCodes.Ldtoken, (MethodInfo)method); } else { if (!(method is ConstructorInfo)) { throw new NotSupportedException($"Method type {method.GetType().FullName} not supported."); } il.Emit(OpCodes.Ldtoken, (ConstructorInfo)method); } il.Emit(OpCodes.Call, _GetMethodFromHandle); } public static int EmitReference<T>(this ILGenerator il, T obj) { Type typeFromHandle = typeof(T); int num = AddReference(obj); il.Emit(OpCodes.Ldc_I4, num); il.Emit(OpCodes.Call, _GetReference); if (typeFromHandle.IsValueType) { il.Emit(OpCodes.Unbox_Any, typeFromHandle); } return num; } } public static class DynDll { public static Dictionary<string, string> DllMap = new Dictionary<string, string>(); public static Dictionary<string, int> DllFlags = new Dictionary<string, int>(); private const int RTLD_LAZY = 1; private const int RTLD_NOW = 2; private const int RTLD_LOCAL = 0; private const int RTLD_GLOBAL = 256; [DllImport("kernel32")] private static extern IntPtr GetModuleHandle(string lpModuleName); [DllImport("kernel32")] private static extern IntPtr LoadLibrary(string lpFileName); [DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)] private static extern IntPtr GetProcAddress(IntPtr hModule, string procName); [DllImport("dl", CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr dlopen([MarshalAs(UnmanagedType.LPTStr)] string filename, int flags); [DllImport("dl", CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr dlsym(IntPtr handle, [MarshalAs(UnmanagedType.LPTStr)] string symbol); [DllImport("dl", CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr dlerror(); public static IntPtr OpenLibrary(string name) { if (name != null && DllMap.TryGetValue(name, out var value)) { name = value; } IntPtr intPtr; if (Environment.OSVersion.Platform == PlatformID.Win32NT) { intPtr = GetModuleHandle(name); if (intPtr == IntPtr.Zero) { intPtr = LoadLibrary(name); } return intPtr; } if (!DllFlags.TryGetValue(name, out var value2)) { value2 = 2; } IntPtr zero = IntPtr.Zero; intPtr = dlopen(name, value2); if (intPtr == IntPtr.Zero && File.Exists(name)) { intPtr = dlopen(Path.GetFullPath(name), value2); } if ((zero = dlerror()) != IntPtr.Zero) { Console.WriteLine(string.Format("DynDll can't access {0}!", name ?? "entry point")); Console.WriteLine("dlerror: " + Marshal.PtrToStringAnsi(zero)); return IntPtr.Zero; } return intPtr; } public static IntPtr GetFunction(this IntPtr lib, string name) { if (lib == IntPtr.Zero) { return IntPtr.Zero; } if (Environment.OSVersion.Platform == PlatformID.Win32NT) { return GetProcAddress(lib, name); } IntPtr result = dlsym(lib, name); IntPtr ptr; if ((ptr = dlerror()) != IntPtr.Zero) { Console.WriteLine("DynDll can't access " + name + "!"); Console.WriteLine("dlerror: " + Marshal.PtrToStringAnsi(ptr)); return IntPtr.Zero; } return result; } public static T AsDelegate<T>(this IntPtr s) where T : class { return Marshal.GetDelegateForFunctionPointer(s, typeof(T)) as T; } public static void ResolveDynDllImports(this Type type) { FieldInfo[] fields = type.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { bool flag = true; object[] customAttributes = fieldInfo.GetCustomAttributes(typeof(DynDllImportAttribute), inherit: true); for (int j = 0; j < customAttributes.Length; j++) { DynDllImportAttribute dynDllImportAttribute = (DynDllImportAttribute)customAttributes[j]; flag = false; IntPtr intPtr = OpenLibrary(dynDllImportAttribute.DLL); if (intPtr == IntPtr.Zero) { continue; } string[] entryPoints = dynDllImportAttribute.EntryPoints; foreach (string name in entryPoints) { IntPtr function = intPtr.GetFunction(name); if (!(function == IntPtr.Zero)) { fieldInfo.SetValue(null, Marshal.GetDelegateForFunctionPointer(function, fieldInfo.FieldType)); flag = true; break; } } if (flag) { break; } } if (!flag) { throw new EntryPointNotFoundException($"No matching entry point found for {fieldInfo.Name} in {fieldInfo.DeclaringType.FullName}"); } } } } [AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] public class DynDllImportAttribute : Attribute { public string DLL; public string[] EntryPoints; [Obsolete("Pass the entry points as parameters instead.")] public string EntryPoint { set { EntryPoints = new string[1] { value }; } } public DynDllImportAttribute(string dll, params string[] entryPoints) { DLL = dll; EntryPoints = entryPoints; } } public static class Extensions { public static string ToHexadecimalString(this byte[] data) { return BitConverter.ToString(data).Replace("-", string.Empty); } public static T InvokePassing<T>(this MulticastDelegate md, T val, params object[] args) { if ((object)md == null) { return val; } object[] array = new object[args.Length + 1]; array[0] = val; Array.Copy(args, 0, array, 1, args.Length); Delegate[] invocationList = md.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { array[0] = invocationList[i].DynamicInvoke(array); } return (T)array[0]; } public static bool InvokeWhileTrue(this MulticastDelegate md, params object[] args) { if ((object)md == null) { return true; } Delegate[] invocationList = md.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { if (!(bool)invocationList[i].DynamicInvoke(args)) { return false; } } return true; } public static bool InvokeWhileFalse(this MulticastDelegate md, params object[] args) { if ((object)md == null) { return false; } Delegate[] invocationList = md.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { if ((bool)invocationList[i].DynamicInvoke(args)) { return true; } } return false; } public static T InvokeWhileNull<T>(this MulticastDelegate md, params object[] args) where T : class { if ((object)md == null) { return null; } Delegate[] invocationList = md.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { T val = (T)invocationList[i].DynamicInvoke(args); if (val != null) { return val; } } return null; } public static string SpacedPascalCase(this string input) { StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < input.Length; i++) { char c = input[i]; if (i > 0 && char.IsUpper(c)) { stringBuilder.Append(' '); } stringBuilder.Append(c); } return stringBuilder.ToString(); } public static string ReadNullTerminatedString(this BinaryReader stream) { string text = ""; char c; while ((c = stream.ReadChar()) != 0) { text += c; } return text; } public static void WriteNullTerminatedString(this BinaryWriter stream, string text) { if (text != null) { foreach (char ch in text) { stream.Write(ch); } } stream.Write('\0'); } public static T CastDelegate<T>(this Delegate source) where T : class { return source.CastDelegate(typeof(T)) as T; } public static Delegate CastDelegate(this Delegate source, Type type) { if ((object)source == null) { return null; } Delegate[] invocationList = source.GetInvocationList(); if (invocationList.Length == 1) { return Delegate.CreateDelegate(type, invocationList[0].Target, invocationList[0].Method); } Delegate[] array = new Delegate[invocationList.Length]; for (int i = 0; i < invocationList.Length; i++) { array[i] = invocationList[i].CastDelegate(type); } return Delegate.Combine(array); } public static bool TryCastDelegate<T>(this Delegate source, out T result) where T : class { if (source is T val) { result = val; return true; } Delegate result2; bool result3 = source.TryCastDelegate(typeof(T), out result2); result = result2 as T; return result3; } public static bool TryCastDelegate(this Delegate source, Type type, out Delegate result) { result = null; if ((object)source == null) { return false; } try { Delegate[] invocationList = source.GetInvocationList(); if (invocationList.Length == 1) { result = Delegate.CreateDelegate(type, invocationList[0].Target, invocationList[0].Method); return true; } Delegate[] array = new Delegate[invocationList.Length]; for (int i = 0; i < invocationList.Length; i++) { array[i] = invocationList[i].CastDelegate(type); } result = Delegate.Combine(array); return true; } catch { return false; } } public static void LogDetailed(this Exception e, string tag = null) { if (tag == null) { Console.WriteLine("--------------------------------"); Console.WriteLine("Detailed exception log:"); } for (Exception ex = e; ex != null; ex = ex.InnerException) { Console.WriteLine("--------------------------------"); Console.WriteLine(ex.GetType().FullName + ": " + ex.Message + "\n" + ex.StackTrace); if (ex is ReflectionTypeLoadException) { ReflectionTypeLoadException ex2 = (ReflectionTypeLoadException)ex; for (int i = 0; i < ex2.Types.Length; i++) { Console.WriteLine("ReflectionTypeLoadException.Types[" + i + "]: " + ex2.Types[i]); } for (int j = 0; j < ex2.LoaderExceptions.Length; j++) { ex2.LoaderExceptions[j].LogDetailed(tag + ((tag == null) ? "" : ", ") + "rtle:" + j); } } if (ex is TypeLoadException) { Console.WriteLine("TypeLoadException.TypeName: " + ((TypeLoadException)ex).TypeName); } if (ex is BadImageFormatException) { Console.WriteLine("BadImageFormatException.FileName: " + ((BadImageFormatException)ex).FileName); } } } public static Delegate CreateDelegate<T>(this MethodBase method) where T : class { return method.CreateDelegate(typeof(T), null); } public static Delegate CreateDelegate<T>(this MethodBase method, object target) where T : class { return method.CreateDelegate(typeof(T), target); } public static Delegate CreateDelegate(this MethodBase method, Type delegateType) { return method.CreateDelegate(delegateType, null); } public static Delegate CreateDelegate(this MethodBase method, Type delegateType, object target) { if (!typeof(Delegate).IsAssignableFrom(delegateType)) { throw new ArgumentException("Type argument must be a delegate type!"); } if (method is DynamicMethod) { return ((DynamicMethod)method).CreateDelegate(delegateType, target); } RuntimeMethodHandle methodHandle = method.MethodHandle; RuntimeHelpers.PrepareMethod(methodHandle); IntPtr functionPointer = methodHandle.GetFunctionPointer(); return (Delegate)Activator.CreateInstance(delegateType, target, functionPointer); } } public class LimitedStream : MemoryStream { public Stream LimitStream; public long LimitOffset; public long LimitLength; public long? LimitPublicLength; public bool LimitStreamShared = false; private long _Position = 0L; protected byte[] CachedBuffer; protected long CachedOffset; protected long CachedLength; private bool _CacheBuffer = true; private readonly byte[] _ToArrayReadBuffer = new byte[2048]; public bool CacheBuffer { get { return _CacheBuffer; } set { if (!value) { CachedBuffer = null; } _CacheBuffer = value; } } public override bool CanRead => LimitStream.CanRead; public override bool CanSeek => LimitStream.CanSeek; public override bool CanWrite => LimitStream.CanWrite; public override long Length => LimitPublicLength ?? LimitLength; public override long Position { get { return (LimitStreamShared || !CanSeek) ? _Position : (LimitStream.Position - LimitOffset); } set { if (CanSeek) { LimitStream.Position = value + LimitOffset; } _Position = value; } } public LimitedStream(Stream stream, long offset, long length) { LimitStream = stream; LimitOffset = offset; LimitLength = length; if (LimitStream.CanSeek) { LimitStream.Seek(offset, SeekOrigin.Begin); } } public override void Flush() { LimitStream.Flush(); } public override int Read(byte[] buffer, int offset, int count) { if (LimitOffset + LimitLength <= Position) { return 0; } if (LimitOffset + LimitLength <= Position + count) { count = (int)(LimitLength - (Position - LimitOffset)); } int num = LimitStream.Read(buffer, offset, count); _Position += num; return num; } public override int ReadByte() { if (LimitOffset + LimitLength <= Position) { return 0; } if (LimitOffset + LimitLength <= Position + 1) { return 0; } int num = LimitStream.ReadByte(); if (num != -1) { _Position++; } return num; } public override long Seek(long offset, SeekOrigin origin) { if (!CanSeek) { throw new NotSupportedException("This stream does not support seek operations."); } switch (origin) { case SeekOrigin.Begin: if (LimitOffset + LimitLength <= offset) { throw new Exception("out of something"); } _Position = offset; return LimitStream.Seek(LimitOffset + offset, SeekOrigin.Begin); case SeekOrigin.Current: if (LimitOffset + LimitLength <= Position + offset) { throw new Exception("out of something"); } _Position += offset; return LimitStream.Seek(offset, SeekOrigin.Current); case SeekOrigin.End: if (LimitLength - offset < 0) { throw new Exception("out of something"); } _Position = LimitLength - offset; return LimitStream.Seek(LimitOffset + LimitLength - offset, SeekOrigin.Begin); default: return 0L; } } public override void SetLength(long value) { if (!CanSeek) { throw new NotSupportedException("This stream does not support seek operations."); } if (LimitStreamShared) { LimitLength = value; } else { LimitStream.SetLength(LimitOffset + value + LimitLength); } } public override void Write(byte[] buffer, int offset, int count) { if (LimitOffset + LimitLength <= Position + count) { throw new Exception("out of something"); } LimitStream.Write(buffer, offset, count); _Position += count; } public override byte[] GetBuffer() { if (CachedBuffer != null && CachedOffset == LimitOffset && CachedLength == LimitLength) { return CachedBuffer; } if (!_CacheBuffer) { return ToArray(); } CachedOffset = LimitOffset; CachedLength = LimitLength; return CachedBuffer = ToArray(); } public override byte[] ToArray() { long position = LimitStream.Position; if (LimitStream.CanSeek) { LimitStream.Seek(LimitOffset, SeekOrigin.Begin); } long num = ((LimitLength == 0L) ? LimitStream.Length : LimitLength); num -= LimitStream.Position - LimitOffset; byte[] result; int count; if (num == 0) { MemoryStream memoryStream = new MemoryStream(); while (0 < (count = LimitStream.Read(_ToArrayReadBuffer, 0, _ToArrayReadBuffer.Length))) { base.Write(_ToArrayReadBuffer, 0, count); } LimitStream.Seek(position, SeekOrigin.Begin); result = base.ToArray(); memoryStream.Close(); return result; } result = new byte[num]; for (int i = 0; i < num; i += count) { count = LimitStream.Read(result, i, result.Length - i); } if (LimitStream.CanSeek) { LimitStream.Seek(position, SeekOrigin.Begin); } return result; } public override void Close() { base.Close(); if (!LimitStreamShared) { LimitStream.Close(); } } protected override void Dispose(bool disposing) { if (!LimitStreamShared) { LimitStream.Dispose(); LimitStream.Close(); } base.Dispose(disposing); } } [MonoMod__OldName__("MonoMod.Relinker")] public delegate IMetadataTokenProvider Relinker(IMetadataTokenProvider mtp, IGenericParameterProvider context); [MonoMod__OldName__("MonoMod.MonoModExt")] public static class MonoModExt { public static IDictionary<string, object> SharedData = new Dictionary<string, object> { { "Platform", (PlatformHelper.Current & ~Platform.X64).ToString() }, { "PlatformPrefix", (PlatformHelper.Current & ~Platform.X64).ToString().ToLowerInvariant() + "_" }, { "Arch", (PlatformHelper.Current & Platform.X64).ToString() }, { "Architecture", (PlatformHelper.Current & Platform.X64).ToString() }, { "ArchPrefix", (PlatformHelper.Current & Platform.X64).ToString().ToLowerInvariant() + "_" }, { "ArchitecturePrefix", (PlatformHelper.Current & Platform.X64).ToString().ToLowerInvariant() + "_" } }; private static readonly Regex TypeGenericParamRegex = new Regex("\\!\\d"); private static readonly Regex MethodGenericParamRegex = new Regex("\\!\\!\\d"); private static Type t_ParamArrayAttribute = typeof(ParamArrayAttribute); public static readonly FieldInfo f_GenericParameter_position = typeof(GenericParameter).GetField("position", BindingFlags.Instance | BindingFlags.NonPublic); public static readonly FieldInfo f_GenericParameter_type = typeof(GenericParameter).GetField("type", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly Type t_Code = typeof(Code); private static readonly Type t_OpCodes = typeof(OpCodes); private static readonly Dictionary<int, OpCode> _ShortToLongOp = new Dictionary<int, OpCode>(); private static readonly Dictionary<int, OpCode> _LongToShortOp = new Dictionary<int, OpCode>(); public static ModuleDefinition ReadModule(string path, ReaderParameters rp) { while (true) { try { return ModuleDefinition.ReadModule(path, rp); } catch { if (rp.ReadSymbols) { rp.ReadSymbols = false; continue; } throw; } } } public static ModuleDefinition ReadModule(Stream input, ReaderParameters rp) { while (true) { try { return ModuleDefinition.ReadModule(input, rp); } catch { if (rp.ReadSymbols) { rp.ReadSymbols = false; continue; } throw; } } } public static MethodBody Clone(this MethodBody o, MethodDefinition m) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (o == null) { return null; } MethodBody val = new MethodBody(m); val.MaxStackSize = o.MaxStackSize; val.InitLocals = o.InitLocals; val.LocalVarToken = o.LocalVarToken; val.Instructions.AddRange<Instruction>(o.Instructions); val.ExceptionHandlers.AddRange<ExceptionHandler>(o.ExceptionHandlers); val.Variables.AddRange<VariableDefinition>(o.Variables); m.CustomDebugInformations.AddRange<CustomDebugInformation>(o.Method.CustomDebugInformations); m.DebugInformation.SequencePoints.AddRange<SequencePoint>(o.Method.DebugInformation.SequencePoints); return val; } public static GenericParameter Update(this GenericParameter param, GenericParameter other) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) return param.Update(other.Position, other.Type); } public static GenericParameter Update(this GenericParameter param, int position, GenericParameterType type) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) f_GenericParameter_position.SetValue(param, position); f_GenericParameter_type.SetValue(param, type); return param; } public static void AddAttribute(this ICustomAttributeProvider cap, MethodReference constructor) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown MonoModExt.AddAttribute(cap, new CustomAttribute(constructor)); } public static void AddAttribute(this ICustomAttributeProvider cap, CustomAttribute attr) { cap.CustomAttributes.Add(attr); } public static bool HasMMAttribute(this ICustomAttributeProvider cap, string attribute) { return cap.HasCustomAttribute("MonoMod.MonoMod" + attribute); } public static CustomAttribute GetMMAttribute(this ICustomAttributeProvider cap, string attribute) { return cap.GetCustomAttribute("MonoMod.MonoMod" + attribute); } public static CustomAttribute GetNextMMAttribute(this ICustomAttributeProvider cap, string attribute) { return cap.GetNextCustomAttribute("MonoMod.MonoMod" + attribute); } public static CustomAttribute GetCustomAttribute(this ICustomAttributeProvider cap, string attribute) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (cap == null || !cap.HasCustomAttributes) { return null; } Enumerator<CustomAttribute> enumerator = cap.CustomAttributes.GetEnumerator(); try { while (enumerator.MoveNext()) { CustomAttribute current = enumerator.Current; if (((MemberReference)current.AttributeType).FullName == attribute) { return current; } } } finally { ((IDisposable)enumerator).Dispose(); } return null; } public static CustomAttribute GetNextCustomAttribute(this ICustomAttributeProvider cap, string attribute) { if (cap == null || !cap.HasCustomAttributes) { return null; } bool flag = false; for (int i = 0; i < cap.CustomAttributes.Count; i++) { CustomAttribute val = cap.CustomAttributes[i]; if (!(((MemberReference)val.AttributeType).FullName != attribute)) { if (flag) { return val; } cap.CustomAttributes.RemoveAt(i); i--; flag = true; } } return null; } public static bool HasCustomAttribute(this ICustomAttributeProvider cap, string attribute) { return cap.GetCustomAttribute(attribute) != null; } public static string GetOriginalName(this MethodDefinition method) { //IL_0008: 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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) Enumerator<CustomAttribute> enumerator = method.CustomAttributes.GetEnumerator(); try { while (enumerator.MoveNext()) { CustomAttribute current = enumerator.Current; if (((MemberReference)current.AttributeType).FullName == "MonoMod.MonoModOriginalName") { CustomAttributeArgument val = current.ConstructorArguments[0]; return (string)((CustomAttributeArgument)(ref val)).Value; } } } finally { ((IDisposable)enumerator).Dispose(); } if (((MemberReference)method).Name == ".ctor" || ((MemberReference)method).Name == ".cctor") { return "orig_ctor_" + ((MemberReference)(object)method.DeclaringType).GetPatchName(); } return "orig_" + ((MemberReference)method).Name; } public static bool MatchingConditionals(this ICustomAttributeProvider cap, ModuleDefinition module) { return cap.MatchingConditionals((AssemblyNameReference)(object)module.Assembly.Name); } public static bool MatchingConditionals(this ICustomAttributeProvider cap, AssemblyNameReference asmName = null) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_0075: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) if (cap == null) { return true; } if (!cap.HasCustomAttributes) { return true; } Platform current = PlatformHelper.Current; bool flag = true; Enumerator<CustomAttribute> enumerator = cap.CustomAttributes.GetEnumerator(); try { while (enumerator.MoveNext()) { CustomAttribute current2 = enumerator.Current; CustomAttributeArgument val; if (((MemberReference)current2.AttributeType).FullName == "MonoMod.MonoModOnPlatform") { val = current2.ConstructorArguments[0]; CustomAttributeArgument[] array = (CustomAttributeArgument[])((CustomAttributeArgument)(ref val)).Value; for (int i = 0; i < array.Length; i++) { if (PlatformHelper.Is((Platform)((CustomAttributeArgument)(ref array[i])).Value)) { } } flag &= array.Length == 0; } else if (((MemberReference)current2.AttributeType).FullName == "MonoMod.MonoModIfFlag") { val = current2.ConstructorArguments[0]; string key = (string)((CustomAttributeArgument)(ref val)).Value; bool flag2; if (!SharedData.TryGetValue(key, out var value) || !(value is bool)) { if (current2.ConstructorArguments.Count == 2) { val = current2.ConstructorArguments[1]; flag2 = (bool)((CustomAttributeArgument)(ref val)).Value; } else { flag2 = true; } } else { flag2 = (bool)value; } flag = flag && flag2; } else if (((MemberReference)current2.AttributeType).FullName == "MonoMod.MonoModTargetModule") { val = current2.ConstructorArguments[0]; string text = ((string)((CustomAttributeArgument)(ref val)).Value).Inject(SharedData); flag &= asmName.Name == text || asmName.FullName == text; } } } finally { ((IDisposable)enumerator).Dispose(); } return flag; } public static string GetFindableID(this MethodReference method, string name = null, string type = null, bool withType = true, bool simple = false) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) while (method.IsGenericInstance) { method = ((MethodSpecification)(GenericInstanceMethod)method).ElementMethod; } StringBuilder stringBuilder = new StringBuilder(); if (simple) { if (withType) { stringBuilder.Append(type ?? ((MemberReference)(object)((MemberReference)method).DeclaringType).GetPatchFullName()).Append("::"); } stringBuilder.Append(name ?? ((MemberReference)method).Name); return stringBuilder.ToString(); } stringBuilder.Append(((MemberReference)(object)method.ReturnType).GetPatchFullName()).Append(" "); if (withType) { stringBuilder.Append(type ?? ((MemberReference)(object)((MemberReference)method).DeclaringType).GetPatchFullName()).Append("::"); } stringBuilder.Append(name ?? ((MemberReference)method).Name); if (method.GenericParameters.Count != 0) { stringBuilder.Append("<"); Collection<GenericParameter> genericParameters = method.GenericParameters; for (int i = 0; i < genericParameters.Count; i++) { if (i > 0) { stringBuilder.Append(","); } stringBuilder.Append(((MemberReference)genericParameters[i]).Name); } stringBuilder.Append(">"); } stringBuilder.Append("("); if (method.HasParameters) { Collection<ParameterDefinition> parameters = method.Parameters; for (int j = 0; j < parameters.Count; j++) { ParameterDefinition val = parameters[j]; if (j > 0) { stringBuilder.Append(","); } if (((ParameterReference)val).ParameterType.IsSentinel) { stringBuilder.Append("...,"); } stringBuilder.Append(((MemberReference)(object)((ParameterReference)val).ParameterType).GetPatchFullName()); } } stringBuilder.Append(")"); return stringBuilder.ToString(); } public static string GetFindableID(this MethodBase method, string name = null, string type = null, bool withType = true, bool proxyMethod = false, bool simple = false) { while (method is MethodInfo && method.IsGenericMethod && !method.IsGenericMethodDefinition) { method = ((MethodInfo)method).GetGenericMethodDefinition(); } StringBuilder stringBuilder = new StringBuilder(); if (simple) { if (withType) { stringBuilder.Append(type ?? method.DeclaringType.FullName).Append("::"); } stringBuilder.Append(name ?? method.Name); return stringBuilder.ToString(); } stringBuilder.Append((method as MethodInfo)?.ReturnType?.FullName ?? "System.Void").Append(" "); if (withType) { stringBuilder.Append(type ?? method.DeclaringType.FullName.Replace("+", "/")).Append("::"); } stringBuilder.Append(name ?? method.Name); if (method.ContainsGenericParameters) { stringBuilder.Append("<"); Type[] genericArguments = method.GetGenericArguments(); for (int i = 0; i < genericArguments.Length; i++) { if (i > 0) { stringBuilder.Append(","); } stringBuilder.Append(genericArguments[i].Name); } stringBuilder.Append(">"); } stringBuilder.Append("("); ParameterInfo[] parameters = method.GetParameters(); for (int j = (proxyMethod ? 1 : 0); j < parameters.Length; j++) { ParameterInfo parameterInfo = parameters[j]; if (j > (proxyMethod ? 1 : 0)) { stringBuilder.Append(","); } if (Attribute.IsDefined(parameterInfo, t_ParamArrayAttribute)) { stringBuilder.Append("...,"); } stringBuilder.Append(parameterInfo.ParameterType.FullName); } stringBuilder.Append(")"); return stringBuilder.ToString(); } public static bool Is(this MemberInfo minfo, MemberReference mref) { return mref.Is(minfo); } public static bool Is(this MemberReference mref, MemberInfo minfo) { if (mref == null) { return false; } GenericParameter val; if ((val = (GenericParameter)(object)((mref is GenericParameter) ? mref : null)) != null) { if (!(minfo is Type type) || !type.IsGenericParameter) { return false; } return val.Position == type.GenericParameterPosition; } if (!(((MemberReference)(object)mref.DeclaringType)?.Is(minfo.DeclaringType) ?? ((object)minfo.DeclaringType == null))) { return false; } if (mref.Name != minfo.Name) { return false; } if (mref is TypeReference) { if (!(minfo is Type type2)) { return false; } GenericInstanceType val2; if ((val2 = (GenericInstanceType)(object)((mref is GenericInstanceType) ? mref : null)) != null) { if (!type2.IsGenericType) { return false; } Collection<TypeReference> genericArguments = val2.GenericArguments; Type[] genericArguments2 = type2.GetGenericArguments(); if (genericArguments.Count != genericArguments2.Length) { return false; } for (int i = 0; i < genericArguments.Count; i++) { if (!((MemberReference)(object)genericArguments[i]).Is(genericArguments2[i])) { return false; } } return ((MemberReference)(object)((TypeSpecification)val2).ElementType).Is(type2.GetGenericTypeDefinition()); } if (mref.DeclaringType != null) { return mref.Name == type2.Name; } return mref.FullName == type2.FullName; } MethodReference val3; if ((val3 = (MethodReference)(object)((mref is MethodReference) ? mref : null)) != null) { if (!(minfo is MethodBase methodBase)) { return false; } Collection<ParameterDefinition> parameters = val3.Parameters; ParameterInfo[] parameters2 = methodBase.GetParameters(); if (parameters.Count != parameters2.Length) { return false; } for (int j = 0; j < parameters.Count; j++) { TypeReference val4 = ((ParameterReference)parameters[j]).ParameterType; GenericParameter val5; if ((val5 = (GenericParameter)(object)((val4 is GenericParameter) ? val4 : null)) != null) { GenericInstanceMethod val6; GenericInstanceType val7; if (val5.Owner is MethodReference && (val6 = (GenericInstanceMethod)(object)((val3 is GenericInstanceMethod) ? val3 : null)) != null) { val4 = val6.GenericArguments[val5.Position]; } else if (val5.Owner is TypeReference && (val7 = (GenericInstanceType)/*isinst with value type is only supported in some contexts*/) != null) { val4 = val7.GenericArguments[val5.Position]; } } if (!((MemberReference)(object)val4).Is(parameters2[j].ParameterType)) { return false; } } return true; } return true; } public static void UpdateOffsets(this MethodBody body, int instri, int delta) { int num = body.Instructions.Count - 1; while (instri <= num) { Instruction obj = body.Instructions[num]; obj.Offset += delta; num--; } } public static int GetInt(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) OpCode opCode = instr.OpCode; if (opCode == OpCodes.Ldc_I4_M1) { return -1; } if (opCode == OpCodes.Ldc_I4_0) { return 0; } if (opCode == OpCodes.Ldc_I4_1) { return 1; } if (opCode == OpCodes.Ldc_I4_2) { return 2; } if (opCode == OpCodes.Ldc_I4_3) { return 3; } if (opCode == OpCodes.Ldc_I4_4) { return 4; } if (opCode == OpCodes.Ldc_I4_5) { return 5; } if (opCode == OpCodes.Ldc_I4_6) { return 6; } if (opCode == OpCodes.Ldc_I4_7) { return 7; } if (opCode == OpCodes.Ldc_I4_8) { return 8; } if (opCode == OpCodes.Ldc_I4_S) { return (sbyte)instr.Operand; } return (int)instr.Operand; } public static int? GetIntOrNull(this Instruction instr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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_0024: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: 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_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) OpCode opCode = instr.OpCode; if (opCode == OpCodes.Ldc_I4_M1) { return -1; } if (opCode == OpCodes.Ldc_I4_0) { return 0; } if (opCode == OpCodes.Ldc_I4_1) { return 1; } if (opCode == OpCodes.Ldc_I4_2) { return 2; } if (opCode == OpCodes.Ldc_I4_3) { return 3; } if (opCode == OpCodes.Ldc_I4_4) { return 4; } if (opCode == OpCodes.Ldc_I4_5) { return 5; } if (opCode == OpCodes.Ldc_I4_6) { return 6; } if (opCode == OpCodes.Ldc_I4_7) { return 7; } if (opCode == OpCodes.Ldc_I4_8) { return 8; } if (opCode == OpCodes.Ldc_I4_S) { return (sbyte)instr.Operand; } if (opCode == OpCodes.Ldc_I4) { return (int)instr.Operand; } return null; } public static ParameterDefinition GetParam(this Instruction instr, MethodDefinition method) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: 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_00c9: 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_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Expected O, but got Unknown //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Expected O, but got Unknown OpCode opCode = instr.OpCode; int num = (((MethodReference)method).HasThis ? (-1) : 0); if (opCode == OpCodes.Ldarg_0) { return ((MethodReference)method).HasThis ? null : ((MethodReference)method).Parameters[num]; } if (opCode == OpCodes.Ldarg_1) { return ((MethodReference)method).Parameters[num + 1]; } if (opCode == OpCodes.Ldarg_2) { return ((MethodReference)method).Parameters[num + 2]; } if (opCode == OpCodes.Ldarg_3) { return ((MethodReference)method).Parameters[num + 3]; } if (opCode == OpCodes.Ldarg_S) { return (ParameterDefinition)instr.Operand; } if (opCode == OpCodes.Ldarg) { return (ParameterDefinition)instr.Operand; } return null; } public static VariableDefinition GetLocal(this Instruction instr, MethodDefinition method) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_009e: 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_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected O, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Expected O, but got Unknown OpCode opCode = instr.OpCode; if (opCode == OpCodes.Ldloc_0) { return method.Body.Variables[0]; } if (opCode == OpCodes.Ldloc_1) { return method.Body.Variables[1]; } if (opCode == OpCodes.Ldloc_2) { return method.Body.Variables[2]; } if (opCode == OpCodes.Ldloc_3) { return method.Body.Variables[3]; } if (opCode == OpCodes.Ldloca_S) { return (VariableDefinition)instr.Operand; } if (opCode == OpCodes.Ldloc) { return (VariableDefinition)instr.Operand; } return null; } public static void AddRange<T>(this Collection<T> list, Collection<T> other) { for (int i = 0; i < other.Count; i++) { list.Add(other[i]); } } public static void AddRange(this IDictionary dict, IDictionary other) { foreach (DictionaryEntry item in other) { dict.Add(item.Key, item.Value); } } public static void AddRange<K, V>(this IDictionary<K, V> dict, IDictionary<K, V> other) { foreach (KeyValuePair<K, V> item in other) { dict.Add(item.Key, item.Value); } } public static void AddRange<K, V>(this Dictionary<K, V> dict, Dictionary<K, V> other) { foreach (KeyValuePair<K, V> item in other) { dict.Add(item.Key, item.Value); } } public static void PushRange<T>(this Stack<T> stack, IEnumerable<T> other) { foreach (T item in other) { stack.Push(item); } } public static void PopRange<T>(this Stack<T> stack, int n) { for (int i = 0; i < n; i++) { stack.Pop(); } } public static void EnqueueRange<T>(this Queue<T> queue, IEnumerable<T> other) { foreach (T item in other) { queue.Enqueue(item); } } public static void DequeueRange<T>(this Queue<T> queue, int n) { for (int i = 0; i < n; i++) { queue.Dequeue(); } } public static T[] Clone<T>(this T[] array, int length) { T[] array2 = new T[length]; Array.Copy(array, array2, length); return array2; } public static GenericParameter GetGenericParameter(this IGenericParameterProvider provider, GenericParameter orig) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Expected O, but got Unknown //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Expected O, but got Unknown if (provider is GenericParameter && ((MemberReference)(GenericParameter)provider).Name == ((MemberReference)orig).Name) { return (GenericParameter)provider; } Enumerator<GenericParameter> enumerator = provider.GenericParameters.GetEnumerator(); try { while (enumerator.MoveNext()) { GenericParameter current = enumerator.Current; if (((MemberReference)current).Name == ((MemberReference)orig).Name) { return current; } } } finally { ((IDisposable)enumerator).Dispose(); } int position = orig.Position; if (provider is MethodReference && orig.DeclaringMethod != null) { if (position < provider.GenericParameters.Count) { return provider.GenericParameters[position]; } return Update(new GenericParameter(((MemberReference)orig).Name, provider), position, (GenericParameterType)1); } if (provider is TypeReference && ((MemberReference)orig).DeclaringType != null) { if (position < provider.GenericParameters.Count) { return provider.GenericParameters[position]; } return Update(new GenericParameter(((MemberReference)orig).Name, provider), position, (GenericParameterType)0); } IGenericParameterProvider obj = ((provider is TypeSpecification) ? provider : null); object obj2 = ((obj != null) ? ((IGenericParameterProvider)(object)((TypeSpecification)obj).ElementType).GetGenericParameter(orig) : null); if (obj2 == null) { IGenericParameterProvider obj3 = ((provider is MemberReference) ? provider : null); obj2 = ((obj3 == null) ? null : ((IGenericParameterProvider)(object)((MemberReference)obj3).DeclaringType)?.GetGenericParameter(orig)); } return (GenericParameter)obj2; } public static IMetadataTokenProvider Relink(this IMetadataTokenProvider mtp, Relinker relinker, IGenericParameterProvider context) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown if (mtp is TypeReference) { return (IMetadataTokenProvider)(object)MonoModExt.Relink((TypeReference)mtp, relinker, context); } if (mtp is MethodReference) { return (IMetadataTokenProvider)(object)MonoModExt.Relink((MethodReference)mtp, relinker, context); } if (mtp is FieldReference) { return MonoModExt.Relink((FieldReference)mtp, relinker, context); } if (mtp is ParameterDefinition) { return (IMetadataTokenProvider)(object)MonoModExt.Relink((ParameterDefinition)mtp, relinker, context); } throw new InvalidOperationException($"MonoMod can't handle metadata token providers of the type {((object)mtp).GetType()}"); } public static TypeReference Relink(this TypeReference type, Relinker relinker, IGenericParameterProvider context) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_02e6: Expected O, but got Unknown //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Expected O, but got Unknown //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Expected O, but got Unknown //IL_00fc: 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_0115: Expected O, but got Unknown //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Expected O, but got Unknown //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Expected O, but got Unknown if (type == null) { return null; } if (type is TypeSpecification) { TypeSpecification val = (TypeSpecification)type; TypeReference val2 = val.ElementType.Relink(relinker, context); if (type.IsSentinel) { return (TypeReference)new SentinelType(val2); } if (type.IsByReference) { return (TypeReference)new ByReferenceType(val2); } if (type.IsPointer) { return (TypeReference)new PointerType(val2); } if (type.IsPinned) { return (TypeReference)new PinnedType(val2); } if (type.IsArray) { return (TypeReference)new ArrayType(val2, ((ArrayType)type).Dimensions.Count); } if (type.IsRequiredModifier) { return (TypeReference)new RequiredModifierType(((RequiredModifierType)type).ModifierType.Relink(relinker, context), val2); } if (type.IsOptionalModifier) { return (TypeReference)new OptionalModifierType(((OptionalModifierType)type).ModifierType.Relink(relinker, context), val2); } if (type.IsGenericInstance) { GenericInstanceType val3 = new GenericInstanceType(val2); Enumerator<TypeReference> enumerator = ((GenericInstanceType)type).GenericArguments.GetEnumerator(); try { while (enumerator.MoveNext()) { TypeReference current = enumerator.Current; val3.GenericArguments.Add(current?.Relink(relinker, context)); } } finally { ((IDisposable)enumerator).Dispose(); } return (TypeReference)(object)val3; } if (type.IsFunctionPointer) { FunctionPointerType val4 = (FunctionPointerType)type; val4.ReturnType = val4.ReturnType.Relink(relinker, context); for (int i = 0; i < val4.Parameters.Count; i++) { ((ParameterReference)val4.Parameters[i]).ParameterType = ((ParameterReference)val4.Parameters[i]).ParameterType.Relink(relinker, context); } return (TypeReference)(object)val4; } throw new NotSupportedException($"MonoMod can't handle TypeSpecification: {((MemberReference)type).FullName} ({((object)type).GetType()})"); } if (type.IsGenericParameter) { GenericParameter genericParameter = context.GetGenericParameter((GenericParameter)type); if (genericParameter == null) { throw new RelinkTargetNotFoundException(string.Format("{0} {1} (context: {2})", "MonoMod relinker failed finding", ((MemberReference)type).FullName, context), (IMetadataTokenProvider)(object)type, (IMetadataTokenProvider)(object)context); } for (int j = 0; j < genericParameter.Constraints.Count; j++) { if (!genericParameter.Constraints[j].IsGenericInstance) { genericParameter.Constraints[j] = genericParameter.Constraints[j].Relink(relinker, context); } } return (TypeReference)(object)genericParameter; } return (TypeReference)relinker((IMetadataTokenProvider)(object)type, context); } public static MethodReference Relink(this MethodReference method, Relinker relinker, IGenericParameterProvider context) { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown //IL_00a3: 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_00d4: 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_0013: Expected O, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Expected O, but got Unknown //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Expected O, but got Unknown if (method.IsGenericInstance) { GenericInstanceMethod val = (GenericInstanceMethod)method; GenericInstanceMethod val2 = new GenericInstanceMethod(((MethodSpecification)val).ElementMethod.Relink(relinker, context)); Enumerator<TypeReference> enumerator = val.GenericArguments.GetEnumerator(); try { while (enumerator.MoveNext()) { TypeReference current = enumerator.Current; val2.GenericArguments.Add(current.Relink(relinker, context)); } } finally { ((IDisposable)enumerator).Dispose(); } return (MethodReference)relinker((IMetadataTokenProvider)(object)val2, context); } MethodReference val3 = new MethodReference(((MemberReference)method).Name, method.ReturnType, ((MemberReference)method).DeclaringType.Relink(relinker, context)); val3.CallingConvention = method.CallingConvention; val3.ExplicitThis = method.ExplicitThis; val3.HasThis = method.HasThis; Enumerator<GenericParameter> enumerator2 = method.GenericParameters.GetEnumerator(); try { while (enumerator2.MoveNext()) { GenericParameter current2 = enumerator2.Current; GenericParameter val4 = Update(new GenericParameter(((MemberReference)current2).Name, current2.Owner) { Attributes = current2.Attributes }, current2); val3.GenericParameters.Add(val4); Enumerator<TypeReference> enumerator3 = current2.Constraints.GetEnumerator(); try { while (enumerator3.MoveNext()) { TypeReference current3 = enumerator3.Current; val4.Constraints.Add(current3.Relink(relinker, (IGenericParameterProvider)(object)val3)); } } finally { ((IDisposable)enumerator3).Dispose(); } } } finally { ((IDisposable)enumerator2).Dispose(); } val3.ReturnType = val3.ReturnType?.Relink(relinker, (IGenericParameterProvider)(object)val3); Enumerator<ParameterDefinition> enumerator4 = method.Parameters.GetEnumerator(); try { while (enumerator4.MoveNext()) { ParameterDefinition current4 = enumerator4.Current; ((ParameterReference)current4).ParameterType = ((ParameterReference)current4).ParameterType.Relink(relinker, (IGenericParameterProvider)(object)method); val3.Parameters.Add(current4); } } finally { ((IDisposable)enumerator4).Dispose(); } return (MethodReference)relinker((IMetadataTokenProvider)(object)val3, context); } public static IMetadataTokenProvider Relink(this FieldReference field, Relinker relinker, IGenericParameterProvider context) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown TypeReference val = ((MemberReference)field).DeclaringType.Relink(relinker, context); return relinker((IMetadataTokenProvider)new FieldReference(((MemberReference)field).Name, field.FieldType.Relink(relinker, (IGenericParameterProvider)(object)val), val), context); } public static ParameterDefinition Relink(this ParameterDefinition param, Relinker relinker, IGenericParameterProvider context) { //IL_0031: 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_0048: 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_0062: 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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown IMethodSignature method = param.Method; IMethodSignature obj = ((method is MethodReference) ? method : null); param = ((obj != null) ? ((MethodReference)obj).Parameters[((ParameterReference)param).Index] : null) ?? param; ParameterDefinition val = new ParameterDefinition(((ParameterReference)param).Name, param.Attributes, ((ParameterReference)param).ParameterType.Relink(relinker, context)) { IsIn = param.IsIn, IsLcid = param.IsLcid, IsOptional = param.IsOptional, IsOut = param.IsOut, IsReturnValue = param.IsReturnValue, MarshalInfo = param.MarshalInfo }; if (param.HasConstant) { val.Constant = param.Constant; } return val; } public static ParameterDefinition Clone(this ParameterDefinition param) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) ParameterDefinition val = new ParameterDefinition(((ParameterReference)param).Name, param.Attributes, ((ParameterReference)param).ParameterType) { IsIn = param.IsIn, IsLcid = param.IsLcid, IsOptional = param.IsOptional, IsOut = param.IsOut, IsReturnValue = param.IsReturnValue, MarshalInfo = param.MarshalInfo }; if (param.HasConstant) { val.Constant = param.Constant; } Enumerator<CustomAttribute> enumerator = param.CustomAttributes.GetEnumerator(); try { while (enumerator.MoveNext()) { CustomAttribute current = enumerator.Current; val.CustomAttributes.Add(current.Clone()); } } finally { ((IDisposable)enumerator).Dispose(); } return val; } public static CustomAttribute Relink(this CustomAttribute attrib, Relinker relinker, IGenericParameterProvider context) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: 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_0046: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: 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_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0120: 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_012e: 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) CustomAttribute val = new CustomAttribute(attrib.Constructor.Relink(relinker, context)); Enumerator<CustomAttributeArgument> enumerator = attrib.ConstructorArguments.GetEnumerator(); try { while (enumerator.MoveNext()) { CustomAttributeArgument current = enumerator.Current; val.ConstructorArguments.Add(new CustomAttributeArgument(((CustomAttributeArgument)(ref current)).Type.Relink(relinker, context), ((CustomAttributeArgument)(ref current)).Value)); } } finally { ((IDisposable)enumerator).Dispose(); } Enumerator<CustomAttributeNamedArgument> enumerator2 = attrib.Fields.GetEnumerator(); CustomAttributeArgument argument; try { while (enumerator2.MoveNext()) { CustomAttributeNamedArgument current2 = enumerator2.Current; Collection<CustomAttributeNamedArgument> fields = val.Fields; string name = ((CustomAttributeNamedArgument)(ref current2)).Name; argument = ((CustomAttributeNamedArgument)(ref current2)).Argument; TypeReference obj = ((CustomAttributeArgument)(ref argument)).Type.Relink(relinker, context); argument = ((CustomAttributeNamedArgument)(ref current2)).Argument; fields.Add(new CustomAttributeNamedArgument(name, new CustomAttributeArgument(obj, ((CustomAttributeArgument)(ref argument)).Value))); } } finally { ((IDisposable)enumerator2).Dispose(); } Enumerator<CustomAttributeNamedArgument> enumerator3 = attrib.Properties.GetEnumerator(); try { while (enumerator3.MoveNext()) { CustomAttributeNamedArgument current3 = enumerator3.Current; Collection<CustomAttributeNamedArgument> properties = val.Properties; string name2 = ((CustomAttributeNamedArgument)(ref current3)).Name; argument = ((CustomAttributeNamedArgument)(ref current3)).Argument; TypeReference obj2 = ((CustomAttributeArgument)(ref argument)).Type.Relink(relinker, context); argument = ((CustomAttributeNamedArgument)(ref current3)).Argument; properties.Add(new CustomAttributeNamedArgument(name2, new CustomAttributeArgument(obj2, ((CustomAttributeArgument)(ref argument)).Value))); } } finally { ((IDisposable)enumerator3).Dispose(); } return val; } public static CustomAttribute Clone(this CustomAttribute attrib) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: 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) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00de: 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_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) CustomAttribute val = new CustomAttribute(attrib.Constructor); Enumerator<CustomAttributeArgument> enumerator = attrib.ConstructorArguments.GetEnumerator(); try { while (enumerator.MoveNext()) { CustomAttributeArgument current = enumerator.Current; val.ConstructorArguments.Add(new CustomAttributeArgument(((CustomAttributeArgument)(ref current)).Type, ((CustomAttributeArgument)(ref current)).Value)); } } finally { ((IDisposable)enumerator).Dispose(); } Enumerator<CustomAttributeNamedArgument> enumerator2 = attrib.Fields.GetEnumerator(); CustomAttributeArgument argument; try { while (enumerator2.MoveNext()) { CustomAttributeNamedArgument current2 = enumerator2.Current; Collection<CustomAttributeNamedArgument> fields = val.Fields; string name = ((CustomAttributeNamedArgument)(ref current2)).Name; argument = ((CustomAttributeNamedArgument)(ref current2)).Argument; TypeReference type = ((CustomAttributeArgument)(ref argument)).Type; argument = ((CustomAttributeNamedArgument)(ref current2)).Argument; fields.Add(new CustomAttributeNamedArgument(name, new CustomAttributeArgument(type, ((CustomAttributeArgument)(ref argument)).Value))); } } finally { ((IDisposable)enumerator2).Dispose(); } Enumerator<CustomAttributeNamedArgument> enumerator3 = attrib.Properties.GetEnumerator(); try { while (enumerator3.MoveNext()) { CustomAttributeNamedArgument current3 = enumerator3.Current; Collection<CustomAttributeNamedArgument> properties = val.Properties; string name2 = ((CustomAttributeNamedArgument)(ref current3)).Name; argument = ((CustomAttributeNamedArgument)(ref current3)).Argument; TypeReference type2 = ((CustomAttributeArgument)(ref argument)).Type; argument = ((CustomAttributeNamedArgument)(ref current3)).Argument; properties.Add(new CustomAttributeNamedArgument(name2, new CustomAttributeArgument(type2, ((CustomAttributeArgument)(ref argument)).Value))); } } finally { ((IDisposable)enumerator3).Dispose(); } return val; } public static GenericParameter Relink(this GenericParameter param, Relinker relinker, IGenericParameterProvider context) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) GenericParameter val = Update(new GenericParameter(((MemberReference)param).Name, param.Owner) { Attributes = param.Attributes }, param); Enumerator<TypeReference> enumerator = param.Constraints.GetEnumerator(); try { while (enumerator.MoveNext()) { TypeReference current = enumerator.Current; val.Constraints.Add(current.Relink(relinker, context)); } } finally { ((IDisposable)enumerator).Dispose(); } return val; } public static GenericParameter Clone(this GenericParameter param) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) GenericParameter val = Update(new GenericParameter(((MemberReference)param).Name, param.Owner) { Attributes = param.Attributes }, param); Enumerator<TypeReference> enumerator = param.Constraints.GetEnumerator(); try { while (enumerator.MoveNext()) { TypeReference current = enumerator.Current; val.Constraints.Add(current); } } finally { ((IDisposable)enumerator).Dispose(); } return val; } public static MethodDefinition FindMethod(this TypeDefinition type, string findableID, bool simple = true) { //IL_00c5: 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_0024: 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_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: 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_0076: Unknown result type (might be due to invalid IL or missing references) if (simple && !findableID.Contains(" ")) { Enumerator<MethodDefinition> enumerator = type.Methods.GetEnumerator(); try { while (enumerator.MoveNext()) { MethodDefinition current = enumerator.Current; if (((MethodReference)(object)current).GetFindableID(null, null, withType: true, simple: true) == findableID) { return current; } } } finally { ((IDisposable)enumerator).Dispose(); } Enumerator<MethodDefinition> enumerator2 = type.Methods.GetEnumerator(); try { while (enumerator2.MoveNext()) { MethodDefinition current2 = enumerator2.Current; if (((MethodReference)(object)current2).GetFindableID(null, null, withType: false, simple: true) == findableID) { return current2; } } } finally { ((IDisposable)enumerator2).Dispose(); } } Enumerator<MethodDefinition> enumerator3 = type.Methods.GetEnumerator(); try { while (enumerator3.MoveNext()) { MethodDefinition current3 = enumerator3.Current; if (((MethodReference)(object)current3).GetFindableID() == findableID) { return current3; } } } finally { ((IDisposable)enumerator3).Dispose(); } Enumerator<MethodDefinition> enumerator4 = type.Methods.GetEnumerator(); try { while (enumerator4.MoveNext()) { MethodDefinition current4 = enumerator4.Current; if (((MethodReference)(object)current4).GetFindableID(null, null, withType: false) == findableID) { return current4; } } } finally { ((IDisposable)enumerator4).Dispose(); } return null; } public static MethodInfo FindMethod(this Type type, string findableID, bool simple = true) { MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); MethodInfo[] array = methods; foreach (MethodInfo methodInfo in array) { if (methodInfo.GetFindableID(null, null, withType: true, proxyMethod: false, simple: false) == findableID) { return methodInfo; } } MethodInfo[] array2 = methods; foreach (MethodInfo methodInfo2 in array2) { if (methodInfo2.GetFindableID(null, null, withType: false, proxyMethod: false, simple: false) == findableID) { return methodInfo2; } } if (!simple) { return null; } MethodInfo[] array3 = methods; foreach (MethodInfo methodInfo3 in array3) { if (methodInfo3.GetFindableID(null, null, withType: true, proxyMethod: false, simple: true) == findableID) { return methodInfo3;