Decompiled source of QuickCart v1.0.1

QuickCart.dll

Decompiled 4 days ago
using System;
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.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Extensions;
using Jotunn.Managers;
using Jotunn.Utils;
using Logging;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("SkilledCarryWeight")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SkilledCarryWeight")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("1.0.1")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
namespace SkilledCarryWeight
{
	[BepInPlugin("Searica.Valheim.QuickCart", "QuickCart", "1.0.1")]
	[BepInDependency("com.jotunn.jotunn", "2.30.0")]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	[SynchronizationMode(/*Could not decode attribute arguments.*/)]
	internal sealed class QuickCart : BaseUnityPlugin
	{
		internal const string Author = "Searica";

		public const string PluginName = "QuickCart";

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

		public const string PluginVersion = "1.0.1";

		internal static QuickCart Instance;

		internal static ConfigFileWatcher ConfigWatcher;

		internal static ConfigEntry<KeyCode> QuickCartKey;

		internal static ConfigEntry<float> AttachDistance;

		internal static ConfigEntry<bool> AttachOutOfPlace;

		internal static ConfigEntry<bool> AttachWhenCartFlipped;

		private const string MainSection = "Global";

		private const string CartSection = "Quick Cart";

		private static bool SettingsUpdated;

		public void Awake()
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			Instance = this;
			Log.Init(((BaseUnityPlugin)this).Logger);
			((BaseUnityPlugin)this).Config.SaveOnConfigSet = false;
			Log.Verbosity = ConfigFileExtensions.BindConfigInOrder<Log.InfoLevel>(((BaseUnityPlugin)this).Config, "Global", "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);
			Initialize();
			((BaseUnityPlugin)this).Config.Save();
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "Searica.Valheim.QuickCart");
			Game.isModded = true;
			ConfigWatcher = new ConfigFileWatcher(((BaseUnityPlugin)this).Config, 1000L);
			ConfigWatcher.OnConfigFileReloaded += delegate
			{
				if (SettingsUpdated)
				{
					((BaseUnityPlugin)this).Config.Save();
					SettingsUpdated = false;
				}
			};
			SynchronizationManager.OnConfigurationWindowClosed += delegate
			{
				if (SettingsUpdated)
				{
					((BaseUnityPlugin)this).Config.Save();
					SettingsUpdated = false;
				}
			};
			SynchronizationManager.OnConfigurationSynchronized += delegate
			{
				if (SettingsUpdated)
				{
					((BaseUnityPlugin)this).Config.Save();
					SettingsUpdated = false;
				}
			};
		}

		public void OnDestroy()
		{
			((BaseUnityPlugin)this).Config.Save();
		}

		private static void OnSettingChanged(object sender, EventArgs e)
		{
			if (!SettingsUpdated)
			{
				SettingsUpdated = true;
			}
		}

		internal static void Initialize()
		{
			Log.Verbosity = ConfigFileExtensions.BindConfigInOrder<Log.InfoLevel>(((BaseUnityPlugin)Instance).Config, "Global", "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);
			Log.Verbosity.SettingChanged += OnSettingChanged;
			QuickCartKey = ConfigFileExtensions.BindConfigInOrder<KeyCode>(((BaseUnityPlugin)Instance).Config, "Quick Cart", "QuickCartKey", (KeyCode)104, "The hotkey used to attach to or detach from a nearby cart.", false, true, true, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			AttachDistance = ConfigFileExtensions.BindConfigInOrder<float>(((BaseUnityPlugin)Instance).Config, "Quick Cart", "AttachDistance", 5f, "Maximum distance to attach a cart from.", true, true, true, (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 8f), (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			AttachOutOfPlace = ConfigFileExtensions.BindConfigInOrder<bool>(((BaseUnityPlugin)Instance).Config, "Quick Cart", "AttachOutOfPlace", true, "Allow attaching to the cart even when you are not looking at the interaction hover text.", true, true, true, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			AttachWhenCartFlipped = ConfigFileExtensions.BindConfigInOrder<bool>(((BaseUnityPlugin)Instance).Config, "Quick Cart", "AttachWhenCartFlipped", false, "Allow attaching to the cart even when it is flipped or otherwise out of position", true, true, true, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
		}

		private void Update()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (Input.GetKeyDown(QuickCartKey.Value) && PlayerCanAttach() && TryGetClosestVagon(out var closestVagon) && Object.op_Implicit((Object)(object)closestVagon))
			{
				closestVagon.Interact((Humanoid)(object)Player.m_localPlayer, false, false);
			}
		}

		private static bool PlayerCanAttach()
		{
			if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && !((Character)Player.m_localPlayer).IsDead())
			{
				return !((Character)Player.m_localPlayer).InPlaceMode();
			}
			return false;
		}

		private static bool TryGetClosestVagon(out Vagon closestVagon)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			closestVagon = null;
			float num = float.PositiveInfinity;
			Vector3 val = ((Component)Player.m_localPlayer).transform.position + Vector3.up;
			Collider[] array = Physics.OverlapSphere(val, AttachDistance.Value);
			foreach (Collider val2 in array)
			{
				if (TryGetVagon(val2, out var vagon) && Object.op_Implicit((Object)(object)val2.attachedRigidbody) && (vagon.IsAttached((Character)(object)Player.m_localPlayer) || !vagon.InUse()))
				{
					float num2 = Vector3.Distance(val2.ClosestPoint(val), val);
					if (num2 < num)
					{
						Log.LogInfo($"Found cart {num2} away", Log.InfoLevel.Medium);
						num = num2;
						closestVagon = vagon;
					}
				}
			}
			return num < AttachDistance.Value;
		}

		private static bool TryGetVagon(Collider collider, out Vagon vagon)
		{
			if (!((Component)collider).TryGetComponent<Vagon>(ref vagon) && Object.op_Implicit((Object)(object)((Component)collider).transform.parent))
			{
				vagon = ((Component)((Component)collider).transform.parent).GetComponent<Vagon>();
			}
			return Object.op_Implicit((Object)(object)vagon);
		}
	}
	[HarmonyPatch]
	internal static class VagonPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(Vagon), "CanAttach")]
		private static bool CanAttachPrefix(Vagon __instance, GameObject go, ref bool __result)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			if (!QuickCart.AttachOutOfPlace.Value || (((Component)__instance).transform.up.y < 0.1f && !QuickCart.AttachWhenCartFlipped.Value) || (Object)(object)go != (Object)(object)((Component)Player.m_localPlayer).gameObject)
			{
				__instance.m_detachDistance = QuickCart.AttachDistance.Value;
				return true;
			}
			bool flag = Vector3.Distance(go.transform.position + __instance.m_attachOffset, __instance.m_attachPoint.position) < QuickCart.AttachDistance.Value;
			__result = !((Character)Player.m_localPlayer).IsTeleporting() && !((Character)Player.m_localPlayer).InDodge() && flag;
			return false;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Vagon), "GetHoverText")]
		private static void GetHoverTextPostfix(Vagon __instance, ref string __result)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			__result = Localization.instance.Localize($"{__instance.m_name}\n[<color=yellow>{QuickCart.QuickCartKey.Value}</color>] $piece_use");
		}
	}
}
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 QuickCart.Extensions
{
	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 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;
		}
	}
}