Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of PutMeDown v1.3.0
PutMeDown.dll
Decompiled 2 weeks 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("PutMeDown")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("PutMeDown")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("287bf250-ae87-4283-867b-9c9351e408fc")] [assembly: AssemblyFileVersion("1.3.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.3.0.0")] [module: UnverifiableCode] [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 PutMeDown { public static class PluginConfig { private static readonly List<ToggleStringListConfigEntry> _itemsToIgnoreConfigs = new List<ToggleStringListConfigEntry>(); private static int _itemsToIgnoreConfigIndex = -1; private static ToggleStringListConfigEntry _itemsToIgnoreConfig = null; public static ConfigEntry<bool> IsModEnabled { get; private set; } public static ToggleStringListConfigEntry ItemsToIgnore { get; private set; } public static ConfigEntry<KeyboardShortcut> ItemsToIgnoreCycleShortcut { get; private set; } public static ToggleStringListConfigEntry ItemsToIgnoreAlt1 { get; private set; } public static ToggleStringListConfigEntry ItemsToIgnoreAlt2 { get; private set; } [ComfyConfig] public static void BindConfig(ConfigFile config) { IsModEnabled = config.BindInOrder("_Global", "isModEnabled", defaultValue: true, "Globally enable or disable this mod."); } [ComfyConfig(LateBind = true)] public static void BindAutoPickupConfig(ConfigFile config) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) _itemsToIgnoreConfigs.Clear(); _itemsToIgnoreConfigIndex = -1; ItemsToIgnore = new ToggleStringListConfigEntry(config, "AutoPickup", "itemsToIgnore", "Wood=0,Stone=0", "Items to ignore for auto-pickup behaviour (normal config).", GetItemDropSearchOptions); _itemsToIgnoreConfigs.Add(ItemsToIgnore); ItemsToIgnore.SettingChanged += OnItemsToIgnoreChanged; ItemsToIgnoreCycleShortcut = config.BindInOrder<KeyboardShortcut>("AutoPickup.Alt", "itemsToIgnoreCycleShortcut", new KeyboardShortcut((KeyCode)0, Array.Empty<KeyCode>()), "Shortcut to cycle through ItemsToIgnore normal and alternate configs."); ItemsToIgnoreAlt1 = new ToggleStringListConfigEntry(config, "AutoPickup.Alt", "itemsToIgnoreAlt1", "Wood=0,Stone=0", "Items to ignore for auto-pickup behaviour (alternate config 1).", GetItemDropSearchOptions); _itemsToIgnoreConfigs.Add(ItemsToIgnoreAlt1); ItemsToIgnoreAlt1.SettingChanged += OnItemsToIgnoreChanged; ItemsToIgnoreAlt2 = new ToggleStringListConfigEntry(config, "AutoPickup.Alt", "itemsToIgnoreAlt2", "Wood=0,Stone=0", "Items to ignore for auto-pickup behaviour (alternate config 2).", GetItemDropSearchOptions); _itemsToIgnoreConfigs.Add(ItemsToIgnoreAlt2); ItemsToIgnoreAlt2.SettingChanged += OnItemsToIgnoreChanged; CycleItemsToIgnoreConfig(); } public static void CycleItemsToIgnoreConfig() { _itemsToIgnoreConfigIndex++; if (_itemsToIgnoreConfigIndex < 0 || _itemsToIgnoreConfigIndex >= _itemsToIgnoreConfigs.Count) { _itemsToIgnoreConfigIndex = 0; } _itemsToIgnoreConfig = _itemsToIgnoreConfigs[_itemsToIgnoreConfigIndex]; AutoPickupController.SetItemsToIgnore(_itemsToIgnoreConfig.ToggledStringValues()); } private static void OnItemsToIgnoreChanged(object sender, IEnumerable<string> itemsToIgnore) { if (sender == _itemsToIgnoreConfig) { AutoPickupController.SetItemsToIgnore(itemsToIgnore); } } public static List<ToggleStringListConfigEntry.SearchOption> GetItemDropSearchOptions() { List<ToggleStringListConfigEntry.SearchOption> list = new List<ToggleStringListConfigEntry.SearchOption>(); ItemDrop val = default(ItemDrop); foreach (GameObject item in ObjectDB.m_instance.m_items) { if (item.TryGetComponent<ItemDrop>(ref val) && val.m_autoPickup && val.m_itemData.m_shared.m_icons.Length != 0 && !string.IsNullOrEmpty(val.m_itemData.m_shared.m_description)) { string text = Localization.m_instance.Localize(val.m_itemData.m_shared.m_name); list.Add(new ToggleStringListConfigEntry.SearchOption(((Object)item).name, text + " (" + ((Object)item).name + ")")); } } return list; } } public static class AutoPickupController { private static readonly HashSet<string> _itemsToIgnore = new HashSet<string>(); public static void SetItemsToIgnore(IEnumerable<string> itemsToIgnore) { _itemsToIgnore.Clear(); _itemsToIgnore.UnionWith(itemsToIgnore); PutMeDown.LogInfo(string.Format("Ignoring {0} items: {1}", _itemsToIgnore.Count, string.Join(", ", _itemsToIgnore))); } public static bool ShouldIgnoreItem(ItemDrop itemDrop) { return _itemsToIgnore.Contains(((Object)itemDrop.m_itemData.m_dropPrefab).name); } } [HarmonyPatch(typeof(Player))] internal static class PlayerPatch { [HarmonyTranspiler] [HarmonyPatch("AutoPickup")] private static IEnumerable<CodeInstruction> AutoPickupTranspiler(IEnumerable<CodeInstruction> instructions) { //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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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 CodeInstruction instruction; return new CodeMatcher(instructions, (ILGenerator)null).Start().MatchStartForward((CodeMatch[])(object)new CodeMatch[2] { new CodeMatch((OpCode?)OpCodes.Ldloc_S, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(ItemDrop), "m_autoPickup"), (string)null) }).ThrowIfInvalid("Could not patch Player.AutoPickup()! (auto-pickup)") .CopyInstruction(out instruction) .Advance(2) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[2] { instruction, new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(PlayerPatch), "AutoPickupDelegate", (Type[])null, (Type[])null)) }) .InstructionEnumeration(); } private static CodeMatcher CopyInstruction(this CodeMatcher matcher, out CodeInstruction instruction) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown instruction = new CodeInstruction(matcher.Opcode, matcher.Operand); return matcher; } private static bool AutoPickupDelegate(bool autoPickup, ItemDrop itemDrop) { if (autoPickup && PluginConfig.IsModEnabled.Value && AutoPickupController.ShouldIgnoreItem(itemDrop)) { return false; } return autoPickup; } [HarmonyTranspiler] [HarmonyPatch("Update")] private static IEnumerable<CodeInstruction> UpdateTranspiler(IEnumerable<CodeInstruction> instructions) { //IL_0002: 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_003b: 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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown return new CodeMatcher(instructions, (ILGenerator)null).Start().MatchStartForward((CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(Player), "UpdateHover", (Type[])null, (Type[])null), (string)null) }).ThrowIfInvalid("Could not patch Player.Update()! (update-hover)") .Advance(1) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[2] { new CodeInstruction(OpCodes.Ldloc_1, (object)null), new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(PlayerPatch), "UpdateHoverPostDelegate", (Type[])null, (Type[])null)) }) .InstructionEnumeration(); } private static void UpdateHoverPostDelegate(bool takeInput) { //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) if (takeInput && PluginConfig.IsModEnabled.Value) { KeyboardShortcut value = PluginConfig.ItemsToIgnoreCycleShortcut.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { PluginConfig.CycleItemsToIgnoreConfig(); } } } } [BepInPlugin("redseiko.valheim.putmedown", "PutMeDown", "1.3.0")] public sealed class PutMeDown : BaseUnityPlugin { public const string PluginGuid = "redseiko.valheim.putmedown"; public const string PluginName = "PutMeDown"; public const string PluginVersion = "1.3.0"; private static ManualLogSource _logger; private void Awake() { _logger = ((BaseUnityPlugin)this).Logger; ComfyConfigUtils.BindConfig(((BaseUnityPlugin)this).Config); Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "redseiko.valheim.putmedown"); } public static void LogInfo(object obj) { _logger.LogInfo((object)$"[{DateTime.Now.ToString(DateTimeFormatInfo.InvariantInfo)}] {obj}"); Chat.m_instance.AddMessage(obj); } } } namespace ComfyLib { [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] public sealed class ComfyConfigAttribute : Attribute { public bool LateBind { get; set; } } public static class ComfyConfigUtils { [HarmonyPatch] private static class ComfyConfigBinder { private static readonly Queue<Action> _lateBindQueue = new Queue<Action>(); private static bool _startupPatched = false; public static void Bind(ConfigFile config, MethodInfo method, ComfyConfigAttribute attribute) { if (!attribute.LateBind || _startupPatched) { method.Invoke(null, new object[1] { config }); return; } _lateBindQueue.Enqueue(delegate { method.Invoke(null, new object[1] { config }); }); } [HarmonyPatch(typeof(FejdStartup), "Start")] private static void Postfix() { while (_lateBindQueue.Count > 0) { _lateBindQueue.Dequeue()?.Invoke(); } _startupPatched = true; } } public static void BindConfig(ConfigFile config) { BindConfigs(config, Assembly.GetExecutingAssembly()); } private static void BindConfigs(ConfigFile config, Assembly assembly) { foreach (var (method, attribute) in GetBindConfigMethods(assembly)) { ComfyConfigBinder.Bind(config, method, attribute); } } private static IEnumerable<(MethodInfo, ComfyConfigAttribute)> GetBindConfigMethods(Assembly assembly) { return assembly.GetTypes().SelectMany((Type type) => type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)).SelectMany((MethodInfo method) => GetBindConfigMethod(method)); } private static IEnumerable<(MethodInfo, ComfyConfigAttribute)> GetBindConfigMethod(MethodInfo method) { ComfyConfigAttribute customAttribute = method.GetCustomAttribute<ComfyConfigAttribute>(inherit: false); if (customAttribute != null) { ParameterInfo[] parameters = method.GetParameters(); if (parameters.Length == 1 && parameters[0].ParameterType == typeof(ConfigFile)) { yield return (method, customAttribute); } } } } public sealed class ToggleStringListConfigEntry { public sealed class SearchOption { public string OptionValue = string.Empty; public string DisplayValue = string.Empty; public SearchOption(string optionValue) : this(optionValue, optionValue) { } public SearchOption(string optionValue, string displayValue) { OptionValue = optionValue; DisplayValue = displayValue; } } public sealed class AutoCompleteBox { private readonly Func<IEnumerable<SearchOption>> _searchOptionsFunc; private List<SearchOption> _options; private readonly List<SearchOption> _currentOptions; private string _value; private Vector2 _scrollPosition; public AutoCompleteBox(Func<IEnumerable<SearchOption>> searchOptionsFunc) { //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) _searchOptionsFunc = searchOptionsFunc; _options = null; _currentOptions = new List<SearchOption>(); _value = string.Empty; _scrollPosition = Vector2.zero; } public string DrawBox(string value) { //IL_0022: 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) if (_value != value) { _value = value; FilterOptions(_value); _scrollPosition = Vector2.zero; } if (string.IsNullOrEmpty(_value)) { return string.Empty; } return DrawCurrentOptions(); } private void FilterOptions(string query) { _currentOptions.Clear(); if (string.IsNullOrEmpty(query)) { return; } if (_options == null) { _options = _searchOptionsFunc().ToList(); } foreach (SearchOption option in _options) { if (option.DisplayValue.IndexOf(query, StringComparison.OrdinalIgnoreCase) >= 0 || option.OptionValue.StartsWith(query, StringComparison.OrdinalIgnoreCase)) { _currentOptions.Add(option); } } } private string DrawCurrentOptions() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //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) _scrollPosition = GUILayout.BeginScrollView(_scrollPosition, GUI.skin.box, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.ExpandWidth(true), GUILayout.Height(120f) }); string result = string.Empty; foreach (SearchOption currentOption in _currentOptions) { if (GUILayout.Button(currentOption.DisplayValue, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MinWidth(40f) })) { result = currentOption.OptionValue; } } GUILayout.EndScrollView(); return result; } } public readonly ConfigEntry<string> BaseConfigEntry; private readonly AutoCompleteBox _autoCompleteLabel; private readonly List<string> _valuesCache = new List<string>(); private string _valueText = string.Empty; public event EventHandler<string[]> SettingChanged; public ToggleStringListConfigEntry(ConfigFile config, string section, string key, string defaultValue, string description, Func<IEnumerable<SearchOption>> autoCompleteFunc = null) { BaseConfigEntry = config.BindInOrder(section, key, defaultValue, description, (Action<ConfigEntryBase>)Drawer, browsable: true, hideDefaultButton: false, hideSettingName: false, isAdvanced: false, readOnly: false); BaseConfigEntry.SettingChanged += OnBaseSettingChanged; if (autoCompleteFunc != null) { _autoCompleteLabel = new AutoCompleteBox(autoCompleteFunc); } } private void OnBaseSettingChanged(object sender, EventArgs eventArgs) { this.SettingChanged?.Invoke(this, ToggledStringValues()); } private static bool IsToggledOn(ReadOnlySpan<char> value) { if (value.Length == 1) { return value[0] == '1'; } return false; } public string[] ToggledStringValues() { _valuesCache.Clear(); ReadOnlySpan<char> readOnlySpan = BaseConfigEntry.Value.AsSpan(); while (!readOnlySpan.IsEmpty) { int num = readOnlySpan.IndexOf(','); ReadOnlySpan<char> span = ((num >= 0) ? readOnlySpan.Slice(0, num) : readOnlySpan); ReadOnlySpan<char> obj; if (num < 0) { obj = default(ReadOnlySpan<char>); } else { ref ReadOnlySpan<char> reference = ref readOnlySpan; int num2 = num + 1; obj = reference.Slice(num2, reference.Length - num2); } readOnlySpan = obj; if (span.IsEmpty) { continue; } int num3 = span.IndexOf('='); if (num3 > 0) { ref ReadOnlySpan<char> reference = ref span; int num2 = num3 + 1; if (IsToggledOn(reference.Slice(num2, reference.Length - num2))) { _valuesCache.Add(span.Slice(0, num3).ToString()); } } } return _valuesCache.ToArray(); } public void Drawer(ConfigEntryBase configEntry) { GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); _valuesCache.Clear(); ReadOnlySpan<char> readOnlySpan = BaseConfigEntry.Value.AsSpan(); while (!readOnlySpan.IsEmpty) { int num = readOnlySpan.IndexOf(','); ReadOnlySpan<char> readOnlySpan2 = ((num >= 0) ? readOnlySpan.Slice(0, num) : readOnlySpan); ReadOnlySpan<char> obj; if (num < 0) { obj = default(ReadOnlySpan<char>); } else { ref ReadOnlySpan<char> reference = ref readOnlySpan; int num2 = num + 1; obj = reference.Slice(num2, reference.Length - num2); } readOnlySpan = obj; if (!readOnlySpan2.IsEmpty) { _valuesCache.Add(readOnlySpan2.ToString()); } } GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); bool flag = GUILayout.Button("Toggle On", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); bool flag2 = GUILayout.Button("Toggle Off", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); GUILayout.EndHorizontal(); bool flag3 = false; int num3 = -1; int i = 0; for (int count = _valuesCache.Count; i < count; i++) { ReadOnlySpan<char> span = _valuesCache[i].AsSpan(); int num4 = span.IndexOf('='); int num5; if (num4 > 0) { ref ReadOnlySpan<char> reference = ref span; int num2 = num4 + 1; num5 = (IsToggledOn(reference.Slice(num2, reference.Length - num2)) ? 1 : 0); } else { num5 = 0; } bool flag4 = (byte)num5 != 0; string text = ((num4 > 0) ? span.Slice(0, num4).ToString() : _valuesCache[i]); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); bool flag5 = GUILayout.Toggle(flag4, text, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); if (GUILayout.Button("−", (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.MinWidth(40f), GUILayout.ExpandWidth(false) })) { num3 = i; } GUILayout.EndHorizontal(); if (flag) { flag5 = true; } else if (flag2) { flag5 = false; } if (flag5 != flag4) { flag3 = true; _valuesCache[i] = text + (flag5 ? "=1" : "=0"); } } GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); _valueText = GUILayout.TextField(_valueText, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); GUILayout.Space(3f); if (GUILayout.Button("+", (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.MinWidth(40f), GUILayout.ExpandWidth(false) }) && !string.IsNullOrWhiteSpace(_valueText) && _valueText.IndexOf('=') < 0) { _valuesCache.Add(_valueText + "=1"); _valueText = string.Empty; flag3 = true; } GUILayout.EndHorizontal(); if (_autoCompleteLabel != null) { string text2 = _autoCompleteLabel.DrawBox(_valueText); if (!string.IsNullOrEmpty(text2)) { _valuesCache.Add(text2 + "=1"); flag3 = true; } } GUILayout.EndVertical(); if (num3 >= 0) { _valuesCache.RemoveAt(num3); flag3 = true; } if (flag3) { BaseConfigEntry.Value = string.Join(",", _valuesCache); } } } 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, 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, acceptableValues, new object[1] { new ConfigurationManagerAttributes { Browsable = browsable, CustomDrawer = null, HideDefaultButton = hideDefaultButton, HideSettingName = hideSettingName, IsAdvanced = isAdvanced, Order = GetSettingOrder(section), ReadOnly = readOnly } })); } 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>)(object)((SettingChangedEventArgs)eventArgs).ChangedSetting); }; } } public static class ChatExtensions { public static void AddMessage(this Chat chat, object obj) { if (Object.op_Implicit((Object)(object)chat)) { ((Terminal)chat).AddString($"{obj}"); chat.m_hideTimer = 0f; } } } public static class ObjectExtensions { public static T Ref<T>(this T unityObject) where T : Object { if (!Object.op_Implicit((Object)(object)unityObject)) { return default(T); } return unityObject; } } }