Decompiled source of MultiDelivery v1.0.0

MultiDelivery-IL2CPP.dll

Decompiled 3 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
using HarmonyLib;
using Il2Cpp;
using Il2CppFishNet;
using Il2CppFishNet.Connection;
using Il2CppFishNet.Object;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppScheduleOne;
using Il2CppScheduleOne.Core.Items.Framework;
using Il2CppScheduleOne.Delivery;
using Il2CppScheduleOne.DevUtilities;
using Il2CppScheduleOne.Graffiti;
using Il2CppScheduleOne.ItemFramework;
using Il2CppScheduleOne.Map;
using Il2CppScheduleOne.Money;
using Il2CppScheduleOne.NPCs.CharacterClasses;
using Il2CppScheduleOne.Persistence.Datas;
using Il2CppScheduleOne.Persistence.Loaders;
using Il2CppScheduleOne.PlayerScripts;
using Il2CppScheduleOne.UI.Phone.Delivery;
using Il2CppScheduleOne.UI.Shop;
using Il2CppScheduleOne.Vehicles;
using Il2CppScheduleOne.Vehicles.Modification;
using Il2CppScheduleOne.Weather;
using Il2CppSteamworks;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.IO;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using MultiDelivery;
using MultiDelivery.Builders;
using MultiDelivery.Helpers;
using MultiDelivery.Network;
using MultiDelivery.Persistence;
using MultiDelivery.Pool;
using MultiDelivery.Quest;
using S1API.Dialogues;
using S1API.Entities;
using S1API.Entities.Dialogue;
using S1API.Entities.NPCs.Suburbia;
using S1API.Internal.Abstraction;
using S1API.Leveling;
using S1API.Messaging;
using S1API.Money;
using S1API.Quests;
using S1API.Quests.Constants;
using S1API.Saveables;
using S1API.Utils;
using SteamNetworkLib;
using SteamNetworkLib.Core;
using SteamNetworkLib.Events;
using SteamNetworkLib.Models;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(global::MultiDelivery.MultiDelivery), "MultiDelivery", "1.0.1", "k073l", null)]
[assembly: MelonColor(1, 0, 255, 0)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: MelonPlatformDomain(/*Could not decode attribute arguments.*/)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("MultiDelivery-IL2CPP")]
[assembly: AssemblyConfiguration("IL2CPP")]
[assembly: AssemblyDescription("Add vehicles, order multiple deliveries from the same place!")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+9f266827b45c3676261f34c577e88b8249083816")]
[assembly: AssemblyProduct("MultiDelivery-IL2CPP")]
[assembly: AssemblyTitle("MultiDelivery-IL2CPP")]
[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.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 MultiDelivery
{
	public class Logger
	{
		[CompilerGenerated]
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private string <categoryName>P;

		[CompilerGenerated]
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private LogLevel? <forceLevel>P;

		public Logger(string categoryName, LogLevel? forceLevel = null)
		{
			<categoryName>P = categoryName;
			<forceLevel>P = forceLevel;
			base..ctor();
		}

		public void NetworkTrace(params object[] args)
		{
			Log(LogLevel.NetworkTrace, args);
		}

		public void Debug(params object[] args)
		{
			Log(LogLevel.Debug, args);
		}

		public void Info(params object[] args)
		{
			Log(LogLevel.Info, args);
		}

		public void Msg(params object[] args)
		{
			Log(LogLevel.Info, args);
		}

		public void Warn(params object[] args)
		{
			Log(LogLevel.Warn, args);
		}

		public void Warning(params object[] args)
		{
			Log(LogLevel.Warn, args);
		}

		public void Error(params object[] args)
		{
			Log(LogLevel.Error, args);
		}

		private void Log(LogLevel level, params object[] args)
		{
			LogLevel? logLevel = <forceLevel>P;
			if (logLevel.HasValue)
			{
				LogLevel valueOrDefault = logLevel.GetValueOrDefault();
				if (level < LogLevel.Error)
				{
					level = valueOrDefault;
				}
			}
			if (args.Length == 0)
			{
				return;
			}
			string text;
			if (args.Length == 1)
			{
				text = args[0]?.ToString() ?? "";
			}
			else
			{
				string format = args[0]?.ToString() ?? "";
				text = string.Format(format, args.Skip(1).ToArray());
			}
			string text2 = (string.IsNullOrWhiteSpace(<categoryName>P) ? "MultiDelivery" : ("MultiDelivery." + <categoryName>P));
			string text3 = "[" + text2 + "] " + text;
			switch (level)
			{
			case LogLevel.NetworkTrace:
				if (MultiDelivery.NetworkLogging.Value)
				{
					Melon<MultiDelivery>.Logger.Msg(text3);
				}
				break;
			case LogLevel.Debug:
				MelonDebug.Msg(text3);
				break;
			case LogLevel.Info:
				Melon<MultiDelivery>.Logger.Msg(text3);
				break;
			case LogLevel.Warn:
				Melon<MultiDelivery>.Logger.Warning(text3);
				break;
			case LogLevel.Error:
				Melon<MultiDelivery>.Logger.Error(text3);
				break;
			}
		}
	}
	public enum LogLevel
	{
		NetworkTrace,
		Debug,
		Info,
		Warn,
		Error
	}
	public static class BuildInfo
	{
		public const string Name = "MultiDelivery";

		public const string Description = "Add vehicles, order multiple deliveries from the same place!";

		public const string Author = "k073l";

		public const string Version = "1.0.1";
	}
	public class MultiDelivery : MelonMod
	{
		[CompilerGenerated]
		private sealed class <InitializeNetworkManager>d__12 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public MultiDelivery <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if (!SteamAPI.Init())
					{
						return false;
					}
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>4__this._networkManager = new DeliveryNetworkManager();
					if (<>4__this._networkManager.Initialize())
					{
						Logger.Msg("Network manager initialized");
						NetworkConvenienceMethods.InitializeNetworking(<>4__this._networkManager);
					}
					else
					{
						<>4__this._networkManager = null;
						Logger.Warning("Network manager initialization failed - running in offline mode");
					}
					return false;
				}
			}

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

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

		[CompilerGenerated]
		private sealed class <WireOnXpChangedDelayed>d__16 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public MultiDelivery <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0045: Unknown result type (might be due to invalid IL or missing references)
				//IL_004f: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitUntil(Func<bool>.op_Implicit((Func<bool>)(() => LevelManager.Exists)));
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (PersistentDropoffQuestData.Instance.HasMessaged)
					{
						DropoffQuestDialogue.Register();
						return false;
					}
					Logger.Debug("Wiring on xp changed");
					LevelManager.OnXPChanged += <>4__this.SendMessageIfRequiredRank;
					return false;
				}
			}

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

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

		internal const string RequestedVehicleCode = "veeper";

		private static FullRank RequiredRank = new FullRank((Rank)5, 1);

		private static Sprite _questIconSprite;

		private static readonly Logger Logger = new Logger("");

		private DeliveryNetworkManager? _networkManager;

		private bool _networkManagerFailed;

		internal static MelonPreferences_Category Category = MelonPreferences.CreateCategory("MultiDeliverySettings", "MultiDelivery's Settings");

		internal static MelonPreferences_Entry<bool> NetworkLogging = Category.CreateEntry<bool>("NetworkDebugLogs", false, "Enable Network Logs", "Display networking-related debug logs in MelonLoader console/log file (may be verbose)", false, false, (ValueValidator)null, (string)null);

		public static Sprite QuestIconSprite => GetIcon(ref _questIconSprite, "MultiDelivery.assets.quest_icon.png");

		public override void OnInitializeMelon()
		{
			Logger.Msg("MultiDelivery initialized");
			MelonCoroutines.Start(InitializeNetworkManager());
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			if (sceneName == "Main")
			{
				Player.LocalPlayerSpawned += WirePlayerEvent;
			}
			else if (!(sceneName != "Menu"))
			{
				PoolManager.Instance.Pool.Clear();
				PoolManager.Instance.Allocations.Clear();
				PoolManager.Instance.BaseVehicleAllocationsForShop.Clear();
				Player.LocalPlayerSpawned -= WirePlayerEvent;
				LevelManager.OnXPChanged -= SendMessageIfRequiredRank;
			}
		}

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

		public override void OnUpdate()
		{
			if (_networkManagerFailed || _networkManager == null)
			{
				return;
			}
			try
			{
				_networkManager.Update();
			}
			catch (Exception ex)
			{
				MelonLogger.Error("Network manager update failed: " + ex.Message + "\n\nYou can ignore this error if you plan on playing singleplayer only and don't want to install SteamNetworkLib");
				_networkManagerFailed = true;
			}
		}

		public override void OnDeinitializeMelon()
		{
			_networkManager?.Dispose();
			Logger.Msg("MultiDelivery deinitialized");
		}

		private void WirePlayerEvent(Player _)
		{
			Logger.Debug("Player loaded event called");
			MelonCoroutines.Start(WireOnXpChangedDelayed());
		}

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

		private void SendMessageIfRequiredRank(FullRank _, FullRank current)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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)
			Logger.Debug($"Current rank {current}, required: {RequiredRank}");
			if (PersistentDropoffQuestData.Instance.HasMessaged)
			{
				MelonDebug.Msg("Xp changed wired, but already messaged - registering dialogue now.");
				DropoffQuestDialogue.Register();
			}
			else
			{
				if (current < RequiredRank)
				{
					return;
				}
				NPC val = NPC.Get<JeremyWilkinson>();
				if (val != null)
				{
					if (NetworkConvenienceMethods.HostOrSingleplayer)
					{
						val.SendTextMessage("Your properties are getting busy. Want to handle more than one delivery at a time? I've got an idea. Stop by the dealership.", (Response[])null, 1f, true);
					}
					PersistentDropoffQuestData.Instance.HasMessaged = true;
					DropoffQuestDialogue.Register();
					LevelManager.OnXPChanged -= SendMessageIfRequiredRank;
				}
			}
		}

		private static Sprite LoadEmbeddedPNG(string resourceName)
		{
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			using Stream stream = executingAssembly.GetManifestResourceStream(resourceName);
			if (stream == null)
			{
				return null;
			}
			byte[] array = new byte[stream.Length];
			stream.Read(array, 0, array.Length);
			Sprite val = ImageUtils.LoadImageRaw(array);
			if ((Object)(object)val != (Object)null)
			{
				((Object)val).name = resourceName;
			}
			return val;
		}

		private static Sprite GetIcon(ref Sprite spriteField, string resourceName)
		{
			if ((Object)(object)spriteField == (Object)null)
			{
				spriteField = LoadEmbeddedPNG(resourceName);
			}
			return spriteField;
		}
	}
}
namespace MultiDelivery.Quest
{
	public class DropoffQuest : Quest
	{
		[CompilerGenerated]
		private sealed class <NotifyCompletion>d__21 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public DropoffQuest <>4__this;

			private NPC <npc>5__1;

			private int <i>5__2;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				//IL_005c: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<i>5__2 = 0;
					break;
				case 1:
				{
					<>1__state = -1;
					int num = <i>5__2 + 1;
					<i>5__2 = num;
					break;
				}
				}
				if (<i>5__2 < 3 && PoolManager.Instance.Pool.Count <= <>4__this._startingCapacity)
				{
					<>2__current = (object)new WaitForSeconds(3f);
					<>1__state = 1;
					return true;
				}
				<npc>5__1 = NPC.Get<JeremyWilkinson>();
				if (<npc>5__1 != null)
				{
					if (PoolManager.Instance.Pool.Count <= <>4__this._startingCapacity)
					{
						<npc>5__1.SendTextMessage("Something went wrong... Vehicle got in a car crash :(", (Response[])null, 1f, true);
					}
					else
					{
						<npc>5__1.SendTextMessage($"Vehicle added, you now can order {PoolManager.Instance.Pool.Count} more deliver{((PoolManager.Instance.Pool.Count > 1) ? "y" : "ies")} from stores.", (Response[])null, 1f, true);
						<npc>5__1.SendTextMessage("If you want to add more, you know where to find me.", (Response[])null, 1f, true);
					}
				}
				return false;
			}

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

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

		internal const string Name = "Expanding the Fleet";

		private bool _vehicleAdded;

		private QuestEntry _addVehicleEntry;

		private int _startingCapacity;

		private static VehicleDropoffZone dropoffZone;

		private static Vector3 _dropoffZonePosition;

		private static readonly Logger Logger = new Logger("DropoffQuest");

		protected override string Title => "Expanding the Fleet";

		protected override string Description => "Bring a delivery vehicle to the dropoff zone to expand your delivery capacity";

		protected override bool AutoBegin => false;

		protected override Sprite QuestIcon => MultiDelivery.QuestIconSprite;

		internal QuestState State => ((Quest)this).QuestState;

		protected override void OnCreated()
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: 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)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			((Registerable)this).OnCreated();
			_startingCapacity = PoolManager.Instance.Pool.Count;
			Logger.Debug($"Starting Quest with {_startingCapacity} capacity");
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(5.1f, 4.2f, 82.58f);
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(0.55f, 4.2f, 76.56f);
			_dropoffZonePosition = (val + val2) / 2f;
			if ((Object)(object)dropoffZone != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)dropoffZone).gameObject);
			}
			dropoffZone = VehicleDropoffZoneFactory.CreateZone(val, val2, 5f, (Color?)new Color(0f, 1f, 0f, 0.4f), showVisuals: true, this);
			Logger.Debug("Dropoff zone created. Spawning " + ((Object)dropoffZone).name);
			((Quest)this).OnComplete += Completed;
			Logger.Debug("Wired completion event");
			UpdateQuestEntries();
		}

		private void UpdateQuestEntries()
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			base.QuestEntries.Clear();
			if (!_vehicleAdded)
			{
				Logger.Debug("Adding add vehicle entry");
				_addVehicleEntry = ((Quest)this).AddEntry("Purchase a " + "veeper".Capitalize() + " and drive it into the green dropoff zone (top floor of the parking garage, next to storage unit)", (Vector3?)_dropoffZonePosition);
				_addVehicleEntry.Begin();
			}
			Logger.Debug("Entries added!");
		}

		public void MarkAddVehicleEntryComplete()
		{
			Logger.Debug("Marked add vehicle entry as completed");
			_addVehicleEntry.Complete();
		}

		private void Completed()
		{
			Logger.Msg("Delivery vehicle dropoff quest completed!");
			MelonCoroutines.Start(NotifyCompletion());
		}

		[IteratorStateMachine(typeof(<NotifyCompletion>d__21))]
		private IEnumerator NotifyCompletion()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <NotifyCompletion>d__21(0)
			{
				<>4__this = this
			};
		}
	}
	public class DropoffQuestDialogue
	{
		private static readonly Logger Logger = new Logger("DropoffQuestDialogue");

		private const string ContainerName = "DeliveryExpansion";

		public static void Register()
		{
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Expected O, but got Unknown
			NPC jeremy = NPC.Get<JeremyWilkinson>();
			if (jeremy == null)
			{
				Logger.Warning("Jeremy Wilkinson not found");
				return;
			}
			jeremy.Dialogue.BuildAndRegisterContainer("DeliveryExpansion", (Action<DialogueContainerBuilder>)delegate(DialogueContainerBuilder c)
			{
				c.AddNode("OFFER_FIRST", "Yeah! I can help with that. If you bring a " + "veeper".Capitalize() + " to the dropoff zone, I'll add it to the fleet. This will let you handle multiple deliveries at once. Want to give it a shot?", (Action<ChoiceList>)delegate(ChoiceList ch)
				{
					ch.Add("BUY_NOW", "Sure! Can I buy one from you right now?", "CHECK_FUNDS");
					ch.Add("ACCEPT", "I already have one, let's do it!", "ACCEPTED");
					ch.Add("DECLINE", "Maybe later.", "DECLINED");
				});
				c.AddNode("OFFER_REPEAT", "Want to expand your fleet even more? Just bring another vehicle to the dropoff zone and I'll add it for you.", (Action<ChoiceList>)delegate(ChoiceList ch)
				{
					ch.Add("BUY_NOW", "Yeah, can I buy another one from you?", "CHECK_FUNDS");
					ch.Add("ACCEPT", "I've got one ready!", "ACCEPTED");
					ch.Add("DECLINE", "Not right now.", "DECLINED");
				});
				c.AddNode("CHECK_FUNDS", $"A {"veeper".Capitalize()} runs <color=#19BEF0>({MoneyManager.FormatAmount(GetVehiclePrice(), false, false)})</color>. Want to pick one up?", (Action<ChoiceList>)delegate(ChoiceList ch)
				{
					ch.Add("PURCHASE", "I'll take it. <color=#19BEF0>(" + MoneyManager.FormatAmount(GetVehiclePrice(), false, false) + ")</color>", "PURCHASE_COMPLETE");
					ch.Add("NEVERMIND", "Let me think about it.", "DECLINED");
				});
				c.AddNode("PURCHASE_COMPLETE", "All yours. You can customize it if you want. Now just drive it to the dropoff zone - I've marked it on your map.", (Action<ChoiceList>)null);
				c.AddNode("NOT_ENOUGH", "You don't have enough money to buy it. Come back later.", (Action<ChoiceList>)null);
				c.AddNode("IN_PROGRESS", "You already have an active delivery expansion going! Just bring the vehicle to the dropoff zone. Top floor of the parking garage, next to the storage units - check your map if you forgot where it is.", (Action<ChoiceList>)null);
				c.AddNode("ACCEPTED", "Great! I've marked the dropoff zone on your map - top floor of the parking garage, next to the storage units. Just drive the vehicle in there when you're ready.", (Action<ChoiceList>)null);
				c.AddNode("DECLINED", "No worries, just let me know if you change your mind!", (Action<ChoiceList>)null);
			});
			jeremy.Dialogue.OnChoiceSelected("ACCEPT", (Action)OnAcceptQuest);
			jeremy.Dialogue.OnChoiceSelected("BUY_NOW", (Action)OnAcceptQuest);
			jeremy.Dialogue.OnChoiceSelected("DECLINE", (Action)delegate
			{
				Logger.Debug("Player declined quest");
			});
			jeremy.Dialogue.OnChoiceSelected("NEVERMIND", (Action)delegate
			{
				Logger.Debug("Player cancelled purchase");
			});
			jeremy.Dialogue.OnChoiceSelected("PURCHASE", (Action)delegate
			{
				//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
				//IL_0100: Unknown result type (might be due to invalid IL or missing references)
				float vehiclePrice = GetVehiclePrice();
				float onlineBalance = Money.GetOnlineBalance();
				if (onlineBalance >= vehiclePrice)
				{
					Money.CreateOnlineTransaction("veeper".Capitalize() + " purchase", 0f - vehiclePrice, 1f, "Bought as a part of delivery expansion");
					Logger.Msg($"Player purchased {"veeper"} for ${vehiclePrice:F2}");
					Jeremy component = jeremy.gameObject.GetComponent<Jeremy>();
					if ((Object)(object)component != (Object)null)
					{
						Dealership dealership = component.Dealership;
						if ((Object)(object)dealership != (Object)null)
						{
							dealership.SpawnVehicle("veeper");
							return;
						}
					}
					NetworkSingleton<VehicleManager>.Instance.SpawnVehicle("veeper", new Vector3(9.92f, 0.54f, -33.55f), Quaternion.identity, true);
				}
				else
				{
					jeremy.Dialogue.JumpTo("DeliveryExpansion", "NOT_ENOUGH", false);
				}
			});
			DialogueInjector.Register(new DialogueInjection(jeremy.ID, "Dealership_Salesman_Sell", "cc0d838e-2824-4fd5-907d-798dc0195c16", "OFFER_FIRST", "ASK_EXPANSION", "Can I expand my delivery capacity?", (Action)delegate
			{
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Invalid comparison between Unknown and I4
				DropoffQuest dropoffQuest = QuestManager.GetQuestByName("Expanding the Fleet") as DropoffQuest;
				bool flag = PoolManager.Instance.Pool.Count > 0;
				bool flag2 = dropoffQuest != null && (int)dropoffQuest.State == 1;
				Logger.Debug($"Quest state - Active: {flag2}, Has expanded: {flag}");
				string text = (flag2 ? "IN_PROGRESS" : (flag ? "OFFER_REPEAT" : "OFFER_FIRST"));
				Logger.Debug($"Jumping to '{"DeliveryExpansion"}', node '{text}'");
				jeremy.Dialogue.JumpTo("DeliveryExpansion", text, false);
			}));
			Logger.Msg("Registered delivery expansion dialogue");
		}

		private static void OnAcceptQuest()
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Invalid comparison between Unknown and I4
			if (!(QuestManager.GetQuestByName("Expanding the Fleet") is DropoffQuest dropoffQuest))
			{
				if (QuestManager.CreateQuest<DropoffQuest>((string)null) is DropoffQuest dropoffQuest2)
				{
					((Quest)dropoffQuest2).Begin();
				}
				Logger.Msg("Started delivery expansion quest");
			}
			else if (dropoffQuest != null && (int)dropoffQuest.State == 2)
			{
				((Quest)dropoffQuest).Begin();
				Logger.Msg("Restarted delivery expansion quest");
			}
		}

		private static float GetVehiclePrice()
		{
			LandVehicle vehiclePrefab = NetworkSingleton<VehicleManager>.Instance.GetVehiclePrefab("veeper");
			return (vehiclePrefab != null) ? vehiclePrefab.VehiclePrice : 5000f;
		}
	}
	[RegisterTypeInIl2Cpp]
	public class VehicleDropoffZone : MonoBehaviour
	{
		private VehicleDetector _detector;

		private Logger _logger;

		private GameObject _visualPlane;

		private Material _visualMaterial;

		private Color _baseColor;

		private DropoffQuest? _quest;

		public Vector3 Corner1 { get; private set; }

		public Vector3 Corner2 { get; private set; }

		public bool ShowVisuals { get; set; } = true;


		private void Awake()
		{
			_logger = new Logger("VehicleDropoffZone");
		}

		private void Start()
		{
			_detector = ((Component)this).gameObject.GetComponent<VehicleDetector>();
			if ((Object)(object)_detector == (Object)null)
			{
				_detector = ((Component)this).gameObject.AddComponent<VehicleDetector>();
			}
		}

		private void Update()
		{
			if (_detector.vehicles.Count <= 0)
			{
				return;
			}
			foreach (LandVehicle item in _detector.vehicles.AsEnumerable<LandVehicle>())
			{
				OnVehicleEntered(item);
			}
		}

		private void OnVehicleEntered(LandVehicle vehicle)
		{
			_logger.Debug("Vehicle entered dropoff zone: " + vehicle.vehicleName);
			if (!IsCorrectVehicleType(vehicle))
			{
				if (Time.frameCount % 60 == 0)
				{
					_logger.Warning("Wrong vehicle type: " + vehicle.vehicleCode);
				}
				return;
			}
			if (vehicle.IsOccupied)
			{
				_logger.Msg("Ejecting player from vehicle");
				vehicle.ExitVehicle();
			}
			ProcessAndAddToPool(vehicle);
			_detector.vehicles.Remove(vehicle);
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}

		private static bool IsCorrectVehicleType(LandVehicle vehicle)
		{
			return vehicle.vehicleCode == "veeper";
		}

		private void ProcessAndAddToPool(LandVehicle vehicle)
		{
			//IL_0029: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			_logger.Debug($"Adding vehicle to pool: {vehicle.GUID}");
			DeliveryVehicle val = ((Component)vehicle).GetComponent<DeliveryVehicle>();
			if ((Object)(object)val == (Object)null)
			{
				Guid gUID = vehicle.GUID;
				val = new DeliveryVehicleBuilder().WithLandVehicle(vehicle).WithGuid(gUID).Build();
			}
			vehicle.IsPlayerOwned = false;
			vehicle.SetIsPlayerOwned((NetworkConnection)null, false);
			vehicle.SetVisible(false);
			vehicle.IsPhysicallySimulated = false;
			((Component)vehicle).transform.position = new Vector3(0f, -100f, 0f);
			PoolManager.Instance.AddToSaveData(val);
			PoolManager.Instance.AddToPool(val);
			_quest?.MarkAddVehicleEntryComplete();
			_logger.Msg($"Vehicle added to pool. Total vehicles: {PoolManager.Instance.Pool.Count}");
		}

		public void SetupZone(Vector3 corner1, Vector3 corner2, float height = 5f, Color? visualColor = null)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: 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)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			Corner1 = corner1;
			Corner2 = corner2;
			Vector3 val = (corner1 + corner2) / 2f;
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(Mathf.Abs(corner2.x - corner1.x), height, Mathf.Abs(corner2.z - corner1.z));
			((Component)this).transform.position = val;
			BoxCollider val3 = ((Component)this).gameObject.GetComponent<BoxCollider>();
			if ((Object)(object)val3 == (Object)null)
			{
				val3 = ((Component)this).gameObject.AddComponent<BoxCollider>();
			}
			((Collider)val3).isTrigger = true;
			val3.size = val2;
			val3.center = Vector3.zero;
			if (ShowVisuals)
			{
				_baseColor = (Color)(((??)visualColor) ?? new Color(0f, 1f, 1f, 0.3f));
				CreateVisualPlane(val2, _baseColor);
			}
			_logger.Debug($"Dropoff zone created: Center={val}, Size={val2}");
		}

		private void CreateVisualPlane(Vector3 size, Color color)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			_visualPlane = GameObject.CreatePrimitive((PrimitiveType)3);
			((Object)_visualPlane).name = "DropoffZoneVisual";
			_visualPlane.transform.SetParent(((Component)this).transform);
			_visualPlane.transform.localPosition = Vector3.zero;
			_visualPlane.transform.localScale = new Vector3(size.x, 0.1f, size.z);
			Collider component = _visualPlane.GetComponent<Collider>();
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
			}
			ApplyDebugMaterial(_visualPlane, color);
		}

		private void ApplyDebugMaterial(GameObject obj, Color color)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_006b: 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_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			Renderer component = obj.GetComponent<Renderer>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			Shader val = Shader.Find("Universal Render Pipeline/Lit");
			if (!((Object)(object)val == (Object)null))
			{
				_visualMaterial = new Material(val);
				if (_visualMaterial.HasProperty("_Surface"))
				{
					_visualMaterial.SetFloat("_Surface", 1f);
				}
				if (color.a <= 0f)
				{
					color.a = 0.3f;
				}
				if (_visualMaterial.HasProperty("_BaseColor"))
				{
					_visualMaterial.SetColor("_BaseColor", color);
				}
				if (_visualMaterial.HasProperty("_EmissionColor"))
				{
					_visualMaterial.EnableKeyword("_EMISSION");
					_visualMaterial.SetColor("_EmissionColor", new Color(color.r, color.g, color.b) * 1.5f);
				}
				_visualMaterial.SetInt("_ZWrite", 0);
				_visualMaterial.renderQueue = 3000;
				component.material = _visualMaterial;
			}
		}

		public void SetVisualsEnabled(bool enabled)
		{
			ShowVisuals = enabled;
			if ((Object)(object)_visualPlane != (Object)null)
			{
				_visualPlane.SetActive(enabled);
			}
		}

		[HideFromIl2Cpp]
		public void SetQuest(DropoffQuest quest)
		{
			_quest = quest;
		}

		private void OnDestroy()
		{
			if ((Object)(object)_visualPlane != (Object)null)
			{
				Object.Destroy((Object)(object)_visualPlane);
			}
		}
	}
	public static class VehicleDropoffZoneFactory
	{
		public static VehicleDropoffZone CreateZone(Vector3 corner1, Vector3 corner2, float height = 5f, Color? visualColor = null, bool showVisuals = true, DropoffQuest? attachedQuest = null)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_001d: 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)
			GameObject val = new GameObject("VehicleDropoffZone");
			VehicleDropoffZone vehicleDropoffZone = val.AddComponent<VehicleDropoffZone>();
			vehicleDropoffZone.ShowVisuals = showVisuals;
			vehicleDropoffZone.SetupZone(corner1, corner2, height, visualColor);
			if (attachedQuest != null)
			{
				vehicleDropoffZone.SetQuest(attachedQuest);
			}
			return vehicleDropoffZone;
		}

		public static VehicleDropoffZone CreateZoneNear(Transform reference, Vector3 offset, Vector3 size, Color? visualColor = null)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = reference.position + offset;
			Vector3 corner = val - size / 2f;
			Vector3 corner2 = val + size / 2f;
			return CreateZone(corner, corner2, size.y, visualColor);
		}
	}
}
namespace MultiDelivery.Pool
{
	[HarmonyPatch(typeof(DeliveryManager))]
	internal static class ActiveDeliveryPatch
	{
		private static readonly Logger Logger = new Logger("ActiveDeliveryPatch");

