Decompiled source of DodgeShortcut v1.3.1

DodgeShortcut.dll

Decompiled 6 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
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.Configuration;
using BepInEx.Logging;
using DodgeShortcut.Extensions;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("DodgeShortcut")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DodgeShortcut")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("57ebdc73-fd85-484c-9e08-2b838274af44")]
[assembly: AssemblyFileVersion("1.3.1")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.1.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;
		}
	}
}
public sealed class ConfigurationManagerAttributes
{
	public delegate void CustomHotkeyDrawerFunc(ConfigEntryBase setting, ref bool isCurrentlyAcceptingInput);

	public bool? ShowRangeAsPercent;

	public Action<ConfigEntryBase> CustomDrawer;

	public CustomHotkeyDrawerFunc CustomHotkeyDrawer;

	public bool? Browsable;

	public string Category;

	public object DefaultValue;

	public bool? HideDefaultButton;

	public bool? HideSettingName;

	public string Description;

	public string DispName;

	public int? Order;

	public bool? ReadOnly;

	public bool? IsAdvanced;

	public Func<object, string> ObjToStr;

	public Func<string, object> StrToObj;
}
namespace DodgeShortcut
{
	internal enum DodgeDir
	{
		CharacterDir,
		LookDir
	}
	[BepInPlugin("Searica.Valheim.DodgeShortcut", "DodgeShortcut", "1.3.1")]
	internal sealed class DodgeShortcut : BaseUnityPlugin
	{
		public const string PluginName = "DodgeShortcut";

		internal const string Author = "Searica";

		public const string PluginGUID = "Searica.Valheim.DodgeShortcut";

		public const string PluginVersion = "1.3.1";

		internal static DodgeShortcut Instance;

		private static readonly string MainSection = "1 - Global";

		private static readonly string MechanicsSection = "Mechanics";

		internal ConfigEntry<bool> ModEnabled;

		internal ConfigEntry<KeyCode> DodgeKey;

		internal ConfigEntry<DodgeDir> DefaultDir;

		internal bool IsModEnabled => ModEnabled.Value;

		internal KeyCode GetDodgeKey()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return DodgeKey.Value;
		}

		internal DodgeDir GetDefaultDir()
		{
			return DefaultDir.Value;
		}

