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()
{
}
}
}