		[HarmonyPatch("GetActiveShopDelivery")]
		[HarmonyPostfix]
		private static void AllowIfPoolAssigmentAvailable(DeliveryManager __instance, DeliveryShop shop, ref DeliveryInstance __result)
		{
			if (__result == null)
			{
				return;
			}
			if (PoolManager.Instance.BaseVehicleAllocationsForShop.TryGetValue(shop.MatchingShopInterfaceName, out var value))
			{
				if (Time.frameCount % 30 == 0)
				{
					Logger.Debug($"Base: {value}");
				}
				if (!value)
				{
					__result = null;
					return;
				}
				DeliveryVehicle firstFree = PoolManager.Instance.GetFirstFree();
				if (!((Object)(object)firstFree == (Object)null))
				{
					Logger.Debug("Free pool vehicle found");
					__result = null;
				}
			}
			else
			{
				DeliveryVehicle firstFree2 = PoolManager.Instance.GetFirstFree();
				if (!((Object)(object)firstFree2 == (Object)null))
				{
					Logger.Debug("Free pool vehicle found");
					__result = null;
				}
			}
		}

		[HarmonyPatch("SendDelivery")]
		[HarmonyPostfix]
		private static void AllocateVehicle(DeliveryManager __instance, DeliveryInstance delivery)
		{
			PoolManager.Instance.BaseVehicleAllocationsForShop.TryAdd(delivery.StoreName, value: false);
			Logger.Debug($"Base allocation: {PoolManager.Instance.BaseVehicleAllocationsForShop[delivery.StoreName]}");
			if (!PoolManager.Instance.BaseVehicleAllocationsForShop[delivery.StoreName])
			{
				Logger.Debug("Base vehicle allocating");
				PoolManager.Instance.BaseVehicleAllocationsForShop[delivery.StoreName] = true;
				NetworkConvenienceMethods.NotifyBaseAllocation(delivery.StoreName, isAllocated: true);
			}
			else
			{
				PoolManager.Instance.GetOrAllocateFirstFree(delivery.DeliveryID);
				Logger.Debug("Allocated for " + delivery.DeliveryID);
			}
		}
	}
	[HarmonyPatch(typeof(DeliveryInstance))]
	internal static class DeliveryInstancePatches
	{
		[HarmonyPatch("SetStatus")]
		[HarmonyPrefix]
		private static bool UsePoolSetStatus(DeliveryInstance __instance, EDeliveryStatus status)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Invalid comparison between Unknown and I4
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Invalid comparison between Unknown and I4
			Console.Log(Object.op_Implicit($"Setting delivery status to {status} for delivery {__instance.DeliveryID}"), (Object)null);
			__instance.Status = status;
			ShopInterface shopInterface = NetworkSingleton<DeliveryManager>.Instance.GetShopInterface(__instance.StoreName);
			if ((int)status != 2)
			{
				if ((int)status == 3)
				{
					if ((Object)(object)__instance.ActiveVehicle == (Object)(object)shopInterface.DeliveryVehicle)
					{
						PoolManager.Instance.BaseVehicleAllocationsForShop[__instance.StoreName] = false;
						NetworkConvenienceMethods.NotifyBaseAllocation(__instance.StoreName, isAllocated: false);
					}
					else
					{
						PoolManager.Instance.FreeAllocation(__instance.DeliveryID);
					}
					if ((Object)(object)__instance.ActiveVehicle != (Object)null)
					{
						__instance.ActiveVehicle.Deactivate();
					}
					UnityEvent onDeliveryCompleted = __instance.onDeliveryCompleted;
					if (onDeliveryCompleted != null)
					{
						onDeliveryCompleted.Invoke();
					}
				}
			}
			else
			{
				if (PoolManager.Instance.Allocations.TryGetValue(__instance.DeliveryID, out DeliveryVehicle value))
				{
					__instance.ActiveVehicle = value;
				}
				else
				{
					__instance.ActiveVehicle = shopInterface.DeliveryVehicle;
				}
				__instance.ActiveVehicle.Activate(__instance);
			}
			return false;
		}

		[HarmonyPatch("AddItemsToDeliveryVehicle")]
		[HarmonyPrefix]
		private static bool UsePoolAddItemsToDeliveryVehicle(DeliveryInstance __instance)
		{
			ShopInterface shopInterface = NetworkSingleton<DeliveryManager>.Instance.GetShopInterface(__instance.StoreName);
			if (!PoolManager.Instance.Allocations.TryGetValue(__instance.DeliveryID, out DeliveryVehicle value))
			{
				value = ((shopInterface != null) ? shopInterface.DeliveryVehicle : null);
			}
			Il2CppReferenceArray<StringIntPair> items = __instance.Items;
			foreach (StringIntPair item2 in (Il2CppArrayBase<StringIntPair>)(object)items)
			{
				ItemDefinition item = Registry.GetItem(item2.String);
				int num = item2.Int;
				while (num > 0)
				{
					int num2 = Mathf.Min(num, ((BaseItemDefinition)item).StackLimit);
					num -= num2;
					ItemInstance defaultInstance = item.GetDefaultInstance(num2);
					value.Vehicle.Storage.InsertItem(defaultInstance, Object.op_Implicit((Object)(object)item));
				}
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(DeliveryVehicle))]
	internal class DeliveryVehiclePatch
	{
		[HarmonyPatch("Deactivate")]
		[HarmonyPostfix]
		private static void NullActiveDelivery(DeliveryVehicle __instance)
		{
			DeliveryInstance activeDelivery = __instance.ActiveDelivery;
			object obj;
			if (activeDelivery == null)
			{
				obj = null;
			}
			else
			{
				LoadingDock loadingDock = activeDelivery.LoadingDock;
				obj = ((loadingDock != null) ? loadingDock.VehicleDetector : null);
			}
			if ((Object)obj != (Object)null)
			{
				__instance.ActiveDelivery.LoadingDock.SetOccupant((LandVehicle)null);
				__instance.ActiveDelivery.LoadingDock.VehicleDetector.Clear();
			}
			if (__instance.ActiveDelivery != null)
			{
				__instance.ActiveDelivery = null;
			}
		}
	}
	[HarmonyPatch(typeof(DeliveriesLoader))]
	internal static class LoaderPatch
	{
		private static readonly Logger Logger = new Logger("LoaderPatch");

		[HarmonyPatch("Load")]
		[HarmonyPrefix]
		private static bool Load(DeliveriesLoader __instance, string mainPath)
		{
			bool flag = false;
			string text = default(string);
			if (((Loader)__instance).TryLoadFile(Path.Combine(mainPath, "Deliveries"), ref text, true) || ((Loader)__instance).TryLoadFile(mainPath, ref text, true))
			{
				DeliveriesData val = null;
				try
				{
					val = JsonUtility.FromJson<DeliveriesData>(text);
				}
				catch (Exception ex)
				{
					Debug.LogError(Object.op_Implicit("Error loading data: " + ex.Message));
				}
				if (val != null && val.ActiveDeliveries != null)
				{
					LoadDelivery(val);
					if (val.DeliveryVehicles != null)
					{
						flag = true;
						VehicleData[] array = Il2CppArrayBase<VehicleData>.op_Implicit((Il2CppArrayBase<VehicleData>)(object)val.DeliveryVehicles);
						VehicleData[] array2 = array;
						foreach (VehicleData data in array2)
						{
							LoadVehicle(data, mainPath);
						}
					}
				}
			}
			if (!flag && Directory.Exists(mainPath))
			{
				Console.Log(Object.op_Implicit("Loading legacy delivery vehicles at: " + mainPath), (Object)null);
				string text2 = Path.Combine(mainPath, "DeliveryVehicles");
				List<DirectoryInfo> directories = ((Loader)__instance).GetDirectories(text2);
				for (int j = 0; j < directories.Count; j++)
				{
					__instance.LoadVehicle(((FileSystemInfo)directories[j]).FullName);
				}
			}
			return false;
		}

		private static void LoadVehicle(VehicleData data, string path)
		{
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			VehicleData data2 = data;
			Logger.Debug("Processing GUID " + data2.GUID);
			DeliveryVehicle? obj = ((IEnumerable<DeliveryVehicle>)PoolManager.Instance.Pool).FirstOrDefault((Func<DeliveryVehicle, bool>)delegate(DeliveryVehicle dv)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				Guid gUID = dv.Vehicle.GUID;
				return ((object)(Guid)(ref gUID)).ToString() == data2.GUID;
			});
			LandVehicle val = ((obj != null) ? obj.Vehicle : null);
			if ((Object)(object)val == (Object)null)
			{
				Logger.Debug("GUID " + data2.GUID + " not found in Pool, lookup via GUIDManager");
				val = GUIDManager.GetObject<LandVehicle>(new Guid(data2.GUID));
			}
			if ((Object)(object)val == (Object)null)
			{
				Logger.Error("Vehicle not found with GUID", data2.GUID);
				Console.LogError(Object.op_Implicit("LoadVehicle: Vehicle not found with GUID " + data2.GUID), (Object)null);
			}
			else
			{
				LoadVehicle(val, data2, path);
			}
		}

		private static void LoadVehicle(LandVehicle vehicle, VehicleData data, string containerPath)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			Logger.Debug($"Processing vehicle {((Object)vehicle).name} with GUID {vehicle.GUID}");
			if ((Object)(object)vehicle.Storage != (Object)null)
			{
				if (data.VehicleContents != null && data.VehicleContents.Items != null)
				{
					DeserializedItemSet val = default(DeserializedItemSet);
					if (ItemSet.TryDeserialize(data.VehicleContents, ref val))
					{
						val.LoadTo(vehicle.Storage.ItemSlots);
					}
				}
				else if (File.Exists(Path.Combine(containerPath, "Contents.json")))
				{
					Console.LogWarning(Object.op_Implicit("Loading legacy vehicle contents."), (Object)null);
					string text = default(string);
					DeserializedItemSet val2 = default(DeserializedItemSet);
					if (vehicle.Loader.TryLoadFile(containerPath, "Contents", ref text) && ItemSet.TryDeserialize(text, ref val2))
					{
						val2.LoadTo(vehicle.Storage.ItemSlots);
					}
				}
			}
			if (data.SpraySurfaces == null)
			{
				return;
			}
			try
			{
				for (int i = 0; i < data.SpraySurfaces.Count; i++)
				{
					if (((Il2CppArrayBase<SpraySurface>)(object)vehicle._spraySurfaces).Length > i)
					{
						SpraySurface obj = ((Il2CppArrayBase<SpraySurface>)(object)vehicle._spraySurfaces)[i];
						if (obj != null)
						{
							obj.Set((NetworkConnection)null, ((Il2CppObjectBase)data.SpraySurfaces[i].Strokes.ToArray()).Cast<Il2CppReferenceArray<SprayStroke>>(), data.SpraySurfaces[i].ContainsCartelGraffiti);
						}
					}
				}
			}
			catch (Exception ex)
			{
				Logger.Error("Exception thrown while loading saved graffities", ex);
			}
		}

		private static void LoadDelivery(DeliveriesData data)
		{
			if (data == null)
			{
				return;
			}
			if (data.ActiveDeliveries != null)
			{
				DeliveryInstance[] array = Il2CppArrayBase<DeliveryInstance>.op_Implicit((Il2CppArrayBase<DeliveryInstance>)(object)data.ActiveDeliveries);
				DeliveryInstance[] array2 = array;
				foreach (DeliveryInstance val in array2)
				{
					NetworkSingleton<DeliveryManager>.Instance.SendDelivery(val);
				}
			}
			if (data.DeliveryHistory != null)
			{
				foreach (DeliveryReceipt item in (Il2CppArrayBase<DeliveryReceipt>)(object)data.DeliveryHistory)
				{
					NetworkSingleton<DeliveryManager>.Instance._deliveryHistory.Add(item);
				}
			}
			if (data.DisplayedDeliveryHistory == null)
			{
				return;
			}
			foreach (DeliveryReceipt item2 in (Il2CppArrayBase<DeliveryReceipt>)(object)data.DisplayedDeliveryHistory)
			{
				NetworkSingleton<DeliveryManager>.Instance._displayedDeliveryHistory.Add(item2);
			}
		}
	}
	public class PoolManager
	{
		private static readonly Logger Logger = new Logger("PoolManager");

		public static PoolManager Instance { get; } = new PoolManager();


		public HashSet<DeliveryVehicle> Pool { get; } = new HashSet<DeliveryVehicle>();


		internal Dictionary<string, DeliveryVehicle> Allocations { get; } = new Dictionary<string, DeliveryVehicle>();


		internal Dictionary<string, bool> BaseVehicleAllocationsForShop { get; } = new Dictionary<string, bool>();


		public void AddToPool(DeliveryVehicle deliveryVehicle, bool notify = true)
		{
			Pool.Add(deliveryVehicle);
			if (notify)
			{
				NetworkConvenienceMethods.NotifyVehicleAdded(deliveryVehicle);
			}
		}

		public void AddToSaveData(DeliveryVehicle deliveryVehicle)
		{
			if ((Object)(object)deliveryVehicle == (Object)null)
			{
				throw new ArgumentNullException("deliveryVehicle");
			}
			VehicleSave.Instance.AddVehicle(deliveryVehicle.Vehicle);
			NetworkConvenienceMethods.NotifyVehicleCreated(deliveryVehicle);
		}

		public DeliveryVehicle? GetFirstFree()
		{
			DeliveryVehicle val = ((IEnumerable<DeliveryVehicle>)Pool).FirstOrDefault((Func<DeliveryVehicle, bool>)((DeliveryVehicle dv) => dv.ActiveDelivery == null && !Allocations.ContainsValue(dv)));
			if (Time.frameCount % 30 == 0)
			{
				Logger.Debug("Pool lookup: " + (((Object)(object)val == (Object)null) ? "null" : "not null"));
			}
			return val;
		}

		public DeliveryVehicle GetOrAllocateFirstFree(string deliveryId)
		{
			Logger.Debug("GetOrAllocateFirstFree called for: " + deliveryId);
			if (Allocations.TryGetValue(deliveryId, out DeliveryVehicle value))
			{
				Logger.Debug("Already allocated, returning existing");
				return value;
			}
			DeliveryVehicle firstFree = GetFirstFree();
			if ((Object)(object)firstFree == (Object)null)
			{
				Logger.Debug($"No free vehicle found! Pool count: {Pool.Count}, Allocations count: {Allocations.Count}");
				foreach (KeyValuePair<string, DeliveryVehicle> allocation in Allocations)
				{
					Logger logger = Logger;
					object[] array = new object[1];
					string key = allocation.Key;
					DeliveryInstance activeDelivery = allocation.Value.ActiveDelivery;
					array[0] = "Allocation: " + key + " -> Vehicle has ActiveDelivery: " + (((activeDelivery != null) ? activeDelivery.DeliveryID : null) ?? "null");
					logger.Debug(array);
				}
				throw new ArgumentException("Tried to allocate a non-free vehicle");
			}
			Allocations.Add(deliveryId, firstFree);
			Logger.Debug("Allocated new vehicle for " + deliveryId + ", vehicle: " + firstFree.GUID);
			NetworkConvenienceMethods.NotifyAllocation(deliveryId, firstFree, isAllocated: true);
			return firstFree;
		}

		public void FreeAllocation(string deliveryId)
		{
			Logger.Debug("Free custom allocation: " + deliveryId);
			if (Allocations.TryGetValue(deliveryId, out DeliveryVehicle value))
			{
				Allocations.Remove(deliveryId);
				NetworkConvenienceMethods.NotifyAllocation(deliveryId, value, isAllocated: false);
			}
		}
	}
	[HarmonyPatch(typeof(Wheel))]
	internal class WheelPatch
	{
		[HarmonyPatch("OnWeatherChange")]
		[HarmonyPrefix]
		private static bool ExitIfNull(Wheel __instance, WeatherConditions newConditions)
		{
			if ((Object)(object)((__instance != null) ? __instance.vehicle : null) == (Object)null)
			{
				return false;
			}
			if (newConditions != null)
			{
				_ = newConditions.Rainy;
				if (0 == 0)
				{
					return true;
				}
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(DeliveryVehicle))]
	internal static class DeliveryVehicleAwakePatch
	{
		[HarmonyPatch("Awake")]
		[HarmonyPrefix]
		private static bool ExitIfNull(DeliveryVehicle __instance)
		{
			Guid val = default(Guid);
			if (Guid.TryParse(__instance.GUID, ref val))
			{
				return true;
			}
			if ((Object)(object)((Component)__instance).GetComponent<LandVehicle>() == (Object)null)
			{
				return false;
			}
			__instance.Vehicle = ((Component)__instance).GetComponent<LandVehicle>();
			__instance.Deactivate();
			return false;
		}
	}
}
namespace MultiDelivery.Persistence
{
	public class PersistentDropoffQuestData : Saveable
	{
		[SaveableField("MessageData")]
		public bool HasMessaged;

