Decompiled source of TippingPoint v1.0.3

TippingPoint.dll

Decompiled 20 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("TippingPoint")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.3.0")]
[assembly: AssemblyInformationalVersion("1.0.3+f66080e2ea7536265c743a5f2e1dd58018bb05ba")]
[assembly: AssemblyProduct("TippingPoint")]
[assembly: AssemblyTitle("TippingPoint")]
[assembly: AssemblyVersion("1.0.3.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace TippingPoint
{
	internal static class Backstab
	{
		private const float CooldownSeconds = 300f;

		private static readonly FieldRef<Character, float> BackstabTime = AccessTools.FieldRefAccess<Character, float>("m_backstabTime");

		public static void TryOpenSide(Character victim, Character attacker, HitData hit)
		{
			//IL_003b: 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_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_00ad: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)attacker == (Object)null) && attacker.IsPlayer() && !(hit.m_backstabBonus <= 1f))
			{
				BaseAI component = ((Component)victim).GetComponent<BaseAI>();
				if (!((Object)(object)component == (Object)null) && component.IsAlerted() && !(Vector3.Dot(hit.m_dir, ((Component)victim).transform.forward) <= 0f) && !(Time.time - BackstabTime.Invoke(victim) <= 300f))
				{
					BackstabTime.Invoke(victim) = Time.time;
					hit.ApplyModifier(hit.m_backstabBonus);
					victim.m_backstabHitEffects.Create(hit.m_point, Quaternion.identity, ((Component)victim).transform, 1f, -1, attacker.GetZDOID());
				}
			}
		}
	}
	[HarmonyPatch(typeof(Character), "RPC_Damage")]
	internal static class CharacterDamagePatch
	{
		private static void Prefix(Character __instance, HitData hit)
		{
			if (Tiers.Ready && hit != null && __instance.IsOwner())
			{
				Character attacker = hit.GetAttacker();
				if (__instance.IsPlayer())
				{
					ScaleCreatureDamage(attacker, hit);
					return;
				}
				Backstab.TryOpenSide(__instance, attacker, hit);
				SuppressStaggerBonus(__instance, hit);
			}
		}

		private static void SuppressStaggerBonus(Character victim, HitData hit)
		{
			if (victim.GetLevel() >= 3 && victim.IsStaggering())
			{
				hit.ApplyModifier(0.5f);
			}
		}

		private static void ScaleCreatureDamage(Character attacker, HitData hit)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			if ((Object)(object)attacker == (Object)null || attacker.IsPlayer() || attacker.m_boss || (int)attacker.GetFaction() == 8)
			{
				return;
			}
			int tier = Tiers.TierOf(attacker);
			float num = Baseline.For(attacker);
			if (!(num <= 0f))
			{
				float num2 = Tiers.ScaleFor(num, tier);
				if (!Mathf.Approximately(num2, 1f))
				{
					hit.ApplyModifier(num2);
				}
			}
		}
	}
	internal static class Baseline
	{
		private static readonly Dictionary<string, float> cache = new Dictionary<string, float>();

		public static float For(Character character)
		{
			string text = Name(character);
			if (text == null)
			{
				return 0f;
			}
			if (cache.TryGetValue(text, out var value))
			{
				return value;
			}
			GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(text) : null);
			Humanoid val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<Humanoid>() : null);
			if ((Object)(object)val2 == (Object)null)
			{
				return 0f;
			}
			float max = 0f;
			Consider(val2.m_defaultItems, ref max);
			Consider(val2.m_randomWeapon, ref max);
			if (val2.m_randomSets != null)
			{
				ItemSet[] randomSets = val2.m_randomSets;
				foreach (ItemSet val3 in randomSets)
				{
					if (val3 != null)
					{
						Consider(val3.m_items, ref max);
					}
				}
			}
			if (val2.m_randomItems != null)
			{
				RandomItem[] randomItems = val2.m_randomItems;
				foreach (RandomItem val4 in randomItems)
				{
					if (val4 != null)
					{
						ConsiderOne(val4.m_prefab, ref max);
					}
				}
			}
			if ((Object)(object)val2.m_unarmedWeapon != (Object)null)
			{
				ConsiderItem(val2.m_unarmedWeapon, ref max);
			}
			cache[text] = max;
			if (Tiers.LogScaling)
			{
				int num = Tiers.TierOf(character);
				Tiers.Log.LogInfo((object)($"{text}: tier {num}, own damage {max:0.#}, scaled to {Tiers.TargetDamage(num):0.#}" + ((max <= 0f) ? " - no weapon found, left at vanilla" : string.Empty)));
			}
			return max;
		}

		private static void Consider(GameObject[] items, ref float max)
		{
			if (items != null)
			{
				for (int i = 0; i < items.Length; i++)
				{
					ConsiderOne(items[i], ref max);
				}
			}
		}

		private static void ConsiderOne(GameObject item, ref float max)
		{
			ConsiderItem(((Object)(object)item != (Object)null) ? item.GetComponent<ItemDrop>() : null, ref max);
		}

		private static void ConsiderItem(ItemDrop drop, ref float max)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)drop == (Object)null) && drop.m_itemData?.m_shared != null)
			{
				float num = PlayerFacingDamage(drop.m_itemData.GetDamage()) * HardestAttack(drop.m_itemData.m_shared);
				if (num > max)
				{
					max = num;
				}
			}
		}

		private static float HardestAttack(SharedData shared)
		{
			float num = 1f;
			if (shared.m_attack != null)
			{
				num = Mathf.Max(num, shared.m_attack.m_damageMultiplier);
			}
			if (shared.m_secondaryAttack != null && !string.IsNullOrEmpty(shared.m_secondaryAttack.m_attackAnimation))
			{
				num = Mathf.Max(num, shared.m_secondaryAttack.m_damageMultiplier);
			}
			return num;
		}

		private static float PlayerFacingDamage(DamageTypes damage)
		{
			//IL_0000: 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)
			//IL_000d: 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_001b: 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_0029: 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)
			return damage.m_blunt + damage.m_slash + damage.m_pierce + damage.m_fire + damage.m_frost + damage.m_lightning + damage.m_poison + damage.m_spirit;
		}

		private static string Name(Character character)
		{
			if ((Object)(object)character == (Object)null)
			{
				return null;
			}
			string name = ((Object)((Component)character).gameObject).name;
			int num = name.IndexOf("(Clone)");
			if (num <= 0)
			{
				return name;
			}
			return name.Substring(0, num);
		}
	}
	[HarmonyPatch(typeof(Attack), "GetLevelDamageFactor")]
	internal static class StarDamagePatch
	{
		private static readonly FieldRef<Attack, Humanoid> CharacterOf = AccessTools.FieldRefAccess<Attack, Humanoid>("m_character");

		private static void Postfix(Attack __instance, ref float __result)
		{
			if (Tiers.Ready && Tiers.RemoveStarDamage)
			{
				Humanoid val = CharacterOf.Invoke(__instance);
				if (!((Object)(object)val == (Object)null) && !((Character)val).IsPlayer())
				{
					__result = 1f;
				}
			}
		}
	}
	[HarmonyPatch(typeof(BaseAI), "Awake")]
	internal static class BaseAiAwakePatch
	{
		private static void Postfix(BaseAI __instance)
		{
			if (Tiers.Ready)
			{
				Tiers.Stamp(((Component)__instance).GetComponent<Character>());
			}
		}
	}
	[HarmonyPatch(typeof(Character), "AddStaggerDamage")]
	internal static class StaggerFloorPatch
	{
		private static void Prefix(Character __instance, ref float damage)
		{
			if (!Tiers.Ready || damage <= 0f || __instance.IsPlayer())
			{
				return;
			}
			float num = Tiers.StaggerFloor(Tiers.TierOf(__instance));
			if (!(num <= 0f))
			{
				float num2 = __instance.GetMaxHealth() * __instance.m_staggerDamageFactor;
				if (!(num2 <= 0f) && !(num2 >= num))
				{
					damage *= num2 / num;
				}
			}
		}
	}
	internal static class Stars
	{
		private const float SpeedPerStar = 0.03f;

		private const float SizePerStar = 0.02f;

		private const float AttackRatePerStar = 0.1f;

		private const float MaxAttackRate = 2f;

		private static int ExtraStars(int level)
		{
			return Mathf.Max(0, level - 2);
		}

		public static float SpeedMultiplier(int level)
		{
			return 1f + 0.03f * (float)Mathf.Max(0, level - 1);
		}

		public static float SizeMultiplier(int level)
		{
			return 1f + 0.02f * (float)Mathf.Max(0, level - 1);
		}

		public static float CooldownCut(int level)
		{
			float num = Mathf.Min(2f, 1f + 0.1f * (float)ExtraStars(level));
			if (!(num <= 1f))
			{
				return (num - 1f) / num;
			}
			return 0f;
		}
	}
	[HarmonyPatch(typeof(Character), "Awake")]
	internal static class StarSpeedPatch
	{
		private static void Postfix(Character __instance)
		{
			//IL_0063: 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)
			if (!Tiers.Ready || !Tiers.RemoveStarDamage || __instance.IsPlayer())
			{
				return;
			}
			int level = __instance.GetLevel();
			if (level > 1)
			{
				float num = Stars.SpeedMultiplier(level);
				__instance.m_speed *= num;
				__instance.m_runSpeed *= num;
				__instance.m_turnSpeed *= num;
				if (!__instance.InInterior())
				{
					Transform transform = ((Component)__instance).transform;
					transform.localScale *= Stars.SizeMultiplier(level);
				}
			}
		}
	}
	[HarmonyPatch(typeof(MonsterAI), "DoAttack")]
	internal static class StarAttackRatePatch
	{
		private static void Postfix(MonsterAI __instance, bool __result)
		{
			if (!__result || !Tiers.Ready || !Tiers.RemoveStarDamage)
			{
				return;
			}
			Character component = ((Component)__instance).GetComponent<Character>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			float num = Stars.CooldownCut(component.GetLevel());
			if (!(num <= 0f))
			{
				Character obj = ((component is Humanoid) ? component : null);
				ItemData val = ((obj != null) ? ((Humanoid)obj).GetCurrentWeapon() : null);
				if (val?.m_shared != null)
				{
					val.m_lastAttackTime -= val.m_shared.m_aiAttackInterval * num;
				}
			}
		}
	}
	internal static class Tiers
	{
		private static readonly int TierKey = StringExtensionMethods.GetStableHashCode("tp_tier");

		private static ConfigEntry<float> difficulty;

		private static ConfigEntry<float>[] anchors;

		private static ConfigEntry<int> oceanTier;

		private static ConfigEntry<int> unknownTier;

		private static ConfigEntry<bool> removeStarDamage;

		private static ConfigEntry<bool> logScaling;

		private static ManualLogSource log;

		public const bool OpenSideBackstab = true;

		private const float Compression = 0.6f;

		public static bool Ready => anchors != null;

		public static float Difficulty => difficulty.Value;

		public static bool RemoveStarDamage => removeStarDamage.Value;

		public static bool LogScaling => logScaling.Value;

		public static ManualLogSource Log => log;

		public static void Bind(ConfigEntry<float> difficultyEntry, ConfigEntry<float>[] anchorEntries, ConfigEntry<int> oceanTierEntry, ConfigEntry<int> unknownTierEntry, ConfigEntry<bool> removeStarDamageEntry, ConfigEntry<bool> logScalingEntry, ManualLogSource logger)
		{
			difficulty = difficultyEntry;
			anchors = anchorEntries;
			oceanTier = oceanTierEntry;
			unknownTier = unknownTierEntry;
			removeStarDamage = removeStarDamageEntry;
			logScaling = logScalingEntry;
			log = logger;
		}

		public static float Anchor(int tier)
		{
			if (tier < 1 || tier > 8)
			{
				return 0f;
			}
			return anchors[tier].Value;
		}

		public static float TargetDamage(int tier)
		{
			return Anchor(tier) * Difficulty;
		}

		public static float ScaleFor(float baseline, int tier)
		{
			float num = TargetDamage(tier);
			if (num <= 0f || baseline <= 0f)
			{
				return 1f;
			}
			float num2 = num / baseline;
			if (!(num2 <= 1f))
			{
				return Mathf.Pow(num2, 0.6f);
			}
			return 1f;
		}

		public static float StaggerFloor(int tier)
		{
			if (tier < 2 || tier > 8)
			{
				return 0f;
			}
			return Anchor(tier - 1) * 2f;
		}

		public static int TierOf(Character character)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			ZDO val = ZdoOf(character);
			if (val == null)
			{
				return 0;
			}
			int num = val.GetInt(TierKey, 0);
			if (num != 0)
			{
				return num;
			}
			int num2 = TierAt(((Component)character).transform.position);
			if (num2 != 0 && character.IsOwner())
			{
				val.Set(TierKey, num2, false);
			}
			return num2;
		}

		public static void Stamp(Character character)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)character == (Object)null || !character.IsOwner())
			{
				return;
			}
			ZDO val = ZdoOf(character);
			if (val != null && val.GetInt(TierKey, 0) == 0)
			{
				int num = TierAt(((Component)character).transform.position);
				if (num != 0)
				{
					val.Set(TierKey, num, false);
				}
			}
		}

		private static ZDO ZdoOf(Character character)
		{
			if ((Object)(object)character == (Object)null)
			{
				return null;
			}
			ZNetView component = ((Component)character).GetComponent<ZNetView>();
			if (!((Object)(object)component != (Object)null) || !component.IsValid())
			{
				return null;
			}
			return component.GetZDO();
		}

		private static int TierAt(Vector3 position)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_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)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			Biome val = Heightmap.FindBiome(position);
			if ((int)val == 0 && WorldGenerator.instance != null)
			{
				val = WorldGenerator.instance.GetBiome(position);
			}
			return TierOf(val);
		}

		private static int TierOf(Biome biome)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Invalid comparison between Unknown and I4
			//IL_0005: 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: Expected I4, but got Unknown
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Invalid comparison between Unknown and I4
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Invalid comparison between Unknown and I4
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Invalid comparison between Unknown and I4
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Invalid comparison between Unknown and I4
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Invalid comparison between Unknown and I4
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Invalid comparison between Unknown and I4
			if ((int)biome <= 16)
			{
				switch (biome - 1)
				{
				default:
					if ((int)biome != 8)
					{
						if ((int)biome != 16)
						{
							break;
						}
						return 5;
					}
					return 2;
				case 0:
					return 1;
				case 1:
					return 3;
				case 3:
					return 4;
				case 2:
					break;
				}
			}
			else if ((int)biome <= 64)
			{
				if ((int)biome == 32)
				{
					return 7;
				}
				if ((int)biome == 64)
				{
					return 8;
				}
			}
			else
			{
				if ((int)biome == 256)
				{
					return oceanTier.Value;
				}
				if ((int)biome == 512)
				{
					return 6;
				}
			}
			return unknownTier.Value;
		}
	}
	[BepInPlugin("elric.TippingPoint", "Tipping Point", "1.0.3")]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class TippingPoint : BaseUnityPlugin
	{
		public const string PluginGUID = "elric.TippingPoint";

		public const string PluginName = "Tipping Point";

		public const string PluginVersion = "1.0.3";

		private void Awake()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			CreateConfig();
			new Harmony("elric.TippingPoint").PatchAll();
		}

		private void CreateConfig()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Expected O, but got Unknown
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Expected O, but got Unknown
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Expected O, but got Unknown
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Expected O, but got Unknown
			ConfigEntry<float> difficultyEntry = ((BaseUnityPlugin)this).Config.Bind<float>("Difficulty", "Difficulty", 1.9f, new ConfigDescription("How hard creatures hit. Higher means every creature is pulled further toward what its biome expects of your armour - though never all the way, so the weak stay weaker than the strong. 1.5 is forgiving, 1.9 normal, 2.1 demanding. Going high is safe here: creatures are moved proportionally, so a large value lifts the whole biome rather than pushing its hardest hitters past the point where your shield still works.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 3f), new object[1] { Primary() }));
			ConfigEntry<bool> removeStarDamageEntry = ((BaseUnityPlugin)this).Config.Bind<bool>("Difficulty", "RemoveStarDamage", true, new ConfigDescription("Stars no longer add damage. Vanilla gives +50% per star, which is what turns a starred creature into a one-shot once its hit passes twice your armour. Off restores vanilla star damage.", (AcceptableValueBase)null, new object[1] { adminOnly() }));
			ConfigEntry<float>[] array = new ConfigEntry<float>[9];
			string[] array2 = new string[9] { null, "Meadows", "BlackForest", "Swamp", "Mountain", "Plains", "Mistlands", "AshLands", "DeepNorth" };
			float[] array3 = new float[9] { 0f, 18f, 36f, 54f, 72f, 90f, 108f, 142f, 160f };
			for (int i = 1; i <= 8; i++)
			{
				array[i] = ((BaseUnityPlugin)this).Config.Bind<float>("Anchors", array2[i], array3[i], new ConfigDescription("Armour a prepared player is expected to have in " + array2[i] + ". Raise it to make that biome harder, lower it to make it easier. Change this to fix one biome, not to change overall difficulty.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 1000f), new object[1] { Advanced() }));
			}
			ConfigEntry<int> oceanTierEntry = ((BaseUnityPlugin)this).Config.Bind<int>("Anchors", "OceanTier", 3, new ConfigDescription("Which biome's anchor to use for creatures that spawned in open water, since the ocean has no gear of its own.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 8), new object[1] { Advanced() }));
			ConfigEntry<int> unknownTierEntry = ((BaseUnityPlugin)this).Config.Bind<int>("Anchors", "UnknownTier", 0, new ConfigDescription("Which anchor to use when a creature's biome cannot be determined, which mainly means spawns inside dungeons. 0 leaves those creatures at their vanilla damage.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 8), new object[1] { Advanced() }));
			ConfigEntry<bool> logScalingEntry = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "LogScaling", false, new ConfigDescription("Write one line to the log the first time each creature type is scaled, saying its biome, its own damage and what it was scaled to.", (AcceptableValueBase)null, Array.Empty<object>()));
			Tiers.Bind(difficultyEntry, array, oceanTierEntry, unknownTierEntry, removeStarDamageEntry, logScalingEntry, ((BaseUnityPlugin)this).Logger);
			static ConfigurationManagerAttributes Advanced()
			{
				//IL_0000: 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)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Expected O, but got Unknown
				return new ConfigurationManagerAttributes
				{
					IsAdminOnly = true,
					IsAdvanced = true
				};
			}
			static ConfigurationManagerAttributes Primary()
			{
				//IL_0000: 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)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Expected O, but got Unknown
				return new ConfigurationManagerAttributes
				{
					IsAdminOnly = true,
					Order = 100
				};
			}
			static ConfigurationManagerAttributes adminOnly()
			{
				//IL_0000: 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)
				//IL_000d: Expected O, but got Unknown
				return new ConfigurationManagerAttributes
				{
					IsAdminOnly = true
				};
			}
		}
	}
}