		public void Awake()
		{
			Instance = this;
			Log.Init(((BaseUnityPlugin)this).Logger);
			((BaseUnityPlugin)this).Config.Init("Searica.Valheim.DodgeShortcut");
			SetUpConfig();
			((BaseUnityPlugin)this).Config.SaveOnConfigSet = true;
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "Searica.Valheim.DodgeShortcut");
			Game.isModded = true;
			((BaseUnityPlugin)this).Config.SetupWatcher();
		}

		public void SetUpConfig()
		{
			ModEnabled = ((BaseUnityPlugin)this).Config.BindConfig(MainSection, "EnableMod", value: true, "Globally enable or disable this mod.");
			Log.Verbosity = ((BaseUnityPlugin)this).Config.BindConfig(MainSection, "Verbosity", LogLevel.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.");
			DodgeKey = ((BaseUnityPlugin)this).Config.BindConfig<KeyCode>(MechanicsSection, "DodgeShortcut", (KeyCode)308, "Set the key to press to dodge in the direction your character is moving.\nIf LeftAlt conflicts with other mods, I recommend setting the dodge key to the back button on your mouse.");
			DefaultDir = ((BaseUnityPlugin)this).Config.BindConfig(MechanicsSection, "DefaultDodgeDir", DodgeDir.CharacterDir, "Default direction that character dodges in if the dodge shortcut key is pressed while not moving. Can be set to the direction the character is facing, or the direction the camera is facing.");
		}

		public void OnDestroy()
		{
			((BaseUnityPlugin)this).Config.Save();
		}
	}
	[HarmonyPatch]
	internal static class KeyHintPatches
	{
		internal const string CombatHintsName = "CombatHints";

		internal const string KeyboardHintsName = "Keyboard";

		internal const string DodgeHintName = "Dodge";

		internal static readonly HashSet<string> KeepChildNames = new HashSet<string> { "Text", "key_bkg" };

		internal static GameObject DodgeKeyHint;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(KeyHints), "Awake")]
		internal static void KeyHints_Awake_Postfix(KeyHints __instance)
		{
			if (!Object.op_Implicit((Object)(object)__instance) || !((Component)__instance).transform.TryGetChild("CombatHints", out var child) || !child.TryGetChild("Keyboard", out var child2) || !child2.TryGetChild("Dodge", out var child3))
			{
				return;
			}
			DodgeKeyHint = ((Component)child3).gameObject;
			for (int num = DodgeKeyHint.transform.childCount - 1; num > -1; num--)
			{
				Transform child4 = DodgeKeyHint.transform.GetChild(num);
				if (!KeepChildNames.Contains(((Object)child4).name))
				{
					Log.LogInfo("Destroying child " + ((Object)child4).name + " of DodgeKeyHint");
					Object.DestroyImmediate((Object)(object)((Component)child4).gameObject);
				}
			}
			Log.LogInfo("Successfully modified Dodge Key Hint prefab.");
			UpdateDodgeKeyHint();
			DodgeShortcut.Instance.DodgeKey.SettingChanged += delegate
			{
				UpdateDodgeKeyHint();
			};
		}

		internal static void UpdateDodgeKeyHint()
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			TextMeshProUGUI val = default(TextMeshProUGUI);
			if (!Object.op_Implicit((Object)(object)DodgeKeyHint) || !DodgeKeyHint.TryGetChild("Key", out var child, breadth: false) || !((Component)child).TryGetComponent<TextMeshProUGUI>(ref val))
			{
				Log.LogWarning("Failed to update Dodge Key Hint!");
				return;
			}
			TextMeshProUGUI obj = val;
			KeyCode dodgeKey = DodgeShortcut.Instance.GetDodgeKey();
			((TMP_Text)obj).text = ((object)(KeyCode)(ref dodgeKey)).ToString();
			Log.LogInfo("Updated Dodge Key Hint!");
		}
	}
	[HarmonyPatch]
	internal static class DodgePatches
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(Player), "Update")]
		private static void DodgePatch()
		{
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: 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_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: 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_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: 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_00f1: Unknown result type (might be due to invalid IL or missing references)
			if (!DodgeShortcut.Instance.IsModEnabled)
			{
				return;
			}
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				Log.LogInfo("Local player is null.", LogLevel.High);
			}
			else if (!((Character)Player.m_localPlayer).IsTeleporting() && !((Character)Player.m_localPlayer).IsAttachedToShip() && !((Character)Player.m_localPlayer).InPlaceMode() && !((Component)((Terminal)Console.instance).m_chatWindow).gameObject.activeInHierarchy && !((Component)((Terminal)Chat.instance).m_chatWindow).gameObject.activeInHierarchy && !TextInput.IsVisible() && !StoreGui.IsVisible() && !InventoryGui.IsVisible() && !Menu.IsVisible() && Input.GetKeyDown(DodgeShortcut.Instance.GetDodgeKey()))
			{
				Vector3 val = ((Character)Player.m_localPlayer).m_moveDir;
				val.y = 0f;
				if (((Vector3)(ref val)).magnitude < 0.1f)
				{
					val = ((DodgeShortcut.Instance.GetDefaultDir() != 0) ? ((Character)Player.m_localPlayer).m_lookDir : (((Component)Player.m_localPlayer).transform.rotation * Vector3.forward));
					val.y = 0f;
				}
				((Vector3)(ref val)).Normalize();
				Log.LogInfo($"Dodge Vector: {val}", LogLevel.Medium);
				Player.m_localPlayer.Dodge(val);
			}
		}
	}
	internal enum LogLevel
	{
		Low,
		Medium,
		High
	}
	internal static class Log
	{
		private static ManualLogSource logSource;

		internal static ConfigEntry<LogLevel> Verbosity { get; set; }

		internal static LogLevel VerbosityLevel => Verbosity.Value;

		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 LogInfo(object data, LogLevel level = LogLevel.Low)
		{
			if (VerbosityLevel >= level)
			{
				logSource.LogInfo(data);
			}
		}

		internal static void LogMessage(object data)
		{
			logSource.LogMessage(data);
		}

		internal static void LogWarning(object data)
		{
			logSource.LogWarning(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;
				LogInfo(" - " + ((Object)((Component)val).gameObject).name);
				components = ((Component)val).gameObject.GetComponents<Component>();
				for (int i = 0; i < components.Length; i++)
				{
					LogComponent(components[i]);
				}
			}
		}

		internal static void LogComponent(Component compo)
		{
			LogInfo("--- " + ((object)compo).GetType().Name + ": " + ((Object)compo).name + " ---");
			PropertyInfo[] properties = ((object)compo).GetType().GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty);
			foreach (PropertyInfo propertyInfo in properties)
			{
				try
				{
					LogInfo($" - {propertyInfo.Name} = {propertyInfo.GetValue(compo)}");
				}
				catch (NullReferenceException)
				{
					LogInfo(" - " + propertyInfo.Name + " = null");
				}
			}
			FieldInfo[] fields = ((object)compo).GetType().GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty);
			foreach (FieldInfo fieldInfo in fields)
			{
				try
				{
					LogInfo($" - {fieldInfo.Name} = {fieldInfo.GetValue(compo)}");
				}
				catch (NullReferenceException)
				{
					LogInfo(" - " + fieldInfo.Name + " = null");
				}
			}
		}
	}
}
namespace DodgeShortcut.Extensions
{
	public static class ConfigFileExtensions
	{
		internal static string ConfigFileName;

		internal static string ConfigFileFullPath;

		internal static DateTime lastRead = DateTime.MinValue;

		internal static event Action OnConfigFileReloaded;

		private static void InvokeOnConfigFileReloaded()
		{
			ConfigFileExtensions.OnConfigFileReloaded?.SafeInvoke();
		}

		public static void Init(this ConfigFile configFile, string GUID, bool saveOnConfigSet = false)
		{
			configFile.SaveOnConfigSet = saveOnConfigSet;
			ConfigFileName = GUID + ".cfg";
			ConfigFileFullPath = Path.Combine(Paths.ConfigPath, ConfigFileName);
		}