		public static PersistentDropoffQuestData Instance { get; private set; } = new PersistentDropoffQuestData();


		public PersistentDropoffQuestData()
		{
			Instance = this;
		}
	}
	public class VehicleSave : Saveable
	{
		[CompilerGenerated]
		private sealed class <DeferredSetColor>d__12 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public LandVehicle vehicle;

			public EVehicleColor color;

			public VehicleSave <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0086: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					goto IL_0044;
				case 1:
					<>1__state = -1;
					goto IL_0044;
				case 2:
					{
						<>1__state = -1;
						vehicle.ApplyColor(color);
						return false;
					}
					IL_0044:
					if ((Object)(object)Player.Local == (Object)null || (Object)(object)((Component)Player.Local).gameObject == (Object)null)
					{
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					<>2__current = null;
					<>1__state = 2;
					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();
			}
		}

		[SaveableField("VehicleSaveData")]
		private List<VehicleSaveDto> _dtos = new List<VehicleSaveDto>();

		private static readonly Logger Logger = new Logger("VehicleSave");

		private static Transform _parent;

		public override SaveableLoadOrder LoadOrder => (SaveableLoadOrder)0;

		public static VehicleSave Instance { get; set; } = new VehicleSave();


		public VehicleSave()
		{
			Instance = this;
		}

		public void AddVehicle(LandVehicle vehicle)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			VehicleSaveDto vehicleSaveDto = new VehicleSaveDto();
			Guid gUID = vehicle.GUID;
			vehicleSaveDto.Guid = ((object)(Guid)(ref gUID)).ToString();
			vehicleSaveDto.VehicleType = vehicle.VehicleCode;
			vehicleSaveDto.Color = vehicle.Color.displayedColor;
			VehicleSaveDto item = vehicleSaveDto;
			if (!_dtos.Contains(item))
			{
				_dtos.Add(item);
			}
		}

		protected override void OnLoaded()
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			Melon<MultiDelivery>.Logger.Msg($"VehicleSave.OnLoaded: Loading {_dtos.Count} vehicles");
			if ((Object)(object)_parent == (Object)null)
			{
				GameObject val = GameObject.Find("VehiclePool");
				if ((Object)(object)val == (Object)null)
				{
					val = new GameObject("VehiclePool");
				}
				_parent = val.transform;
			}
			Guid guid = default(Guid);
			for (int i = 0; i < _dtos.Count; i++)
			{
				Logger.Debug($"Loading vehicle {i}: {_dtos[i].Guid}");
				((Guid)(ref guid))..ctor(_dtos[i].Guid);
				LandVehicle val2 = new LandVehicleBuilder().WithVehicleCode(_dtos[i].VehicleType).WithVehicleName($"Additional Delivery Vehicle {i + 1}").WithGuid(guid)
					.WithColor(_dtos[i].Color)
					.WithParent(_parent)
					.Build();
				MelonCoroutines.Start(DeferredSetColor(val2, _dtos[i].Color));
				Logger.Debug($"Built LandVehicle: {val2.vehicleName}, ObjectId: {((NetworkBehaviour)val2).ObjectId}");
				DeliveryVehicle val3 = new DeliveryVehicleBuilder().WithLandVehicle(val2).WithGuid(guid).Build();
				Logger.Debug("Built DeliveryVehicle: " + val3.GUID);
				PoolManager.Instance.AddToPool(val3);
				Logger.Debug($"Added to pool. Pool count now: {PoolManager.Instance.Pool.Count}");
			}
			Logger.Msg($"VehicleSave.OnLoaded complete. Final pool count: {PoolManager.Instance.Pool.Count}");
		}

		[IteratorStateMachine(typeof(<DeferredSetColor>d__12))]
		private IEnumerator DeferredSetColor(LandVehicle vehicle, EVehicleColor color)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DeferredSetColor>d__12(0)
			{
				<>4__this = this,
				vehicle = vehicle,
				color = color
			};
		}
	}
	public record VehicleSaveDto
	{
		public string Guid { get; set; }

		public string VehicleType { get; set; }

		public EVehicleColor Color { get; set; }

		[CompilerGenerated]
		protected virtual bool PrintMembers(StringBuilder builder)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			RuntimeHelpers.EnsureSufficientExecutionStack();
			builder.Append("Guid = ");
			builder.Append((object?)Guid);
			builder.Append(", VehicleType = ");
			builder.Append((object?)VehicleType);
			builder.Append(", Color = ");
			EVehicleColor color = Color;
			builder.Append(((object)(EVehicleColor)(ref color)).ToString());
			return true;
		}
	}
}
namespace MultiDelivery.Network
{
	public class DeliveryNetworkManager
	{
		[CompilerGenerated]
		private sealed class <>c__DisplayClass22_0
		{
			public DeliveryNetworkManager <>4__this;

			public VehicleAddedMessage message;

			internal bool <OnVehicleAdded>b__2()
			{
				return (Object)(object)<>4__this.FindLandVehicleByObjectId(message.ObjectId) != (Object)null;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass23_0
		{
			public DeliveryNetworkManager <>4__this;

			public VehicleCreatedMessage message;

			internal bool <OnVehicleCreated>b__2()
			{
				return (Object)(object)<>4__this.FindLandVehicleByObjectId(message.ObjectId) != (Object)null;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass25_0
		{
			public VehiclePoolSyncResponse message;

			public DeliveryNetworkManager <>4__this;

			public Func<VehiclePoolSyncResponse.VehicleData, bool> <>9__3;

			internal bool <OnPoolSyncResponse>b__2()
			{
				return message.Vehicles.All((VehiclePoolSyncResponse.VehicleData v) => (Object)(object)<>4__this.FindLandVehicleByObjectId(v.ObjectId) != (Object)null);
			}

			internal bool <OnPoolSyncResponse>b__3(VehiclePoolSyncResponse.VehicleData v)
			{
				return (Object)(object)<>4__this.FindLandVehicleByObjectId(v.ObjectId) != (Object)null;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass26_0
		{
			public VehicleAllocationMessage message;

			public DeliveryNetworkManager <>4__this;

			public Func<DeliveryVehicle, bool> <>9__3;

			internal bool <OnVehicleAllocation>b__2()
			{
				return (Object)(object)((IEnumerable<DeliveryVehicle>)PoolManager.Instance.Pool).FirstOrDefault((Func<DeliveryVehicle, bool>)((DeliveryVehicle v) => v.GUID == message.VehicleGuid)) != (Object)null;
			}

			internal bool <OnVehicleAllocation>b__3(DeliveryVehicle v)
			{
				return v.GUID == message.VehicleGuid;
			}

			internal bool <OnVehicleAllocation>b__4(DeliveryVehicle v)
			{
				return v.GUID == message.VehicleGuid;
			}
		}

		[CompilerGenerated]
		private sealed class <ExponentialBackoff>d__34 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Func<bool> predicate;

			public float initialDelay;

			public float finalDelay;

			public float timeout;

			private float <delay>5__1;

			private float <elapsed>5__2;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_004b: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<delay>5__1 = initialDelay;
					<elapsed>5__2 = 0f;
					break;
				case 1:
					<>1__state = -1;
					<elapsed>5__2 += <delay>5__1;
					<delay>5__1 = Mathf.Min(<delay>5__1 * 2f, finalDelay);
					break;
				}
				if (!predicate() && <elapsed>5__2 < timeout)
				{
					<>2__current = (object)new WaitForSeconds(<delay>5__1);
					<>1__state = 1;
					return true;
				}
				return false;
			}

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

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

		private SteamNetworkClient _client;

		private readonly Logger _logger;

		private const string ModDataKey = "MultiDelivery_Version";

		private const string ModVersion = "1.0.0";

		private bool IsInLobby
		{
			get
			{
				SteamNetworkClient client = _client;
				return client != null && client.IsInLobby;
			}
		}

		private bool IsHost
		{
			get
			{
				SteamNetworkClient client = _client;
				return client != null && client.IsHost;
			}
		}

		private bool IsSingleplayer => !IsInLobby;

		internal bool HostOrSingleplayer => IsHost || IsSingleplayer;

		public DeliveryNetworkManager()
		{
			_logger = new Logger("Network", LogLevel.NetworkTrace);
		}

		public bool Initialize()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			try
			{
				NetworkRules val = new NetworkRules
				{
					EnableRelay = true,
					AcceptOnlyFriends = false
				};
				_client = new SteamNetworkClient(val);
				if (!_client.Initialize())
				{
					_logger.Error("Failed to initialize SteamNetworkClient");
					return false;
				}
				RegisterMessageHandlers();
				SubscribeToEvents();
				_logger.Msg("Network manager initialized successfully");
				return true;
			}
			catch (Exception value)
			{
				_client = null;
				_logger.Error($"Failed to initialize network manager: {value}");
				return false;
			}
		}

		private void RegisterMessageHandlers()
		{
			_client.RegisterMessageHandler<VehicleAddedMessage>((Action<VehicleAddedMessage, CSteamID>)OnVehicleAdded);
			_client.RegisterMessageHandler<VehicleCreatedMessage>((Action<VehicleCreatedMessage, CSteamID>)OnVehicleCreated);
			_client.RegisterMessageHandler<VehiclePoolSyncRequest>((Action<VehiclePoolSyncRequest, CSteamID>)OnPoolSyncRequest);
			_client.RegisterMessageHandler<VehiclePoolSyncResponse>((Action<VehiclePoolSyncResponse, CSteamID>)OnPoolSyncResponse);
			_client.RegisterMessageHandler<VehicleAllocationMessage>((Action<VehicleAllocationMessage, CSteamID>)OnVehicleAllocation);
			_client.RegisterMessageHandler<BaseVehicleAllocationMessage>((Action<BaseVehicleAllocationMessage, CSteamID>)OnBaseVehicleAllocation);
		}

		private void SubscribeToEvents()
		{
			_client.OnLobbyCreated += OnLobbyCreated;
			_client.OnLobbyJoined += OnLobbyJoined;
			_client.OnMemberJoined += OnMemberJoined;
			_client.OnLobbyLeft += OnLobbyLeft;
		}

		public void Update()
		{
			SteamNetworkClient client = _client;
			if (client != null)
			{
				client.ProcessIncomingMessages();
			}
		}

		public void Dispose()
		{
			SteamNetworkClient client = _client;
			if (client != null)
			{
				client.Dispose();
			}
		}

		public async void BroadcastVehicleAdded(DeliveryVehicle vehicle)
		{
			if (!IsSingleplayer)
			{
				VehicleAddedMessage message = new VehicleAddedMessage
				{
					ObjectId = ((NetworkBehaviour)vehicle.Vehicle).ObjectId,
					VehicleGuid = vehicle.GUID,
					VehicleName = vehicle.Vehicle.vehicleName,
					VehicleCode = vehicle.Vehicle.VehicleCode,
					VehicleColor = (int)vehicle.Vehicle.Color.displayedColor
				};
				_logger.Msg($"Broadcasting vehicle added: ObjectId={message.ObjectId}, GUID={message.VehicleGuid}");
				await _client.BroadcastMessageAsync((P2PMessage)(object)message);
			}
		}

		public async void BroadcastVehicleCreated(DeliveryVehicle vehicle)
		{
			if (!IsSingleplayer && !IsHost)
			{
				VehicleCreatedMessage message = new VehicleCreatedMessage
				{
					ObjectId = ((NetworkBehaviour)vehicle.Vehicle).ObjectId,
					VehicleGuid = vehicle.GUID
				};
				_logger.Msg($"Broadcasting vehicle created: ObjectId={message.ObjectId}");
				await _client.BroadcastMessageAsync((P2PMessage)(object)message);
			}
		}

		public async void BroadcastVehicleAllocation(string deliveryId, DeliveryVehicle vehicle, bool isAllocated)
		{
			if (!IsSingleplayer)
			{
				VehicleAllocationMessage message = new VehicleAllocationMessage
				{
					DeliveryId = deliveryId,
					VehicleGuid = vehicle.GUID,
					IsAllocated = isAllocated
				};
				_logger.Msg($"Broadcasting allocation: Delivery={deliveryId}, Vehicle={vehicle.GUID}, Allocated={isAllocated}");
				await _client.BroadcastMessageAsync((P2PMessage)(object)message);
			}
		}

		public async void BroadcastBaseVehicleAllocation(string shopName, bool isAllocated)
		{
			if (!IsSingleplayer)
			{
				BaseVehicleAllocationMessage message = new BaseVehicleAllocationMessage
				{
					ShopName = shopName,
					IsAllocated = isAllocated
				};
				_logger.Msg($"Broadcasting base allocation: Shop={shopName}, Allocated={isAllocated}");
				await _client.BroadcastMessageAsync((P2PMessage)(object)message);
			}
		}

		private void OnVehicleAdded(VehicleAddedMessage message, CSteamID cSteamID)
		{
			<>c__DisplayClass22_0 CS$<>8__locals0 = new <>c__DisplayClass22_0();
			CS$<>8__locals0.<>4__this = this;
			CS$<>8__locals0.message = message;
			_logger.Msg($"Received VehicleAdded: ObjectId={CS$<>8__locals0.message.ObjectId}, GUID={CS$<>8__locals0.message.VehicleGuid}");
			MelonCoroutines.Start(ProcessMessage());
			[IteratorStateMachine(typeof(<>c__DisplayClass22_0.<<OnVehicleAdded>g__ProcessMessage|0>d))]
			IEnumerator ProcessMessage()
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <>c__DisplayClass22_0.<<OnVehicleAdded>g__ProcessMessage|0>d(0)
				{
					<>4__this = CS$<>8__locals0
				};
			}
		}

		private void OnVehicleCreated(VehicleCreatedMessage message, CSteamID senderId)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			<>c__DisplayClass23_0 CS$<>8__locals0 = new <>c__DisplayClass23_0();
			CS$<>8__locals0.<>4__this = this;
			CS$<>8__locals0.message = message;
			if (IsHost)
			{
				_logger.Msg($"Received vehicle created message from {senderId}");
				MelonCoroutines.Start(ProcessMessage());
			}
			[IteratorStateMachine(typeof(<>c__DisplayClass23_0.<<OnVehicleCreated>g__ProcessMessage|0>d))]
			IEnumerator ProcessMessage()
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <>c__DisplayClass23_0.<<OnVehicleCreated>g__ProcessMessage|0>d(0)
				{
					<>4__this = CS$<>8__locals0
				};
			}
		}

		private async void OnPoolSyncRequest(VehiclePoolSyncRequest message, CSteamID senderId)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			if (!IsHost)
			{
				return;
			}
			_logger.Msg($"Received pool sync request from {senderId}");
			try
			{
				VehiclePoolSyncResponse response = new VehiclePoolSyncResponse();
				foreach (DeliveryVehicle vehicle in PoolManager.Instance.Pool)
				{
					response.Vehicles.Add(new VehiclePoolSyncResponse.VehicleData
					{
						ObjectId = ((NetworkBehaviour)vehicle.Vehicle).ObjectId,
						Guid = vehicle.GUID,
						Name = vehicle.Vehicle.vehicleName,
						Code = vehicle.Vehicle.VehicleCode,
						Color = (int)vehicle.Vehicle.Color.displayedColor
					});
				}
				_logger.Msg($"Sending pool sync with {response.Vehicles.Count} vehicles");
				await _client.SendMessageToPlayerAsync(senderId, (P2PMessage)(object)response);
			}
			catch (Exception ex)
			{
				_logger.Error($"Failed to send pool sync: {ex}");
			}
		}

