Decompiled source of BetterCart v1.5.3

GammaSmartCart.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mirror;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("GammaSmartCart")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+1121b34b4052170eaae0e80b536c22e285196e2b")]
[assembly: AssemblyProduct("GammaSmartCart")]
[assembly: AssemblyTitle("GammaSmartCart")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace GammaSmartCart
{
	[BepInPlugin("com.gamma.smartcart", "GammaSmartCart", "1.5.1")]
	public class SmartCartPlugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private sealed class <ScanLoop>d__17 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public SmartCartPlugin <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ScanLoop>d__17(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Expected O, but got Unknown
				int num = <>1__state;
				SmartCartPlugin smartCartPlugin = <>4__this;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					if (smartCartPlugin.modActive && NetworkServer.active)
					{
						MiniTransportBehaviour val = smartCartPlugin.FindActiveVehicle();
						if (!((Object)(object)val == (Object)null))
						{
							try
							{
								if (smartCartPlugin.AutoPickupEnabled.Value)
								{
									smartCartPlugin.DoAutoPickup(val);
								}
							}
							catch (Exception ex)
							{
								((BaseUnityPlugin)smartCartPlugin).Logger.LogError((object)("Pickup error: " + ex.Message + "\n" + ex.StackTrace));
							}
							try
							{
								if (smartCartPlugin.AutoDepositEnabled.Value)
								{
									smartCartPlugin.DoAutoDeposit(val);
								}
							}
							catch (Exception ex2)
							{
								((BaseUnityPlugin)smartCartPlugin).Logger.LogError((object)("Deposit error: " + ex2.Message + "\n" + ex2.StackTrace));
							}
						}
					}
				}
				else
				{
					<>1__state = -1;
				}
				<>2__current = (object)new WaitForSeconds(0.3f);
				<>1__state = 1;
				return true;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public const string PluginGUID = "com.gamma.smartcart";

		public const string PluginName = "GammaSmartCart";

		public const string PluginVersion = "1.5.1";

		public static SmartCartPlugin Instance;

		public ConfigEntry<float> PickupRadius;

		public ConfigEntry<float> DepositRadius;

		public ConfigEntry<bool> AutoPickupEnabled;

		public ConfigEntry<bool> AutoDepositEnabled;

		public ConfigEntry<KeyCode> ToggleKey;

		private Harmony harmony;

		private bool modActive = true;

		private Coroutine scanCoroutine;

		private Dictionary<int, float> depositCooldowns = new Dictionary<int, float>();

		private const float DEPOSIT_COOLDOWN = 0.8f;

		private void Awake()
		{
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			Instance = this;
			PickupRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "PickupRadius", 4f, "Radio de deteccion de cajas (metros)");
			DepositRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "DepositRadius", 10f, "Radio de deteccion de gondolas (metros)");
			AutoPickupEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Features", "AutoPickup", true, "Recoger cajas automaticamente");
			AutoDepositEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Features", "AutoDeposit", true, "Depositar en gondolas automaticamente");
			ToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "ToggleKey", (KeyCode)289, "Tecla para activar/desactivar");
			harmony = new Harmony("com.gamma.smartcart");
			harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"GammaSmartCart v1.5.1 cargado! (ZERO REFLECTION)");
		}

		private void Start()
		{
			scanCoroutine = ((MonoBehaviour)this).StartCoroutine(ScanLoop());
		}

		private void Update()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			if (Input.GetKeyDown(ToggleKey.Value))
			{
				modActive = !modActive;
				((BaseUnityPlugin)this).Logger.LogInfo((object)("SmartCart " + (modActive ? "ACTIVADO" : "DESACTIVADO")));
			}
			if (Input.GetKeyDown((KeyCode)290))
			{
				DebugScanArea();
			}
		}

		[IteratorStateMachine(typeof(<ScanLoop>d__17))]
		private IEnumerator ScanLoop()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ScanLoop>d__17(0)
			{
				<>4__this = this
			};
		}

		private MiniTransportBehaviour FindActiveVehicle()
		{
			MiniTransportBehaviour[] array = Object.FindObjectsByType<MiniTransportBehaviour>((FindObjectsSortMode)0);
			foreach (MiniTransportBehaviour val in array)
			{
				if (val.hasAuthority && val.hasDriver)
				{
					return val;
				}
			}
			return null;
		}

		private void DoAutoPickup(MiniTransportBehaviour vehicle)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (vehicle.velocity < 0.3f)
			{
				return;
			}
			Collider[] array = Physics.OverlapSphere(((Component)vehicle).transform.position, PickupRadius.Value);
			foreach (Collider val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				BoxData val2 = ((Component)val).GetComponent<BoxData>();
				if ((Object)(object)val2 == (Object)null)
				{
					val2 = ((Component)val).GetComponentInParent<BoxData>();
				}
				if (!((Object)(object)val2 == (Object)null) && val2.productID >= 0 && val2.numberOfProducts > 0)
				{
					int num = FindEmptySlot(vehicle.productInfoArray);
					if (num < 0)
					{
						break;
					}
					int num2 = num * 2;
					int productID = val2.productID;
					int numberOfProducts = val2.numberOfProducts;
					vehicle.EmployeeUpdateArrayValuesStorage(num2, productID, numberOfProducts);
					NetworkServer.Destroy(((Component)val2).gameObject);
					((BaseUnityPlugin)this).Logger.LogInfo((object)$"Pickup: {ProductName(productID)} x{numberOfProducts} -> slot {num}");
				}
			}
		}

		private int FindEmptySlot(int[] arr)
		{
			for (int i = 0; i < arr.Length / 2; i++)
			{
				if (arr[i * 2] < 0 || arr[i * 2 + 1] <= -1)
				{
					return i;
				}
			}
			return -1;
		}

		private void DoAutoDeposit(MiniTransportBehaviour vehicle)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			int[] productInfoArray = vehicle.productInfoArray;
			int num = -1;
			for (int i = 0; i < productInfoArray.Length / 2; i++)
			{
				if (productInfoArray[i * 2] >= 0 && productInfoArray[i * 2 + 1] > 0)
				{
					num = i;
					break;
				}
			}
			if (num < 0)
			{
				return;
			}
			int num2 = productInfoArray[num * 2];
			int num3 = productInfoArray[num * 2 + 1];
			if ((Object)(object)ProductListing.Instance == (Object)null || num2 >= ProductListing.Instance.productsData.Length)
			{
				return;
			}
			Data_Container val = FindNearestContainer(((Component)vehicle).transform.position);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			if ((Object)(object)((NetworkBehaviour)val).netIdentity == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"Shelf sin NetworkIdentity, skipping");
				return;
			}
			int[] productInfoArray2 = val.productInfoArray;
			int num4 = productInfoArray2.Length / 2;
			for (int j = 0; j < num4; j++)
			{
				if (productInfoArray2[j * 2] == num2)
				{
					int num5 = productInfoArray2[j * 2 + 1];
					int capacity = GetCapacity(num2, val);
					if (num5 < capacity)
					{
						int num6 = Mathf.Min(num3, capacity - num5);
						DoDeposit(vehicle, num, num2, num3, val, j, num5 + num6, num6);
						return;
					}
				}
			}
			for (int k = 0; k < num4; k++)
			{
				if (productInfoArray2[k * 2] == -1)
				{
					int capacity2 = GetCapacity(num2, val);
					int num7 = Mathf.Min(num3, capacity2);
					DoDeposit(vehicle, num, num2, num3, val, k, num7, num7);
					break;
				}
			}
		}

		private void DoDeposit(MiniTransportBehaviour vehicle, int vi, int vPID, int vCount, Data_Container shelf, int si, int newShelfCount, int deposited)
		{
			int num = vi * 2;
			int num2 = si * 2;
			int num3 = vCount - deposited;
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"[DEP] {ProductName(vPID)} x{deposited} vSlot={vi} -> sSlot={si}");
			shelf.EmployeeUpdateArrayValuesStorage(num2, vPID, newShelfCount);
			int num4 = ((num3 > 0) ? vPID : (-1));
			int num5 = ((num3 > 0) ? num3 : (-1));
			vehicle.EmployeeUpdateArrayValuesStorage(num, num4, num5);
			SetCooldown(shelf);
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"[DEP] OK (remaining: {num3})");
		}

		private Data_Container FindNearestContainer(Vector3 pos)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			Data_Container[] array = Object.FindObjectsByType<Data_Container>((FindObjectsSortMode)0);
			Data_Container result = null;
			float num = float.MaxValue;
			Data_Container[] array2 = array;
			foreach (Data_Container val in array2)
			{
				if (!((Object)(object)val == (Object)null) && val.containerClass != 99 && !((Object)(object)((NetworkBehaviour)val).netIdentity == (Object)null))
				{
					float num2 = Vector3.Distance(pos, ((Component)val).transform.position);
					if (!(num2 > DepositRadius.Value) && !IsOnCooldown(val) && num2 < num)
					{
						num = num2;
						result = val;
					}
				}
			}
			return result;
		}

		private bool IsOnCooldown(Data_Container c)
		{
			int instanceID = ((Object)c).GetInstanceID();
			if (depositCooldowns.TryGetValue(instanceID, out var value))
			{
				if (Time.time < value)
				{
					return true;
				}
				depositCooldowns.Remove(instanceID);
			}
			return false;
		}

		private void SetCooldown(Data_Container c)
		{
			depositCooldowns[((Object)c).GetInstanceID()] = Time.time + 0.8f;
		}

		private int GetCapacity(int productID, Data_Container shelf)
		{
			//IL_0031: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: 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 ((Object)(object)ProductListing.Instance == (Object)null || productID < 0 || productID >= ProductListing.Instance.productsData.Length)
			{
				return 10;
			}
			ProductData val = ProductListing.Instance.productsData[productID];
			Vector3 colliderSize = val.colliderSize;
			if (colliderSize.x <= 0f || colliderSize.z <= 0f)
			{
				return 10;
			}
			int num = Mathf.Clamp(Mathf.FloorToInt(shelf.shelfLength / (colliderSize.x * 1.1f)), 1, 100);
			int num2 = Mathf.Clamp(Mathf.FloorToInt(shelf.shelfWidth / (colliderSize.z * 1.1f)), 1, 100);
			int num3 = num * num2;
			if (val.isStackable && colliderSize.y > 0f)
			{
				num3 *= Mathf.Clamp(Mathf.FloorToInt(shelf.shelfHeight / (colliderSize.y * 1.1f)), 1, 100);
			}
			return Mathf.Max(num3, 1);
		}

		private string ProductName(int pid)
		{
			if ((Object)(object)ProductListing.Instance == (Object)null || pid < 0 || pid >= ProductListing.Instance.productsData.Length)
			{
				return $"P#{pid}";
			}
			ProductData val = ProductListing.Instance.productsData[pid];
			if (!((Object)(object)val.productSprite != (Object)null))
			{
				return $"P#{pid}";
			}
			return ((Object)val.productSprite).name;
		}

		private void DebugScanArea()
		{
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			MiniTransportBehaviour val = FindActiveVehicle();
			if ((Object)(object)val == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"[DEBUG] No estas en vehiculo");
				return;
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"========== DEBUG ==========");
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"Host: {NetworkServer.active}, Vel: {val.velocity:F2}");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Mode: ZERO REFLECTION");
			int[] productInfoArray = val.productInfoArray;
			for (int i = 0; i < productInfoArray.Length / 2; i++)
			{
				int num = productInfoArray[i * 2];
				int num2 = productInfoArray[i * 2 + 1];
				((BaseUnityPlugin)this).Logger.LogInfo((object)((num >= 0) ? $"  V{i}: {ProductName(num)} x{num2}" : $"  V{i}: ---"));
			}
			Data_Container[] array = Object.FindObjectsByType<Data_Container>((FindObjectsSortMode)0);
			float value = DepositRadius.Value;
			Data_Container[] array2 = array;
			foreach (Data_Container val2 in array2)
			{
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				float num3 = Vector3.Distance(((Component)val).transform.position, ((Component)val2).transform.position);
				if (!(num3 > value + 2f))
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)$"  [C] class={val2.containerClass} dist={num3:F1} inR={num3 <= value} cd={IsOnCooldown(val2)}");
					int[] productInfoArray2 = val2.productInfoArray;
					for (int k = 0; k < productInfoArray2.Length / 2; k++)
					{
						int num4 = productInfoArray2[k * 2];
						int num5 = productInfoArray2[k * 2 + 1];
						((BaseUnityPlugin)this).Logger.LogInfo((object)((num4 >= 0) ? $"    S{k}: {ProductName(num4)} x{num5} (cap={GetCapacity(num4, val2)})" : $"    S{k}: ---"));
					}
				}
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"========== FIN ==========");
		}

		private void OnDestroy()
		{
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
			if (scanCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(scanCoroutine);
			}
		}
	}
}