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 QuickCart v1.0.1
QuickCart.dll
Decompiled 4 days agousing 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; } } }