		private void OnPoolSyncResponse(VehiclePoolSyncResponse message, CSteamID senderId)
		{
			<>c__DisplayClass25_0 CS$<>8__locals0 = new <>c__DisplayClass25_0();
			CS$<>8__locals0.message = message;
			CS$<>8__locals0.<>4__this = this;
			if (!IsHost)
			{
				_logger.Msg($"Received pool sync response with {CS$<>8__locals0.message.Vehicles.Count} vehicles");
				MelonCoroutines.Start(ProcessMessage());
			}
			[IteratorStateMachine(typeof(<>c__DisplayClass25_0.<<OnPoolSyncResponse>g__ProcessMessage|0>d))]
			IEnumerator ProcessMessage()
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <>c__DisplayClass25_0.<<OnPoolSyncResponse>g__ProcessMessage|0>d(0)
				{
					<>4__this = CS$<>8__locals0
				};
			}
		}

		private void OnVehicleAllocation(VehicleAllocationMessage message, CSteamID senderId)
		{
			<>c__DisplayClass26_0 CS$<>8__locals0 = new <>c__DisplayClass26_0();
			CS$<>8__locals0.message = message;
			CS$<>8__locals0.<>4__this = this;
			_logger.Msg($"Received allocation: Delivery={CS$<>8__locals0.message.DeliveryId}, Vehicle={CS$<>8__locals0.message.VehicleGuid}, Allocated={CS$<>8__locals0.message.IsAllocated}");
			MelonCoroutines.Start(ProcessMessage());
			[IteratorStateMachine(typeof(<>c__DisplayClass26_0.<<OnVehicleAllocation>g__ProcessMessage|0>d))]
			IEnumerator ProcessMessage()
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <>c__DisplayClass26_0.<<OnVehicleAllocation>g__ProcessMessage|0>d(0)
				{
					<>4__this = CS$<>8__locals0
				};
			}
		}

		private void OnBaseVehicleAllocation(BaseVehicleAllocationMessage message, CSteamID senderId)
		{
			_logger.Msg($"Received base allocation: Shop={message.ShopName}, Allocated={message.IsAllocated}");
			try
			{
				PoolManager.Instance.BaseVehicleAllocationsForShop[message.ShopName] = message.IsAllocated;
			}
			catch (Exception value)
			{
				_logger.Error($"Failed to process base allocation: {value}");
			}
		}

		private void OnLobbyCreated(object sender, LobbyCreatedEventArgs e)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			_logger.Msg($"Lobby created: {e.Lobby.LobbyId}");
			_client.SetMyData("MultiDelivery_Version", "1.0.0");
		}

		private void OnLobbyJoined(object sender, LobbyJoinedEventArgs e)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			_logger.Msg($"Joined lobby: {e.Lobby.LobbyId}");
			_client.SetMyData("MultiDelivery_Version", "1.0.0");
			if (!IsHost)
			{
				RequestPoolSync();
			}
		}

		private async void OnMemberJoined(object sender, MemberJoinedEventArgs e)
		{
			if (!IsHost)
			{
				return;
			}
			_logger.Msg("Member joined: " + e.Member.DisplayName);
			await Task.Delay(1000);
			VehiclePoolSyncResponse response = new VehiclePoolSyncResponse();
			foreach (DeliveryVehicle vehicle in PoolManager.Instance.Pool)
			{
				response.Vehicles.Add(new VehiclePoolSyncResponse.VehicleData
				{
					ObjectId = ((NetworkBehaviour)vehicle.Vehicle).ObjectId,
					Guid = vehicle.GUID,
					Name = vehicle.Vehicle.vehicleName,
					Code = vehicle.Vehicle.VehicleCode,
					Color = (int)vehicle.Vehicle.Color.displayedColor
				});
			}
			_logger.Msg($"Sending pool sync to new member ({response.Vehicles.Count} vehicles)");
			await _client.SendMessageToPlayerAsync(e.Member.SteamId, (P2PMessage)(object)response);
		}

		private void OnLobbyLeft(object sender, LobbyLeftEventArgs e)
		{
			_logger.Msg("Left lobby: " + e.Reason);
		}

		private async void RequestPoolSync()
		{
			if (!IsSingleplayer && !IsHost)
			{
				List<MemberInfo> members = _client.GetLobbyMembers();
				MemberInfo host = ((IEnumerable<MemberInfo>)members).FirstOrDefault((Func<MemberInfo, bool>)((MemberInfo m) => m.IsOwner));
				if (host == null)
				{
					_logger.Error("Cannot request pool sync - no host found");
					return;
				}
				VehiclePoolSyncRequest vehiclePoolSyncRequest = new VehiclePoolSyncRequest();
				CSteamID localPlayerId = _client.LocalPlayerId;
				vehiclePoolSyncRequest.RequesterId = ((object)(CSteamID)(ref localPlayerId)).ToString();
				VehiclePoolSyncRequest message = vehiclePoolSyncRequest;
				_logger.Msg("Requesting pool sync from host");
				await _client.SendMessageToPlayerAsync(host.SteamId, (P2PMessage)(object)message);
			}
		}

		private LandVehicle? FindLandVehicleByObjectId(int objectId)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			Scene sceneByName = SceneManager.GetSceneByName("Main");
			if (!((Scene)(ref sceneByName)).isLoaded)
			{
				_logger.Error("Main scene is not loaded");
				return null;
			}
			Il2CppReferenceArray<GameObject> rootGameObjects = ((Scene)(ref sceneByName)).GetRootGameObjects();
			foreach (GameObject item in (Il2CppArrayBase<GameObject>)(object)rootGameObjects)
			{
				Il2CppArrayBase<LandVehicle> componentsInChildren = item.GetComponentsInChildren<LandVehicle>(true);
				foreach (LandVehicle item2 in componentsInChildren)
				{
					if (((NetworkBehaviour)item2).ObjectId == objectId)
					{
						_logger.Msg($"Found LandVehicle: ObjectId={objectId}, Name={item2.vehicleName}");
						return item2;
					}
				}
			}
			_logger.Warning($"LandVehicle with ObjectId {objectId} not found in Main scene");
			return null;
		}

		[IteratorStateMachine(typeof(<ExponentialBackoff>d__34))]
		private static IEnumerator ExponentialBackoff(Func<bool> predicate, float initialDelay, float finalDelay, float timeout)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ExponentialBackoff>d__34(0)
			{
				predicate = predicate,
				initialDelay = initialDelay,
				finalDelay = finalDelay,
				timeout = timeout
			};
		}
	}
	public class VehicleAddedMessage : P2PMessage
	{
		public override string MessageType => "VehicleAdded";

		public int ObjectId { get; set; }

		public string VehicleGuid { get; set; }

		public string VehicleName { get; set; }

		public string VehicleCode { get; set; }

		public int VehicleColor { get; set; }

		public override byte[] Serialize()
		{
			string s = ((P2PMessage)this).CreateJsonBase($"\"ObjectId\":{ObjectId},\"VehicleGuid\":\"{VehicleGuid}\",\"VehicleName\":\"{VehicleName}\",\"VehicleCode\":\"{VehicleCode}\",\"VehicleColor\":{VehicleColor}");
			return Encoding.UTF8.GetBytes(s);
		}

		public override void Deserialize(byte[] data)
		{
			string @string = Encoding.UTF8.GetString(data);
			((P2PMessage)this).ParseJsonBase(@string);
			ObjectId = int.Parse(((P2PMessage)this).ExtractJsonValue(@string, "ObjectId"));
			VehicleGuid = ((P2PMessage)this).ExtractJsonValue(@string, "VehicleGuid");
			VehicleName = ((P2PMessage)this).ExtractJsonValue(@string, "VehicleName");
			VehicleCode = ((P2PMessage)this).ExtractJsonValue(@string, "VehicleCode");
			VehicleColor = int.Parse(((P2PMessage)this).ExtractJsonValue(@string, "VehicleColor"));
		}
	}
	public class VehicleCreatedMessage : P2PMessage
	{
		public override string MessageType => "VehicleCreated";

		public int ObjectId { get; set; }

		public string VehicleGuid { get; set; }

		public override byte[] Serialize()
		{
			string s = ((P2PMessage)this).CreateJsonBase($"\"ObjectId\":{ObjectId},\"VehicleGuid\":\"{VehicleGuid}\"");
			return Encoding.UTF8.GetBytes(s);
		}

		public override void Deserialize(byte[] data)
		{
			string @string = Encoding.UTF8.GetString(data);
			((P2PMessage)this).ParseJsonBase(@string);
			ObjectId = int.Parse(((P2PMessage)this).ExtractJsonValue(@string, "ObjectId"));
			VehicleGuid = ((P2PMessage)this).ExtractJsonValue(@string, "VehicleGuid");
		}
	}
	public class VehiclePoolSyncRequest : P2PMessage
	{
		public override string MessageType => "VehiclePoolSyncRequest";

		public string RequesterId { get; set; }

		public override byte[] Serialize()
		{
			string s = ((P2PMessage)this).CreateJsonBase("\"RequesterId\":\"" + RequesterId + "\"");
			return Encoding.UTF8.GetBytes(s);
		}

		public override void Deserialize(byte[] data)
		{
			string @string = Encoding.UTF8.GetString(data);
			((P2PMessage)this).ParseJsonBase(@string);
			RequesterId = ((P2PMessage)this).ExtractJsonValue(@string, "RequesterId");
		}
	}
	public class VehiclePoolSyncResponse : P2PMessage
	{
		[Serializable]
		public class VehicleData
		{
			public int ObjectId { get; set; }

			public string Guid { get; set; }

			public string Name { get; set; }

			public string Code { get; set; }

			public int Color { get; set; }
		}

		public override string MessageType => "VehiclePoolSyncResponse";

		public List<VehicleData> Vehicles { get; set; } = new List<VehicleData>();


		public override byte[] Serialize()
		{
			string text = string.Join(",", Vehicles.Select((VehicleData v) => $"{{\"ObjectId\":{v.ObjectId},\"Guid\":\"{v.Guid}\",\"Name\":\"{v.Name}\",\"Code\":\"{v.Code}\",\"Color\":{v.Color}}}"));
			string s = ((P2PMessage)this).CreateJsonBase("\"Vehicles\":[" + text + "]");
			return Encoding.UTF8.GetBytes(s);
		}

		public override void Deserialize(byte[] data)
		{
			string @string = Encoding.UTF8.GetString(data);
			((P2PMessage)this).ParseJsonBase(@string);
			int num = @string.IndexOf("\"Vehicles\":[", StringComparison.Ordinal) + 12;
			int num2 = @string.IndexOf("]", num, StringComparison.Ordinal);
			string text = @string.Substring(num, num2 - num);
			Vehicles.Clear();
			if (string.IsNullOrWhiteSpace(text))
			{
				return;
			}
			string[] array = text.Split(new string[1] { "}," }, StringSplitOptions.None);
			string[] array2 = array;
			foreach (string text2 in array2)
			{
				string text3 = text2.TrimStart('{').TrimEnd('}') + "}";
				if (text3.Contains("ObjectId"))
				{
					Vehicles.Add(new VehicleData
					{
						ObjectId = int.Parse(((P2PMessage)this).ExtractJsonValue(text3, "ObjectId")),
						Guid = ((P2PMessage)this).ExtractJsonValue(text3, "Guid"),
						Name = ((P2PMessage)this).ExtractJsonValue(text3, "Name"),
						Code = ((P2PMessage)this).ExtractJsonValue(text3, "Code"),
						Color = int.Parse(((P2PMessage)this).ExtractJsonValue(text3, "Color"))
					});
				}
			}
		}
	}
	public class VehicleAllocationMessage : P2PMessage
	{
		public override string MessageType => "VehicleAllocation";

		public string DeliveryId { get; set; }

		public string VehicleGuid { get; set; }

		public bool IsAllocated { get; set; }

		public override byte[] Serialize()
		{
			string s = ((P2PMessage)this).CreateJsonBase($"\"DeliveryId\":\"{DeliveryId}\",\"VehicleGuid\":\"{VehicleGuid}\",\"IsAllocated\":{IsAllocated.ToString().ToLower()}");
			return Encoding.UTF8.GetBytes(s);
		}

		public override void Deserialize(byte[] data)
		{
			string @string = Encoding.UTF8.GetString(data);
			((P2PMessage)this).ParseJsonBase(@string);
			DeliveryId = ((P2PMessage)this).ExtractJsonValue(@string, "DeliveryId");
			VehicleGuid = ((P2PMessage)this).ExtractJsonValue(@string, "VehicleGuid");
			IsAllocated = bool.Parse(((P2PMessage)this).ExtractJsonValue(@string, "IsAllocated"));
		}
	}
	public class BaseVehicleAllocationMessage : P2PMessage
	{
		public override string MessageType => "BaseVehicleAllocation";

		public string ShopName { get; set; }

		public bool IsAllocated { get; set; }

		public override byte[] Serialize()
		{
			string s = ((P2PMessage)this).CreateJsonBase("\"ShopName\":\"" + ShopName + "\",\"IsAllocated\":" + IsAllocated.ToString().ToLower());
			return Encoding.UTF8.GetBytes(s);
		}

		public override void Deserialize(byte[] data)
		{
			string @string = Encoding.UTF8.GetString(data);
			((P2PMessage)this).ParseJsonBase(@string);
			ShopName = ((P2PMessage)this).ExtractJsonValue(@string, "ShopName");
			IsAllocated = bool.Parse(((P2PMessage)this).ExtractJsonValue(@string, "IsAllocated"));
		}
	}
	public static class NetworkConvenienceMethods
	{
		private static DeliveryNetworkManager? _networkManager;

		public static bool HostOrSingleplayer => _networkManager?.HostOrSingleplayer ?? true;

		public static void InitializeNetworking(DeliveryNetworkManager networkManager)
		{
			_networkManager = networkManager;
		}

		public static void NotifyVehicleAdded(DeliveryVehicle vehicle)
		{
			_networkManager?.BroadcastVehicleAdded(vehicle);
		}

		public static void NotifyVehicleCreated(DeliveryVehicle vehicle)
		{
			_networkManager?.BroadcastVehicleCreated(vehicle);
		}

		public static void NotifyAllocation(string deliveryId, DeliveryVehicle vehicle, bool isAllocated)
		{
			_networkManager?.BroadcastVehicleAllocation(deliveryId, vehicle, isAllocated);
		}

		public static void NotifyBaseAllocation(string shopName, bool isAllocated)
		{
			_networkManager?.BroadcastBaseVehicleAllocation(shopName, isAllocated);
		}
	}
}
namespace MultiDelivery.Helpers
{
	public static class MelonLoggerExtensions
	{
		public static void Debug(this Instance logger, string message, bool stacktrace = true)
		{
			MelonDebug.Msg(stacktrace ? ("[" + GetCallerInfo() + "] " + message) : message);
		}

		private static string GetCallerInfo()
		{
			StackTrace stackTrace = new StackTrace();
			for (int i = 2; i < stackTrace.FrameCount; i++)
			{
				StackFrame frame = stackTrace.GetFrame(i);
				MethodBase method = frame.GetMethod();
				if (!(method?.DeclaringType == null))
				{
					return method.DeclaringType.FullName + "." + method.Name;
				}
			}
			return "unknown";
		}
	}
	public static class Il2CppListExtensions
	{
		public static IEnumerable<T> AsEnumerable<T>(this List<T> list)
		{
			return list ?? new List<T>();
		}

		public static object ToNativeList<T>(this List<T> source)
		{
			return source.ToIl2CppList();
		}

		public static List<T> ToIl2CppList<T>(this IEnumerable<T> source)
		{
			List<T> val = new List<T>();
			foreach (T item in source)
			{
				val.Add(item);
			}
			return val;
		}

		public static List<T> ConvertToList<T>(List<T> il2CppList)
		{
			List<T> list = new List<T>();
			T[] collection = Il2CppArrayBase<T>.op_Implicit(il2CppList.ToArray());
			list.AddRange(collection);
			return list;
		}

		public static IEnumerable<T> AsEnumerable<T>(this List<T> list)
		{
			IEnumerable<T> result;
			if (list != null)
			{
				result = ((IEnumerable<T>)list._items).Take(list._size);
			}
			else
			{
				IEnumerable<T> enumerable = Array.Empty<T>();
				result = enumerable;
			}
			return result;
		}

		public static object ToNativeList<T>(this List<T> source)
		{
			return source;
		}
	}
	public static class Utils
	{
		[CompilerGenerated]
		private sealed class <WaitForCondition>d__6 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Func<bool> condition;

			public float timeout;

			public Action onTimeout;

			public Action onFinish;

			private float <startTime>5__1;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<startTime>5__1 = Time.time;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (!condition())
				{
					if (!float.IsNaN(timeout) && Time.time - <startTime>5__1 > timeout)
					{
						onTimeout?.Invoke();
						return false;
					}
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				onFinish?.Invoke();
				return false;
			}

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

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

		[CompilerGenerated]
		private sealed class <WaitForNetwork>d__5 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public IEnumerator routine;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (!InstanceFinder.IsServer && !InstanceFinder.IsClient)
				{
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				MelonCoroutines.Start(routine);
				return false;
			}

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

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

		[CompilerGenerated]
		private sealed class <WaitForPlayer>d__4 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public IEnumerator routine;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if ((Object)(object)Player.Local == (Object)null || (Object)(object)((Component)Player.Local).gameObject == (Object)null)
				{
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				MelonCoroutines.Start(routine);
				return false;
			}

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

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

		private static readonly Instance Logger = new Instance("MultiDelivery-Utils");

		public static T? FindObjectByName<T>(string objectName) where T : Object
		{
			try
			{
				foreach (T item in Resources.FindObjectsOfTypeAll<T>())
				{
					if (((Object)item).name != objectName)
					{
						continue;
					}
					Logger.Debug($"Found {typeof(T).Name} '{objectName}' directly in loaded objects");
					return item;
				}
				return default(T);
			}
			catch (Exception ex)
			{
				Logger.Error($"Error finding {typeof(T).Name} '{objectName}': {ex.Message}");
				return default(T);
			}
		}

		public static List<T> GetAllComponentsInChildrenRecursive<T>(GameObject obj) where T : Component
		{
			List<T> list = new List<T>();
			if ((Object)(object)obj == (Object)null)
			{
				return list;
			}
			T[] array = Il2CppArrayBase<T>.op_Implicit(obj.GetComponents<T>());
			if (array.Length != 0)
			{
				list.AddRange(array);
			}
			for (int i = 0; i < obj.transform.childCount; i++)
			{
				Transform child = obj.transform.GetChild(i);
				list.AddRange(GetAllComponentsInChildrenRecursive<T>(((Component)child).gameObject));
			}
			return list;
		}

		public static bool Is<T>(object obj, out T? result) where T : Object
		{
			Object val = (Object)((obj is Object) ? obj : null);
			if (val != null)
			{
				Type val2 = Il2CppType.Of<T>();
				Type il2CppType = val.GetIl2CppType();
				if (val2.IsAssignableFrom(il2CppType))
				{
					result = ((Il2CppObjectBase)val).TryCast<T>();
					return result != null;
				}
			}
			result = default(T);
			return false;
		}

		[IteratorStateMachine(typeof(<WaitForPlayer>d__4))]
		public static IEnumerator WaitForPlayer(IEnumerator routine)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WaitForPlayer>d__4(0)
			{
				routine = routine
			};
		}

		[IteratorStateMachine(typeof(<WaitForNetwork>d__5))]
		public static IEnumerator WaitForNetwork(IEnumerator routine)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WaitForNetwork>d__5(0)
			{
				routine = routine
			};
		}

		[IteratorStateMachine(typeof(<WaitForCondition>d__6))]
		public static IEnumerator WaitForCondition(Func<bool> condition, float timeout = float.NaN, Action? onTimeout = null, Action? onFinish = null)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WaitForCondition>d__6(0)
			{
				condition = condition,
				timeout = timeout,
				onTimeout = onTimeout,
				onFinish = onFinish
			};
		}

		public static string GetHierarchyPath(this Transform transform)
		{
			if ((Object)(object)transform == (Object)null)
			{
				return "null";
			}
			string text = ((Object)transform).name;
			Transform parent = transform.parent;
			while ((Object)(object)parent != (Object)null)
			{
				text = ((Object)parent).name + "/" + text;
				parent = parent.parent;
			}
			return text;
		}

		public static T GetOrAddComponent<T>(this GameObject gameObject) where T : Component
		{
			T component = gameObject.GetComponent<T>();
			if ((Object)(object)component != (Object)null)
			{
				return component;
			}
			component = gameObject.AddComponent<T>();
			Logger.Debug("Added component " + typeof(T).Name + " to GameObject " + ((Object)gameObject).name);
			return component;
		}

		public static Material? DrawDebugVisuals(this GameObject gameObject, Color? color = null)
		{
			//IL_0040: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Expected O, but got Unknown
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			Renderer component = gameObject.GetComponent<Renderer>();
			if ((Object)(object)component == (Object)null)
			{
				Logger.Error("GameObject " + ((Object)gameObject).name + " has no Renderer component");
				return null;
			}
			Color valueOrDefault = color.GetValueOrDefault();
			if (!color.HasValue)
			{
				((Color)(ref valueOrDefault))..ctor(1f, 0f, 1f, 0.5f);
				color = valueOrDefault;
			}
			Shader val = Shader.Find("Universal Render Pipeline/Lit");
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Material val2 = new Material(val);
			if (val2.HasProperty("_Surface"))
			{
				val2.SetFloat("_Surface", 1f);
			}
			Color value = color.Value;
			if (value.a <= 0f)
			{
				value.a = 0.2f;
			}
			if (val2.HasProperty("_BaseColor"))
			{
				val2.SetColor("_BaseColor", value);
			}
			if (val2.HasProperty("_EmissionColor"))
			{
				val2.EnableKeyword("_EMISSION");
				val2.SetColor("_EmissionColor", new Color(value.r, value.g, value.b) * 1.5f);
			}
			val2.SetInt("_ZWrite", 0);
			val2.renderQueue = 3000;
			Material material = component.material;
			component.material = val2;
			return material;
		}

		public static string Capitalize(this string str)
		{
			if (str.Length < 1)
			{
				throw new ArgumentOutOfRangeException("str");
			}
			return char.ToUpper(str[0]) + str.Substring(1, str.Length - 1);
		}
	}
}
namespace MultiDelivery.Builders
{
	public class DeliveryVehicleBuilder
	{
		private Guid _guid;

		private LandVehicle _landVehicle;

		public DeliveryVehicleBuilder WithGuid(Guid guid)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			_guid = guid;
			return this;
		}

		public DeliveryVehicleBuilder WithGuid(string guid)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			_guid = new Guid(guid);
			return this;
		}

		public DeliveryVehicleBuilder WithLandVehicle(LandVehicle landVehicle)
		{
			_landVehicle = landVehicle;
			return this;
		}

		public DeliveryVehicleBuilder WithLandVehicle(GameObject landVehicle)
		{
			_landVehicle = landVehicle.GetComponent<LandVehicle>();
			return this;
		}

		public DeliveryVehicle Build()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			DeliveryVehicle val = ((Component)_landVehicle).gameObject.AddComponent<DeliveryVehicle>();
			val.GUID = ((object)(Guid)(ref _guid)).ToString();
			_landVehicle.SetGUID(_guid);
			return val;
		}
	}
	public class LandVehicleBuilder
	{
		private string _vehicleName = "CustomVehicle";

		private string _vehicleCode = "veeper";

		private EVehicleColor _color = (EVehicleColor)16;

		private Guid _guid = GUIDManager.GenerateUniqueGUID();

		private static Transform? _parent;

		public LandVehicleBuilder WithVehicleName(string vehicleName)
		{
			_vehicleName = vehicleName;
			return this;
		}

		public LandVehicleBuilder WithVehicleCode(string vehicleCode)
		{
			_vehicleCode = vehicleCode;
			return this;
		}

		public LandVehicleBuilder WithColor(EVehicleColor color)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			_color = color;
			return this;
		}

		public LandVehicleBuilder WithGuid(Guid guid)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			_guid = guid;
			return this;
		}

		public LandVehicleBuilder WithGuid(string guid)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			_guid = new Guid(guid);
			return this;
		}

		public LandVehicleBuilder WithParent(Transform parent)
		{
			_parent = parent;
			return this;
		}

		public LandVehicle Build()
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_parent == (Object)null)
			{
				GameObject val = GameObject.Find("VehiclePool");
				if ((Object)(object)val == (Object)null)
				{
					val = new GameObject("VehiclePool");
				}
				_parent = val.transform;
			}
			Vector3 position = default(Vector3);
			((Vector3)(ref position))..ctor(0f, -100f, 0f);
			Quaternion identity = Quaternion.identity;
			if (!InstanceFinder.IsServer)
			{
				throw new ArgumentException("LandVehicleBuilder can only be used on the server");
			}
			LandVehicle vehiclePrefab = NetworkSingleton<VehicleManager>.Instance.GetVehiclePrefab(_vehicleCode);
			if ((Object)(object)vehiclePrefab == (Object)null)
			{
				throw new ArgumentException("Vehicle prefab with code '" + _vehicleCode + "' not found.");
			}
			GameObject val2 = Object.Instantiate<GameObject>(((Component)vehiclePrefab).gameObject, _parent, true);
			LandVehicle component = val2.GetComponent<LandVehicle>();
			component.IsPlayerOwned = false;
			component.SetVisible(false);
			component.IsPhysicallySimulated = false;
			((Component)component).transform.position = position;
			((Component)component).transform.rotation = identity;
			component.SetGUID(_guid);
			((Object)component).name = _vehicleName;
			((Object)((Component)component).gameObject).name = _vehicleName;
			component.vehicleName = _vehicleName;
			component.SetIsPlayerOwned((NetworkConnection)null, false);
			component.Rb.isKinematic = false;
			((NetworkBehaviour)component).Owner.ClientId = -1;
			component.ApplyColor(_color);
			NetworkSingleton<VehicleManager>.Instance.AllVehicles.Add(component);
			((NetworkBehaviour)NetworkSingleton<VehicleManager>.Instance).NetworkObject.Spawn(((Component)component).gameObject, (NetworkConnection)null, default(Scene));
			return component;
		}
	}
}

