Please disclose if your mod was created primarily using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of GetOffMyLawn v1.12.0
GetOffMyLawn.dll
Decompiled 6 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ComfyLib; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("GetOffMyLawn")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("GetOffMyLawn")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("514d9344-a1b0-4edf-93a8-17c7ae859946")] [assembly: AssemblyFileVersion("1.12.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.12.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace GetOffMyLawn { public static class PluginConfig { public static ConfigEntry<bool> IsModEnabled { get; private set; } public static ConfigEntry<float> TargetPieceHealth { get; private set; } public static ConfigEntry<bool> RepairPiecesOnWardActivation { get; private set; } public static ConfigEntry<bool> EnablePieceHealthDamageThreshold { get; private set; } public static ConfigEntry<bool> ShowTopLeftMessageOnPieceRepair { get; private set; } public static ConfigEntry<bool> ShowRepairEffectOnWardActivation { get; private set; } public static ConfigEntry<bool> ShowStatusEffectIndicator { get; private set; } public static void BindConfig(ConfigFile config) { IsModEnabled = config.BindInOrder("_Global", "isModEnabled", defaultValue: true, "Globally enable or disable this mod."); TargetPieceHealth = config.BindInOrder("PieceValue", "targetPieceHealth", 1E+17f, "Target value to set piece health to when creating and repairing."); RepairPiecesOnWardActivation = config.BindInOrder("Behaviour", "repairPiecesOnWardActivation", defaultValue: true, "IF set, will repair all Pieces in Ward range when a Ward is activated."); EnablePieceHealthDamageThreshold = config.BindInOrder("Optimization", "enablePieceHealthDamageThreshold", defaultValue: true, "If piece health exceeds 100K, DO NOT execute ApplyDamage() or send WNTHealthChanged messages."); ShowTopLeftMessageOnPieceRepair = config.BindInOrder("Indicators", "showTopLeftMessageOnPieceRepair", defaultValue: false, "Shows a message in the top-left message area on piece repair."); ShowRepairEffectOnWardActivation = config.BindInOrder("Indicators", "showRepairEffectOnWardActivation", defaultValue: false, "Shows the repair effect on affected pieces when activating a ward."); ShowStatusEffectIndicator = config.BindInOrder("Indicators", "showStatusEffectIndicator", defaultValue: false, "If set, shows a StatusEffect with the current TargetPieceHealth value."); IsModEnabled.OnSettingChanged<bool>(HandleShowStatusEffectIndicatorConfigChange); ShowStatusEffectIndicator.OnSettingChanged<bool>(HandleShowStatusEffectIndicatorConfigChange); TargetPieceHealth.OnSettingChanged<float>(HandleShowStatusEffectIndicatorConfigChange); } private static void HandleTargetPieceHealthConfigChange(float targetPieceHealth) { if (IsModEnabled.Value && ShowStatusEffectIndicator.Value) { LawnManager.ToggleStatusEffectIndicator(toggleOn: true); } } private static void HandleShowStatusEffectIndicatorConfigChange() { LawnManager.ToggleStatusEffectIndicator(IsModEnabled.Value && ShowStatusEffectIndicator.Value); } } public static class LawnManager { public static void ToggleStatusEffectIndicator(bool toggleOn) { if (Object.op_Implicit((Object)(object)Player.m_localPlayer)) { SEMan seman = ((Character)Player.m_localPlayer).m_seman; if (toggleOn) { seman.AddStatusEffect((StatusEffect)(object)TargetPieceHealthStatusEffect.Instance, true, 0, 0f); } else { seman.RemoveStatusEffect(((StatusEffect)TargetPieceHealthStatusEffect.Instance).NameHash(), false); } } } } public static class PieceUtils { private static readonly List<Piece> _pieceCache = new List<Piece>(); private static int _pieceCount = 0; public static bool CanRemovePiece(Piece piece) { Vagon component2; if (!((Component)(object)piece).TryGetComponentInChildren<Ship>(out Ship _)) { return ((Component)(object)piece).TryGetComponentInChildren<Vagon>(out component2); } return true; } public static bool IsEligiblePiece(Piece piece) { Plant val = default(Plant); Character val2 = default(Character); if (((Component)piece).TryGetComponent<Plant>(ref val) || ((Component)piece).TryGetComponent<Character>(ref val2)) { return false; } return true; } public static bool TryGetValidOwnedNetView(Piece piece, out ZNetView netView) { netView = piece.m_nview; if (Object.op_Implicit((Object)(object)netView) && netView.IsValid()) { return netView.IsOwner(); } return false; } public static bool RepairPiece(this Player player, ItemData toolItem, Piece piece) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0098: 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) if (!Object.op_Implicit((Object)(object)piece) || !Object.op_Implicit((Object)(object)piece.m_nview) || !piece.m_nview.IsValid() || !IsEligiblePiece(piece)) { return false; } if (!player.CheckCanRemovePiece(piece) || !PrivateArea.CheckAccess(((Component)piece).transform.position, 0f, true, false)) { return false; } RepairPiece(piece, PluginConfig.TargetPieceHealth.Value, Time.time); player.FaceLookDirection(); ((Character)player).m_zanim.SetTrigger(toolItem.m_shared.m_attack.m_attackAnimation); EffectList placeEffect = piece.m_placeEffect; if (placeEffect != null) { placeEffect.Create(((Component)piece).transform.position, ((Component)piece).transform.rotation, (Transform)null, 1f, -1); } if (PluginConfig.ShowTopLeftMessageOnPieceRepair.Value) { ((Character)player).Message((MessageType)1, Localization.instance.Localize("$msg_repaired", new string[1] { piece.m_name }), 0, (Sprite)null); } return true; } public static void RepairPiece(Piece piece, float targetHealth, float repairTime) { piece.m_nview.ClaimOwnership(); piece.m_nview.m_zdo.Set(ZDOVars.s_health, targetHealth); WearNTear val = default(WearNTear); if (((Component)piece).TryGetComponent<WearNTear>(ref val)) { val.m_lastRepair = repairTime; val.m_healthPercentage = Mathf.Clamp01(targetHealth / val.m_health); val.SetHealthVisual(val.m_healthPercentage, true); } } public static void RepairPiecesInRadius(Vector3 origin, float radius) { //IL_0010: 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_00a0: Unknown result type (might be due to invalid IL or missing references) _pieceCache.Clear(); _pieceCount = 0; GetAllPiecesInRadius(origin, radius, _pieceCache); float value = PluginConfig.TargetPieceHealth.Value; float time = Time.time; foreach (Piece item in _pieceCache) { if (!Object.op_Implicit((Object)(object)item) || !Object.op_Implicit((Object)(object)item.m_nview) || !item.m_nview.IsValid() || !IsEligiblePiece(item)) { continue; } RepairPiece(item, value, time); if (PluginConfig.ShowRepairEffectOnWardActivation.Value) { EffectList placeEffect = item.m_placeEffect; if (placeEffect != null) { placeEffect.Create(((Component)item).transform.position, ((Component)item).transform.rotation, (Transform)null, 1f, -1); } } _pieceCount++; } GetOffMyLawn.LogInfo($"Repaired {_pieceCount} pieces to health: {PluginConfig.TargetPieceHealth.Value}"); if (PluginConfig.ShowTopLeftMessageOnPieceRepair.Value) { ((Character)Player.m_localPlayer).Message((MessageType)1, $"Repaired {_pieceCount} pieces to health: {PluginConfig.TargetPieceHealth.Value}", 0, (Sprite)null); } _pieceCache.Clear(); } private static void GetAllPiecesInRadius(Vector3 origin, float radius, List<Piece> pieces) { //IL_0027: 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) foreach (Piece s_allPiece in Piece.s_allPieces) { if (((Component)s_allPiece).gameObject.layer != Piece.s_ghostLayer && !(Vector3.Distance(origin, ((Component)s_allPiece).transform.position) >= radius)) { pieces.Add(s_allPiece); } } } } public sealed class TargetPieceHealthStatusEffect : StatusEffect { public static readonly TargetPieceHealthStatusEffect Instance = CreateStatusEffect(); private string _targetPieceHealthText = string.Empty; public static TargetPieceHealthStatusEffect CreateStatusEffect() { TargetPieceHealthStatusEffect targetPieceHealthStatusEffect = ScriptableObject.CreateInstance<TargetPieceHealthStatusEffect>(); ((Object)targetPieceHealthStatusEffect).name = "TargetPieceHealthStatusEffect"; ((StatusEffect)targetPieceHealthStatusEffect).m_name = "GOML"; ((StatusEffect)targetPieceHealthStatusEffect).m_icon = Resources.FindObjectsOfTypeAll<Sprite>().FirstByNameOrThrow<Sprite>("hammer_icon_gold"); ((StatusEffect)targetPieceHealthStatusEffect).m_ttl = 0f; return targetPieceHealthStatusEffect; } public override void SetLevel(int itemLevel, float skillLevel) { ((StatusEffect)this).SetLevel(itemLevel, skillLevel); _targetPieceHealthText = $"{PluginConfig.TargetPieceHealth.Value}"; base.m_isNew = true; } public override string GetIconText() { return _targetPieceHealthText; } } [BepInPlugin("redseiko.valheim.getoffmylawn", "GetOffMyLawn", "1.12.0")] public sealed class GetOffMyLawn : BaseUnityPlugin { public const string PluginGUID = "redseiko.valheim.getoffmylawn"; public const string PluginName = "GetOffMyLawn"; public const string PluginVersion = "1.12.0"; private static ManualLogSource _logger; private void Awake() { _logger = ((BaseUnityPlugin)this).Logger; PluginConfig.BindConfig(((BaseUnityPlugin)this).Config); Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "redseiko.valheim.getoffmylawn"); } public static void LogInfo(object obj) { _logger.LogInfo((object)$"[{DateTime.Now.ToString(DateTimeFormatInfo.InvariantInfo)}] {obj}"); } public static void LogWarning(object obj) { _logger.LogWarning((object)$"[{DateTime.Now.ToString(DateTimeFormatInfo.InvariantInfo)}] {obj}"); } } [HarmonyPatch(typeof(BaseAI))] internal static class BaseAIPatch { [HarmonyTranspiler] [HarmonyPatch("Awake")] private static IEnumerable<CodeInstruction> AwakeTranspiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown return new CodeMatcher(instructions, generator).Start().MatchStartForward((CodeMatch[])(object)new CodeMatch[2] { new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(LayerMask), "GetMask", new Type[1] { typeof(string[]) }, (Type[])null), (string)null), new CodeMatch((OpCode?)OpCodes.Stsfld, (object)AccessTools.Field(typeof(BaseAI), "m_monsterTargetRayMask"), (string)null) }).ThrowIfInvalid("Could not patch BaseAI.Awake()! (monster-target-ray-mask)") .Advance(1) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(BaseAIPatch), "GetMonsterTargetRayMaskDelegate", (Type[])null, (Type[])null)) }) .InstructionEnumeration(); } private static int GetMonsterTargetRayMaskDelegate(int value) { if (PluginConfig.IsModEnabled.Value) { return LayerMask.GetMask(new string[4] { "Default", "static_solid", "Default_small", "vehicle" }); } return value; } [HarmonyPrefix] [HarmonyPatch("FindRandomStaticTarget")] private static bool FindRandomStaticTargetPrefix(ref StaticTarget __result) { if (PluginConfig.IsModEnabled.Value) { __result = null; return false; } return true; } [HarmonyPrefix] [HarmonyPatch("FindClosestStaticPriorityTarget")] private static bool FindClosestStaticPriorityTargetPrefix(ref StaticTarget __result) { if (PluginConfig.IsModEnabled.Value) { __result = null; return false; } return true; } } [HarmonyPatch(typeof(MonsterAI))] internal static class MonsterAIPatch { [HarmonyPostfix] [HarmonyPatch("Awake")] private static void AwakePostfix(MonsterAI __instance) { if (PluginConfig.IsModEnabled.Value && __instance.m_attackPlayerObjects) { __instance.m_attackPlayerObjects = false; } } } [HarmonyPatch(typeof(Piece))] internal static class PiecePatch { [HarmonyPostfix] [HarmonyPatch("SetCreator")] private static void SetCreatorPostfix(Piece __instance) { if (PluginConfig.IsModEnabled.Value && Object.op_Implicit((Object)(object)__instance) && PieceUtils.TryGetValidOwnedNetView(__instance, out var netView) && PieceUtils.IsEligiblePiece(__instance)) { netView.m_zdo.Set(ZDOVars.s_health, PluginConfig.TargetPieceHealth.Value); } } } [HarmonyPatch(typeof(Player))] internal static class PlayerPatch { [HarmonyPrefix] [HarmonyPatch("Repair")] private static bool RepairPrefix(Player __instance, ItemData toolItem) { if (PluginConfig.IsModEnabled.Value) { __instance.RepairPiece(toolItem, __instance.m_hoveringPiece); return false; } return true; } [HarmonyTranspiler] [HarmonyPatch("RemovePiece")] private static IEnumerable<CodeInstruction> RemovePieceTranspiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown return new CodeMatcher(instructions, generator).Start().MatchStartForward((CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Ldfld, (object)typeof(Piece).GetField("m_canBeRemoved"), (string)null) }).ThrowIfInvalid("Could not patch Player.RemovePiece()! (can-ve-removed)") .Advance(1) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[2] { new CodeInstruction(OpCodes.Ldloc_1, (object)null), new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(PlayerPatch), "CanBeRemovedDelegate", (Type[])null, (Type[])null)) }) .InstructionEnumeration(); } private static bool CanBeRemovedDelegate(bool canBeRemoved, Piece piece) { if (!canBeRemoved) { if (PluginConfig.IsModEnabled.Value) { return PieceUtils.CanRemovePiece(piece); } return false; } return true; } [HarmonyPostfix] [HarmonyPatch("OnSpawned")] private static void OnSpawnedPostfix(Player __instance) { if (PluginConfig.IsModEnabled.Value && PluginConfig.ShowStatusEffectIndicator.Value) { LawnManager.ToggleStatusEffectIndicator(toggleOn: true); } } } [HarmonyPatch(typeof(PrivateArea))] internal static class PrivateAreaPatch { [HarmonyPostfix] [HarmonyPatch("Interact")] private static void InteractPostfix(PrivateArea __instance) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) if (PluginConfig.IsModEnabled.Value && PluginConfig.RepairPiecesOnWardActivation.Value && Object.op_Implicit((Object)(object)__instance) && __instance.IsEnabled() && Object.op_Implicit((Object)(object)__instance.m_piece) && __instance.m_piece.IsCreator()) { PieceUtils.RepairPiecesInRadius(((Component)__instance).transform.position, __instance.m_radius); } } } [HarmonyPatch(typeof(WearNTear))] internal static class WearNTearPatch { public const float PieceHealthDamageThreshold = 100000f; [HarmonyTranspiler] [HarmonyPatch("ApplyDamage")] private static IEnumerable<CodeInstruction> ApplyDamageTranspiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { //IL_0002: 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_0026: Expected O, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Expected O, but got Unknown //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Expected O, but got Unknown //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Expected O, but got Unknown List<Label> labels; Label label; return new CodeMatcher(instructions, generator).Start().MatchStartForward((CodeMatch[])(object)new CodeMatch[5] { new CodeMatch((OpCode?)OpCodes.Ldloc_0, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Ldc_R4, (object)0f, (string)null), new CodeMatch((OpCode?)OpCodes.Bgt_Un, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Ldc_I4_0, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Ret, (object)null, (string)null) }).ThrowIfInvalid("Could not patch WearNTear.ApplyDamage()! (health-lt-0)") .Advance(5) .ExtractLabels(out labels) .Insert((CodeInstruction[])(object)new CodeInstruction[5] { new CodeInstruction(OpCodes.Ldloc_0, (object)null), new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(WearNTearPatch), "IsHealthGreaterThanDamageThreshold", (Type[])null, (Type[])null)), new CodeInstruction(OpCodes.Brfalse, (object)null), new CodeInstruction(OpCodes.Ldc_I4_0, (object)null), new CodeInstruction(OpCodes.Ret, (object)null) }) .AddLabels((IEnumerable<Label>)labels) .CreateLabelOffset(5, out label) .Advance(2) .SetOperandAndAdvance((object)label) .InstructionEnumeration(); } private static bool IsHealthGreaterThanDamageThreshold(float health) { if (health >= 100000f && PluginConfig.IsModEnabled.Value && PluginConfig.EnablePieceHealthDamageThreshold.Value) { return true; } return false; } } } namespace ComfyLib { public static class CodeMatcherExtensions { public static CodeMatcher CreateLabelOffset(this CodeMatcher matcher, int offset, out Label label) { return matcher.CreateLabelAt(matcher.Pos + offset, ref label); } public static CodeMatcher DeclareLocal(this CodeMatcher matcher, ILGenerator generator, Type localType, out LocalBuilder localBuilder) { localBuilder = generator.DeclareLocal(localType); return matcher; } public static CodeMatcher ExtractLabels(this CodeMatcher matcher, out List<Label> labels) { labels = matcher.Labels.ToList(); matcher.Labels.Clear(); return matcher; } public static CodeMatcher SaveOperand(this CodeMatcher matcher, out object operand) { operand = matcher.Operand; return matcher; } } public static class ConfigFileExtensions { internal sealed class ConfigurationManagerAttributes { public Action<ConfigEntryBase> CustomDrawer; public bool? Browsable; public bool? HideDefaultButton; public bool? HideSettingName; public bool? IsAdvanced; public int? Order; public bool? ReadOnly; } private static readonly Dictionary<string, int> _sectionToSettingOrder = new Dictionary<string, int>(); private static int GetSettingOrder(string section) { if (!_sectionToSettingOrder.TryGetValue(section, out var value)) { value = 0; } _sectionToSettingOrder[section] = value - 1; return value; } public static ConfigEntry<T> BindInOrder<T>(this ConfigFile config, string section, string key, T defaultValue, string description, AcceptableValueBase acceptableValues) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown return config.Bind<T>(section, key, defaultValue, new ConfigDescription(description, acceptableValues, new object[1] { new ConfigurationManagerAttributes { Order = GetSettingOrder(section) } })); } public static ConfigEntry<T> BindInOrder<T>(this ConfigFile config, string section, string key, T defaultValue, string description, Action<ConfigEntryBase> customDrawer = null, bool browsable = true, bool hideDefaultButton = false, bool hideSettingName = false, bool isAdvanced = false, bool readOnly = false) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown return config.Bind<T>(section, key, defaultValue, new ConfigDescription(description, (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Browsable = browsable, CustomDrawer = customDrawer, HideDefaultButton = hideDefaultButton, HideSettingName = hideSettingName, IsAdvanced = isAdvanced, Order = GetSettingOrder(section), ReadOnly = readOnly } })); } public static void OnSettingChanged<T>(this ConfigEntry<T> configEntry, Action settingChangedHandler) { configEntry.SettingChanged += delegate { settingChangedHandler(); }; } public static void OnSettingChanged<T>(this ConfigEntry<T> configEntry, Action<T> settingChangedHandler) { configEntry.SettingChanged += delegate(object _, EventArgs eventArgs) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) settingChangedHandler((T)((SettingChangedEventArgs)eventArgs).ChangedSetting.BoxedValue); }; } public static void OnSettingChanged<T>(this ConfigEntry<T> configEntry, Action<ConfigEntry<T>> settingChangedHandler) { configEntry.SettingChanged += delegate(object _, EventArgs eventArgs) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) settingChangedHandler((ConfigEntry<T>)((SettingChangedEventArgs)eventArgs).ChangedSetting.BoxedValue); }; } } public static class ComponentExtensions { public static bool TryGetComponentInChildren<T>(this Component rootComponent, out T component) where T : Component { component = rootComponent.GetComponentInChildren<T>(true); return Object.op_Implicit((Object)(object)component); } } public static class ObjectExtensions { public static T FirstByNameOrThrow<T>(this T[] unityObjects, string name) where T : Object { foreach (T val in unityObjects) { if (((Object)val).name == name) { return val; } } throw new InvalidOperationException($"Could not find Unity object of type {typeof(T)} with name: {name}"); } public static T Ref<T>(this T unityObject) where T : Object { if (!Object.op_Implicit((Object)(object)unityObject)) { return default(T); } return unityObject; } } }