Decompiled source of ZenDistributor v0.2.3

plugins/ZenDistributor.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
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.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using Zen;
using Zen.Lib;
using Zen.Lib.Config;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ZenDistributor")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ZenDistributor")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("0.0.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.1.0")]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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;
		}
	}
}
namespace ZenDistributor
{
	[HarmonyPatch]
	internal class CartPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(Vagon), "CanAttach")]
		private static void Vagon_CanAttach(Vagon __instance, GameObject go, ref bool __result, ref bool __runOriginal)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			if (Configs.SnapToPlayer.Value)
			{
				Catapult val = default(Catapult);
				if (((Component)__instance).TryGetComponent<Catapult>(ref val) && val.m_lockedLegs)
				{
					__result = false;
					__runOriginal = false;
				}
				else if (Configs.IgnoreUpsideDown.Value || !(((Component)__instance).transform.up.y < 0.1f))
				{
					Humanoid component = go.GetComponent<Humanoid>();
					bool flag = MathExt.AlignmentRatioTo(((Component)__instance).transform, ((Component)component).transform.position) > 0f;
					__result = !Object.op_Implicit((Object)(object)component) || ((flag & !((Character)component).IsTeleporting()) && !((Character)component).InDodge() && !((Character)component).IsBlocking() && !((Character)component).InAttack() && !((Character)component).IsCrouching() && !((Character)component).InEmote() && !((Character)component).IsDrawingBow() && !ZInput.GetButtonDown("JoyButtonB") && MathExt.DistanceTo((MonoBehaviour)(object)component, ((Component)__instance).transform.position) < Configs.AttachDistance.Value);
					__runOriginal = false;
				}
			}
		}
	}
	internal static class Configs
	{
		public static readonly ConfigEntry<StringList> AllowedDistributors;

		public static readonly ConfigEntry<StringList> AllowedContainers;

		public static readonly ConfigEntry<float> MaxRange;

		public static readonly ConfigEntry<float> HighlightDuration;

		public static readonly ConfigEntry<bool> SnapToPlayer;

		public static readonly ConfigEntry<float> AttachDistance;

		public static readonly ConfigEntry<bool> IgnoreUpsideDown;

		static Configs()
		{
			//IL_000b: 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)
			//IL_001b: Expected O, but got Unknown
			//IL_0025: Expected O, but got Unknown
			StringList val = new StringList();
			((List<string>)val).Add("Cart");
			AllowedDistributors = Config.Define<StringList>(true, "General", "Allowed Distributor Prefabs", val, "Comma separated list of prefabs that can be used as a distribution source.\r\nThey must have a Container component or they will not work.\r\nExample, ship prefabs: Karve, VikingShip, VikingShip_Ashlands\r\nHowever, they are not included by default because unloading ships manually encourages building proper docks.");
			AllowedContainers = Config.Define<StringList>(true, "General", "Allowed Container Prefabs", Config.ContainersCommon, "Only distribute into these container prefab names.\r\nThey must have a Container component or they will not work.");
			MaxRange = Config.Define<float>(true, "General", "Max Distribution Range", 10f, Config.AcceptRange<float>(3f, 20f), "How far away to search for containers from the cart's location");
			HighlightDuration = Config.Define<float>(true, "General", "Higlight Duration", 5f, Config.AcceptRange<float>(0f, 30f), "Highlight duration for chests that had items distributed into them (in seconds)");
			SnapToPlayer = Config.Define<bool>(true, "Cart", "Snap To Player", true, "When true the cart attaches to the player much more easily. (Vanilla: false)");
			AttachDistance = Config.Define<float>(true, "Cart", "Attach Distance", 7f, Config.AcceptRange<float>(1f, 10f), "Minimum distance the player must be from the cart in order to attach it. (Vanilla: 2)");
			IgnoreUpsideDown = Config.Define<bool>(true, "Cart", "Ignore Upside Down", true, "If true the cart will not prevent attach when upside down. (Vanilla: false)");
		}
	}
	[HarmonyPatch]
	internal static class Distribute
	{
		[CompilerGenerated]
		private sealed class <>c__DisplayClass6_0
		{
			public IEnumerable<Container> nearbyContainers;

			public Container source;

			public Func<Container, float> <>9__2;

			internal float <SendFrom>b__2(Container c)
			{
				return MathExt.DistanceTo((MonoBehaviour)(object)c, (MonoBehaviour)(object)source);
			}
		}

		public const float Cooldown = 3f;

		private static float _lastDistributeTime;

		private static readonly Dictionary<Container, Container> PendingContainers = new Dictionary<Container, Container>();

		private static bool IsReady
		{
			get
			{
				if (Time.time > _lastDistributeTime + 3f)
				{
					return PendingContainers.Count == 0;
				}
				return false;
			}
		}

		private static IEnumerable<Container> GetNearbyContainers(this Container self, float range)
		{
			return from container in GameObjectExt.GetNearby<Container>(((Component)self).gameObject, range, "piece")
				where Configs.AllowedContainers.Value.Contains(container.m_nview.GetPrefabName(), true)
				where WardAccessExt.CanAccessWard(container, false)
				select container;
		}

		private static void SendFrom(Container source)
		{
			<>c__DisplayClass6_0 CS$<>8__locals0 = new <>c__DisplayClass6_0();
			CS$<>8__locals0.source = source;
			if (!IsReady)
			{
				Logging<Plugin>.Warning((object)"Cooldown has not elapsed, too soon to distribute again", 0);
				return;
			}
			_lastDistributeTime = Time.time;
			if (PendingContainers.Count != 0)
			{
				Logging<Plugin>.Error((object)"RPC containers pending stacking list is not empty, rpc send/recv mismatch?", (ushort)0);
				PendingContainers.Clear();
			}
			if (Logging<Plugin>.IsEnabled)
			{
				Logging<Plugin>.Info((object)("Inventory Items: " + GeneralExtensions.Join<ItemData>((IEnumerable<ItemData>)CS$<>8__locals0.source.GetInventory().GetAllItems(), (Func<ItemData, string>)((ItemData item) => ItemDataExt.GetPrefabName(item)), ", ")), 0);
			}
			Highlight.None();
			CS$<>8__locals0.nearbyContainers = CS$<>8__locals0.source.GetNearbyContainers(Configs.MaxRange.Value);
			((MonoBehaviour)CS$<>8__locals0.source).StartCoroutine(ProcessSend());
			[IteratorStateMachine(typeof(<>c__DisplayClass6_0.<<SendFrom>g__ProcessSend|1>d))]
			IEnumerator ProcessSend()
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <>c__DisplayClass6_0.<<SendFrom>g__ProcessSend|1>d(0)
				{
					<>4__this = CS$<>8__locals0
				};
			}
		}

		private static bool IsDistributor(this Container container)
		{
			if (Object.op_Implicit((Object)(object)container.m_nview))
			{
				return Configs.AllowedDistributors.Value.Contains(container.m_nview.GetPrefabName(), true);
			}
			return false;
		}

		private static bool IsValidSource(Container container)
		{
			if (!IsReady)
			{
				return false;
			}
			if (((List<string>)(object)Configs.AllowedContainers.Value).Count == 0)
			{
				return false;
			}
			if (container.GetInventory().NrOfItems() == 0)
			{
				return false;
			}
			if (container.IsInUse())
			{
				return false;
			}
			if (!container.IsDistributor())
			{
				return false;
			}
			if (Object.op_Implicit((Object)(object)container.m_wagon) && container.m_wagon.InUse() && !container.m_wagon.IsAttached((Character)(object)Player.m_localPlayer))
			{
				return false;
			}
			return true;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Container), "Interact")]
		private static void Container_Interact(Container __instance, bool alt, bool hold, ref bool __result, ref bool __runOriginal)
		{
			if (!(!alt || hold))
			{
				__runOriginal = false;
				if (WardAccessExt.CanAccessWard(__instance, true) && IsValidSource(__instance))
				{
					SendFrom(__instance);
					__result = true;
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Container), "GetHoverText")]
		[HarmonyPriority(100)]
		private static void Container_GetHoverText(Container __instance, ref string __result)
		{
			if (IsValidSource(__instance))
			{
				__result = StringExt.Localize(UI.InsertInteractAlt(__result, "$inventory_transfer"));
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Container), "RPC_StackResponse")]
		private static void Container_RPC_StackResponse(Container __instance, bool granted, ref bool __runOriginal)
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			if (!PendingContainers.TryGetValue(__instance, out Container value))
			{
				return;
			}
			__runOriginal = false;
			if (granted && Object.op_Implicit((Object)(object)value))
			{
				if (WardAccessExt.CanAccessWard(__instance, false))
				{
					value.m_nview.ClaimOwnership();
					__instance.m_nview.ClaimOwnership();
					int num = __instance.GetInventory().StackAll(value.GetInventory(), false);
					if (Object.op_Implicit((Object)(object)__instance.m_piece) && num > 0)
					{
						Logging<Plugin>.Info((object)$"Stacked {num} items to {((Object)__instance).name} at {MathExt.XZY(((Component)__instance).transform.position)}", 0);
						Highlight.Select(__instance.m_piece, Configs.HighlightDuration.Value, false, default(Color), (Action)null);
					}
				}
				else
				{
					Logging<Plugin>.Info((object)"Distribution target container is warded, skipping.", 0);
				}
			}
			PendingContainers.Remove(__instance);
			Logging<Plugin>.Debug((object)$"Remaining containers: {PendingContainers.Count}", 0);
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(Inventory), "StackAll")]
		private static IEnumerable<CodeInstruction> Inventory_StackAll_Transpiler(IEnumerable<CodeInstruction> codes)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			return new CodeMatcher(codes, (ILGenerator)null).MatchStartForward((CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Ldarg_2, (object)null, (string)null)
			}).ThrowIfInvalid("Unable to find matching IL").Set(OpCodes.Ldc_I4_1, (object)null)
				.InstructionEnumeration();
		}
	}
	[BepInPlugin("ZenDragon.ZenDistributor", "ZenDistributor", "0.2.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[SynchronizationMode(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	internal class Plugin : ZenMod<Plugin>
	{
		public const string PluginGUID = "ZenDragon.ZenDistributor";

		public const string PluginName = "ZenDistributor";

		public const string PluginVersion = "0.2.3";

		protected override void Setup()
		{
		}

		protected override void TitleScene(bool isFirstBoot)
		{
		}

		protected override void WorldStart()
		{
		}

		protected override void Shutdown()
		{
		}
	}
}