MultiDelivery-Mono.dll

Decompiled 3 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
using FishNet;
using FishNet.Connection;
using FishNet.Object;
using HarmonyLib;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using MultiDelivery;
using MultiDelivery.Builders;
using MultiDelivery.Helpers;
using MultiDelivery.Network;
using MultiDelivery.Persistence;
using MultiDelivery.Pool;
using MultiDelivery.Quest;
using S1API.Dialogues;
using S1API.Entities;
using S1API.Entities.Dialogue;
using S1API.Entities.NPCs.Suburbia;
using S1API.Internal.Abstraction;
using S1API.Leveling;
using S1API.Messaging;
using S1API.Money;
using S1API.Quests;
using S1API.Quests.Constants;
using S1API.Saveables;
using S1API.Utils;
using ScheduleOne;
using ScheduleOne.Core.Items.Framework;
using ScheduleOne.Delivery;
using ScheduleOne.DevUtilities;
using ScheduleOne.Graffiti;
using ScheduleOne.ItemFramework;
using ScheduleOne.Map;
using ScheduleOne.Money;
using ScheduleOne.NPCs.CharacterClasses;
using ScheduleOne.Persistence.Datas;
using ScheduleOne.Persistence.Loaders;
using ScheduleOne.PlayerScripts;
using ScheduleOne.UI.Phone.Delivery;
using ScheduleOne.UI.Shop;
using ScheduleOne.Vehicles;
using ScheduleOne.Vehicles.Modification;
using ScheduleOne.Weather;
using SteamNetworkLib;
using SteamNetworkLib.Core;
using SteamNetworkLib.Events;
using SteamNetworkLib.Models;
using Steamworks;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(global::MultiDelivery.MultiDelivery), "MultiDelivery", "1.0.1", "k073l", null)]
[assembly: MelonColor(1, 0, 255, 0)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: MelonPlatformDomain(/*Could not decode attribute arguments.*/)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("MultiDelivery-Mono")]
[assembly: AssemblyConfiguration("Mono")]
[assembly: AssemblyDescription("Add vehicles, order multiple deliveries from the same place!")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+9f266827b45c3676261f34c577e88b8249083816")]
[assembly: AssemblyProduct("MultiDelivery-Mono")]
[assembly: AssemblyTitle("MultiDelivery-Mono")]
[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.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 MultiDelivery
{
	public class Logger
	{
		[CompilerGenerated]
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private string <categoryName>P;

		[CompilerGenerated]
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private LogLevel? <forceLevel>P;

		public Logger(string categoryName, LogLevel? forceLevel = null)
		{
			<categoryName>P = categoryName;
			<forceLevel>P = forceLevel;
			base..ctor();
		}

		public void NetworkTrace(params object[] args)
		{
			Log(LogLevel.NetworkTrace, args);
		}

		public void Debug(params object[] args)
		{
			Log(LogLevel.Debug, args);
		}

		public void Info(params object[] args)
		{
			Log(LogLevel.Info, args);
		}

		public void Msg(params object[] args)
		{
			Log(LogLevel.Info, args);
		}

		public void Warn(params object[] args)
		{
			Log(LogLevel.Warn, args);
		}

		public void Warning(params object[] args)
		{
			Log(LogLevel.Warn, args);
		}

		public void Error(params object[] args)
		{
			Log(LogLevel.Error, args);
		}

		private void Log(LogLevel level, params object[] args)
		{
			LogLevel? logLevel = <forceLevel>P;
			if (logLevel.HasValue)
			{
				LogLevel valueOrDefault = logLevel.GetValueOrDefault();
				if (level < LogLevel.Error)
				{
					level = valueOrDefault;
				}
			}
			if (args.Length == 0)
			{
				return;
			}
			string text;
			if (args.Length == 1)
			{
				text = args[0]?.ToString() ?? "";
			}
			else
			{
				string format = args[0]?.ToString() ?? "";
				text = string.Format(format, args.Skip(1).ToArray());
			}
			string text2 = (string.IsNullOrWhiteSpace(<categoryName>P) ? "MultiDelivery" : ("MultiDelivery." + <categoryName>P));
			string text3 = "[" + text2 + "] " + text;
			switch (level)
			{
			case LogLevel.NetworkTrace:
				if (MultiDelivery.NetworkLogging.Value)
				{
					Melon<MultiDelivery>.Logger.Msg(text3);
				}
				break;
			case LogLevel.Debug:
				MelonDebug.Msg(text3);
				break;
			case LogLevel.Info:
				Melon<MultiDelivery>.Logger.Msg(text3);
				break;
			case LogLevel.Warn:
				Melon<MultiDelivery>.Logger.Warning(text3);
				break;
			case LogLevel.Error:
				Melon<MultiDelivery>.Logger.Error(text3);
				break;
			}
		}
	}
	public enum LogLevel
	{
		NetworkTrace,
		Debug,
		Info,
		Warn,
		Error
	}
	public static class BuildInfo
	{
		public const string Name = "MultiDelivery";

		public const string Description = "Add vehicles, order multiple deliveries from the same place!";

		public const string Author = "k073l";

		public const string Version = "1.0.1";
	}
	public class MultiDelivery : MelonMod
	{
		[CompilerGenerated]
		private sealed class <InitializeNetworkManager>d__12 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public MultiDelivery <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if (!SteamAPI.Init())
					{
						return false;
					}
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>4__this._networkManager = new DeliveryNetworkManager();
					if (<>4__this._networkManager.Initialize())
					{
						Logger.Msg("Network manager initialized");
						NetworkConvenienceMethods.InitializeNetworking(<>4__this._networkManager);
					}
					else
					{
						<>4__this._networkManager = null;
						Logger.Warning("Network manager initialization failed - running in offline mode");
					}
					return false;
				}
			}

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

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

		[CompilerGenerated]
		private sealed class <WireOnXpChangedDelayed>d__16 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public MultiDelivery <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				//IL_004a: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitUntil((Func<bool>)(() => LevelManager.Exists));
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (PersistentDropoffQuestData.Instance.HasMessaged)
					{
						DropoffQuestDialogue.Register();
						return false;
					}
					Logger.Debug("Wiring on xp changed");
					LevelManager.OnXPChanged += <>4__this.SendMessageIfRequiredRank;
					return false;
				}
			}

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

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

		internal const string RequestedVehicleCode = "veeper";

		private static FullRank RequiredRank = new FullRank((Rank)5, 1);

		private static Sprite _questIconSprite;

		private static readonly Logger Logger = new Logger("");

		private DeliveryNetworkManager? _networkManager;

		private bool _networkManagerFailed;

		internal static MelonPreferences_Category Category = MelonPreferences.CreateCategory("MultiDeliverySettings", "MultiDelivery's Settings");

		internal static MelonPreferences_Entry<bool> NetworkLogging = Category.CreateEntry<bool>("NetworkDebugLogs", false, "Enable Network Logs", "Display networking-related debug logs in MelonLoader console/log file (may be verbose)", false, false, (ValueValidator)null, (string)null);

		public static Sprite QuestIconSprite => GetIcon(ref _questIconSprite, "MultiDelivery.assets.quest_icon.png");

		public override void OnInitializeMelon()
		{
			Logger.Msg("MultiDelivery initialized");
			MelonCoroutines.Start(InitializeNetworkManager());
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			if (sceneName == "Main")
			{
				Player.LocalPlayerSpawned += WirePlayerEvent;
			}
			else if (!(sceneName != "Menu"))
			{
				PoolManager.Instance.Pool.Clear();
				PoolManager.Instance.Allocations.Clear();
				PoolManager.Instance.BaseVehicleAllocationsForShop.Clear();
				Player.LocalPlayerSpawned -= WirePlayerEvent;
				LevelManager.OnXPChanged -= SendMessageIfRequiredRank;
			}
		}

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

		public override void OnUpdate()
		{
			if (_networkManagerFailed || _networkManager == null)
			{
				return;
			}
			try
			{
				_networkManager.Update();
			}
			catch (Exception ex)
			{
				MelonLogger.Error("Network manager update failed: " + ex.Message + "\n\nYou can ignore this error if you plan on playing singleplayer only and don't want to install SteamNetworkLib");
				_networkManagerFailed = true;
			}
		}

		public override void OnDeinitializeMelon()
		{
			_networkManager?.Dispose();
			Logger.Msg("MultiDelivery deinitialized");
		}

		private void WirePlayerEvent(Player _)
		{
			Logger.Debug("Player loaded event called");
			MelonCoroutines.Start(WireOnXpChangedDelayed());
		}

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

		private void SendMessageIfRequiredRank(FullRank _, FullRank current)
		{
			//IL_0013: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			Logger.Debug($"Current rank {current}, required: {RequiredRank}");
			if (PersistentDropoffQuestData.Instance.HasMessaged)
			{
				MelonDebug.Msg("Xp changed wired, but already messaged - registering dialogue now.");
				DropoffQuestDialogue.Register();
			}
			else
			{
				if (current < RequiredRank)
				{
					return;
				}
				NPC val = NPC.Get<JeremyWilkinson>();
				if (val != null)
				{
					if (NetworkConvenienceMethods.HostOrSingleplayer)
					{
						val.SendTextMessage("Your properties are getting busy. Want to handle more than one delivery at a time? I've got an idea. Stop by the dealership.", (Response[])null, 1f, true);
					}
					PersistentDropoffQuestData.Instance.HasMessaged = true;
					DropoffQuestDialogue.Register();
					LevelManager.OnXPChanged -= SendMessageIfRequiredRank;
				}
			}
		}

		private static Sprite LoadEmbeddedPNG(string resourceName)
		{
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			using Stream stream = executingAssembly.GetManifestResourceStream(resourceName);
			if (stream == null)
			{
				return null;
			}
			byte[] array = new byte[stream.Length];
			stream.Read(array, 0, array.Length);
			Sprite val = ImageUtils.LoadImageRaw(array);
			if ((Object)(object)val != (Object)null)
			{
				((Object)val).name = resourceName;
			}
			return val;
		}

		private static Sprite GetIcon(ref Sprite spriteField, string resourceName)
		{
			if ((Object)(object)spriteField == (Object)null)
			{
				spriteField = LoadEmbeddedPNG(resourceName);
			}
			return spriteField;
		}
	}
}
namespace MultiDelivery.Quest
{
	public class DropoffQuest : Quest
	{
		[CompilerGenerated]
		private sealed class <NotifyCompletion>d__21 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public DropoffQuest <>4__this;

			private NPC <npc>5__1;

			private int <i>5__2;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				//IL_005c: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<i>5__2 = 0;
					break;
				case 1:
				{
					<>1__state = -1;
					int num = <i>5__2 + 1;
					<i>5__2 = num;
					break;
				}
				}
				if (<i>5__2 < 3 && PoolManager.Instance.Pool.Count <= <>4__this._startingCapacity)
				{
					<>2__current = (object)new WaitForSeconds(3f);
					<>1__state = 1;
					return true;
				}
				<npc>5__1 = NPC.Get<JeremyWilkinson>();
				if (<npc>5__1 != null)
				{
					if (PoolManager.Instance.Pool.Count <= <>4__this._startingCapacity)
					{
						<npc>5__1.SendTextMessage("Something went wrong... Vehicle got in a car crash :(", (Response[])null, 1f, true);
					}
					else
					{
						<npc>5__1.SendTextMessage($"Vehicle added, you now can order {PoolManager.Instance.Pool.Count} more " + "deliver" + ((PoolManager.Instance.Pool.Count > 1) ? "y" : "ies") + " from stores.", (Response[])null, 1f, true);
						<npc>5__1.SendTextMessage("If you want to add more, you know where to find me.", (Response[])null, 1f, true);
					}
				}
				return false;
			}

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

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

		internal const string Name = "Expanding the Fleet";

		private bool _vehicleAdded;

		private QuestEntry _addVehicleEntry;

		private int _startingCapacity;

		private static VehicleDropoffZone dropoffZone;

		private static Vector3 _dropoffZonePosition;

		private static readonly Logger Logger = new Logger("DropoffQuest");

		protected override string Title => "Expanding the Fleet";

		protected override string Description => "Bring a delivery vehicle to the dropoff zone to expand your delivery capacity";

		protected override bool AutoBegin => false;

		protected override Sprite QuestIcon => MultiDelivery.QuestIconSprite;

		internal QuestState State => ((Quest)this).QuestState;

		protected override void OnCreated()
		{
			//IL_0072: 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)
			//IL_0074: 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)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			((Registerable)this).OnCreated();
			_startingCapacity = PoolManager.Instance.Pool.Count;
			Logger.Debug($"Starting Quest with {_startingCapacity} capacity");
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(5.1f, 4.2f, 82.58f);
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(0.55f, 4.2f, 76.56f);
			_dropoffZonePosition = (val + val2) / 2f;
			if ((Object)(object)dropoffZone != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)dropoffZone).gameObject);
			}
			dropoffZone = VehicleDropoffZoneFactory.CreateZone(val, val2, 5f, (Color?)new Color(0f, 1f, 0f, 0.4f), showVisuals: true, this);
			Logger.Debug("Dropoff zone created. Spawning " + ((Object)dropoffZone).name);
			((Quest)this).OnComplete += Completed;
			Logger.Debug("Wired completion event");
			UpdateQuestEntries();
		}

		private void UpdateQuestEntries()
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			base.QuestEntries.Clear();
			if (!_vehicleAdded)
			{
				Logger.Debug("Adding add vehicle entry");
				_addVehicleEntry = ((Quest)this).AddEntry("Purchase a " + "veeper".Capitalize() + " and drive it into the green dropoff zone (top floor of the parking garage, next to storage unit)", (Vector3?)_dropoffZonePosition);
				_addVehicleEntry.Begin();
			}
			Logger.Debug("Entries added!");
		}

		public void MarkAddVehicleEntryComplete()
		{
			Logger.Debug("Marked add vehicle entry as completed");
			_addVehicleEntry.Complete();
		}

		private void Completed()
		{
			Logger.Msg("Delivery vehicle dropoff quest completed!");
			MelonCoroutines.Start(NotifyCompletion());
		}

		[IteratorStateMachine(typeof(<NotifyCompletion>d__21))]
		private IEnumerator NotifyCompletion()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <NotifyCompletion>d__21(0)
			{
				<>4__this = this
			};
		}
	}
	public class DropoffQuestDialogue
	{
		private static readonly Logger Logger = new Logger("DropoffQuestDialogue");

		private const string ContainerName = "DeliveryExpansion";

		public static void Register()
		{
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Expected O, but got Unknown
			NPC jeremy = NPC.Get<JeremyWilkinson>();
			if (jeremy == null)
			{
				Logger.Warning("Jeremy Wilkinson not found");
				return;
			}
			jeremy.Dialogue.BuildAndRegisterContainer("DeliveryExpansion", (Action<DialogueContainerBuilder>)delegate(DialogueContainerBuilder c)
			{
				c.AddNode("OFFER_FIRST", "Yeah! I can help with that. If you bring a " + "veeper".Capitalize() + " to the dropoff zone, I'll add it to the fleet. This will let you handle multiple deliveries at once. Want to give it a shot?", (Action<ChoiceList>)delegate(ChoiceList ch)
				{
					ch.Add("BUY_NOW", "Sure! Can I buy one from you right now?", "CHECK_FUNDS");
					ch.Add("ACCEPT", "I already have one, let's do it!", "ACCEPTED");
					ch.Add("DECLINE", "Maybe later.", "DECLINED");
				});
				c.AddNode("OFFER_REPEAT", "Want to expand your fleet even more? Just bring another vehicle to the dropoff zone and I'll add it for you.", (Action<ChoiceList>)delegate(ChoiceList ch)
				{
					ch.Add("BUY_NOW", "Yeah, can I buy another one from you?", "CHECK_FUNDS");
					ch.Add("ACCEPT", "I've got one ready!", "ACCEPTED");
					ch.Add("DECLINE", "Not right now.", "DECLINED");
				});
				c.AddNode("CHECK_FUNDS", "A " + "veeper".Capitalize() + " runs <color=#19BEF0>(" + MoneyManager.FormatAmount(GetVehiclePrice(), false, false) + ")</color>. Want to pick one up?", (Action<ChoiceList>)delegate(ChoiceList ch)
				{
					ch.Add("PURCHASE", "I'll take it. <color=#19BEF0>(" + MoneyManager.FormatAmount(GetVehiclePrice(), false, false) + ")</color>", "PURCHASE_COMPLETE");
					ch.Add("NEVERMIND", "Let me think about it.", "DECLINED");
				});
				c.AddNode("PURCHASE_COMPLETE", "All yours. You can customize it if you want. Now just drive it to the dropoff zone - I've marked it on your map.", (Action<ChoiceList>)null);
				c.AddNode("NOT_ENOUGH", "You don't have enough money to buy it. Come back later.", (Action<ChoiceList>)null);
				c.AddNode("IN_PROGRESS", "You already have an active delivery expansion going! Just bring the vehicle to the dropoff zone. Top floor of the parking garage, next to the storage units - check your map if you forgot where it is.", (Action<ChoiceList>)null);
				c.AddNode("ACCEPTED", "Great! I've marked the dropoff zone on your map - top floor of the parking garage, next to the storage units. Just drive the vehicle in there when you're ready.", (Action<ChoiceList>)null);
				c.AddNode("DECLINED", "No worries, just let me know if you change your mind!", (Action<ChoiceList>)null);
			});
			jeremy.Dialogue.OnChoiceSelected("ACCEPT", (Action)OnAcceptQuest);
			jeremy.Dialogue.OnChoiceSelected("BUY_NOW", (Action)OnAcceptQuest);
			jeremy.Dialogue.OnChoiceSelected("DECLINE", (Action)delegate
			{
				Logger.Debug("Player declined quest");
			});
			jeremy.Dialogue.OnChoiceSelected("NEVERMIND", (Action)delegate
			{
				Logger.Debug("Player cancelled purchase");
			});
			jeremy.Dialogue.OnChoiceSelected("PURCHASE", (Action)delegate
			{
				//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
				float vehiclePrice = GetVehiclePrice();
				float onlineBalance = Money.GetOnlineBalance();
				if (onlineBalance >= vehiclePrice)
				{
					Money.CreateOnlineTransaction("veeper".Capitalize() + " purchase", 0f - vehiclePrice, 1f, "Bought as a part of delivery expansion");
					Logger.Msg(string.Format("Player purchased {0} for ${1:F2}", "veeper", vehiclePrice));
					Jeremy component = jeremy.gameObject.GetComponent<Jeremy>();
					if ((Object)(object)component != (Object)null)
					{
						Dealership dealership = component.Dealership;
						if ((Object)(object)dealership != (Object)null)
						{
							dealership.SpawnVehicle("veeper");
							return;
						}
					}
					NetworkSingleton<VehicleManager>.Instance.SpawnVehicle("veeper", new Vector3(9.92f, 0.54f, -33.55f), Quaternion.identity, true);
				}
				else
				{
					jeremy.Dialogue.JumpTo("DeliveryExpansion", "NOT_ENOUGH", false);
				}
			});
			DialogueInjector.Register(new DialogueInjection(jeremy.ID, "Dealership_Salesman_Sell", "cc0d838e-2824-4fd5-907d-798dc0195c16", "OFFER_FIRST", "ASK_EXPANSION", "Can I expand my delivery capacity?", (Action)delegate
			{
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Invalid comparison between Unknown and I4
				DropoffQuest dropoffQuest = QuestManager.GetQuestByName("Expanding the Fleet") as DropoffQuest;
				bool flag = PoolManager.Instance.Pool.Count > 0;
				bool flag2 = dropoffQuest != null && (int)dropoffQuest.State == 1;
				Logger.Debug($"Quest state - Active: {flag2}, Has expanded: {flag}");
				string text = (flag2 ? "IN_PROGRESS" : (flag ? "OFFER_REPEAT" : "OFFER_FIRST"));
				Logger.Debug("Jumping to 'DeliveryExpansion', node '" + text + "'");
				jeremy.Dialogue.JumpTo("DeliveryExpansion", text, false);
			}));
			Logger.Msg("Registered delivery expansion dialogue");
		}

		private static void OnAcceptQuest()
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Invalid comparison between Unknown and I4
			if (!(QuestManager.GetQuestByName("Expanding the Fleet") is DropoffQuest dropoffQuest))
			{
				if (QuestManager.CreateQuest<DropoffQuest>((string)null) is DropoffQuest dropoffQuest2)
				{
					((Quest)dropoffQuest2).Begin();
				}
				Logger.Msg("Started delivery expansion quest");
			}
			else if (dropoffQuest != null && (int)dropoffQuest.State == 2)
			{
				((Quest)dropoffQuest).Begin();
				Logger.Msg("Restarted delivery expansion quest");
			}
		}

		private static float GetVehiclePrice()
		{
			LandVehicle vehiclePrefab = NetworkSingleton<VehicleManager>.Instance.GetVehiclePrefab("veeper");
			return (vehiclePrefab != null) ? vehiclePrefab.VehiclePrice : 5000f;
		}
	}
	[RegisterTypeInIl2Cpp]
	public class VehicleDropoffZone : MonoBehaviour
	{
		private VehicleDetector _detector;

		private Logger _logger;

		private GameObject _visualPlane;

		private Material _visualMaterial;

		private Color _baseColor;

		private DropoffQuest? _quest;

		public Vector3 Corner1 { get; private set; }

		public Vector3 Corner2 { get; private set; }

		public bool ShowVisuals { get; set; } = true;


		private void Awake()
		{
			_logger = new Logger("VehicleDropoffZone");
		}

		private void Start()
		{
			_detector = ((Component)this).gameObject.GetComponent<VehicleDetector>();
			if ((Object)(object)_detector == (Object)null)
			{
				_detector = ((Component)this).gameObject.AddComponent<VehicleDetector>();
			}
		}

		private void Update()
		{
			if (_detector.vehicles.Count <= 0)
			{
				return;
			}
			foreach (LandVehicle item in _detector.vehicles.AsEnumerable())
			{
				OnVehicleEntered(item);
			}
		}

		private void OnVehicleEntered(LandVehicle vehicle)
		{
			_logger.Debug("Vehicle entered dropoff zone: " + vehicle.vehicleName);
			if (!IsCorrectVehicleType(vehicle))
			{
				if (Time.frameCount % 60 == 0)
				{
					_logger.Warning("Wrong vehicle type: " + vehicle.vehicleCode);
				}
				return;
			}
			if (vehicle.IsOccupied)
			{
				_logger.Msg("Ejecting player from vehicle");
				vehicle.ExitVehicle();
			}
			ProcessAndAddToPool(vehicle);
			_detector.vehicles.Remove(vehicle);
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}

		private static bool IsCorrectVehicleType(LandVehicle vehicle)
		{
			return vehicle.vehicleCode == "veeper";
		}

		private void ProcessAndAddToPool(LandVehicle vehicle)
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			_logger.Debug($"Adding vehicle to pool: {vehicle.GUID}");
			DeliveryVehicle val = ((Component)vehicle).GetComponent<DeliveryVehicle>();
			if ((Object)(object)val == (Object)null)
			{
				Guid gUID = vehicle.GUID;
				val = new DeliveryVehicleBuilder().WithLandVehicle(vehicle).WithGuid(gUID).Build();
			}
			vehicle.IsPlayerOwned = false;
			vehicle.SetIsPlayerOwned((NetworkConnection)null, false);
			vehicle.SetVisible(false);
			vehicle.IsPhysicallySimulated = false;
			((Component)vehicle).transform.position = new Vector3(0f, -100f, 0f);
			PoolManager.Instance.AddToSaveData(val);
			PoolManager.Instance.AddToPool(val);
			_quest?.MarkAddVehicleEntryComplete();
			_logger.Msg($"Vehicle added to pool. Total vehicles: {PoolManager.Instance.Pool.Count}");
		}

		public void SetupZone(Vector3 corner1, Vector3 corner2, float height = 5f, Color? visualColor = null)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			Corner1 = corner1;
			Corner2 = corner2;
			Vector3 val = (corner1 + corner2) / 2f;
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(Mathf.Abs(corner2.x - corner1.x), height, Mathf.Abs(corner2.z - corner1.z));
			((Component)this).transform.position = val;
			BoxCollider val3 = ((Component)this).gameObject.GetComponent<BoxCollider>();
			if ((Object)(object)val3 == (Object)null)
			{
				val3 = ((Component)this).gameObject.AddComponent<BoxCollider>();
			}
			((Collider)val3).isTrigger = true;
			val3.size = val2;
			val3.center = Vector3.zero;
			if (ShowVisuals)
			{
				_baseColor = (Color)(((??)visualColor) ?? new Color(0f, 1f, 1f, 0.3f));
				CreateVisualPlane(val2, _baseColor);
			}
			_logger.Debug($"Dropoff zone created: Center={val}, Size={val2}");
		}

		private void CreateVisualPlane(Vector3 size, Color color)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			_visualPlane = GameObject.CreatePrimitive((PrimitiveType)3);
			((Object)_visualPlane).name = "DropoffZoneVisual";
			_visualPlane.transform.SetParent(((Component)this).transform);
			_visualPlane.transform.localPosition = Vector3.zero;
			_visualPlane.transform.localScale = new Vector3(size.x, 0.1f, size.z);
			Collider component = _visualPlane.GetComponent<Collider>();
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
			}
			ApplyDebugMaterial(_visualPlane, color);
		}

		private void ApplyDebugMaterial(GameObject obj, Color color)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_006b: 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_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			Renderer component = obj.GetComponent<Renderer>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			Shader val = Shader.Find("Universal Render Pipeline/Lit");
			if (!((Object)(object)val == (Object)null))
			{
				_visualMaterial = new Material(val);
				if (_visualMaterial.HasProperty("_Surface"))
				{
					_visualMaterial.SetFloat("_Surface", 1f);
				}
				if (color.a <= 0f)
				{
					color.a = 0.3f;
				}
				if (_visualMaterial.HasProperty("_BaseColor"))
				{
					_visualMaterial.SetColor("_BaseColor", color);
				}
				if (_visualMaterial.HasProperty("_EmissionColor"))
				{
					_visualMaterial.EnableKeyword("_EMISSION");
					_visualMaterial.SetColor("_EmissionColor", new Color(color.r, color.g, color.b) * 1.5f);
				}
				_visualMaterial.SetInt("_ZWrite", 0);
				_visualMaterial.renderQueue = 3000;
				component.material = _visualMaterial;
			}
		}

		public void SetVisualsEnabled(bool enabled)
		{
			ShowVisuals = enabled;
			if ((Object)(object)_visualPlane != (Object)null)
			{
				_visualPlane.SetActive(enabled);
			}
		}

		public void SetQuest(DropoffQuest quest)
		{
			_quest = quest;
		}

		private void OnDestroy()
		{
			if ((Object)(object)_visualPlane != (Object)null)
			{
				Object.Destroy((Object)(object)_visualPlane);
			}
		}
	}
	public static class VehicleDropoffZoneFactory
	{
		public static VehicleDropoffZone CreateZone(Vector3 corner1, Vector3 corner2, float height = 5f, Color? visualColor = null, bool showVisuals = true, DropoffQuest? attachedQuest = null)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_001d: 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)
			GameObject val = new GameObject("VehicleDropoffZone");
			VehicleDropoffZone vehicleDropoffZone = val.AddComponent<VehicleDropoffZone>();
			vehicleDropoffZone.ShowVisuals = showVisuals;
			vehicleDropoffZone.SetupZone(corner1, corner2, height, visualColor);
			if (attachedQuest != null)
			{
				vehicleDropoffZone.SetQuest(attachedQuest);
			}
			return vehicleDropoffZone;
		}

		public static VehicleDropoffZone CreateZoneNear(Transform reference, Vector3 offset, Vector3 size, Color? visualColor = null)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = reference.position + offset;
			Vector3 corner = val - size / 2f;
			Vector3 corner2 = val + size / 2f;
			return CreateZone(corner, corner2, size.y, visualColor);
		}
	}
}
namespace MultiDelivery.Pool
{
	[HarmonyPatch(typeof(DeliveryManager))]
	internal static class ActiveDeliveryPatch
	{
		private static readonly Logger Logger = new Logger("ActiveDeliveryPatch");

