

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;
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 Semver;
using SteamNetworkLib;
using SteamNetworkLib.Core;
using SteamNetworkLib.Events;
using SteamNetworkLib.Models;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
[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.2", "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.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2+b40318182c658627bb7a3309a0e6dd136e13a267")]
[assembly: AssemblyProduct("MultiDelivery-IL2CPP")]
[assembly: AssemblyTitle("MultiDelivery-IL2CPP")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.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.2";
}
public class MultiDelivery : MelonMod
{
[CompilerGenerated]
private sealed class <InitializeNetworkManager>d__7 : 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__7(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();
}
}
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 override void OnInitializeMelon()
{
Logger.Msg("MultiDelivery initialized");
DependenciesChecker.PrintMissing();
MelonCoroutines.Start(InitializeNetworkManager());
}
public override void OnSceneWasLoaded(int buildIndex, string sceneName)
{
QuestSetupManager.OnSceneWasLoaded(buildIndex, sceneName);
if (!(sceneName != "Menu"))
{
PoolManager.Instance.Pool.Clear();
PoolManager.Instance.Allocations.Clear();
PoolManager.Instance.BaseVehicleAllocationsForShop.Clear();
}
}
[IteratorStateMachine(typeof(<InitializeNetworkManager>d__7))]
private IEnumerator InitializeNetworkManager()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <InitializeNetworkManager>d__7(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");
}
}
}
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) ? "ies" : "y")} 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 => IconLoader.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;
}
}
public class QuestSetupManager
{
[CompilerGenerated]
private sealed class <WireOnXpChangedDelayed>d__5 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <WireOnXpChangedDelayed>d__5(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 += 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 readonly Logger Logger = new Logger("QuestSetupManager");
public static void OnSceneWasLoaded(int buildIndex, string sceneName)
{
if (!(sceneName == "Main"))
{
if (sceneName == "Menu")
{
Player.LocalPlayerSpawned -= WirePlayerEvent;
LevelManager.OnXPChanged -= SendMessageIfRequiredRank;
}
}
else
{
Player.LocalPlayerSpawned += WirePlayerEvent;
}
}
private static void WirePlayerEvent(Player _)
{
Logger.Debug("Player loaded event called");
MelonCoroutines.Start(WireOnXpChangedDelayed());
}
[IteratorStateMachine(typeof(<WireOnXpChangedDelayed>d__5))]
private static IEnumerator WireOnXpChangedDelayed()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <WireOnXpChangedDelayed>d__5(0);
}
private static 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;
}
}
}
}
[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_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_011a: 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_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
LandVehicle vehicle2 = vehicle;
_logger.Debug($"Adding vehicle to pool: {vehicle2.GUID}");
DeliveryVehicle val = ((Component)vehicle2).GetComponent<DeliveryVehicle>();
if ((Object)(object)val == (Object)null)
{
Guid gUID = vehicle2.GUID;
val = new DeliveryVehicleBuilder().WithLandVehicle(vehicle2).WithGuid(gUID).Build();
}
vehicle2.IsPlayerOwned = false;
vehicle2.SetIsPlayerOwned((NetworkConnection)null, false);
vehicle2.SetVisible(false);
vehicle2.IsPhysicallySimulated = false;
IEnumerable<LandVehicle> source = NetworkSingleton<VehicleManager>.Instance.PlayerOwnedVehicles.AsEnumerable<LandVehicle>().Where(delegate(LandVehicle lv)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: 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)
Guid gUID2 = lv.GUID;
string? text = ((object)(Guid)(ref gUID2)).ToString();
gUID2 = vehicle2.GUID;
return text != ((object)(Guid)(ref gUID2)).ToString();
});
NetworkSingleton<VehicleManager>.Instance.PlayerOwnedVehicles = source.ToIl2CppList();
((Component)vehicle2).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(DeliveryShop))]
internal static class CapacityText
{
private static readonly Logger Logger = new Logger("CapacityText");
private static ConditionalWeakTable<DeliveryShop, Text> _capacityTexts = new ConditionalWeakTable<DeliveryShop, Text>();
[HarmonyPatch("Initialize")]
[HarmonyPostfix]
private static void AddCapacityTextPostfix(DeliveryShop __instance)
{
Logger.Debug("Adding capacity text for " + ((Object)__instance).name);
if (_capacityTexts.TryGetValue(__instance, out Text _))
{
return;
}
Text deliveryTimeLabel = __instance.DeliveryTimeLabel;
GameObject val = ((deliveryTimeLabel != null) ? ((Component)((Component)deliveryTimeLabel).transform.parent).gameObject : null);
Logger.Debug($"Adding capacity text: {deliveryTimeLabel}, templatego: {val}");
if (val == null)
{
return;
}
GameObject val2 = Object.Instantiate<GameObject>(val);
val2.transform.SetParent(val.transform.parent, false);
val2.transform.SetSiblingIndex(val.transform.GetSiblingIndex());
Text component = ((Component)val2.transform.Find("Label")).GetComponent<Text>();
component.text = "Free vehicles";
Text component2 = ((Component)val2.transform.Find("Time")).GetComponent<Text>();
component2.text = "1/1";
_capacityTexts.Add(__instance, component2);
List<Transform> list = val.transform.parent.FindAllTransforms("Spacer");
if (list.Count > 0)
{
Transform val3 = list[list.Count - 1];
if ((Object)(object)val3 != (Object)null)
{
((Component)val3).gameObject.SetActive(false);
}
}
}
[HarmonyPatch("FixedUpdate")]
[HarmonyPostfix]
private static void UpdateCapacityTextPostfix(DeliveryShop __instance)
{
if (__instance.IsOpen && ((App<DeliveryApp>)(object)PlayerSingleton<DeliveryApp>.Instance).isOpen && _capacityTexts.TryGetValue(__instance, out Text value))
{
var (value2, value3) = GetVehiclesForShop(__instance);
value.text = $"{value2}/{value3}";
}
}
private static (int available, int total) GetVehiclesForShop(DeliveryShop shop)
{
string matchingShopInterfaceName = shop.MatchingShopInterfaceName;
PoolManager instance = PoolManager.Instance;
int item = 1 + instance.Pool.Count;
int num = 0;
if (!(instance.BaseVehicleAllocationsForShop.TryGetValue(matchingShopInterfaceName, out var value) && value))
{
num++;
}
int num2 = Math.Min(instance.Allocations.Count, instance.Pool.Count);
int num3 = instance.Pool.Count - num2;
num += num3;
return (num, item);
}
}
[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 DependenciesChecker
{
private static readonly Logger Logger = new Logger("DependenciesChecker");
private static readonly List<Dependency> Dependencies = new List<Dependency>(2)
{
new Dependency
{
Name = "S1API (Forked)",
AssemblyName = "S1API",
MinVersion = new SemVersion(3, 0, 1, "", ""),
IsRequired = true
},
new Dependency
{
Name = "SteamNetworkLib",
AssemblyName = "SteamNetworkLib",
MinVersion = new SemVersion(1, 2, 1, "", ""),
IsRequired = false
}
};
private static bool IsPresent(Dependency dependency)
{
Dependency dependency2 = dependency;
Assembly foundInDomain = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly assembly) => assembly.GetName().Name == dependency2.AssemblyName);
if (foundInDomain == null)
{
return false;
}
MelonMod val = ((IEnumerable<MelonMod>)MelonTypeBase<MelonMod>.RegisteredMelons).FirstOrDefault((Func<MelonMod, bool>)((MelonMod m) => ((MelonBase)m).MelonAssembly.Assembly == foundInDomain));
if (val == null)
{
Logger.Debug(foundInDomain.GetName().Name + " wasn't found in RegisteredMelons, cannot verify version. Assuming present.");
return true;
}
SemVersion semanticVersion = ((MelonBase)val).Info.SemanticVersion;
if (semanticVersion == (SemVersion)null)
{
Logger.Debug($"{foundInDomain.GetName().Name}'s version {semanticVersion} is not SemVer. Assuming present.");
return true;
}
return semanticVersion >= dependency2.MinVersion;
}
private static List<Dependency> GetMissing()
{
return Dependencies.Where((Dependency dependency) => !IsPresent(dependency)).ToList();
}
public static void PrintMissing()
{
List<Dependency> missing = GetMissing();
if (!missing.Any())
{
return;
}
foreach (Dependency item in missing)
{
if (item.IsRequired)
{
Logger.Error($"Critical:\nRequired dependency {item.Name} is missing or outdated (min version {item.MinVersion}). Mod will not function correctly without it.");
}
else
{
Logger.Warn($"Optional dependency {item.Name} is missing or outdated (min version {item.MinVersion}).");
}
}
}
}
public record Dependency
{
public string Name { get; set; }
public string AssemblyName { get; set; }
public SemVersion MinVersion { get; set; }
public bool IsRequired { get; set; }
}
public class IconLoader
{
private static Sprite _questIconSprite;
public static Sprite QuestIconSprite => GetIcon(ref _questIconSprite, "MultiDelivery.assets.quest_icon.png");
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;
}
}
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__7 : 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__7(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__6 : 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__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;
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__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 <WaitForPlayer>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 ((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 List<Transform> FindAllTransforms(this Transform transform, string name)
{
List<Transform> list = new List<Transform>();
for (int i = 0; i < transform.childCount; i++)
{
Transform child = transform.GetChild(i);
if (((Object)child).name == name)
{
list.Add(child);
}
}
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__5))]
public static IEnumerator WaitForPlayer(IEnumerator routine)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <WaitForPlayer>d__5(0)
{
routine = routine
};
}
[IteratorStateMachine(typeof(<WaitForNetwork>d__6))]
public static IEnumerator WaitForNetwork(IEnumerator routine)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <WaitForNetwork>d__6(0)
{
routine = routine
};
}
[IteratorStateMachine(typeof(<WaitForCondition>d__7))]
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__7(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)
{
returnusing 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;
using ScheduleOne.UI.Phone.Delivery;
using ScheduleOne.UI.Shop;
using ScheduleOne.Vehicles;
using ScheduleOne.Vehicles.Modification;
using ScheduleOne.Weather;
using Semver;
using SteamNetworkLib;
using SteamNetworkLib.Core;
using SteamNetworkLib.Events;
using SteamNetworkLib.Models;
using Steamworks;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
[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.2", "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.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2+b40318182c658627bb7a3309a0e6dd136e13a267")]
[assembly: AssemblyProduct("MultiDelivery-Mono")]
[assembly: AssemblyTitle("MultiDelivery-Mono")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.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.2";
}
public class MultiDelivery : MelonMod
{
[CompilerGenerated]
private sealed class <InitializeNetworkManager>d__7 : 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__7(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();
}
}
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 override void OnInitializeMelon()
{
Logger.Msg("MultiDelivery initialized");
DependenciesChecker.PrintMissing();
MelonCoroutines.Start(InitializeNetworkManager());
}
public override void OnSceneWasLoaded(int buildIndex, string sceneName)
{
QuestSetupManager.OnSceneWasLoaded(buildIndex, sceneName);
if (!(sceneName != "Menu"))
{
PoolManager.Instance.Pool.Clear();
PoolManager.Instance.Allocations.Clear();
PoolManager.Instance.BaseVehicleAllocationsForShop.Clear();
}
}
[IteratorStateMachine(typeof(<InitializeNetworkManager>d__7))]
private IEnumerator InitializeNetworkManager()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <InitializeNetworkManager>d__7(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");
}
}
}
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) ? "ies" : "y") + " 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 => IconLoader.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;
}
}
public class QuestSetupManager
{
[CompilerGenerated]
private sealed class <WireOnXpChangedDelayed>d__5 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <WireOnXpChangedDelayed>d__5(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 += 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 readonly Logger Logger = new Logger("QuestSetupManager");
public static void OnSceneWasLoaded(int buildIndex, string sceneName)
{
if (!(sceneName == "Main"))
{
if (sceneName == "Menu")
{
Player.LocalPlayerSpawned -= WirePlayerEvent;
LevelManager.OnXPChanged -= SendMessageIfRequiredRank;
}
}
else
{
Player.LocalPlayerSpawned += WirePlayerEvent;
}
}
private static void WirePlayerEvent(Player _)
{
Logger.Debug("Player loaded event called");
MelonCoroutines.Start(WireOnXpChangedDelayed());
}
[IteratorStateMachine(typeof(<WireOnXpChangedDelayed>d__5))]
private static IEnumerator WireOnXpChangedDelayed()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <WireOnXpChangedDelayed>d__5(0);
}
private static 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;
}
}
}
}
[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_0102: Unknown result type (might be due to invalid IL or missing references)
LandVehicle vehicle2 = vehicle;
_logger.Debug($"Adding vehicle to pool: {vehicle2.GUID}");
DeliveryVehicle val = ((Component)vehicle2).GetComponent<DeliveryVehicle>();
if ((Object)(object)val == (Object)null)
{
Guid gUID = vehicle2.GUID;
val = new DeliveryVehicleBuilder().WithLandVehicle(vehicle2).WithGuid(gUID).Build();
}
vehicle2.IsPlayerOwned = false;
vehicle2.SetIsPlayerOwned((NetworkConnection)null, false);
vehicle2.SetVisible(false);
vehicle2.IsPhysicallySimulated = false;
IEnumerable<LandVehicle> source = from lv in NetworkSingleton<VehicleManager>.Instance.PlayerOwnedVehicles.AsEnumerable()
where lv.GUID.ToString() != vehicle2.GUID.ToString()
select lv;
NetworkSingleton<VehicleManager>.Instance.PlayerOwnedVehicles = source.ToList();
((Component)vehicle2).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(DeliveryShop))]
internal static class CapacityText
{
private static readonly Logger Logger = new Logger("CapacityText");
private static ConditionalWeakTable<DeliveryShop, Text> _capacityTexts = new ConditionalWeakTable<DeliveryShop, Text>();
[HarmonyPatch("Initialize")]
[HarmonyPostfix]
private static void AddCapacityTextPostfix(DeliveryShop __instance)
{
Logger.Debug("Adding capacity text for " + ((Object)__instance).name);
if (_capacityTexts.TryGetValue(__instance, out Text _))
{
return;
}
Text deliveryTimeLabel = __instance.DeliveryTimeLabel;
GameObject val = ((deliveryTimeLabel != null) ? ((Component)((Component)deliveryTimeLabel).transform.parent).gameObject : null);
Logger.Debug($"Adding capacity text: {deliveryTimeLabel}, templatego: {val}");
if (val == null)
{
return;
}
GameObject val2 = Object.Instantiate<GameObject>(val);
val2.transform.SetParent(val.transform.parent, false);
val2.transform.SetSiblingIndex(val.transform.GetSiblingIndex());
Text component = ((Component)val2.transform.Find("Label")).GetComponent<Text>();
component.text = "Free vehicles";
Text component2 = ((Component)val2.transform.Find("Time")).GetComponent<Text>();
component2.text = "1/1";
_capacityTexts.Add(__instance, component2);
List<Transform> list = val.transform.parent.FindAllTransforms("Spacer");
if (list.Count > 0)
{
Transform val3 = list[list.Count - 1];
if ((Object)(object)val3 != (Object)null)
{
((Component)val3).gameObject.SetActive(false);
}
}
}
[HarmonyPatch("FixedUpdate")]
[HarmonyPostfix]
private static void UpdateCapacityTextPostfix(DeliveryShop __instance)
{
if (__instance.IsOpen && ((App<DeliveryApp>)(object)PlayerSingleton<DeliveryApp>.Instance).isOpen && _capacityTexts.TryGetValue(__instance, out Text value))
{
var (num, num2) = GetVehiclesForShop(__instance);
value.text = $"{num}/{num2}";
}
}
private static (int available, int total) GetVehiclesForShop(DeliveryShop shop)
{
string matchingShopInterfaceName = shop.MatchingShopInterfaceName;
PoolManager instance = PoolManager.Instance;
int item = 1 + instance.Pool.Count;
int num = 0;
if (!(instance.BaseVehicleAllocationsForShop.TryGetValue(matchingShopInterfaceName, out var value) && value))
{
num++;
}
int num2 = Math.Min(instance.Allocations.Count, instance.Pool.Count);
int num3 = instance.Pool.Count - num2;
num += num3;
return (num, item);
}
}
[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 DependenciesChecker
{
private static readonly Logger Logger = new Logger("DependenciesChecker");
private static readonly List<Dependency> Dependencies = new List<Dependency>(2)
{
new Dependency
{
Name = "S1API (Forked)",
AssemblyName = "S1API",
MinVersion = new SemVersion(3, 0, 1, "", ""),
IsRequired = true
},
new Dependency
{
Name = "SteamNetworkLib",
AssemblyName = "SteamNetworkLib",
MinVersion = new SemVersion(1, 2, 1, "", ""),
IsRequired = false
}
};
private static bool IsPresent(Dependency dependency)
{
Dependency dependency2 = dependency;
Assembly foundInDomain = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly assembly) => assembly.GetName().Name == dependency2.AssemblyName);
if (foundInDomain == null)
{
return false;
}
MelonMod val = ((IEnumerable<MelonMod>)MelonTypeBase<MelonMod>.RegisteredMelons).FirstOrDefault((Func<MelonMod, bool>)((MelonMod m) => ((MelonBase)m).MelonAssembly.Assembly == foundInDomain));
if (val == null)
{
Logger.Debug(foundInDomain.GetName().Name + " wasn't found in RegisteredMelons, cannot verify version. Assuming present.");
return true;
}
SemVersion semanticVersion = ((MelonBase)val).Info.SemanticVersion;
if (semanticVersion == (SemVersion)null)
{
Logger.Debug($"{foundInDomain.GetName().Name}'s version {semanticVersion} is not SemVer. Assuming present.");
return true;
}
return semanticVersion >= dependency2.MinVersion;
}
private static List<Dependency> GetMissing()
{
return Dependencies.Where((Dependency dependency) => !IsPresent(dependency)).ToList();
}
public static void PrintMissing()
{
List<Dependency> missing = GetMissing();
if (!missing.Any())
{
return;
}
foreach (Dependency item in missing)
{
if (item.IsRequired)
{
Logger.Error($"Critical:\nRequired dependency {item.Name} is missing or outdated (min version {item.MinVersion}). Mod will not function correctly without it.");
}
else
{
Logger.Warn($"Optional dependency {item.Name} is missing or outdated (min version {item.MinVersion}).");
}
}
}
}
public record Dependency
{
public string Name { get; set; }
public string AssemblyName { get; set; }
public SemVersion MinVersion { get; set; }
public bool IsRequired { get; set; }
}
public class IconLoader
{
private static Sprite _questIconSprite;
public static Sprite QuestIconSprite => GetIcon(ref _questIconSprite, "MultiDelivery.assets.quest_icon.png");
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;
}
}
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__7 : 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__7(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__6 : 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__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;
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__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 <WaitForPlayer>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 ((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 List<Transform> FindAllTransforms(this Transform transform, string name)
{
List<Transform> list = new List<Transform>();
for (int i = 0; i < transform.childCount; i++)
{
Transform child = transform.GetChild(i);
if (((Object)child).name == name)
{
list.Add(child);
}
}
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__5))]
public static IEnumerator WaitForPlayer(IEnumerator routine)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <WaitForPlayer>d__5(0)
{
routine = routine
};
}
[IteratorStateMachine(typeof(<WaitForNetwork>d__6))]
public static IEnumerator WaitForNetwork(IEnumerator routine)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <WaitForNetwork>d__6(0)
{
routine = routine
};
}
[IteratorStateMachine(typeof(<WaitForCondition>d__7))]
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__7(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)(re