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 KeyBindManager v0.1.0
KeyBindManager.dll
Decompiled 3 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Extensions; using Jotunn.Managers; using Jotunn.Utils; using Logging; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("KeyBindManager")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("DiscoveryPins")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("08a6f7d7-cf93-4931-aecd-abf2ce6ed34c")] [assembly: AssemblyFileVersion("0.1.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.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 Logging { internal static class Log { internal enum InfoLevel { Low, Medium, High } private static ManualLogSource logSource; internal static ConfigEntry<InfoLevel> Verbosity { get; set; } internal static InfoLevel VerbosityLevel => Verbosity.Value; internal static bool IsVerbosityLow => Verbosity.Value >= InfoLevel.Low; internal static bool IsVerbosityMedium => Verbosity.Value >= InfoLevel.Medium; internal static bool IsVerbosityHigh => Verbosity.Value >= InfoLevel.High; internal static void Init(ManualLogSource logSource) { Log.logSource = logSource; } internal static void LogDebug(object data) { logSource.LogDebug(data); } internal static void LogError(object data) { logSource.LogError(data); } internal static void LogFatal(object data) { logSource.LogFatal(data); } internal static void LogMessage(object data) { logSource.LogMessage(data); } internal static void LogWarning(object data) { logSource.LogWarning(data); } internal static void LogInfo(object data, InfoLevel level = InfoLevel.Low) { if (Verbosity == null || VerbosityLevel >= level) { logSource.LogInfo(data); } } internal static void LogGameObject(GameObject prefab, bool includeChildren = false) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown LogInfo("***** " + ((Object)prefab).name + " *****"); Component[] components = prefab.GetComponents<Component>(); for (int i = 0; i < components.Length; i++) { LogComponent(components[i]); } if (!includeChildren) { return; } LogInfo("***** " + ((Object)prefab).name + " (children) *****"); foreach (Transform item in prefab.transform) { Transform val = item; if (Object.op_Implicit((Object)(object)val)) { LogInfo(" - " + ((Object)val).name); components = ((Component)val).GetComponents<Component>(); for (int i = 0; i < components.Length; i++) { LogComponent(components[i]); } } } } internal static void LogComponent(Component compo) { if (!Object.op_Implicit((Object)(object)compo)) { return; } try { LogInfo("--- " + ((object)compo).GetType().Name + ": " + ((Object)compo).name + " ---"); } catch (Exception ex) { LogError(ex.ToString()); LogWarning("Could not get type name for component!"); return; } try { foreach (PropertyInfo declaredProperty in AccessTools.GetDeclaredProperties(((object)compo).GetType())) { try { LogInfo($" - {declaredProperty.Name} = {declaredProperty.GetValue(compo)}"); } catch (Exception ex2) { LogError(ex2.ToString()); LogWarning("Could not get property: " + declaredProperty.Name + " for component!"); } } } catch (Exception ex3) { LogError(ex3.ToString()); LogWarning("Could not get properties for component!"); } try { foreach (FieldInfo declaredField in AccessTools.GetDeclaredFields(((object)compo).GetType())) { try { LogInfo($" - {declaredField.Name} = {declaredField.GetValue(compo)}"); } catch (Exception ex4) { LogError(ex4.ToString()); LogWarning("Could not get field: " + declaredField.Name + " for component!"); } } } catch (Exception ex5) { LogError(ex5.ToString()); LogWarning("Could not get fields for component!"); } } } } namespace KeyBindManager { [BepInPlugin("Searica.Valheim.KeyBindManager", "KeyBindManager", "0.1.0")] [BepInDependency("com.jotunn.jotunn", "2.30.1")] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] [SynchronizationMode(/*Could not decode attribute arguments.*/)] internal sealed class KeyBindManager : BaseUnityPlugin { internal sealed class ConfigHandlerDB { private readonly string PluginGuid; private readonly ConfigDefinition ConfigDef; private readonly ConfigEntryBase OriginalConfigEntry; private ConfigEntry<string> StringHandler; private ConfigEntry<KeyCode> KeyCodeHandler; private ConfigEntry<KeyboardShortcut> ShortcutHandler; private ConfigEntry<string> StringOriginal; private ConfigEntry<KeyCode> KeyCodeOriginal; private ConfigEntry<KeyboardShortcut> ShortcutOriginal; private readonly Type ConfigType; private bool PauseUpdateEvents; public ConfigHandlerDB(string pluginGuid, ConfigEntryBase configEntry, Type type) { PluginGuid = pluginGuid; ConfigDef = configEntry.Definition; OriginalConfigEntry = configEntry; ConfigType = type; try { if (type == typeof(KeyCode)) { KeyCodeOriginal = (ConfigEntry<KeyCode>)(object)configEntry; KeyCodeHandler = BindHandlerConfig<KeyCode>(pluginGuid, ConfigDef, KeyCodeOriginal); } else if (type == typeof(KeyboardShortcut)) { ShortcutOriginal = (ConfigEntry<KeyboardShortcut>)(object)configEntry; ShortcutHandler = BindHandlerConfig<KeyboardShortcut>(pluginGuid, ConfigDef, ShortcutOriginal); } else if (type == typeof(string)) { StringOriginal = (ConfigEntry<string>)(object)configEntry; StringHandler = BindHandlerConfig<string>(pluginGuid, ConfigDef, StringOriginal); } else { Log.LogWarning("Invalid type for config handler! " + type.ToString()); } } catch (Exception ex) { Log.LogError(ex.Message ?? ""); Log.LogWarning("Failed to create handler config entry for " + pluginGuid + " - " + configEntry.Definition.Key); } } private ConfigEntry<T> BindHandlerConfig<T>(string pluginGuid, ConfigDefinition originalDefinition, ConfigEntry<T> originalEntry) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown ConfigEntry<T> val = ((BaseUnityPlugin)Instance).Config.Bind<T>(pluginGuid, originalDefinition.Key, (T)((ConfigEntryBase)originalEntry).DefaultValue, new ConfigDescription(((ConfigEntryBase)originalEntry).Description.Description, ((ConfigEntryBase)originalEntry).Description.AcceptableValues, ((ConfigEntryBase)originalEntry).Description.Tags)); originalEntry.Value = val.Value; originalEntry.SettingChanged += OriginalConfigChanged; val.SettingChanged += HandlerConfigChanged; return val; } public void HandlerConfigChanged(object obj, EventArgs args) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) if (!PauseUpdateEvents) { Log.LogInfo("Handler setting changed", Log.InfoLevel.Medium); PauseUpdateEvents = true; if (ConfigType == typeof(string)) { StringOriginal.Value = StringHandler.Value; } else if (ConfigType == typeof(KeyCode)) { KeyCodeOriginal.Value = KeyCodeHandler.Value; } else if (ConfigType == typeof(KeyboardShortcut)) { ShortcutOriginal.Value = ShortcutHandler.Value; } PauseUpdateEvents = false; } } public void OriginalConfigChanged(object obj, EventArgs args) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) if (!PauseUpdateEvents) { Log.LogInfo("Original setting changed", Log.InfoLevel.Medium); PauseUpdateEvents = true; if (ConfigType == typeof(string)) { StringHandler.Value = StringOriginal.Value; } else if (ConfigType == typeof(KeyCode)) { KeyCodeHandler.Value = KeyCodeOriginal.Value; } else if (ConfigType == typeof(KeyboardShortcut)) { ShortcutHandler.Value = ShortcutOriginal.Value; } PauseUpdateEvents = false; } } } public const string PluginName = "KeyBindManager"; internal const string Author = "Searica"; public const string PluginGUID = "Searica.Valheim.KeyBindManager"; public const string PluginVersion = "0.1.0"; internal static MethodInfo ConfigGetterInfo = AccessTools.PropertyGetter(typeof(BaseUnityPlugin), "Config"); internal static readonly List<string> KeyBindDescHints = new List<string> { "key bind", "shortcut", "key" }; internal static HashSet<ConfigDefinition> IgnoreConfigList = new HashSet<ConfigDefinition>(); internal static KeyBindManager Instance; internal static ConfigFileWatcher ConfigFileWatcher; internal static Dictionary<string, ConfigFile> PluginConfigsMap = new Dictionary<string, ConfigFile>(); internal static Dictionary<string, Dictionary<ConfigDefinition, ConfigHandlerDB>> ConfigHandlers = new Dictionary<string, Dictionary<ConfigDefinition, ConfigHandlerDB>>(); internal const string GlobalSection = "Global"; internal static bool PauseUpdateEvents = false; public void Awake() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown Instance = this; Log.Init(((BaseUnityPlugin)this).Logger); Log.Verbosity = ConfigFileExtensions.BindConfigInOrder<Log.InfoLevel>(((BaseUnityPlugin)this).Config, "Logging", "Verbosity", Log.InfoLevel.Low, "Low will log basic information about the mod. Medium will log information that is useful for troubleshooting. High will log a lot of information, do not set it to this without good reason as it will slow down your game.", false, true, true, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFileWatcher = new ConfigFileWatcher(((BaseUnityPlugin)this).Config, 1000L); ((BaseUnityPlugin)this).Config.SaveOnConfigSet = false; Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "Searica.Valheim.KeyBindManager"); Game.isModded = true; ConfigFileWatcher.OnConfigFileReloaded += delegate { UpdatePlugin(saveConfig: false); }; SynchronizationManager.OnConfigurationWindowClosed += delegate { UpdatePlugin(); }; SynchronizationManager.OnConfigurationSynchronized += delegate { UpdatePlugin(); }; } internal static bool TryGetPluginConfig(PluginInfo pluginInfo, out ConfigFile config) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown config = null; if (pluginInfo == null || pluginInfo.Instance == null) { Log.LogWarning("Null PluginInfo!"); return false; } config = (ConfigFile)ConfigGetterInfo.Invoke(pluginInfo.Instance, null); return config != null; } private void UpdatePlugin(bool saveConfig = true, bool initialUpdate = false) { if (saveConfig) { ((BaseUnityPlugin)this).Config.Save(); } } public void OnDestroy() { ((BaseUnityPlugin)this).Config.Save(); } } [HarmonyPatch] internal static class Patches { [HarmonyPrefix] [HarmonyPriority(200)] [HarmonyPatch(typeof(FejdStartup), "Start")] internal static void ScanPluginConfigFiles() { Log.LogInfo("Prefix FjedStartup.Start", Log.InfoLevel.Medium); foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos) { if (!KeyBindManager.PluginConfigsMap.ContainsKey(pluginInfo.Key) && !(pluginInfo.Key == "Searica.Valheim.KeyBindManager")) { if (!KeyBindManager.TryGetPluginConfig(pluginInfo.Value, out var config)) { Log.LogWarning($"Failed to get config for {pluginInfo.Value}"); continue; } KeyBindManager.PluginConfigsMap.Add(pluginInfo.Key, config); Log.LogInfo($"Found config for {pluginInfo.Value}"); } } } [HarmonyPrefix] [HarmonyPriority(100)] [HarmonyPatch(typeof(ZoneSystem), "Start")] internal static void ScanForKeyBinds() { Log.LogInfo("Prefix ZoneSystem.Start", Log.InfoLevel.Medium); foreach (KeyValuePair<string, ConfigFile> item in KeyBindManager.PluginConfigsMap) { if (item.Value == null) { continue; } if (!KeyBindManager.ConfigHandlers.ContainsKey(item.Key)) { KeyBindManager.ConfigHandlers.Add(item.Key, new Dictionary<ConfigDefinition, KeyBindManager.ConfigHandlerDB>()); } Log.LogInfo("Scanning configs for " + item.Key, Log.InfoLevel.Medium); foreach (KeyValuePair<ConfigDefinition, ConfigEntryBase> item2 in item.Value) { Log.LogInfo("Config Entry: " + item2.Key.Key, Log.InfoLevel.High); ConfigDefinition key = item2.Key; ConfigEntryBase value = item2.Value; Type type; if (KeyBindManager.ConfigHandlers[item.Key].ContainsKey(key) || KeyBindManager.IgnoreConfigList.Contains(key)) { Log.LogInfo("Already scanned, skipping config entry", Log.InfoLevel.High); } else if (IsKeyBindConfig(value, out type)) { Log.LogInfo("Adding keybind handler", Log.InfoLevel.High); KeyBindManager.ConfigHandlers[item.Key].Add(key, new KeyBindManager.ConfigHandlerDB(item.Key, value, type)); } else { Log.LogInfo("Not a keybind, skipping config entry", Log.InfoLevel.High); KeyBindManager.IgnoreConfigList.Add(key); } } } } internal static bool IsKeyBindConfig(ConfigEntryBase configEntry, out Type type) { type = configEntry.SettingType; if (type == typeof(KeyCode) || type == typeof(KeyboardShortcut)) { return true; } if (type == typeof(string)) { return HasKeyBindDesc(configEntry); } return false; } internal static bool HasKeyBindDesc(ConfigEntryBase configEntry) { string text = configEntry.Description.Description.ToLowerInvariant(); foreach (string keyBindDescHint in KeyBindManager.KeyBindDescHints) { if (text.Contains(keyBindDescHint)) { return true; } } return false; } } } namespace DiscoveryPins.Extensions { internal static class SafeInvokEvents { public static void SafeInvoke(this Action events) { if (events == null) { return; } Delegate[] invocationList = events.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { Action action = (Action)invocationList[i]; try { action(); } catch (Exception ex) { Log.LogWarning($"Exception thrown at event {new StackFrame(1).GetMethod().Name} in {action.Method.DeclaringType.Name}.{action.Method.Name}:\n{ex}"); } } } public static void SafeInvoke<TArg1>(this Action<TArg1> events, TArg1 arg1) { if (events == null) { return; } Delegate[] invocationList = events.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { Action<TArg1> action = (Action<TArg1>)invocationList[i]; try { action(arg1); } catch (Exception ex) { Log.LogWarning($"Exception thrown at event {new StackFrame(1).GetMethod().Name} in {action.Method.DeclaringType.Name}.{action.Method.Name}:\n{ex}"); } } } public static void SafeInvoke<TArg1, TArg2>(this Action<TArg1, TArg2> events, TArg1 arg1, TArg2 arg2) { if (events == null) { return; } Delegate[] invocationList = events.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { Action<TArg1, TArg2> action = (Action<TArg1, TArg2>)invocationList[i]; try { action(arg1, arg2); } catch (Exception ex) { Log.LogWarning($"Exception thrown at event {new StackFrame(1).GetMethod().Name} in {action.Method.DeclaringType.Name}.{action.Method.Name}:\n{ex}"); } } } public static void SafeInvoke<TEventArg>(this EventHandler<TEventArg> events, object sender, TEventArg arg1) { if (events == null) { return; } Delegate[] invocationList = events.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { EventHandler<TEventArg> eventHandler = (EventHandler<TEventArg>)invocationList[i]; try { eventHandler(sender, arg1); } catch (Exception ex) { Log.LogWarning($"Exception thrown at event {new StackFrame(1).GetMethod().Name} in {eventHandler.Method.DeclaringType.Name}.{eventHandler.Method.Name}:\n{ex}"); } } } } }