		[HarmonyPatch("GetActiveShopDelivery")]
		[HarmonyPostfix]
		private static void AllowIfPoolAssigmentAvailable(DeliveryManager __instance, DeliveryShop shop, ref DeliveryInstance __result)
		{
			if (__result == null)
			{
				return;
			}
			if (PoolManager.Instance.BaseVehicleAllocationsForShop.TryGetValue(shop.MatchingShopInterfaceName, out var value))
			{
				if (Time.frameCount % 30 == 0)
				{
					Logger.Debug($"Base: {value}");
				}
				if (!value)
				{
					__result = null;
					return;
				}
				DeliveryVehicle firstFree = PoolManager.Instance.GetFirstFree();
				if (!((Object)(object)firstFree == (Object)null))
				{
					Logger.Debug("Free pool vehicle found");
					__result = null;
				}
			}
			else
			{
				DeliveryVehicle firstFree2 = PoolManager.Instance.GetFirstFree();
				if (!((Object)(object)firstFree2 == (Object)null))
				{
					Logger.Debug("Free pool vehicle found");
					__result = null;
				}
			}
		}

		[HarmonyPatch("SendDelivery")]
		[HarmonyPostfix]
		private static void AllocateVehicle(DeliveryManager __instance, DeliveryInstance delivery)
		{
			PoolManager.Instance.BaseVehicleAllocationsForShop.TryAdd(delivery.StoreName, value: false);
			Logger.Debug($"Base allocation: {PoolManager.Instance.BaseVehicleAllocationsForShop[delivery.StoreName]}");
			if (!PoolManager.Instance.BaseVehicleAllocationsForShop[delivery.StoreName])
			{
				Logger.Debug("Base vehicle allocating");
				PoolManager.Instance.BaseVehicleAllocationsForShop[delivery.StoreName] = true;
				NetworkConvenienceMethods.NotifyBaseAllocation(delivery.StoreName, isAllocated: true);
			}
			else
			{
				PoolManager.Instance.GetOrAllocateFirstFree(delivery.DeliveryID);
				Logger.Debug("Allocated for " + delivery.DeliveryID);
			}
		}
	}
	[HarmonyPatch(typeof(DeliveryInstance))]
	internal static class DeliveryInstancePatches
	{
		[HarmonyPatch("SetStatus")]
		[HarmonyPrefix]
		private static bool UsePoolSetStatus(DeliveryInstance __instance, EDeliveryStatus status)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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_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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Invalid comparison between Unknown and I4
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Invalid comparison between Unknown and I4
			Console.Log((object)$"Setting delivery status to {status} for delivery {__instance.DeliveryID}", (Object)null);
			__instance.Status = status;
			ShopInterface shopInterface = NetworkSingleton<DeliveryManager>.Instance.GetShopInterface(__instance.StoreName);
			if ((int)status != 2)
			{
				if ((int)status == 3)
				{
					if ((Object)(object)__instance.ActiveVehicle == (Object)(object)shopInterface.DeliveryVehicle)
					{
						PoolManager.Instance.BaseVehicleAllocationsForShop[__instance.StoreName] = false;
						NetworkConvenienceMethods.NotifyBaseAllocation(__instance.StoreName, isAllocated: false);
					}
					else
					{
						PoolManager.Instance.FreeAllocation(__instance.DeliveryID);
					}
					if ((Object)(object)__instance.ActiveVehicle != (Object)null)
					{
						__instance.ActiveVehicle.Deactivate();
					}
					UnityEvent onDeliveryCompleted = __instance.onDeliveryCompleted;
					if (onDeliveryCompleted != null)
					{
						onDeliveryCompleted.Invoke();
					}
				}
			}
			else
			{
				if (PoolManager.Instance.Allocations.TryGetValue(__instance.DeliveryID, out DeliveryVehicle value))
				{
					__instance.ActiveVehicle = value;
				}
				else
				{
					__instance.ActiveVehicle = shopInterface.DeliveryVehicle;
				}
				__instance.ActiveVehicle.Activate(__instance);
			}
			return false;
		}

		[HarmonyPatch("AddItemsToDeliveryVehicle")]
		[HarmonyPrefix]
		private static bool UsePoolAddItemsToDeliveryVehicle(DeliveryInstance __instance)
		{
			ShopInterface shopInterface = NetworkSingleton<DeliveryManager>.Instance.GetShopInterface(__instance.StoreName);
			if (!PoolManager.Instance.Allocations.TryGetValue(__instance.DeliveryID, out DeliveryVehicle value))
			{
				value = shopInterface?.DeliveryVehicle;
			}
			StringIntPair[] items = __instance.Items;
			StringIntPair[] array = items;
			foreach (StringIntPair val in array)
			{
				ItemDefinition item = Registry.GetItem(val.String);
				int num = val.Int;
				while (num > 0)
				{
					int num2 = Mathf.Min(num, ((BaseItemDefinition)item).StackLimit);
					num -= num2;
					ItemInstance defaultInstance = item.GetDefaultInstance(num2);
					value.Vehicle.Storage.InsertItem(defaultInstance, Object.op_Implicit((Object)(object)item));
				}
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(DeliveryVehicle))]
	internal class DeliveryVehiclePatch
	{
		[HarmonyPatch("Deactivate")]
		[HarmonyPostfix]
		private static void NullActiveDelivery(DeliveryVehicle __instance)
		{
			DeliveryInstance activeDelivery = __instance.ActiveDelivery;
			if ((Object)(object)((activeDelivery == null) ? null : activeDelivery.LoadingDock?.VehicleDetector) != (Object)null)
			{
				__instance.ActiveDelivery.LoadingDock.SetOccupant((LandVehicle)null);
				__instance.ActiveDelivery.LoadingDock.VehicleDetector.Clear();
			}
			if (__instance.ActiveDelivery != null)
			{
				__instance.ActiveDelivery = null;
			}
		}
	}
	[HarmonyPatch(typeof(DeliveriesLoader))]
	internal static class LoaderPatch
	{
		private static readonly Logger Logger = new Logger("LoaderPatch");

		[HarmonyPatch("Load")]
		[HarmonyPrefix]
		private static bool Load(DeliveriesLoader __instance, string mainPath)
		{
			bool flag = false;
			string text = default(string);
			if (((Loader)__instance).TryLoadFile(Path.Combine(mainPath, "Deliveries"), ref text, true) || ((Loader)__instance).TryLoadFile(mainPath, ref text, true))
			{
				DeliveriesData val = null;
				try
				{
					val = JsonUtility.FromJson<DeliveriesData>(text);
				}
				catch (Exception ex)
				{
					Debug.LogError((object)("Error loading data: " + ex.Message));
				}
				if (val != null && val.ActiveDeliveries != null)
				{
					LoadDelivery(val);
					if (val.DeliveryVehicles != null)
					{
						flag = true;
						VehicleData[] deliveryVehicles = val.DeliveryVehicles;
						VehicleData[] array = deliveryVehicles;
						foreach (VehicleData data in array)
						{
							LoadVehicle(data, mainPath);
						}
					}
				}
			}
			if (!flag && Directory.Exists(mainPath))
			{
				Console.Log((object)("Loading legacy delivery vehicles at: " + mainPath), (Object)null);
				string text2 = Path.Combine(mainPath, "DeliveryVehicles");
				List<DirectoryInfo> directories = ((Loader)__instance).GetDirectories(text2);
				for (int j = 0; j < directories.Count; j++)
				{
					__instance.LoadVehicle(directories[j].FullName);
				}
			}
			return false;
		}

		private static void LoadVehicle(VehicleData data, string path)
		{
			VehicleData data2 = data;
			Logger.Debug("Processing GUID " + data2.GUID);
			DeliveryVehicle? obj = ((IEnumerable<DeliveryVehicle>)PoolManager.Instance.Pool).FirstOrDefault((Func<DeliveryVehicle, bool>)((DeliveryVehicle dv) => dv.Vehicle.GUID.ToString() == data2.GUID));
			LandVehicle val = ((obj != null) ? obj.Vehicle : null);
			if ((Object)(object)val == (Object)null)
			{
				Logger.Debug("GUID " + data2.GUID + " not found in Pool, lookup via GUIDManager");
				val = GUIDManager.GetObject<LandVehicle>(new Guid(data2.GUID));
			}
			if ((Object)(object)val == (Object)null)
			{
				Logger.Error("Vehicle not found with GUID", data2.GUID);
				Console.LogError((object)("LoadVehicle: Vehicle not found with GUID " + data2.GUID), (Object)null);
			}
			else
			{
				LoadVehicle(val, data2, path);
			}
		}

		private static void LoadVehicle(LandVehicle vehicle, VehicleData data, string containerPath)
		{
			Logger.Debug($"Processing vehicle {((Object)vehicle).name} with GUID {vehicle.GUID}");
			if ((Object)(object)vehicle.Storage != (Object)null)
			{
				if (data.VehicleContents != null && data.VehicleContents.Items != null)
				{
					DeserializedItemSet val = default(DeserializedItemSet);
					if (ItemSet.TryDeserialize(data.VehicleContents, ref val))
					{
						val.LoadTo(vehicle.Storage.ItemSlots);
					}
				}
				else if (File.Exists(Path.Combine(containerPath, "Contents.json")))
				{
					Console.LogWarning((object)"Loading legacy vehicle contents.", (Object)null);
					string text = default(string);
					DeserializedItemSet val2 = default(DeserializedItemSet);
					if (vehicle.Loader.TryLoadFile(containerPath, "Contents", ref text) && ItemSet.TryDeserialize(text, ref val2))
					{
						val2.LoadTo(vehicle.Storage.ItemSlots);
					}
				}
			}
			if (data.SpraySurfaces == null)
			{
				return;
			}
			try
			{
				for (int i = 0; i < data.SpraySurfaces.Count; i++)
				{
					if (vehicle._spraySurfaces.Length > i)
					{
						SpraySurface obj = vehicle._spraySurfaces[i];
						if (obj != null)
						{
							obj.Set((NetworkConnection)null, data.SpraySurfaces[i].Strokes.ToArray(), data.SpraySurfaces[i].ContainsCartelGraffiti);
						}
					}
				}
			}
			catch (Exception ex)
			{
				Logger.Error("Exception thrown while loading saved graffities", ex);
			}
		}

		private static void LoadDelivery(DeliveriesData data)
		{
			if (data == null)
			{
				return;
			}
			if (data.ActiveDeliveries != null)
			{
				DeliveryInstance[] activeDeliveries = data.ActiveDeliveries;
				DeliveryInstance[] array = activeDeliveries;
				foreach (DeliveryInstance val in array)
				{
					NetworkSingleton<DeliveryManager>.Instance.SendDelivery(val);
				}
			}
			if (data.DeliveryHistory != null)
			{
				DeliveryReceipt[] deliveryHistory = data.DeliveryHistory;
				foreach (DeliveryReceipt val2 in deliveryHistory)
				{
					NetworkSingleton<DeliveryManager>.Instance._deliveryHistory.Add(val2);
				}
			}
			if (data.DisplayedDeliveryHistory != null)
			{
				DeliveryReceipt[] displayedDeliveryHistory = data.DisplayedDeliveryHistory;
				foreach (DeliveryReceipt val3 in displayedDeliveryHistory)
				{
					NetworkSingleton<DeliveryManager>.Instance._displayedDeliveryHistory.Add(val3);
				}
			}
		}
	}
	public class PoolManager
	{
		private static readonly Logger Logger = new Logger("PoolManager");

		public static PoolManager Instance { get; } = new PoolManager();


		public HashSet<DeliveryVehicle> Pool { get; } = new HashSet<DeliveryVehicle>();


		internal Dictionary<string, DeliveryVehicle> Allocations { get; } = new Dictionary<string, DeliveryVehicle>();


		internal Dictionary<string, bool> BaseVehicleAllocationsForShop { get; } = new Dictionary<string, bool>();


		public void AddToPool(DeliveryVehicle deliveryVehicle, bool notify = true)
		{
			Pool.Add(deliveryVehicle);
			if (notify)
			{
				NetworkConvenienceMethods.NotifyVehicleAdded(deliveryVehicle);
			}
		}

		public void AddToSaveData(DeliveryVehicle deliveryVehicle)
		{
			if ((Object)(object)deliveryVehicle == (Object)null)
			{
				throw new ArgumentNullException("deliveryVehicle");
			}
			VehicleSave.Instance.AddVehicle(deliveryVehicle.Vehicle);
			NetworkConvenienceMethods.NotifyVehicleCreated(deliveryVehicle);
		}

		public DeliveryVehicle? GetFirstFree()
		{
			DeliveryVehicle val = ((IEnumerable<DeliveryVehicle>)Pool).FirstOrDefault((Func<DeliveryVehicle, bool>)((DeliveryVehicle dv) => dv.ActiveDelivery == null && !Allocations.ContainsValue(dv)));
			if (Time.frameCount % 30 == 0)
			{
				Logger.Debug("Pool lookup: " + (((Object)(object)val == (Object)null) ? "null" : "not null"));
			}
			return val;
		}

