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 ZenDistributor v1.0.3
plugins/ZenDistributor.dll
Decompiled 2 months agousing 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 \ufffd 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_00c0: 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).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_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_0046: Expected O, but got Unknown //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown StringList val = new StringList(); ((List<string>)val).Add("Cart"); ((List<string>)val).Add("Karve"); ((List<string>)val).Add("VikingShip"); ((List<string>)val).Add("VikingShip_Ashlands"); 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."); AllowedContainers = Config.Define<StringList>(true, "General", "Allowed Container Prefabs", new StringList(Config.ContainersCommon.Append("Cart")), "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, 25f), "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__DisplayClass12_0 { public Container source; public Func<Container, float> <>9__0; internal float <ProcessSend>b__0(Container c) { return MathExt.DistanceTo((MonoBehaviour)(object)c, (MonoBehaviour)(object)source); } } [CompilerGenerated] private sealed class <ProcessSend>d__12 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public Container source; public IEnumerable<Container> nearbyContainers; private <>c__DisplayClass12_0 <>8__1; public bool isSourceShip; private int <invCountBefore>5__2; private IEnumerator<Container> <>7__wrap2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ProcessSend>d__12(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <>8__1 = null; <>7__wrap2 = null; <>1__state = -2; } private bool MoveNext() { try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass12_0(); <>8__1.source = source; <invCountBefore>5__2 = <>8__1.source.GetInventory().CountItems((string)null, -1, true); <>7__wrap2 = nearbyContainers.OrderBy((Container c) => MathExt.DistanceTo((MonoBehaviour)(object)c, (MonoBehaviour)(object)<>8__1.source)).GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; break; } while (<>7__wrap2.MoveNext()) { Container current = <>7__wrap2.Current; if (Object.op_Implicit((Object)(object)current) && current.m_nview.IsValid() && !current.IsInUse()) { Logging<Plugin>.Info((object)("Processing target: " + ((Object)current).name), 0); PendingContainersRPC.Add(current, <>8__1.source); Logging<Plugin>.Debug((object)$"Added container to rpc pending list, count: {PendingContainersRPC.Count}", 0); current.StackAll(); if (isSourceShip && current.IsCart(out Vagon cart) && !cart.InUse() && current.GetInventory().HaveEmptySlot()) { current.m_nview.ClaimOwnership(); current.GetInventory().MoveAll(<>8__1.source.GetInventory()); current.ShowHighlight(); } <>2__current = null; <>1__state = 1; return true; } } <>m__Finally1(); <>7__wrap2 = null; int num = <invCountBefore>5__2 - <>8__1.source.GetInventory().CountItems((string)null, -1, true); if (num > 0) { ((Character)Player.m_localPlayer).Message((MessageType)2, $"$msg_stackall {num}", 0, (Sprite)null); } return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>7__wrap2 != null) { <>7__wrap2.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public const float Cooldown = 3f; private static float _lastDistributeTime; private static readonly Dictionary<Container, Container> PendingContainersRPC = new Dictionary<Container, Container>(); private static bool IsReady { get { if (Time.time > _lastDistributeTime + 3f) { return PendingContainersRPC.Count == 0; } return false; } } private static bool IsCart(this Container c) { Vagon cart; return c.IsCart(out cart); } private static bool IsCart(this Container c, out Vagon cart) { return Object.op_Implicit((Object)(object)(cart = c.m_wagon)); } private static bool IsShip(this Container c) { return Object.op_Implicit((Object)(object)((Component)c).GetComponentInParent<Ship>()); } private static bool TryGetPiece(this Container c, out Piece? piece) { return Object.op_Implicit((Object)(object)(piece = (Object.op_Implicit((Object)(object)c.m_piece) ? c.m_piece : ((Component)c).GetComponentInParent<Piece>()))); } private static void ShowHighlight(this Container c) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (c.TryGetPiece(out Piece piece)) { Highlight.Select(piece, Configs.HighlightDuration.Value, false, default(Color), (Action)null); } } private static IEnumerable<Container> GetNearbyContainers(this Container self, float range) { Container self2 = self; return from container in GameObjectExt.GetNearbyPiecesXZ<Container>(((Component)self2).gameObject, range) where Configs.AllowedContainers.Value.Contains(container.m_nview.GetPrefabName(), true) where WardAccessExt.CanAccessWard(container, false) orderby MathExt.DistanceTo((MonoBehaviour)(object)container, (MonoBehaviour)(object)self2) select container; } private static void SendFrom(Container source) { if (!IsReady) { Logging<Plugin>.Warning((object)"Cooldown has not elapsed, too soon to distribute again", 0); return; } _lastDistributeTime = Time.time; if (PendingContainersRPC.Count != 0) { Logging<Plugin>.Error((object)"RPC containers pending stacking list is not empty, rpc send/recv mismatch?", (ushort)0); PendingContainersRPC.Clear(); } if (Logging<Plugin>.IsEnabled) { Logging<Plugin>.Info((object)("Inventory Items: " + GeneralExtensions.Join<ItemData>((IEnumerable<ItemData>)source.GetInventory().GetAllItems(), (Func<ItemData, string>)((ItemData item) => ItemDataExt.GetPrefabName(item)), ", ")), 0); } Highlight.None(); IEnumerable<Container> nearbyContainers = source.GetNearbyContainers(Configs.MaxRange.Value); bool isSourceShip = source.IsShip(); ((MonoBehaviour)source).StartCoroutine(ProcessSend(source, nearbyContainers, isSourceShip)); } [IteratorStateMachine(typeof(<ProcessSend>d__12))] private static IEnumerator ProcessSend(Container source, IEnumerable<Container> nearbyContainers, bool isSourceShip) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ProcessSend>d__12(0) { source = source, nearbyContainers = nearbyContainers, isSourceShip = isSourceShip }; } 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 (container.IsCart(out Vagon cart) && cart.InUse()) { return cart.IsAttached((Character)(object)Player.m_localPlayer); } 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) if (!PendingContainersRPC.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 (num > 0) { Logging<Plugin>.Info((object)$"Stacked {num} items to {((Object)__instance).name} at {MathExt.XZY(((Component)__instance).transform.position)}", 0); __instance.ShowHighlight(); } } else { Logging<Plugin>.Info((object)"Distribution target container is warded, skipping.", 0); } } PendingContainersRPC.Remove(__instance); Logging<Plugin>.Debug((object)$"Remaining containers: {PendingContainersRPC.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) return new CodeMatcher(codes, (ILGenerator)null).MatchStartForward((CodeMatch[])(object)new CodeMatch[1] { CodeMatch.op_Implicit(OpCodes.Ldarg_2) }).ThrowIfInvalid("Unable to find matching IL").Set(OpCodes.Ldc_I4_1, (object)null) .InstructionEnumeration(); } } [BepInPlugin("ZenDragon.ZenDistributor", "ZenDistributor", "1.0.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 = "1.0.3"; protected override void Setup() { } protected override void TitleScene(bool isFirstBoot) { } protected override void WorldStart() { } protected override void Shutdown() { } } }