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.2.2
plugins/ZenDistributor.dll
Decompiled a month 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 System.Text; 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] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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] [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), "SetMass")] private static void Vagon_SetMass(Vagon __instance, ref float mass) { //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_007e: Unknown result type (might be due to invalid IL or missing references) int num = 0; if (((List<string>)(object)Configs.CartAssistBuffs.Value).Count > 0 && __instance.IsAttached((Character)(object)Player.m_localPlayer)) { SEMan sEMan = ((Character)Player.m_localPlayer).GetSEMan(); bool flag = default(bool); foreach (string item in (List<string>)(object)Configs.CartAssistBuffs.Value) { if (sEMan.HaveStatusEffect(StringExtensionMethods.GetStableHashCode(item))) { InterpolatedString<Plugin> val = new InterpolatedString<Plugin>(35, 1, ref flag); if (flag) { val.AppendFormatted(item); val.AppendLiteral(" makes the cart much easier to pull"); } Logging<Plugin>.Info(val, 0); num = Mathf.Clamp(Configs.CartMassCeiling.Value / 3, 1, 35); break; } } } if (num == 0) { num = Configs.CartMassCeiling.Value; } if (num > 0) { mass = Mathf.Min(mass, (float)num); } } [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; public static readonly ConfigEntry<int> CartMassCeiling; public static readonly ConfigEntry<StringList> CartAssistBuffs; 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 //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Expected O, but got Unknown //IL_0185: 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, "Attach the cart 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, "The cart will not prevent attach when upside down. (Vanilla: false)"); CartMassCeiling = Config.Define<int>(true, "Cart", "Mass Ceiling", 100, Config.AcceptRange<int>(0, 1000), "The maximum computed mass of the cart, anything above this will be ignored.\r\nThis makes it possible to haul extra heavy cargo up a hill without the cart becomming immovable.\r\n[Set to 0 to disable this feature] \r\n(vanilla: 0)"); StringList val2 = new StringList(); ((List<string>)val2).Add("Potion_strength"); CartAssistBuffs = Config.Define<StringList>(true, "Cart", "Assist Buffs", val2, "If any of these effects are active the cart is much easier to pull.\r\n(vanilla: false)"); } } [HarmonyPatch] internal static class Distribute { private const double Cooldown = 3.0; private static readonly Dictionary<Container, Container> PendingContainersRPC = new Dictionary<Container, Container>(); private static double _lastDistributeTime; private static int _stackItemTotal; private static bool IsCooldownExpired => Time.timeAsDouble > _lastDistributeTime + 3.0; private static bool IsReady { get { if (IsCooldownExpired) { 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>()))); } internal static void RegisterRPC() { ZRoutedRpc.instance.Register<ZDOID, long>("RPC_DistributeContainerRequest", (Action<long, ZDOID, long>)RPC_DistributeContainerRequest); ZRoutedRpc.instance.Register<ZDOID, bool>("RPC_DistributeContainerResponse", (Action<long, ZDOID, bool>)RPC_DistributeContainerResponse); } internal static void UnregisterRPC() { ZRoutedRpcExt.Unregister(ZRoutedRpc.instance, "RPC_DistributeContainerRequest"); ZRoutedRpcExt.Unregister(ZRoutedRpc.instance, "RPC_DistributeContainerResponse"); } 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) { return from container in GameObjectExt.GetNearbyPiecesXZ<Container>(((Component)self).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)self) select container; } private static void SendFrom(Container source, Player user) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) if (IsCooldownExpired) { PendingContainersRPC.Clear(); } if (!IsReady) { ((Character)user).Message((MessageType)2, "$menu_pleasewait", 0, (Sprite)null); Logging<Plugin>.Info("Cooldown has not elapsed, too soon to distribute again", 0); return; } _lastDistributeTime = Time.timeAsDouble; PendingContainersRPC.Clear(); if (Logging<Plugin>.IsEnabled) { bool flag = default(bool); InterpolatedString<Plugin> val = new InterpolatedString<Plugin>(17, 1, ref flag); if (flag) { val.AppendLiteral("Inventory Items: "); val.AppendFormatted(GeneralExtensions.Join<ItemData>((IEnumerable<ItemData>)source.GetInventory().GetAllItems(), (Func<ItemData, string>)((ItemData item) => ItemDataExt.GetPrefabName(item)), ", ")); } Logging<Plugin>.Info(val, 0); } Highlight.None(); IEnumerable<Container> nearbyContainers = source.GetNearbyContainers(Configs.MaxRange.Value); bool isSourceShip = source.IsShip(); ((MonoBehaviour)source).StartCoroutine(ProcessSend(source, user, nearbyContainers, isSourceShip)); } private static IEnumerator ProcessSend(Container source, Player user, IEnumerable<Container> nearbyContainers, bool isSourceShip) { _stackItemTotal = 0; bool flag = default(bool); foreach (Container item in nearbyContainers.OrderBy((Container c) => MathExt.DistanceTo((MonoBehaviour)(object)c, (MonoBehaviour)(object)source))) { if (Object.op_Implicit((Object)(object)item) && item.m_nview.IsValid() && !item.IsInUse()) { InterpolatedString<Plugin> val = new InterpolatedString<Plugin>(19, 1, ref flag); if (flag) { val.AppendLiteral("Processing target: "); val.AppendFormatted(((Object)item).name); } Logging<Plugin>.Info(val, 0); PendingContainersRPC.Add(item, source); val = new InterpolatedString<Plugin>(44, 1, ref flag); if (flag) { val.AppendLiteral("Added container to rpc pending list, count: "); val.AppendFormatted<int>(PendingContainersRPC.Count); } Logging<Plugin>.Debug(val, 0); item.StackAll(); if (isSourceShip && item.IsCart(out Vagon cart) && !cart.InUse() && item.GetInventory().HaveEmptySlot()) { item.m_nview.ClaimOwnership(); item.GetInventory().MoveAll(source.GetInventory()); item.ShowHighlight(); } yield return null; } } yield return (object)new WaitUntil((Func<bool>)(() => PendingContainersRPC.Count <= 0 || IsCooldownExpired)); if (Object.op_Implicit((Object)(object)user)) { ((Character)user).Message((MessageType)2, $"$msg_stackall {_stackItemTotal}", 0, (Sprite)null); } } 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, Player? user, bool showMsg) { if (((List<string>)(object)Configs.AllowedContainers.Value).Count == 0) { return false; } if (!container.IsDistributor()) { return false; } if (!IsReady) { MsgUser("$menu_pleasewait"); return false; } if (container.GetInventory().NrOfItems() == 0) { MsgUser("$msg_stackall_none"); return false; } if (container.IsInUse()) { MsgUser("$msg_inuse"); return false; } if (!container.IsCart(out Vagon cart)) { return true; } if (cart.InUse()) { if (Object.op_Implicit((Object)(object)user) && cart.IsAttached((Character)(object)user)) { return true; } MsgUser("$msg_inuse"); return false; } return true; void MsgUser(string msg) { if (Object.op_Implicit((Object)(object)user) && showMsg) { ((Character)user).Message((MessageType)2, msg, 0, (Sprite)null); } } } private static Container? GetContainerFromZDOID(ZDOID zid) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) GameObject val = ZNetScene.instance.FindInstance(zid); if (!Object.op_Implicit((Object)(object)val)) { bool flag = default(bool); InterpolatedString<Plugin> val2 = new InterpolatedString<Plugin>(29, 1, ref flag); if (flag) { val2.AppendLiteral("Scene instance not found for "); val2.AppendFormatted<ZDOID>(zid); } Logging<Plugin>.Info(val2, 0); return null; } Container componentInChildren = val.GetComponentInChildren<Container>(); if (Object.op_Implicit((Object)(object)componentInChildren)) { return componentInChildren; } Logging<Plugin>.Info("Container component missing from scene object", 0); return null; } private static void RPC_DistributeContainerRequest(long sender, ZDOID containerID, long requesterID) { //IL_0000: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) Container containerFromZDOID = GetContainerFromZDOID(containerID); Player player = Player.GetPlayer(requesterID); if (!Object.op_Implicit((Object)(object)player)) { bool flag = default(bool); InterpolatedString<Plugin> val = new InterpolatedString<Plugin>(38, 1, ref flag); if (flag) { val.AppendLiteral("Player "); val.AppendFormatted<long>(requesterID); val.AppendLiteral(" not found, or no longer nearby"); } Logging<Plugin>.Info(val, 0); } bool flag2 = Object.op_Implicit((Object)(object)player) && Object.op_Implicit((Object)(object)containerFromZDOID) && IsValidSource(containerFromZDOID, player, showMsg: true); if (flag2 && Object.op_Implicit((Object)(object)containerFromZDOID)) { ZDOMan.instance.ForceSendZDO(sender, containerID); containerFromZDOID.m_nview.GetZDO().SetOwner(sender); } ZRoutedRpc.instance.InvokeRoutedRPC(sender, "RPC_DistributeContainerResponse", new object[2] { containerID, flag2 }); } private static void RPC_DistributeContainerResponse(long sender, ZDOID containerID, bool isGranted) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) if (isGranted) { Container containerFromZDOID = GetContainerFromZDOID(containerID); if (Object.op_Implicit((Object)(object)containerFromZDOID)) { SendFrom(containerFromZDOID, Player.m_localPlayer); } } } [HarmonyPrefix] [HarmonyPatch(typeof(Container), "Interact")] private static void Container_Interact(Container __instance, bool alt, bool hold, ref bool __result, ref bool __runOriginal) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) if (!alt) { return; } __runOriginal = false; if (!hold) { __result = true; if (WardAccessExt.CanAccessWard(__instance, true)) { ZDO zDO = __instance.m_nview.GetZDO(); long playerID = Player.m_localPlayer.GetPlayerID(); ZRoutedRpc.instance.InvokeRoutedRPC(zDO.GetOwner(), "RPC_DistributeContainerRequest", new object[2] { zDO.m_uid, playerID }); } } } [HarmonyPostfix] [HarmonyPatch(typeof(Container), "GetHoverText")] [HarmonyPriority(100)] private static void Container_GetHoverText(Container __instance, ref string __result) { if (IsValidSource(__instance, Player.m_localPlayer, showMsg: false)) { __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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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_0105: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) if (!PendingContainersRPC.TryGetValue(__instance, out Container value)) { return; } PendingContainersRPC.Remove(__instance); bool flag = default(bool); InterpolatedString<Plugin> val = new InterpolatedString<Plugin>(22, 1, ref flag); if (flag) { val.AppendLiteral("Remaining containers: "); val.AppendFormatted<int>(PendingContainersRPC.Count); } Logging<Plugin>.Debug(val, 0); __runOriginal = false; if (!granted || !Object.op_Implicit((Object)(object)value)) { return; } if (WardAccessExt.CanAccessWard(__instance, false)) { value.m_nview.ClaimOwnership(); __instance.m_nview.ClaimOwnership(); int num = __instance.GetInventory().StackAll(value.GetInventory(), false); _stackItemTotal += num; if (num > 0) { val = new InterpolatedString<Plugin>(22, 3, ref flag); if (flag) { val.AppendLiteral("Stacked "); val.AppendFormatted<int>(num); val.AppendLiteral(" items to "); val.AppendFormatted(((Object)__instance).name); val.AppendLiteral(" at "); val.AppendFormatted<Vector3>(MathExt.XZY(((Component)__instance).transform.position)); } Logging<Plugin>.Info(val, 0); __instance.ShowHighlight(); } } else { Logging<Plugin>.Info("Distribution target container is warded, skipping.", 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.2.2")] [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.2.2"; protected override void Setup() { } protected override void TitleScene(bool isFirstBoot) { } protected override void WorldStart() { Distribute.RegisterRPC(); } protected override void Shutdown() { Distribute.UnregisterRPC(); } protected override HelpInfo? GetHelpInfo() { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine(HelpInfo.Format("Description", "Carts and ships can distribute their cargo to nearby containers", (string)null, true, true)); if (Configs.SnapToPlayer.Value) { stringBuilder.AppendLine(HelpInfo.Format<bool>(Configs.SnapToPlayer, false, true, true)); } if (Configs.IgnoreUpsideDown.Value) { stringBuilder.AppendLine(HelpInfo.Format<bool>(Configs.IgnoreUpsideDown, false, true, true)); } if (((List<string>)(object)Configs.CartAssistBuffs.Value).Count > 0) { stringBuilder.AppendLine(HelpInfo.Format<StringList>(Configs.CartAssistBuffs, true, true, true)); } return new HelpInfo("Distributor", stringBuilder.ToString()); } } }