		public DeliveryVehicle GetOrAllocateFirstFree(string deliveryId)
		{
			Logger.Debug("GetOrAllocateFirstFree called for: " + deliveryId);
			if (Allocations.TryGetValue(deliveryId, out DeliveryVehicle value))
			{
				Logger.Debug("Already allocated, returning existing");
				return value;
			}
			DeliveryVehicle firstFree = GetFirstFree();
			if ((Object)(object)firstFree == (Object)null)
			{
				Logger.Debug($"No free vehicle found! Pool count: {Pool.Count}, Allocations count: {Allocations.Count}");
				foreach (KeyValuePair<string, DeliveryVehicle> allocation in Allocations)
				{
					Logger.Debug("Allocation: " + allocation.Key + " -> Vehicle has ActiveDelivery: " + (allocation.Value.ActiveDelivery?.DeliveryID ?? "null"));
				}
				throw new ArgumentException("Tried to allocate a non-free vehicle");
			}
			Allocations.Add(deliveryId, firstFree);
			Logger.Debug("Allocated new vehicle for " + deliveryId + ", vehicle: " + firstFree.GUID);
			NetworkConvenienceMethods.NotifyAllocation(deliveryId, firstFree, isAllocated: true);
			return firstFree;
		}

		public void FreeAllocation(string deliveryId)
		{
			Logger.Debug("Free custom allocation: " + deliveryId);
			if (Allocations.TryGetValue(deliveryId, out DeliveryVehicle value))
			{
				Allocations.Remove(deliveryId);
				NetworkConvenienceMethods.NotifyAllocation(deliveryId, value, isAllocated: false);
			}
		}
	}
	[HarmonyPatch(typeof(Wheel))]
	internal class WheelPatch
	{
		[HarmonyPatch("OnWeatherChange")]
		[HarmonyPrefix]
		private static bool ExitIfNull(Wheel __instance, WeatherConditions newConditions)
		{
			if ((Object)(object)__instance?.vehicle == (Object)null)
			{
				return false;
			}
			if (newConditions != null)
			{
				_ = newConditions.Rainy;
				if (0 == 0)
				{
					return true;
				}
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(DeliveryVehicle))]
	internal static class DeliveryVehicleAwakePatch
	{
		[HarmonyPatch("Awake")]
		[HarmonyPrefix]
		private static bool ExitIfNull(DeliveryVehicle __instance)
		{
			if (Guid.TryParse(__instance.GUID, out var _))
			{
				return true;
			}
			if ((Object)(object)((Component)__instance).GetComponent<LandVehicle>() == (Object)null)
			{
				return false;
			}
			__instance.Vehicle = ((Component)__instance).GetComponent<LandVehicle>();
			__instance.Deactivate();
			return false;
		}
	}
}
namespace MultiDelivery.Persistence
{
	public class PersistentDropoffQuestData : Saveable
	{
		[SaveableField("MessageData")]
		public bool HasMessaged;

		public static PersistentDropoffQuestData Instance { get; private set; } = new PersistentDropoffQuestData();


		public PersistentDropoffQuestData()
		{
			Instance = this;
		}
	}
	public class VehicleSave : Saveable
	{
		[CompilerGenerated]
		private sealed class <DeferredSetColor>d__12 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public LandVehicle vehicle;

			public EVehicleColor color;

			public VehicleSave <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0086: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					goto IL_0044;
				case 1:
					<>1__state = -1;
					goto IL_0044;
				case 2:
					{
						<>1__state = -1;
						vehicle.ApplyColor(color);
						return false;
					}
					IL_0044:
					if ((Object)(object)Player.Local == (Object)null || (Object)(object)((Component)Player.Local).gameObject == (Object)null)
					{
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					<>2__current = null;
					<>1__state = 2;
					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();
			}
		}

		[SaveableField("VehicleSaveData")]
		private List<VehicleSaveDto> _dtos = new List<VehicleSaveDto>();

		private static readonly Logger Logger = new Logger("VehicleSave");

		private static Transform _parent;

		public override SaveableLoadOrder LoadOrder => (SaveableLoadOrder)0;

		public static VehicleSave Instance { get; set; } = new VehicleSave();


		public VehicleSave()
		{
			Instance = this;
		}

		public void AddVehicle(LandVehicle vehicle)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			VehicleSaveDto item = new VehicleSaveDto
			{
				Guid = vehicle.GUID.ToString(),
				VehicleType = vehicle.VehicleCode,
				Color = vehicle.Color.displayedColor
			};
			if (!_dtos.Contains(item))
			{
				_dtos.Add(item);
			}
		}

		protected override void OnLoaded()
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			Melon<MultiDelivery>.Logger.Msg($"VehicleSave.OnLoaded: Loading {_dtos.Count} vehicles");
			if ((Object)(object)_parent == (Object)null)
			{
				GameObject val = GameObject.Find("VehiclePool");
				if ((Object)(object)val == (Object)null)
				{
					val = new GameObject("VehiclePool");
				}
				_parent = val.transform;
			}
			for (int i = 0; i < _dtos.Count; i++)
			{
				Logger.Debug($"Loading vehicle {i}: {_dtos[i].Guid}");
				Guid guid = new Guid(_dtos[i].Guid);
				LandVehicle val2 = new LandVehicleBuilder().WithVehicleCode(_dtos[i].VehicleType).WithVehicleName($"Additional Delivery Vehicle {i + 1}").WithGuid(guid)
					.WithColor(_dtos[i].Color)
					.WithParent(_parent)
					.Build();
				MelonCoroutines.Start(DeferredSetColor(val2, _dtos[i].Color));
				Logger.Debug($"Built LandVehicle: {val2.vehicleName}, ObjectId: {((NetworkBehaviour)val2).ObjectId}");
				DeliveryVehicle val3 = new DeliveryVehicleBuilder().WithLandVehicle(val2).WithGuid(guid).Build();
				Logger.Debug("Built DeliveryVehicle: " + val3.GUID);
				PoolManager.Instance.AddToPool(val3);
				Logger.Debug($"Added to pool. Pool count now: {PoolManager.Instance.Pool.Count}");
			}
			Logger.Msg($"VehicleSave.OnLoaded complete. Final pool count: {PoolManager.Instance.Pool.Count}");
		}

		[IteratorStateMachine(typeof(<DeferredSetColor>d__12))]
		private IEnumerator DeferredSetColor(LandVehicle vehicle, EVehicleColor color)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DeferredSetColor>d__12(0)
			{
				<>4__this = this,
				vehicle = vehicle,
				color = color
			};
		}
	}
	public record VehicleSaveDto
	{
		public string Guid { get; set; }

		public string VehicleType { get; set; }

		public EVehicleColor Color { get; set; }

		[CompilerGenerated]
		protected virtual bool PrintMembers(StringBuilder builder)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			RuntimeHelpers.EnsureSufficientExecutionStack();
			builder.Append("Guid = ");
			builder.Append((object?)Guid);
			builder.Append(", VehicleType = ");
			builder.Append((object?)VehicleType);
			builder.Append(", Color = ");
			EVehicleColor color = Color;
			builder.Append(((object)(EVehicleColor)(ref color)).ToString());
			return true;
		}
	}
}
namespace MultiDelivery.Network
{
	public class DeliveryNetworkManager
	{
		[CompilerGenerated]
		private sealed class <>c__DisplayClass22_0
		{
			public DeliveryNetworkManager <>4__this;

			public VehicleAddedMessage message;

			internal bool <OnVehicleAdded>b__2()
			{
				return (Object)(object)<>4__this.FindLandVehicleByObjectId(message.ObjectId) != (Object)null;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass23_0
		{
			public DeliveryNetworkManager <>4__this;

			public VehicleCreatedMessage message;

			internal bool <OnVehicleCreated>b__2()
			{
				return (Object)(object)<>4__this.FindLandVehicleByObjectId(message.ObjectId) != (Object)null;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass25_0
		{
			public VehiclePoolSyncResponse message;

			public DeliveryNetworkManager <>4__this;

			public Func<VehiclePoolSyncResponse.VehicleData, bool> <>9__3;

			internal bool <OnPoolSyncResponse>b__2()
			{
				return message.Vehicles.All((VehiclePoolSyncResponse.VehicleData v) => (Object)(object)<>4__this.FindLandVehicleByObjectId(v.ObjectId) != (Object)null);
			}

			internal bool <OnPoolSyncResponse>b__3(VehiclePoolSyncResponse.VehicleData v)
			{
				return (Object)(object)<>4__this.FindLandVehicleByObjectId(v.ObjectId) != (Object)null;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass26_0
		{
			public VehicleAllocationMessage message;

			public DeliveryNetworkManager <>4__this;

			public Func<DeliveryVehicle, bool> <>9__3;

			internal bool <OnVehicleAllocation>b__2()
			{
				return (Object)(object)((IEnumerable<DeliveryVehicle>)PoolManager.Instance.Pool).FirstOrDefault((Func<DeliveryVehicle, bool>)((DeliveryVehicle v) => v.GUID == message.VehicleGuid)) != (Object)null;
			}

			internal bool <OnVehicleAllocation>b__3(DeliveryVehicle v)
			{
				return v.GUID == message.VehicleGuid;
			}

			internal bool <OnVehicleAllocation>b__4(DeliveryVehicle v)
			{
				return v.GUID == message.VehicleGuid;
			}
		}

		[CompilerGenerated]
		private sealed class <ExponentialBackoff>d__34 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Func<bool> predicate;

			public float initialDelay;

			public float finalDelay;

			public float timeout;

			private float <delay>5__1;

			private float <elapsed>5__2;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_004b: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<delay>5__1 = initialDelay;
					<elapsed>5__2 = 0f;
					break;
				case 1:
					<>1__state = -1;
					<elapsed>5__2 += <delay>5__1;
					<delay>5__1 = Mathf.Min(<delay>5__1 * 2f, finalDelay);
					break;
				}
				if (!predicate() && <elapsed>5__2 < timeout)
				{
					<>2__current = (object)new WaitForSeconds(<delay>5__1);
					<>1__state = 1;
					return true;
				}
				return false;
			}

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

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

		private SteamNetworkClient _client;

		private readonly Logger _logger;

		private const string ModDataKey = "MultiDelivery_Version";

		private const string ModVersion = "1.0.0";

		private bool IsInLobby
		{
			get
			{
				SteamNetworkClient client = _client;
				return client != null && client.IsInLobby;
			}
		}

		private bool IsHost
		{
			get
			{
				SteamNetworkClient client = _client;
				return client != null && client.IsHost;
			}
		}

		private bool IsSingleplayer => !IsInLobby;

		internal bool HostOrSingleplayer => IsHost || IsSingleplayer;

		public DeliveryNetworkManager()
		{
			_logger = new Logger("Network", LogLevel.NetworkTrace);
		}

		public bool Initialize()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			try
			{
				NetworkRules val = new NetworkRules
				{
					EnableRelay = true,
					AcceptOnlyFriends = false
				};
				_client = new SteamNetworkClient(val);
				if (!_client.Initialize())
				{
					_logger.Error("Failed to initialize SteamNetworkClient");
					return false;
				}
				RegisterMessageHandlers();
				SubscribeToEvents();
				_logger.Msg("Network manager initialized successfully");
				return true;
			}
			catch (Exception arg)
			{
				_client = null;
				_logger.Error($"Failed to initialize network manager: {arg}");
				return false;
			}
		}

		private void RegisterMessageHandlers()
		{
			_client.RegisterMessageHandler<VehicleAddedMessage>((Action<VehicleAddedMessage, CSteamID>)OnVehicleAdded);
			_client.RegisterMessageHandler<VehicleCreatedMessage>((Action<VehicleCreatedMessage, CSteamID>)OnVehicleCreated);
			_client.RegisterMessageHandler<VehiclePoolSyncRequest>((Action<VehiclePoolSyncRequest, CSteamID>)OnPoolSyncRequest);
			_client.RegisterMessageHandler<VehiclePoolSyncResponse>((Action<VehiclePoolSyncResponse, CSteamID>)OnPoolSyncResponse);
			_client.RegisterMessageHandler<VehicleAllocationMessage>((Action<VehicleAllocationMessage, CSteamID>)OnVehicleAllocation);
			_client.RegisterMessageHandler<BaseVehicleAllocationMessage>((Action<BaseVehicleAllocationMessage, CSteamID>)OnBaseVehicleAllocation);
		}

		private void SubscribeToEvents()
		{
			_client.OnLobbyCreated += OnLobbyCreated;
			_client.OnLobbyJoined += OnLobbyJoined;
			_client.OnMemberJoined += OnMemberJoined;
			_client.OnLobbyLeft += OnLobbyLeft;
		}

		public void Update()
		{
			SteamNetworkClient client = _client;
			if (client != null)
			{
				client.ProcessIncomingMessages();
			}
		}

		public void Dispose()
		{
			SteamNetworkClient client = _client;
			if (client != null)
			{
				client.Dispose();
			}
		}

		public async void BroadcastVehicleAdded(DeliveryVehicle vehicle)
		{
			if (!IsSingleplayer)
			{
				VehicleAddedMessage message = new VehicleAddedMessage
				{
					ObjectId = ((NetworkBehaviour)vehicle.Vehicle).ObjectId,
					VehicleGuid = vehicle.GUID,
					VehicleName = vehicle.Vehicle.vehicleName,
					VehicleCode = vehicle.Vehicle.VehicleCode,
					VehicleColor = (int)vehicle.Vehicle.Color.displayedColor
				};
				_logger.Msg($"Broadcasting vehicle added: ObjectId={message.ObjectId}, GUID={message.VehicleGuid}");
				await _client.BroadcastMessageAsync((P2PMessage)(object)message);
			}
		}

		public async void BroadcastVehicleCreated(DeliveryVehicle vehicle)
		{
			if (!IsSingleplayer && !IsHost)
			{
				VehicleCreatedMessage message = new VehicleCreatedMessage
				{
					ObjectId = ((NetworkBehaviour)vehicle.Vehicle).ObjectId,
					VehicleGuid = vehicle.GUID
				};
				_logger.Msg($"Broadcasting vehicle created: ObjectId={message.ObjectId}");
				await _client.BroadcastMessageAsync((P2PMessage)(object)message);
			}
		}

		public async void BroadcastVehicleAllocation(string deliveryId, DeliveryVehicle vehicle, bool isAllocated)
		{
			if (!IsSingleplayer)
			{
				VehicleAllocationMessage message = new VehicleAllocationMessage
				{
					DeliveryId = deliveryId,
					VehicleGuid = vehicle.GUID,
					IsAllocated = isAllocated
				};
				_logger.Msg($"Broadcasting allocation: Delivery={deliveryId}, Vehicle={vehicle.GUID}, Allocated={isAllocated}");
				await _client.BroadcastMessageAsync((P2PMessage)(object)message);
			}
		}

		public async void BroadcastBaseVehicleAllocation(string shopName, bool isAllocated)
		{
			if (!IsSingleplayer)
			{
				BaseVehicleAllocationMessage message = new BaseVehicleAllocationMessage
				{
					ShopName = shopName,
					IsAllocated = isAllocated
				};
				_logger.Msg($"Broadcasting base allocation: Shop={shopName}, Allocated={isAllocated}");
				await _client.BroadcastMessageAsync((P2PMessage)(object)message);
			}
		}

		private void OnVehicleAdded(VehicleAddedMessage message, CSteamID cSteamID)
		{
			<>c__DisplayClass22_0 CS$<>8__locals0 = new <>c__DisplayClass22_0();
			CS$<>8__locals0.<>4__this = this;
			CS$<>8__locals0.message = message;
			_logger.Msg($"Received VehicleAdded: ObjectId={CS$<>8__locals0.message.ObjectId}, GUID={CS$<>8__locals0.message.VehicleGuid}");
			MelonCoroutines.Start(ProcessMessage());
			[IteratorStateMachine(typeof(<>c__DisplayClass22_0.<<OnVehicleAdded>g__ProcessMessage|0>d))]
			IEnumerator ProcessMessage()
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <>c__DisplayClass22_0.<<OnVehicleAdded>g__ProcessMessage|0>d(0)
				{
					<>4__this = CS$<>8__locals0
				};
			}
		}

		private void OnVehicleCreated(VehicleCreatedMessage message, CSteamID senderId)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			<>c__DisplayClass23_0 CS$<>8__locals0 = new <>c__DisplayClass23_0();
			CS$<>8__locals0.<>4__this = this;
			CS$<>8__locals0.message = message;
			if (IsHost)
			{
				_logger.Msg($"Received vehicle created message from {senderId}");
				MelonCoroutines.Start(ProcessMessage());
			}
			[IteratorStateMachine(typeof(<>c__DisplayClass23_0.<<OnVehicleCreated>g__ProcessMessage|0>d))]
			IEnumerator ProcessMessage()
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <>c__DisplayClass23_0.<<OnVehicleCreated>g__ProcessMessage|0>d(0)
				{
					<>4__this = CS$<>8__locals0
				};
			}
		}

		private async void OnPoolSyncRequest(VehiclePoolSyncRequest message, CSteamID senderId)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			if (!IsHost)
			{
				return;
			}
			_logger.Msg($"Received pool sync request from {senderId}");
			try
			{
				VehiclePoolSyncResponse response = new VehiclePoolSyncResponse();
				foreach (DeliveryVehicle vehicle in PoolManager.Instance.Pool)
				{
					response.Vehicles.Add(new VehiclePoolSyncResponse.VehicleData
					{
						ObjectId = ((NetworkBehaviour)vehicle.Vehicle).ObjectId,
						Guid = vehicle.GUID,
						Name = vehicle.Vehicle.vehicleName,
						Code = vehicle.Vehicle.VehicleCode,
						Color = (int)vehicle.Vehicle.Color.displayedColor
					});
				}
				_logger.Msg($"Sending pool sync with {response.Vehicles.Count} vehicles");
				await _client.SendMessageToPlayerAsync(senderId, (P2PMessage)(object)response);
			}
			catch (Exception ex)
			{
				_logger.Error($"Failed to send pool sync: {ex}");
			}
		}