		public static bool DisableSaveOnConfigSet(this ConfigFile configFile)
		{
			bool saveOnConfigSet = configFile.SaveOnConfigSet;
			configFile.SaveOnConfigSet = false;
			return saveOnConfigSet;
		}

		public static ConfigEntry<T> BindConfig<T>(this ConfigFile configFile, string section, string name, T value, string description, AcceptableValueBase acceptVals = null, int order = 0, int sectionOrder = 0, Action<ConfigEntryBase> drawer = null, ConfigurationManagerAttributes configAttributes = null)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			string orderedSectionName = GetOrderedSectionName(section, sectionOrder);
			if (configAttributes == null)
			{
				configAttributes = new ConfigurationManagerAttributes();
			}
			configAttributes.Order = order;
			if (drawer != null)
			{
				configAttributes.CustomDrawer = drawer;
			}
			return configFile.Bind<T>(orderedSectionName, name, value, new ConfigDescription(description, acceptVals, new object[1] { configAttributes }));
		}

		internal static string GetOrderedSectionName(string section, int sectionOrder)
		{
			if (sectionOrder > 0)
			{
				return $"{sectionOrder} - {section}";
			}
			return section;
		}

		internal static string GetExtendedDescription(string description, bool synchronizedSetting)
		{
			return description + (synchronizedSetting ? " [Synced with Server]" : " [Not Synced with Server]");
		}

		internal static void SetupWatcher(this ConfigFile configFile)
		{
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName);
			fileSystemWatcher.Changed += configFile.ReloadConfigFile;
			fileSystemWatcher.Created += configFile.ReloadConfigFile;
			fileSystemWatcher.Renamed += configFile.ReloadConfigFile;
			fileSystemWatcher.IncludeSubdirectories = true;
			fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher.EnableRaisingEvents = true;
		}

		internal static void ReloadConfigFile(this ConfigFile configFile, object sender, FileSystemEventArgs eventArgs)
		{
			if (!File.Exists(ConfigFileFullPath))
			{
				return;
			}
			try
			{
				DateTime lastWriteTime = File.GetLastWriteTime(eventArgs.FullPath);
				if (lastRead != lastWriteTime)
				{
					Log.LogInfo("Reloading config file");
					bool saveOnConfigSet = configFile.DisableSaveOnConfigSet();
					configFile.Reload();
					configFile.SaveOnConfigSet = saveOnConfigSet;
					InvokeOnConfigFileReloaded();
					lastRead = lastWriteTime;
				}
			}
			catch
			{
				Log.LogError("There was an issue loading your " + ConfigFileName);
				Log.LogError("Please check your config entries for spelling and format!");
			}
		}
	}
	internal static class EventExtensions
	{
		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}");
				}
			}
		}
	}
	internal static class GameObjectExtensions
	{
		internal static bool TryGetChild(this GameObject parent, string name, out Transform child, bool breadth = true)
		{
			return parent.transform.TryGetChild(name, out child, breadth);
		}
	}
	internal static class ReflectionUtils
	{
		public const BindingFlags AllBindings = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty;

		internal static MethodInfo GetMethod(Type type, string name, Type[] types)
		{
			MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty);
			foreach (MethodInfo methodInfo in methods)
			{
				if (methodInfo.Name == name && HasMatchingParameterTypes(0, types, methodInfo.GetParameters()))
				{
					return methodInfo;
				}
			}
			return null;
		}

		internal static MethodInfo GetGenericMethod(Type type, string name, int genericParameterCount, Type[] types)
		{
			MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty);
			foreach (MethodInfo methodInfo in methods)
			{
				if (methodInfo.IsGenericMethod && methodInfo.ContainsGenericParameters && methodInfo.Name == name && HasMatchingParameterTypes(genericParameterCount, types, methodInfo.GetParameters()))
				{
					return methodInfo;
				}
			}
			return null;
		}

		private static bool HasMatchingParameterTypes(int genericParameterCount, Type[] types, ParameterInfo[] parameters)
		{
			if (parameters.Length < genericParameterCount || parameters.Length != types.Length)
			{
				return false;
			}
			int num = 0;
			for (int i = 0; i < parameters.Length; i++)
			{
				if (parameters[i].ParameterType.IsGenericParameter)
				{
					num++;
				}
				else if (types[i] != parameters[i].ParameterType)
				{
					return false;
				}
			}
			if (num != genericParameterCount)
			{
				return false;
			}
			return true;
		}
	}
	internal static class TransformExtensions
	{
		internal static bool TryGetChild(this Transform parent, string name, out Transform child, bool breadth = true)
		{
			//IL_0007: 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)
			IterativeSearchType val = (IterativeSearchType)(breadth ? 1 : 0);
			child = Utils.FindChild(((Component)parent).transform, name, val);
			if (!Object.op_Implicit((Object)(object)child))
			{
				Log.LogWarning(((Object)parent).name + " does not have a child named $" + name + "! Could not patch dodge key hint.");
				return false;
			}
			return true;
		}
	}
}