		private void OnPoolSyncResponse(VehiclePoolSyncResponse message, CSteamID senderId)
		{
			<>c__DisplayClass25_0 CS$<>8__locals0 = new <>c__DisplayClass25_0();
			CS$<>8__locals0.message = message;
			CS$<>8__locals0.<>4__this = this;
			if (!IsHost)
			{
				_logger.Msg($"Received pool sync response with {CS$<>8__locals0.message.Vehicles.Count} vehicles");
				MelonCoroutines.Start(ProcessMessage());
			}
			[IteratorStateMachine(typeof(<>c__DisplayClass25_0.<<OnPoolSyncResponse>g__ProcessMessage|0>d))]
			IEnumerator ProcessMessage()
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <>c__DisplayClass25_0.<<OnPoolSyncResponse>g__ProcessMessage|0>d(0)
				{
					<>4__this = CS$<>8__locals0
				};
			}
		}

		private void OnVehicleAllocation(VehicleAllocationMessage message, CSteamID senderId)
		{
			<>c__DisplayClass26_0 CS$<>8__locals0 = new <>c__DisplayClass26_0();
			CS$<>8__locals0.message = message;
			CS$<>8__locals0.<>4__this = this;
			_logger.Msg($"Received allocation: Delivery={CS$<>8__locals0.message.DeliveryId}, Vehicle={CS$<>8__locals0.message.VehicleGuid}, Allocated={CS$<>8__locals0.message.IsAllocated}");
			MelonCoroutines.Start(ProcessMessage());
			[IteratorStateMachine(typeof(<>c__DisplayClass26_0.<<OnVehicleAllocation>g__ProcessMessage|0>d))]
			IEnumerator ProcessMessage()
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <>c__DisplayClass26_0.<<OnVehicleAllocation>g__ProcessMessage|0>d(0)
				{
					<>4__this = CS$<>8__locals0
				};
			}
		}

		private void OnBaseVehicleAllocation(BaseVehicleAllocationMessage message, CSteamID senderId)
		{
			_logger.Msg($"Received base allocation: Shop={message.ShopName}, Allocated={message.IsAllocated}");
			try
			{
				PoolManager.Instance.BaseVehicleAllocationsForShop[message.ShopName] = message.IsAllocated;
			}
			catch (Exception arg)
			{
				_logger.Error($"Failed to process base allocation: {arg}");
			}
		}

		private void OnLobbyCreated(object sender, LobbyCreatedEventArgs e)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			_logger.Msg($"Lobby created: {e.Lobby.LobbyId}");
			_client.SetMyData("MultiDelivery_Version", "1.0.0");
		}

		private void OnLobbyJoined(object sender, LobbyJoinedEventArgs e)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			_logger.Msg($"Joined lobby: {e.Lobby.LobbyId}");
			_client.SetMyData("MultiDelivery_Version", "1.0.0");
			if (!IsHost)
			{
				RequestPoolSync();
			}
		}

		private async void OnMemberJoined(object sender, MemberJoinedEventArgs e)
		{
			if (!IsHost)
			{
				return;
			}
			_logger.Msg("Member joined: " + e.Member.DisplayName);
			await Task.Delay(1000);
			VehiclePoolSyncResponse response = new VehiclePoolSyncResponse();
			foreach (DeliveryVehicle vehicle in PoolManager.Instance.Pool)
			{
				response.Vehicles.Add(new VehiclePoolSyncResponse.VehicleData
				{
					ObjectId = ((NetworkBehaviour)vehicle.Vehicle).ObjectId,
					Guid = vehicle.GUID,
					Name = vehicle.Vehicle.vehicleName,
					Code = vehicle.Vehicle.VehicleCode,
					Color = (int)vehicle.Vehicle.Color.displayedColor
				});
			}
			_logger.Msg($"Sending pool sync to new member ({response.Vehicles.Count} vehicles)");
			await _client.SendMessageToPlayerAsync(e.Member.SteamId, (P2PMessage)(object)response);
		}

		private void OnLobbyLeft(object sender, LobbyLeftEventArgs e)
		{
			_logger.Msg("Left lobby: " + e.Reason);
		}

		private async void RequestPoolSync()
		{
			if (!IsSingleplayer && !IsHost)
			{
				List<MemberInfo> members = _client.GetLobbyMembers();
				MemberInfo host = ((IEnumerable<MemberInfo>)members).FirstOrDefault((Func<MemberInfo, bool>)((MemberInfo m) => m.IsOwner));
				if (host == null)
				{
					_logger.Error("Cannot request pool sync - no host found");
					return;
				}
				VehiclePoolSyncRequest vehiclePoolSyncRequest = new VehiclePoolSyncRequest();
				CSteamID localPlayerId = _client.LocalPlayerId;
				vehiclePoolSyncRequest.RequesterId = ((object)(CSteamID)(ref localPlayerId)).ToString();
				VehiclePoolSyncRequest message = vehiclePoolSyncRequest;
				_logger.Msg("Requesting pool sync from host");
				await _client.SendMessageToPlayerAsync(host.SteamId, (P2PMessage)(object)message);
			}
		}

		private LandVehicle? FindLandVehicleByObjectId(int objectId)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			Scene sceneByName = SceneManager.GetSceneByName("Main");
			if (!((Scene)(ref sceneByName)).isLoaded)
			{
				_logger.Error("Main scene is not loaded");
				return null;
			}
			GameObject[] rootGameObjects = ((Scene)(ref sceneByName)).GetRootGameObjects();
			GameObject[] array = rootGameObjects;
			foreach (GameObject val in array)
			{
				LandVehicle[] componentsInChildren = val.GetComponentsInChildren<LandVehicle>(true);
				LandVehicle[] array2 = componentsInChildren;
				foreach (LandVehicle val2 in array2)
				{
					if (((NetworkBehaviour)val2).ObjectId == objectId)
					{
						_logger.Msg($"Found LandVehicle: ObjectId={objectId}, Name={val2.vehicleName}");
						return val2;
					}
				}
			}
			_logger.Warning($"LandVehicle with ObjectId {objectId} not found in Main scene");
			return null;
		}

		[IteratorStateMachine(typeof(<ExponentialBackoff>d__34))]
		private static IEnumerator ExponentialBackoff(Func<bool> predicate, float initialDelay, float finalDelay, float timeout)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ExponentialBackoff>d__34(0)
			{
				predicate = predicate,
				initialDelay = initialDelay,
				finalDelay = finalDelay,
				timeout = timeout
			};
		}
	}
	public class VehicleAddedMessage : P2PMessage
	{
		public override string MessageType => "VehicleAdded";

		public int ObjectId { get; set; }

		public string VehicleGuid { get; set; }

		public string VehicleName { get; set; }

		public string VehicleCode { get; set; }

		public int VehicleColor { get; set; }

		public override byte[] Serialize()
		{
			string s = ((P2PMessage)this).CreateJsonBase($"\"ObjectId\":{ObjectId},\"VehicleGuid\":\"{VehicleGuid}\",\"VehicleName\":\"{VehicleName}\",\"VehicleCode\":\"{VehicleCode}\",\"VehicleColor\":{VehicleColor}");
			return Encoding.UTF8.GetBytes(s);
		}

		public override void Deserialize(byte[] data)
		{
			string @string = Encoding.UTF8.GetString(data);
			((P2PMessage)this).ParseJsonBase(@string);
			ObjectId = int.Parse(((P2PMessage)this).ExtractJsonValue(@string, "ObjectId"));
			VehicleGuid = ((P2PMessage)this).ExtractJsonValue(@string, "VehicleGuid");
			VehicleName = ((P2PMessage)this).ExtractJsonValue(@string, "VehicleName");
			VehicleCode = ((P2PMessage)this).ExtractJsonValue(@string, "VehicleCode");
			VehicleColor = int.Parse(((P2PMessage)this).ExtractJsonValue(@string, "VehicleColor"));
		}
	}
	public class VehicleCreatedMessage : P2PMessage
	{
		public override string MessageType => "VehicleCreated";

		public int ObjectId { get; set; }

		public string VehicleGuid { get; set; }

		public override byte[] Serialize()
		{
			string s = ((P2PMessage)this).CreateJsonBase($"\"ObjectId\":{ObjectId},\"VehicleGuid\":\"{VehicleGuid}\"");
			return Encoding.UTF8.GetBytes(s);
		}

		public override void Deserialize(byte[] data)
		{
			string @string = Encoding.UTF8.GetString(data);
			((P2PMessage)this).ParseJsonBase(@string);
			ObjectId = int.Parse(((P2PMessage)this).ExtractJsonValue(@string, "ObjectId"));
			VehicleGuid = ((P2PMessage)this).ExtractJsonValue(@string, "VehicleGuid");
		}
	}
	public class VehiclePoolSyncRequest : P2PMessage
	{
		public override string MessageType => "VehiclePoolSyncRequest";

		public string RequesterId { get; set; }

		public override byte[] Serialize()
		{
			string s = ((P2PMessage)this).CreateJsonBase("\"RequesterId\":\"" + RequesterId + "\"");
			return Encoding.UTF8.GetBytes(s);
		}

		public override void Deserialize(byte[] data)
		{
			string @string = Encoding.UTF8.GetString(data);
			((P2PMessage)this).ParseJsonBase(@string);
			RequesterId = ((P2PMessage)this).ExtractJsonValue(@string, "RequesterId");
		}
	}
	public class VehiclePoolSyncResponse : P2PMessage
	{
		[Serializable]
		public class VehicleData
		{
			public int ObjectId { get; set; }

			public string Guid { get; set; }

			public string Name { get; set; }

			public string Code { get; set; }

			public int Color { get; set; }
		}

		public override string MessageType => "VehiclePoolSyncResponse";

		public List<VehicleData> Vehicles { get; set; } = new List<VehicleData>();


		public override byte[] Serialize()
		{
			string text = string.Join(",", Vehicles.Select((VehicleData v) => $"{{\"ObjectId\":{v.ObjectId},\"Guid\":\"{v.Guid}\",\"Name\":\"{v.Name}\",\"Code\":\"{v.Code}\",\"Color\":{v.Color}}}"));
			string s = ((P2PMessage)this).CreateJsonBase("\"Vehicles\":[" + text + "]");
			return Encoding.UTF8.GetBytes(s);
		}

		public override void Deserialize(byte[] data)
		{
			string @string = Encoding.UTF8.GetString(data);
			((P2PMessage)this).ParseJsonBase(@string);
			int num = @string.IndexOf("\"Vehicles\":[", StringComparison.Ordinal) + 12;
			int num2 = @string.IndexOf("]", num, StringComparison.Ordinal);
			string text = @string.Substring(num, num2 - num);
			Vehicles.Clear();
			if (string.IsNullOrWhiteSpace(text))
			{
				return;
			}
			string[] array = text.Split(new string[1] { "}," }, StringSplitOptions.None);
			string[] array2 = array;
			foreach (string text2 in array2)
			{
				string text3 = text2.TrimStart('{').TrimEnd('}') + "}";
				if (text3.Contains("ObjectId"))
				{
					Vehicles.Add(new VehicleData
					{
						ObjectId = int.Parse(((P2PMessage)this).ExtractJsonValue(text3, "ObjectId")),
						Guid = ((P2PMessage)this).ExtractJsonValue(text3, "Guid"),
						Name = ((P2PMessage)this).ExtractJsonValue(text3, "Name"),
						Code = ((P2PMessage)this).ExtractJsonValue(text3, "Code"),
						Color = int.Parse(((P2PMessage)this).ExtractJsonValue(text3, "Color"))
					});
				}
			}
		}
	}
	public class VehicleAllocationMessage : P2PMessage
	{
		public override string MessageType => "VehicleAllocation";

		public string DeliveryId { get; set; }

		public string VehicleGuid { get; set; }

		public bool IsAllocated { get; set; }

		public override byte[] Serialize()
		{
			string s = ((P2PMessage)this).CreateJsonBase("\"DeliveryId\":\"" + DeliveryId + "\",\"VehicleGuid\":\"" + VehicleGuid + "\",\"IsAllocated\":" + IsAllocated.ToString().ToLower());
			return Encoding.UTF8.GetBytes(s);
		}

		public override void Deserialize(byte[] data)
		{
			string @string = Encoding.UTF8.GetString(data);
			((P2PMessage)this).ParseJsonBase(@string);
			DeliveryId = ((P2PMessage)this).ExtractJsonValue(@string, "DeliveryId");
			VehicleGuid = ((P2PMessage)this).ExtractJsonValue(@string, "VehicleGuid");
			IsAllocated = bool.Parse(((P2PMessage)this).ExtractJsonValue(@string, "IsAllocated"));
		}
	}
	public class BaseVehicleAllocationMessage : P2PMessage
	{
		public override string MessageType => "BaseVehicleAllocation";

		public string ShopName { get; set; }

		public bool IsAllocated { get; set; }

		public override byte[] Serialize()
		{
			string s = ((P2PMessage)this).CreateJsonBase("\"ShopName\":\"" + ShopName + "\",\"IsAllocated\":" + IsAllocated.ToString().ToLower());
			return Encoding.UTF8.GetBytes(s);
		}

		public override void Deserialize(byte[] data)
		{
			string @string = Encoding.UTF8.GetString(data);
			((P2PMessage)this).ParseJsonBase(@string);
			ShopName = ((P2PMessage)this).ExtractJsonValue(@string, "ShopName");
			IsAllocated = bool.Parse(((P2PMessage)this).ExtractJsonValue(@string, "IsAllocated"));
		}
	}
	public static class NetworkConvenienceMethods
	{
		private static DeliveryNetworkManager? _networkManager;

		public static bool HostOrSingleplayer => _networkManager?.HostOrSingleplayer ?? true;

		public static void InitializeNetworking(DeliveryNetworkManager networkManager)
		{
			_networkManager = networkManager;
		}

		public static void NotifyVehicleAdded(DeliveryVehicle vehicle)
		{
			_networkManager?.BroadcastVehicleAdded(vehicle);
		}

		public static void NotifyVehicleCreated(DeliveryVehicle vehicle)
		{
			_networkManager?.BroadcastVehicleCreated(vehicle);
		}

		public static void NotifyAllocation(string deliveryId, DeliveryVehicle vehicle, bool isAllocated)
		{
			_networkManager?.BroadcastVehicleAllocation(deliveryId, vehicle, isAllocated);
		}

		public static void NotifyBaseAllocation(string shopName, bool isAllocated)
		{
			_networkManager?.BroadcastBaseVehicleAllocation(shopName, isAllocated);
		}
	}
}
namespace MultiDelivery.Helpers
{
	public static class MelonLoggerExtensions
	{
		public static void Debug(this Instance logger, string message, bool stacktrace = true)
		{
			MelonDebug.Msg(stacktrace ? ("[" + GetCallerInfo() + "] " + message) : message);
		}

		private static string GetCallerInfo()
		{
			StackTrace stackTrace = new StackTrace();
			for (int i = 2; i < stackTrace.FrameCount; i++)
			{
				StackFrame frame = stackTrace.GetFrame(i);
				MethodBase method = frame.GetMethod();
				if (!(method?.DeclaringType == null))
				{
					return method.DeclaringType.FullName + "." + method.Name;
				}
			}
			return "unknown";
		}
	}
	public static class Il2CppListExtensions
	{
		public static IEnumerable<T> AsEnumerable<T>(this List<T> list)
		{
			return list ?? new List<T>();
		}

		public static object ToNativeList<T>(this List<T> source)
		{
			return source ?? new List<T>();
		}
	}
	public static class Utils
	{
		[CompilerGenerated]
		private sealed class <WaitForCondition>d__6 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Func<bool> condition;

			public float timeout;

			public Action onTimeout;

			public Action onFinish;

			private float <startTime>5__1;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<startTime>5__1 = Time.time;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (!condition())
				{
					if (!float.IsNaN(timeout) && Time.time - <startTime>5__1 > timeout)
					{
						onTimeout?.Invoke();
						return false;
					}
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				onFinish?.Invoke();
				return false;
			}

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

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

		[CompilerGenerated]
		private sealed class <WaitForNetwork>d__5 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public IEnumerator routine;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (!InstanceFinder.IsServer && !InstanceFinder.IsClient)
				{
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				MelonCoroutines.Start(routine);
				return false;
			}

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

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

		[CompilerGenerated]
		private sealed class <WaitForPlayer>d__4 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public IEnumerator routine;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if ((Object)(object)Player.Local == (Object)null || (Object)(object)((Component)Player.Local).gameObject == (Object)null)
				{
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				MelonCoroutines.Start(routine);
				return false;
			}

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

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

		private static readonly Instance Logger = new Instance("MultiDelivery-Utils");

		public static T? FindObjectByName<T>(string objectName) where T : Object
		{
			try
			{
				T[] array = Resources.FindObjectsOfTypeAll<T>();
				foreach (T val in array)
				{
					if (!(((Object)val).name != objectName))
					{
						Logger.Debug("Found " + typeof(T).Name + " '" + objectName + "' directly in loaded objects");
						return val;
					}
				}
				return default(T);
			}
			catch (Exception ex)
			{
				Logger.Error("Error finding " + typeof(T).Name + " '" + objectName + "': " + ex.Message);
				return default(T);
			}
		}

		public static List<T> GetAllComponentsInChildrenRecursive<T>(GameObject obj) where T : Component
		{
			List<T> list = new List<T>();
			if ((Object)(object)obj == (Object)null)
			{
				return list;
			}
			T[] components = obj.GetComponents<T>();
			if (components.Length != 0)
			{
				list.AddRange(components);
			}
			for (int i = 0; i < obj.transform.childCount; i++)
			{
				Transform child = obj.transform.GetChild(i);
				list.AddRange(GetAllComponentsInChildrenRecursive<T>(((Component)child).gameObject));
			}
			return list;
		}

		public static bool Is<T>(object obj, out T? result) where T : class
		{
			if (obj is T val)
			{
				result = val;
				return true;
			}
			result = null;
			return false;
		}

		[IteratorStateMachine(typeof(<WaitForPlayer>d__4))]
		public static IEnumerator WaitForPlayer(IEnumerator routine)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WaitForPlayer>d__4(0)
			{
				routine = routine
			};
		}

		[IteratorStateMachine(typeof(<WaitForNetwork>d__5))]
		public static IEnumerator WaitForNetwork(IEnumerator routine)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WaitForNetwork>d__5(0)
			{
				routine = routine
			};
		}

		[IteratorStateMachine(typeof(<WaitForCondition>d__6))]
		public static IEnumerator WaitForCondition(Func<bool> condition, float timeout = float.NaN, Action? onTimeout = null, Action? onFinish = null)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WaitForCondition>d__6(0)
			{
				condition = condition,
				timeout = timeout,
				onTimeout = onTimeout,
				onFinish = onFinish
			};
		}

		public static string GetHierarchyPath(this Transform transform)
		{
			if ((Object)(object)transform == (Object)null)
			{
				return "null";
			}
			string text = ((Object)transform).name;
			Transform parent = transform.parent;
			while ((Object)(object)parent != (Object)null)
			{
				text = ((Object)parent).name + "/" + text;
				parent = parent.parent;
			}
			return text;
		}

		public static T GetOrAddComponent<T>(this GameObject gameObject) where T : Component
		{
			T component = gameObject.GetComponent<T>();
			if ((Object)(object)component != (Object)null)
			{
				return component;
			}
			component = gameObject.AddComponent<T>();
			Logger.Debug("Added component " + typeof(T).Name + " to GameObject " + ((Object)gameObject).name);
			return component;
		}

		public static Material? DrawDebugVisuals(this GameObject gameObject, Color? color = null)
		{
			//IL_0040: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Expected O, but got Unknown
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			Renderer component = gameObject.GetComponent<Renderer>();
			if ((Object)(object)component == (Object)null)
			{
				Logger.Error("GameObject " + ((Object)gameObject).name + " has no Renderer component");
				return null;
			}
			Color valueOrDefault = color.GetValueOrDefault();
			if (!color.HasValue)
			{
				((Color)(ref valueOrDefault))..ctor(1f, 0f, 1f, 0.5f);
				color = valueOrDefault;
			}
			Shader val = Shader.Find("Universal Render Pipeline/Lit");
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Material val2 = new Material(val);
			if (val2.HasProperty("_Surface"))
			{
				val2.SetFloat("_Surface", 1f);
			}
			Color value = color.Value;
			if (value.a <= 0f)
			{
				value.a = 0.2f;
			}
			if (val2.HasProperty("_BaseColor"))
			{
				val2.SetColor("_BaseColor", value);
			}
			if (val2.HasProperty("_EmissionColor"))
			{
				val2.EnableKeyword("_EMISSION");
				val2.SetColor("_EmissionColor", new Color(value.r, value.g, value.b) * 1.5f);
			}
			val2.SetInt("_ZWrite", 0);
			val2.renderQueue = 3000;
			Material material = component.material;
			component.material = val2;
			return material;
		}

		public static string Capitalize(this string str)
		{
			if (str.Length < 1)
			{
				throw new ArgumentOutOfRangeException("str");
			}
			return char.ToUpper(str[0]) + str.Substring(1, str.Length - 1);
		}
	}
}
namespace MultiDelivery.Builders
{
	public class DeliveryVehicleBuilder
	{
		private Guid _guid;

		private LandVehicle _landVehicle;

		public DeliveryVehicleBuilder WithGuid(Guid guid)
		{
			_guid = guid;
			return this;
		}

		public DeliveryVehicleBuilder WithGuid(string guid)
		{
			_guid = new Guid(guid);
			return this;
		}

		public DeliveryVehicleBuilder WithLandVehicle(LandVehicle landVehicle)
		{
			_landVehicle = landVehicle;
			return this;
		}

		public DeliveryVehicleBuilder WithLandVehicle(GameObject landVehicle)
		{
			_landVehicle = landVehicle.GetComponent<LandVehicle>();
			return this;
		}

		public DeliveryVehicle Build()
		{
			DeliveryVehicle val = ((Component)_landVehicle).gameObject.AddComponent<DeliveryVehicle>();
			val.GUID = _guid.ToString();
			_landVehicle.SetGUID(_guid);
			return val;
		}
	}
	public class LandVehicleBuilder
	{
		private string _vehicleName = "CustomVehicle";

		private string _vehicleCode = "veeper";

		private EVehicleColor _color = (EVehicleColor)16;

		private Guid _guid = GUIDManager.GenerateUniqueGUID();

		private static Transform? _parent;

		public LandVehicleBuilder WithVehicleName(string vehicleName)
		{
			_vehicleName = vehicleName;
			return this;
		}

		public LandVehicleBuilder WithVehicleCode(string vehicleCode)
		{
			_vehicleCode = vehicleCode;
			return this;
		}

		public LandVehicleBuilder WithColor(EVehicleColor color)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			_color = color;
			return this;
		}

		public LandVehicleBuilder WithGuid(Guid guid)
		{
			_guid = guid;
			return this;
		}

		public LandVehicleBuilder WithGuid(string guid)
		{
			_guid = new Guid(guid);
			return this;
		}

		public LandVehicleBuilder WithParent(Transform parent)
		{
			_parent = parent;
			return this;
		}

		public LandVehicle Build()
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_parent == (Object)null)
			{
				GameObject val = GameObject.Find("VehiclePool");
				if ((Object)(object)val == (Object)null)
				{
					val = new GameObject("VehiclePool");
				}
				_parent = val.transform;
			}
			Vector3 position = default(Vector3);
			((Vector3)(ref position))..ctor(0f, -100f, 0f);
			Quaternion identity = Quaternion.identity;
			if (!InstanceFinder.IsServer)
			{
				throw new ArgumentException("LandVehicleBuilder can only be used on the server");
			}
			LandVehicle vehiclePrefab = NetworkSingleton<VehicleManager>.Instance.GetVehiclePrefab(_vehicleCode);
			if ((Object)(object)vehiclePrefab == (Object)null)
			{
				throw new ArgumentException("Vehicle prefab with code '" + _vehicleCode + "' not found.");
			}
			GameObject val2 = Object.Instantiate<GameObject>(((Component)vehiclePrefab).gameObject, _parent, true);
			LandVehicle component = val2.GetComponent<LandVehicle>();
			component.IsPlayerOwned = false;
			component.SetVisible(false);
			component.IsPhysicallySimulated = false;
			((Component)component).transform.position = position;
			((Component)component).transform.rotation = identity;
			component.SetGUID(_guid);
			((Object)component).name = _vehicleName;
			((Object)((Component)component).gameObject).name = _vehicleName;
			component.vehicleName = _vehicleName;
			component.SetIsPlayerOwned((NetworkConnection)null, false);
			component.Rb.isKinematic = false;
			((NetworkBehaviour)component).Owner.ClientId = -1;
			component.ApplyColor(_color);
			NetworkSingleton<VehicleManager>.Instance.AllVehicles.Add(component);
			((NetworkBehaviour)NetworkSingleton<VehicleManager>.Instance).NetworkObject.Spawn(((Component)component).gameObject, (NetworkConnection)null, default(Scene));
			return component;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		internal IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}