Decompiled source of AdvancedDealingCommunity v1.5.2

Mods/AdvancedDealing.Il2Cpp.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using AdvancedDealing;
using AdvancedDealing.Economy;
using AdvancedDealing.Localization;
using AdvancedDealing.Messaging;
using AdvancedDealing.Messaging.Messages;
using AdvancedDealing.NPCs.Behaviour;
using AdvancedDealing.Persistence;
using AdvancedDealing.Persistence.Datas;
using AdvancedDealing.Persistence.IO;
using AdvancedDealing.UI;
using AdvancedDealing.Utils;
using HarmonyLib;
using Il2CppFishNet;
using Il2CppGameKit.Utilities;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppScheduleOne;
using Il2CppScheduleOne.Core.Items.Framework;
using Il2CppScheduleOne.DevUtilities;
using Il2CppScheduleOne.Dialogue;
using Il2CppScheduleOne.Economy;
using Il2CppScheduleOne.GameTime;
using Il2CppScheduleOne.ItemFramework;
using Il2CppScheduleOne.Map;
using Il2CppScheduleOne.Messaging;
using Il2CppScheduleOne.Money;
using Il2CppScheduleOne.NPCs;
using Il2CppScheduleOne.NPCs.Behaviour;
using Il2CppScheduleOne.Networking;
using Il2CppScheduleOne.Persistence;
using Il2CppScheduleOne.PlayerScripts;
using Il2CppScheduleOne.Product;
using Il2CppScheduleOne.Storage;
using Il2CppScheduleOne.UI;
using Il2CppScheduleOne.UI.Phone;
using Il2CppScheduleOne.UI.Phone.Messages;
using Il2CppSteamworks;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Text;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Events;
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::AdvancedDealing.AdvancedDealing), "AdvancedDealing", "1.5.1", "ManZune & UrbanSide Community", "https://github.com/UrbanSide/AdvancedDealing-Community")]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: MelonColor(255, 113, 195, 230)]
[assembly: MelonPlatformDomain(/*Could not decode attribute arguments.*/)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("ManZune; UrbanSide Community")]
[assembly: AssemblyConfiguration("Il2Cpp")]
[assembly: AssemblyDescription("Community-maintained Schedule I dealer automation mod with localization and separate product/cash dead drops")]
[assembly: AssemblyFileVersion("1.5.1.0")]
[assembly: AssemblyInformationalVersion("1.5.1")]
[assembly: AssemblyProduct("AdvancedDealing")]
[assembly: AssemblyTitle("AdvancedDealing")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/UrbanSide/AdvancedDealing-Community")]
[assembly: AssemblyVersion("1.5.1.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace AdvancedDealing
{
	public class AdvancedDealing : MelonMod
	{
		public bool IsInitialized { get; private set; }

		public SaveModifier SaveModifier { get; private set; }

		public NetworkSynchronizer NetworkSynchronizer { get; private set; }

		public override void OnSceneWasInitialized(int buildIndex, string sceneName)
		{
			if (sceneName == "Menu")
			{
				if (!IsInitialized)
				{
					ModConfig.Initialize();
					LocalizationManager.Initialize(ModConfig.Language);
					ConflictChecker.CheckForConflicts();
					SaveModifier = new SaveModifier();
					NetworkSynchronizer = new NetworkSynchronizer();
					Logger.Msg("AdvancedDealing v1.5.1 initialized");
					IsInitialized = true;
				}
				if (SaveModifier.SavegameLoaded)
				{
					SaveModifier.ClearModifications();
				}
			}
			else if (sceneName == "Main")
			{
				SaveModifier.LoadModifications();
			}
		}
	}
	public static class ModConfig
	{
		private static MelonPreferences_Category generalCategory;

		private static bool isInitialized;

		public static string Language
		{
			get
			{
				return generalCategory.GetEntry<string>("Language").Value;
			}
			set
			{
				generalCategory.GetEntry<string>("Language").Value = value;
			}
		}

		public static bool Debug
		{
			get
			{
				return generalCategory.GetEntry<bool>("Debug").Value;
			}
			set
			{
				generalCategory.GetEntry<bool>("Debug").Value = value;
			}
		}

		public static bool SkipMovement
		{
			get
			{
				return generalCategory.GetEntry<bool>("SkipMovement").Value;
			}
			set
			{
				generalCategory.GetEntry<bool>("SkipMovement").Value = value;
			}
		}

		public static bool NotifyOnAction
		{
			get
			{
				return generalCategory.GetEntry<bool>("NotifyOnAction").Value;
			}
			set
			{
				generalCategory.GetEntry<bool>("NotifyOnAction").Value = value;
			}
		}

		public static bool CustomersSearchAndSort
		{
			get
			{
				return generalCategory.GetEntry<bool>("CustomersSearchAndSort").Value;
			}
			set
			{
				generalCategory.GetEntry<bool>("CustomersSearchAndSort").Value = value;
			}
		}

		public static bool AccessInventory
		{
			get
			{
				if (NetworkSynchronizer.IsSyncing && NetworkSynchronizer.Instance.SessionData != null)
				{
					return NetworkSynchronizer.Instance.SessionData.AccessInventory;
				}
				return generalCategory.GetEntry<bool>("AccessInventory").Value;
			}
			set
			{
				generalCategory.GetEntry<bool>("AccessInventory").Value = value;
			}
		}

		public static bool SettingsMenu
		{
			get
			{
				if (NetworkSynchronizer.IsSyncing && NetworkSynchronizer.Instance.SessionData != null)
				{
					return NetworkSynchronizer.Instance.SessionData.SettingsMenu;
				}
				return generalCategory.GetEntry<bool>("SettingsMenu").Value;
			}
			set
			{
				generalCategory.GetEntry<bool>("SettingsMenu").Value = value;
			}
		}

		public static float NegotiationModifier
		{
			get
			{
				if (NetworkSynchronizer.IsSyncing && NetworkSynchronizer.Instance.SessionData != null)
				{
					return NetworkSynchronizer.Instance.SessionData.NegotiationModifier;
				}
				return generalCategory.GetEntry<float>("NegotiationModifier").Value;
			}
			set
			{
				generalCategory.GetEntry<float>("NegotiationModifier").Value = value;
			}
		}

		public static void Initialize()
		{
			if (isInitialized)
			{
				return;
			}
			generalCategory = MelonPreferences.CreateCategory("AdvancedDealing_01_General", "AdvancedDealing - General Settings", false, true);
			string text = Path.Combine(MelonEnvironment.UserDataDirectory, "AdvancedDealing.cfg");
			generalCategory.SetFilePath(text, true, false);
			CreateEntries();
			if (!File.Exists(text))
			{
				foreach (MelonPreferences_Entry entry in generalCategory.Entries)
				{
					entry.ResetToDefault();
				}
				generalCategory.SaveToFile(false);
			}
			isInitialized = true;
		}

		private static void CreateEntries()
		{
			generalCategory.CreateEntry<string>("Language", "auto", "Language (Needs Reload)", "Localization code: auto, en-US, ru-RU, or a custom JSON file name", false, false, (ValueValidator)null, (string)null);
			generalCategory.CreateEntry<bool>("Debug", false, "Enable Debug Mode", "Enables debugging for this mod", false, false, (ValueValidator)null, (string)null);
			generalCategory.CreateEntry<bool>("SkipMovement", false, "Skip Movement (Instant Delivery)", "Skips all movement actions for dealers", false, false, (ValueValidator)null, (string)null);
			generalCategory.CreateEntry<bool>("NotifyOnAction", true, "Notify On Actions", "Sends notifications after some actions got triggered", false, false, (ValueValidator)null, (string)null);
			generalCategory.CreateEntry<bool>("CustomersSearchAndSort", true, "Search And Sort Customers (Needs Reload)", "Enable customers searching and sorting by region and alphabetical", false, false, (ValueValidator)null, (string)null);
			generalCategory.CreateEntry<bool>("AccessInventory", false, "Access Dealer Inventories Remotely", "Enables the option to access the dealer inventory via text message", false, false, (ValueValidator)null, (string)null);
			generalCategory.CreateEntry<bool>("SettingsMenu", false, "Enable Dealer Settings Menu", "Allows access to the dealer settings menu via text message", false, false, (ValueValidator)null, (string)null);
			generalCategory.CreateEntry<float>("NegotiationModifier", 0.5f, "Negotiation Modifier (Higher = Better Chance)", "Modifier used to calculate the negotiation success.", false, false, (ValueValidator)(object)new ValueRange<float>(0f, 1f), (string)null);
		}
	}
	public static class ModInfo
	{
		public const string NAME = "AdvancedDealing";

		public const string VERSION = "1.5.1";

		public const string AUTHOR = "ManZune & UrbanSide Community";

		public const string DOWNLOAD_LINK = "https://github.com/UrbanSide/AdvancedDealing-Community";
	}
}
namespace AdvancedDealing.Utils
{
	public static class ConflictChecker
	{
		public static bool DisableMoreItemSlots { get; private set; }

		public static void CheckForConflicts()
		{
			bool flag = false;
			if (MelonBase.FindMelon("Bread's Storage Tweak Mod", "BreadCh4n") != null)
			{
				flag = true;
				DisableMoreItemSlots = true;
				Logger.Msg("ConflictChecker", "Bread's Storage Tweaks found: More item slots feature disabled.");
			}
			if (!flag)
			{
				Logger.Msg("ConflictChecker", "No known conflicting mods found.");
			}
		}
	}
	public static class Logger
	{
		public static void Msg(string msg)
		{
			Msg(null, msg);
		}

		public static void Msg(string prefix, string msg)
		{
			if (prefix != null)
			{
				msg = "[" + prefix + "] " + msg;
			}
			MelonLogger.Msg(msg);
		}

		public static void Error(string msg)
		{
			Error(null, msg, null);
		}

		public static void Error(string prefix, string msg)
		{
			Error(prefix, msg, null);
		}

		public static void Error(string msg, Exception ex)
		{
			Error(null, msg, ex);
		}

		public static void Error(string prefix, string msg, Exception ex)
		{
			if (prefix != null)
			{
				msg = "[" + prefix + "] " + msg;
			}
			if (ex != null)
			{
				MelonLogger.Error(msg, ex);
			}
			else
			{
				MelonLogger.Error(msg);
			}
		}

		public static void Debug(string msg)
		{
			Debug(null, msg);
		}

		public static void Debug(string prefix, string msg)
		{
			if (ModConfig.Debug)
			{
				if (prefix != null)
				{
					msg = "[" + prefix + "] " + msg;
				}
				MelonLogger.Msg(ConsoleColor.Cyan, msg);
			}
		}

		public static void Warning(string msg)
		{
			Warning(null, msg);
		}

		public static void Warning(string prefix, string msg)
		{
			if (prefix != null)
			{
				msg = "[" + prefix + "] " + msg;
			}
			MelonLogger.Warning(msg);
		}
	}
}
namespace AdvancedDealing.UI
{
	public class CustomerSelector
	{
		public RectTransform Content;

		public InputField Searchbar;

		private readonly List<RectTransform> _entries = new List<RectTransform>();

		public bool UICreated { get; private set; }

		public void BuildUI()
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			if (!UICreated)
			{
				Transform transform = ((Component)PlayerSingleton<DealerManagementApp>.Instance.CustomerSelector).transform;
				Content = PlayerSingleton<DealerManagementApp>.Instance.CustomerSelector.EntriesContainer;
				Transform obj = transform.Find("Shade/Content/Scroll View");
				RectTransform val = ((obj != null) ? ((Component)obj).GetComponent<RectTransform>() : null);
				val.sizeDelta = new Vector2(val.sizeDelta.x, val.sizeDelta.y - 100f);
				GameObject val2 = Object.Instantiate<GameObject>(((Component)((Component)PlayerSingleton<MessagesApp>.Instance.CounterofferInterface).transform.Find("Shade/Content/Selection/SearchInput")).gameObject, ((Transform)val).parent);
				val2.SetActive(true);
				((Object)val2).name = "Searchbar";
				Searchbar = val2.GetComponent<InputField>();
				((UnityEventBase)Searchbar.onEndEdit).RemoveAllListeners();
				((UnityEventBase)Searchbar.onValueChanged).RemoveAllListeners();
				((UnityEvent<string>)(object)Searchbar.onValueChanged).AddListener(UnityAction<string>.op_Implicit((Action<string>)OnSearchValueChanged));
				Searchbar.contentType = (ContentType)0;
				RectTransform component = ((Component)Searchbar).GetComponent<RectTransform>();
				component.offsetMax = new Vector2(-25f, -80f);
				component.offsetMin = new Vector2(25f, -130f);
				Text component2 = ((Component)((Transform)component).Find("Text Area/Placeholder")).GetComponent<Text>();
				component2.text = LocalizationManager.Get("ui.customers.search_placeholder");
				Logger.Debug("CustomerSelector", "Customer selector UI created");
				UICreated = true;
			}
		}

		public void SortCustomers()
		{
			for (int i = 0; i < PlayerSingleton<DealerManagementApp>.Instance.CustomerSelector.customerEntries.Count; i++)
			{
				RectTransform val = PlayerSingleton<DealerManagementApp>.Instance.CustomerSelector.customerEntries[i];
				Customer val2 = PlayerSingleton<DealerManagementApp>.Instance.CustomerSelector.entryToCustomer[val];
				if ((Object)(object)val2.AssignedDealer != (Object)null)
				{
					_entries.Remove(val);
				}
				else
				{
					_entries.Add(val);
				}
			}
			List<RectTransform> collection = _entries.OrderBy((RectTransform e) => ((Component)((Transform)e).Find("Name")).GetComponent<Text>().text).ToList();
			_entries.Clear();
			_entries.AddRange(collection);
			for (int num = 0; num < _entries.Count; num++)
			{
				RectTransform val3 = _entries[num];
				((Transform)val3).SetAsLastSibling();
			}
		}

		private void OnSearchValueChanged(string value)
		{
			for (int i = 0; i < _entries.Count; i++)
			{
				RectTransform val = _entries[i];
				Text component = ((Component)((Transform)val).Find("Name")).GetComponent<Text>();
				if (component.text.Contains(value, StringComparison.OrdinalIgnoreCase) || value == null || value == string.Empty)
				{
					((Component)val).gameObject.SetActive(true);
				}
				else
				{
					((Component)val).gameObject.SetActive(false);
				}
			}
		}
	}
	public class CustomersScrollView
	{
		public const int MAX_ENTRIES = 24;

		public GameObject Container;

		public GameObject Viewport;

		public GameObject AssignButton;

		public List<GameObject> CustomerEntries = new List<GameObject>();

		public Text TitleLabel;

		public bool UICreated { get; private set; }

		public void BuildUI()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_0055: 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_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected O, but got Unknown
			//IL_00de: 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_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Expected O, but got Unknown
			Container = ((Component)((Component)PlayerSingleton<DealerManagementApp>.Instance).transform.Find("Container/Background/Content/Container")).gameObject;
			GameObject val = new GameObject("Scroll");
			RectTransform val2 = val.AddComponent<RectTransform>();
			((Transform)val2).SetParent(Container.transform.parent, false);
			val2.anchorMin = new Vector2(0f, 0f);
			val2.anchorMax = new Vector2(1f, 1f);
			val2.pivot = new Vector2(0.5f, 0.5f);
			val2.anchoredPosition = Vector2.zero;
			val2.sizeDelta = new Vector2(0f, 0f);
			Viewport = new GameObject("Viewport");
			RectTransform val3 = Viewport.AddComponent<RectTransform>();
			((Transform)val3).SetParent((Transform)(object)val2, false);
			val3.anchorMin = new Vector2(0f, 0f);
			val3.anchorMax = new Vector2(1f, 1f);
			val3.pivot = new Vector2(0.5f, 0.5f);
			val3.anchoredPosition = Vector2.zero;
			val3.sizeDelta = new Vector2(0f, 0f);
			val3.offsetMax = new Vector2(0f, -90f);
			Viewport.AddComponent<Mask>().showMaskGraphic = false;
			Viewport.AddComponent<Image>();
			RectTransform component = Container.GetComponent<RectTransform>();
			((Transform)component).SetParent((Transform)(object)val3, true);
			component.pivot = new Vector2(0.5f, 1f);
			VerticalLayoutGroup component2 = Container.GetComponent<VerticalLayoutGroup>();
			((LayoutGroup)component2).padding = new RectOffset(40, 40, 0, 20);
			ContentSizeFitter val4 = Container.AddComponent<ContentSizeFitter>();
			val4.horizontalFit = (FitMode)0;
			val4.verticalFit = (FitMode)2;
			ScrollRect val5 = val.AddComponent<ScrollRect>();
			val5.viewport = val3;
			val5.content = component;
			val5.horizontal = false;
			val5.vertical = true;
			val5.movementType = (MovementType)1;
			val5.inertia = true;
			val5.elasticity = 0.1f;
			val5.verticalNormalizedPosition = 1f;
			val5.scrollSensitivity = 8f;
			TitleLabel = ((Component)Container.transform.Find("CustomerTitle")).GetComponent<Text>();
			AssignButton = ((Component)PlayerSingleton<DealerManagementApp>.Instance.AssignCustomerButton).gameObject;
			CreateCustomerEntries();
			Logger.Debug("CustomersScrollView", "Customers scroll view UI created");
			UICreated = true;
		}

		private void CreateCustomerEntries()
		{
			Il2CppReferenceArray<RectTransform> customerEntries = PlayerSingleton<DealerManagementApp>.Instance.CustomerEntries;
			Il2CppReferenceArray<RectTransform> val = new Il2CppReferenceArray<RectTransform>(24L);
			int length = ((Il2CppArrayBase<RectTransform>)(object)customerEntries).Length;
			if (length == 24)
			{
				return;
			}
			for (int i = 0; i < 24; i++)
			{
				if (i < length)
				{
					((Il2CppArrayBase<RectTransform>)(object)val)[i] = ((Il2CppArrayBase<RectTransform>)(object)customerEntries)[i];
					CustomerEntries.Add(((Component)((Il2CppArrayBase<RectTransform>)(object)customerEntries)[i]).gameObject);
					continue;
				}
				RectTransform val2 = ((IEnumerable<RectTransform>)customerEntries).Last();
				RectTransform val3 = Object.Instantiate<RectTransform>(val2, ((Transform)val2).parent);
				((Object)val3).name = $"CustomerEntry ({i})";
				((Component)val3).gameObject.SetActive(false);
				((Il2CppArrayBase<RectTransform>)(object)val)[i] = val3;
				CustomerEntries.Add(((Component)val3).gameObject);
			}
			PlayerSingleton<DealerManagementApp>.Instance.CustomerEntries = val;
		}
	}
	public enum DeadDropPurpose
	{
		ProductPickup,
		CashDelivery
	}
	public class DeadDropSelector
	{
		public GameObject Container;

		public Text TitleLabel;

		public Transform Content;

		public GameObject Details;

		public GameObject DeadDropButton;

		public Text ButtonLabel;

		private readonly List<GameObject> _selectables = new List<GameObject>();

		private DealerExtension _dealer;

		private GameObject _selectableTemplate;

		public DeadDropPurpose Purpose { get; }

		public string EmptySelectionLabel => LocalizationManager.Get("ui.dead_drop.none");

		public bool UICreated { get; private set; }

		public bool IsOpen { get; private set; }

		public DeadDropSelector(DeadDropPurpose purpose)
		{
			Purpose = purpose;
		}

		public void Open(DealerExtension dealerExtension)
		{
			if (dealerExtension == null)
			{
				return;
			}
			IsOpen = true;
			_dealer = dealerExtension;
			foreach (DeadDrop deadDrop in DeadDropExtension.GetDeadDropsByDistance(((Component)Player.Local).transform))
			{
				GameObject val = _selectables.Find((GameObject x) => ((Component)x.transform.Find("Name")).GetComponent<Text>().text == deadDrop.DeadDropName);
				if (val != null)
				{
					val.transform.SetAsLastSibling();
				}
			}
			Container.SetActive(true);
		}

		public void Close()
		{
			IsOpen = false;
			Container.SetActive(false);
		}

		private void OnSelected(string guid, string name)
		{
			if (_dealer == null)
			{
				Close();
				return;
			}
			if (Purpose == DeadDropPurpose.CashDelivery)
			{
				_dealer.CashDeadDrop = guid;
				if (string.IsNullOrWhiteSpace(guid))
				{
					_dealer.DeliverCash = false;
				}
			}
			else
			{
				_dealer.ProductDeadDrop = guid;
			}
			ButtonLabel.text = name;
			_dealer.HasChanged = true;
			Logger.Debug("DeadDropSelector", $"{Purpose} dead drop for {((NPC)_dealer.Dealer).fullName} selected: {guid ?? "None"}");
			if (NetworkSynchronizer.IsSyncing)
			{
				NetworkSynchronizer.Instance.SendData(_dealer.FetchData());
			}
			Close();
		}

		public void BuildUI()
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			if (!UICreated)
			{
				GameObject gameObject = ((Component)PlayerSingleton<DealerManagementApp>.Instance.CustomerSelector).gameObject;
				Container = Object.Instantiate<GameObject>(gameObject, gameObject.transform.parent);
				((Object)Container).name = ((Purpose == DeadDropPurpose.CashDelivery) ? "CashDeadDropSelector" : "ProductDeadDropSelector");
				Container.SetActive(true);
				RectTransform component = ((Component)Container.transform.Find("Shade/Content/Scroll View/Viewport/Content")).gameObject.GetComponent<RectTransform>();
				GameObject val = new GameObject("Content");
				RectTransform val2 = val.AddComponent<RectTransform>();
				((Transform)val2).SetParent(((Transform)component).parent, false);
				val2.anchorMin = component.anchorMin;
				val2.anchorMax = component.anchorMax;
				val2.pivot = component.pivot;
				val2.anchoredPosition = component.anchoredPosition;
				val2.sizeDelta = component.sizeDelta;
				TitleLabel = ((Component)Container.transform.Find("Shade/Content/Title")).GetComponent<Text>();
				TitleLabel.text = ((Purpose == DeadDropPurpose.CashDelivery) ? LocalizationManager.Get("ui.dead_drop.cash.select_title") : LocalizationManager.Get("ui.dead_drop.product.select_title"));
				Content = (Transform)(object)val2;
				Object.Destroy((Object)(object)((Component)component).gameObject);
				((Component)Container.transform.Find("Shade/Content/Scroll View")).gameObject.GetComponent<ScrollRect>().content = val2;
				ContentSizeFitter val3 = val.AddComponent<ContentSizeFitter>();
				val3.horizontalFit = (FitMode)0;
				val3.verticalFit = (FitMode)2;
				VerticalLayoutGroup val4 = val.AddComponent<VerticalLayoutGroup>();
				((HorizontalOrVerticalLayoutGroup)val4).childControlHeight = false;
				((HorizontalOrVerticalLayoutGroup)val4).childControlWidth = true;
				((HorizontalOrVerticalLayoutGroup)val4).childForceExpandHeight = false;
				((HorizontalOrVerticalLayoutGroup)val4).childForceExpandWidth = true;
				((HorizontalOrVerticalLayoutGroup)val4).childScaleHeight = false;
				((HorizontalOrVerticalLayoutGroup)val4).childScaleWidth = false;
				CreateSelectable(null, EmptySelectionLabel);
				for (int i = 0; i <= DeadDrop.DeadDrops.Count - 1; i++)
				{
					CreateSelectable(((object)DeadDrop.DeadDrops[i].GUID/*cast due to .constrained prefix*/).ToString(), DeadDrop.DeadDrops[i].DeadDropName);
				}
				CreateButton();
				Logger.Debug("DeadDropSelector", $"{Purpose} dead-drop selector UI created");
				UICreated = true;
			}
		}

		private void CreateButton()
		{
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			GameObject gameObject = ((Component)((Component)PlayerSingleton<DealerManagementApp>.Instance).transform.Find("Container/Background/Content/Scroll/Viewport/Container/Details")).gameObject;
			Details = Object.Instantiate<GameObject>(gameObject, gameObject.transform.parent);
			Details.SetActive(true);
			((Object)Details).name = ((Purpose == DeadDropPurpose.CashDelivery) ? "Details (Advanced Dealing - Cash Dead Drop)" : "Details (Advanced Dealing - Product Dead Drop)");
			Details.transform.SetSiblingIndex((Purpose == DeadDropPurpose.CashDelivery) ? 6 : 5);
			GameObject gameObject2 = ((Component)Details.transform.Find("Container")).gameObject;
			for (int num = gameObject2.transform.childCount - 1; num > 0; num--)
			{
				Object.Destroy((Object)(object)((Component)gameObject2.transform.GetChild(num)).gameObject);
			}
			DeadDropButton = ((Component)gameObject2.transform.GetChild(0)).gameObject;
			((Object)DeadDropButton).name = ((Purpose == DeadDropPurpose.CashDelivery) ? "Cash Dead Drop" : "Product Dead Drop");
			((Component)DeadDropButton.transform.Find("Title")).GetComponent<Text>().text = ((Purpose == DeadDropPurpose.CashDelivery) ? LocalizationManager.Get("ui.dead_drop.cash.label") : LocalizationManager.Get("ui.dead_drop.product.label"));
			RectTransform component = ((Component)DeadDropButton.transform.Find("Value")).GetComponent<RectTransform>();
			component.offsetMax = new Vector2(-30f, -45f);
			ButtonLabel = ((Component)component).GetComponent<Text>();
			ButtonLabel.text = EmptySelectionLabel;
			((Graphic)ButtonLabel).color = new Color(0.6f, 1f, 1f, 1f);
			ButtonLabel.resizeTextForBestFit = true;
			ButtonLabel.resizeTextMaxSize = 28;
			((UnityEvent)Details.AddComponent<Button>().onClick).AddListener(UnityAction.op_Implicit((Action)OpenSelector));
			void OpenSelector()
			{
				Open(DealerExtension.GetDealer(PlayerSingleton<DealerManagementApp>.Instance.SelectedDealer));
			}
		}

		private void CreateSelectableTemplate()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: 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)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Expected O, but got Unknown
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			_selectableTemplate = new GameObject("DeadDropEntry");
			_selectableTemplate.SetActive(false);
			RectTransform val = _selectableTemplate.AddComponent<RectTransform>();
			val.anchorMin = new Vector2(0f, 1f);
			val.anchorMax = new Vector2(0f, 1f);
			val.pivot = new Vector2(0.5f, 0.5f);
			val.anchoredPosition = new Vector2(243f, -40f);
			val.sizeDelta = new Vector2(486f, 80f);
			Image val2 = _selectableTemplate.AddComponent<Image>();
			Button val3 = _selectableTemplate.AddComponent<Button>();
			ColorBlock colors = default(ColorBlock);
			((ColorBlock)(ref colors)).normalColor = new Color(0f, 0f, 0f, 0f);
			((ColorBlock)(ref colors)).highlightedColor = new Color(0f, 0f, 0f, 0.2353f);
			((ColorBlock)(ref colors)).pressedColor = new Color(0f, 0f, 0f, 0.3922f);
			((ColorBlock)(ref colors)).selectedColor = new Color(0.9608f, 0.9608f, 0.9608f, 1f);
			((ColorBlock)(ref colors)).disabledColor = new Color(0.7843f, 0.7843f, 0.7843f, 0.502f);
			((ColorBlock)(ref colors)).colorMultiplier = 1f;
			((ColorBlock)(ref colors)).fadeDuration = 0.1f;
			((Selectable)val3).colors = colors;
			((Selectable)val3).image = val2;
			((Selectable)val3).targetGraphic = (Graphic)(object)val2;
			((Selectable)val3).transition = (Transition)1;
			GameObject val4 = new GameObject("Name");
			RectTransform val5 = val4.AddComponent<RectTransform>();
			((Transform)val5).SetParent((Transform)(object)val, false);
			val5.anchorMin = new Vector2(0f, 0f);
			val5.anchorMax = new Vector2(1f, 1f);
			val5.pivot = new Vector2(0.5f, 0.5f);
			val5.anchoredPosition = new Vector2(0f, 0f);
			val5.sizeDelta = new Vector2(0f, 0f);
			val5.offsetMax = new Vector2(-20f, 0f);
			val5.offsetMin = new Vector2(20f, 0f);
			Text val6 = val4.AddComponent<Text>();
			val6.alignment = (TextAnchor)3;
			val6.font = TitleLabel.font;
			val6.fontSize = 28;
			val6.fontStyle = (FontStyle)0;
			val6.horizontalOverflow = (HorizontalWrapMode)1;
			val6.lineSpacing = 1f;
			val6.resizeTextMaxSize = 76;
			val6.resizeTextMinSize = 1;
			val6.text = "Name";
		}

		private void CreateSelectable(string deadDropGuid, string name)
		{
			if ((Object)(object)_selectableTemplate == (Object)null)
			{
				CreateSelectableTemplate();
			}
			GameObject val = Object.Instantiate<GameObject>(_selectableTemplate, Content);
			val.SetActive(true);
			((Component)val.transform.Find("Name")).GetComponent<Text>().text = name;
			((UnityEvent)val.GetComponent<Button>().onClick).AddListener(UnityAction.op_Implicit((Action)Selected));
			_selectables.Add(val);
			void Selected()
			{
				OnSelected(deadDropGuid, name);
			}
		}
	}
	public class SettingsPopup
	{
		public GameObject Container;

		public Text TitleLabel;

		public Button ApplyButton;

		public Transform Content;

		private readonly List<GameObject> _inputFields = new List<GameObject>();

		private DealerExtension _dealer;

		private GameObject _inputFieldTemplate;

		public bool UICreated { get; private set; }

		public bool IsOpen { get; private set; }

		public SettingsPopup()
		{
			GameInput.RegisterExitListener(ExitDelegate.op_Implicit((Action<ExitAction>)RightClick), 4);
		}

		private void RightClick(ExitAction action)
		{
			if (!action.Used && IsOpen)
			{
				action.Used = true;
				Close();
			}
		}

		public void Open(DealerExtension dealerExtension)
		{
			IsOpen = true;
			_dealer = dealerExtension;
			Container.SetActive(true);
			TitleLabel.text = LocalizationManager.Get("ui.settings.title_dealer", ((Object)_dealer.Dealer).name);
			foreach (GameObject inputField in _inputFields)
			{
				inputField.GetComponent<InputField>().text = GetDataValue(((Object)inputField).name);
				inputField.SetActive(true);
			}
		}

		public void Close()
		{
			IsOpen = false;
			Container.SetActive(false);
		}

		private void OnApply()
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Invalid comparison between Unknown and I4
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Invalid comparison between Unknown and I4
			if (!IsOpen)
			{
				return;
			}
			bool flag = false;
			foreach (GameObject inputField in _inputFields)
			{
				InputField component = inputField.GetComponent<InputField>();
				string dataValue = GetDataValue(((Object)inputField).name);
				string text = component.text;
				if (text != dataValue)
				{
					if ((int)component.contentType == 2)
					{
						typeof(DealerExtension).GetField(((Object)inputField).name).SetValue(_dealer, int.Parse(text));
					}
					else if ((int)component.contentType == 3)
					{
						typeof(DealerExtension).GetField(((Object)inputField).name).SetValue(_dealer, float.Parse(text));
					}
					flag = true;
				}
			}
			if (flag)
			{
				if (NetworkSynchronizer.IsSyncing)
				{
					NetworkSynchronizer.Instance.SendData(_dealer.FetchData());
				}
				_dealer.HasChanged = true;
				_dealer.SendPlayerMessage(LocalizationManager.Get("messages.settings.player"));
				_dealer.SendMessage(LocalizationManager.Get("messages.settings.dealer"), notify: false, network: true, 2f);
			}
			Close();
		}

		private void OnCancel()
		{
			Close();
		}

		public void BuildUI()
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			if (!UICreated)
			{
				GameObject gameObject = ((Component)PlayerSingleton<MessagesApp>.Instance.ConfirmationPopup).gameObject;
				Container = Object.Instantiate<GameObject>(gameObject, gameObject.transform.parent);
				((Object)Container).name = "SettingsPopup";
				Container.SetActive(true);
				CreateInputFieldTemplate();
				Content = Container.transform.Find("Shade/Content");
				((Component)Content).GetComponent<RectTransform>().sizeDelta = new Vector2(-160f, 100f);
				Object.Destroy((Object)(object)((Component)Content.Find("Subtitle")).gameObject);
				TitleLabel = ((Component)Content.Find("Title")).GetComponent<Text>();
				TitleLabel.text = LocalizationManager.Get("ui.settings.title");
				Button[] array = Il2CppArrayBase<Button>.op_Implicit(((Component)Content).GetComponentsInChildren<Button>());
				((UnityEventBase)array[0].onClick).RemoveAllListeners();
				((UnityEvent)array[0].onClick).AddListener(UnityAction.op_Implicit((Action)OnCancel));
				ApplyButton = array[2];
				((Object)((Component)ApplyButton).gameObject).name = "Apply";
				((Component)ApplyButton).GetComponentInChildren<Text>().text = LocalizationManager.Get("ui.settings.apply");
				Button applyButton = ApplyButton;
				ColorBlock colors = default(ColorBlock);
				((ColorBlock)(ref colors)).normalColor = new Color(0.2941f, 0.6863f, 0.8824f, 1f);
				((ColorBlock)(ref colors)).highlightedColor = new Color(0.4532f, 0.7611f, 0.9151f, 1f);
				((ColorBlock)(ref colors)).pressedColor = new Color(0.5674f, 0.8306f, 0.9623f, 1f);
				((ColorBlock)(ref colors)).selectedColor = new Color(0.9608f, 0.9608f, 0.9608f, 1f);
				((ColorBlock)(ref colors)).disabledColor = new Color(0.2941f, 0.6863f, 0.8824f, 1f);
				((ColorBlock)(ref colors)).colorMultiplier = 1f;
				((ColorBlock)(ref colors)).fadeDuration = 0f;
				((Selectable)applyButton).colors = colors;
				((UnityEventBase)ApplyButton.onClick).RemoveAllListeners();
				((UnityEvent)ApplyButton.onClick).AddListener(UnityAction.op_Implicit((Action)OnApply));
				((Graphic)((Component)ApplyButton).GetComponent<Image>()).color = Color.white;
				Object.Destroy((Object)(object)((Component)array[1]).gameObject);
				CreateInputField((ContentType)2, "MaxCustomers", LocalizationManager.Get("ui.settings.max_customers"), 0f, 24f);
				CreateInputField((ContentType)3, "Cut", LocalizationManager.Get("ui.settings.cut"), 0f, 1f);
				CreateInputField((ContentType)3, "SpeedMultiplier", LocalizationManager.Get("ui.settings.speed_multiplier"));
				if (!ConflictChecker.DisableMoreItemSlots)
				{
					CreateInputField((ContentType)2, "ItemSlots", LocalizationManager.Get("ui.settings.item_slots"), 0f, 20f);
				}
				Logger.Debug("SettingsPopup", "Settings popup UI created");
				UICreated = true;
			}
		}

		private void CreateInputFieldTemplate()
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: 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)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(((Component)((Component)PlayerSingleton<MessagesApp>.Instance.CounterofferInterface).transform.Find("Shade/Content/Selection/SearchInput")).gameObject);
			val.SetActive(false);
			((Object)val).name = "InputFieldUITemplate";
			((UnityEventBase)val.GetComponent<InputField>().onEndEdit).RemoveAllListeners();
			RectTransform component = val.GetComponent<RectTransform>();
			component.offsetMax = new Vector2(-20f, -100f);
			component.offsetMin = new Vector2(20f, -160f);
			RectTransform component2 = ((Component)((Transform)component).Find("Image")).GetComponent<RectTransform>();
			component2.offsetMin = new Vector2(350f, component2.offsetMin.y);
			RectTransform component3 = ((Component)((Transform)component).Find("Text Area")).GetComponent<RectTransform>();
			component3.offsetMin = new Vector2(350f, component3.offsetMin.y);
			Text component4 = ((Component)((Transform)component3).Find("Placeholder")).GetComponent<Text>();
			component4.text = LocalizationManager.Get("ui.settings.placeholder");
			RectTransform val2 = new GameObject("Title").AddComponent<RectTransform>();
			((Transform)val2).SetParent((Transform)(object)component);
			((Transform)val2).SetAsFirstSibling();
			val2.sizeDelta = new Vector2(-358f, -13f);
			val2.offsetMax = new Vector2(-150f, -10f);
			val2.offsetMin = new Vector2(10f, 8f);
			val2.anchorMax = new Vector2(1f, 1f);
			val2.anchorMin = new Vector2(0f, 0f);
			Text val3 = ((Component)val2).gameObject.AddComponent<Text>();
			val3.font = component4.font;
			val3.alignment = (TextAnchor)3;
			val3.text = "Title";
			((Graphic)val3).color = Color.black;
			val3.fontSize = 20;
			_inputFieldTemplate = val;
		}

		private void CreateInputField(ContentType type, string key, string description, float rangeMin = 0f, float rangeMax = 0f)
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(_inputFieldTemplate, Content);
			val.SetActive(true);
			((Object)val).name = key;
			float num = 0f;
			if (_inputFields.Count > 0)
			{
				num = 80f * (float)_inputFields.Count;
			}
			RectTransform component = val.GetComponent<RectTransform>();
			component.offsetMax = new Vector2(component.offsetMax.x, component.offsetMax.y - num);
			component.offsetMin = new Vector2(component.offsetMin.x, component.offsetMin.y - num);
			((Component)((Transform)component).Find("Title")).GetComponent<Text>().text = description;
			InputField input = val.GetComponent<InputField>();
			input.contentType = type;
			if (rangeMin != 0f || rangeMax != 0f)
			{
				((UnityEvent<string>)(object)input.onEndEdit).AddListener(UnityAction<string>.op_Implicit((Action<string>)ValidateRange));
			}
			_inputFields.Add(val);
			void ValidateRange(string text)
			{
				if (text.Length > 0)
				{
					float num2 = float.Parse(text);
					if (!(rangeMin <= num2) || !(num2 <= rangeMax))
					{
						input.text = GetDataValue(key);
					}
				}
			}
		}

		private string GetDataValue(string key)
		{
			if (_dealer == null)
			{
				return null;
			}
			return typeof(DealerExtension).GetField(key).GetValue(_dealer).ToString();
		}
	}
	public class SliderPopup
	{
		public GameObject Container;

		public Text TitleLabel;

		public Text SubtitleLabel;

		public Text ValueLabel;

		public Button SendButton;

		public Transform Content;

		public Slider Slider;

		public Action<float> OnSend;

		public Action OnCancel;

		private int _digits;

		private float _stepSize;

		private string _format;

		public bool UICreated { get; private set; }

		public bool IsOpen { get; private set; }

		public SliderPopup()
		{
			GameInput.RegisterExitListener(ExitDelegate.op_Implicit((Action<ExitAction>)RightClick), 4);
		}

		private void RightClick(ExitAction action)
		{
			if (!action.Used && IsOpen)
			{
				action.Used = true;
				Close();
			}
		}

		public void Open(string title, string subtitle, float startValue, float minValue, float maxValue, float stepSize = 0.05f, int digits = 2, Action<float> onSendCallback = null, Action onCancelCallback = null, string format = "")
		{
			IsOpen = true;
			Container.SetActive(true);
			OnSend = onSendCallback;
			OnCancel = onCancelCallback;
			_digits = digits;
			_stepSize = stepSize;
			_format = format;
			TitleLabel.text = title;
			SubtitleLabel.text = subtitle;
			ValueLabel.text = LocalizationManager.Format(_format, GetSteppedValue(startValue));
			Slider.value = startValue;
			Slider.minValue = minValue;
			Slider.maxValue = maxValue;
		}

		public void Close()
		{
			IsOpen = false;
			Container.SetActive(false);
		}

		private void Send()
		{
			if (IsOpen)
			{
				OnSend?.Invoke(GetSteppedValue(Slider.value));
				Close();
			}
		}

		private void Cancel()
		{
			OnCancel?.Invoke();
			Close();
		}

		private void OnValueChanged(float value)
		{
			ValueLabel.text = LocalizationManager.Format(_format, GetSteppedValue(value));
		}

		private float GetSteppedValue(float value)
		{
			return (float)Math.Round(Mathf.Round(value / _stepSize) * _stepSize, _digits);
		}

		public void BuildUI()
		{
			//IL_0087: 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_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0311: Unknown result type (might be due to invalid IL or missing references)
			//IL_0336: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0473: Unknown result type (might be due to invalid IL or missing references)
			//IL_048a: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cb: Unknown result type (might be due to invalid IL or missing references)
			if (!UICreated)
			{
				GameObject gameObject = ((Component)PlayerSingleton<MessagesApp>.Instance.ConfirmationPopup).gameObject;
				Container = Object.Instantiate<GameObject>(gameObject, gameObject.transform.parent);
				((Object)Container).name = "NegotiationPopup";
				Container.SetActive(true);
				Content = Container.transform.Find("Shade/Content");
				((Component)Content).GetComponent<RectTransform>().sizeDelta = new Vector2(-160f, 40f);
				SubtitleLabel = ((Component)Content.Find("Subtitle")).GetComponent<Text>();
				SubtitleLabel.text = LocalizationManager.Get("ui.slider.default_subtitle");
				ValueLabel = Object.Instantiate<GameObject>(((Component)SubtitleLabel).gameObject, ((Component)SubtitleLabel).transform.parent).GetComponent<Text>();
				((Object)ValueLabel).name = "Value";
				ValueLabel.text = LocalizationManager.Format(LocalizationManager.Get("formats.percent"), 0f);
				ValueLabel.fontSize = 30;
				ValueLabel.fontStyle = (FontStyle)1;
				RectTransform component = ((Component)ValueLabel).GetComponent<RectTransform>();
				component.anchorMax = new Vector2(1f, 1f);
				component.anchorMin = new Vector2(0f, 0f);
				component.offsetMax = new Vector2(-30f, 200f);
				component.offsetMin = new Vector2(30f, -280f);
				TitleLabel = ((Component)Content.Find("Title")).GetComponent<Text>();
				TitleLabel.text = LocalizationManager.Get("ui.slider.default_title");
				Button[] array = Il2CppArrayBase<Button>.op_Implicit(((Component)Content).GetComponentsInChildren<Button>());
				((UnityEventBase)array[0].onClick).RemoveAllListeners();
				((UnityEvent)array[0].onClick).AddListener(UnityAction.op_Implicit((Action)Cancel));
				SendButton = array[2];
				((Object)((Component)SendButton).gameObject).name = "Send";
				((Component)SendButton).GetComponentInChildren<Text>().text = LocalizationManager.Get("ui.slider.send");
				Button sendButton = SendButton;
				ColorBlock colors = default(ColorBlock);
				((ColorBlock)(ref colors)).normalColor = new Color(0.2941f, 0.6863f, 0.8824f, 1f);
				((ColorBlock)(ref colors)).highlightedColor = new Color(0.4532f, 0.7611f, 0.9151f, 1f);
				((ColorBlock)(ref colors)).pressedColor = new Color(0.5674f, 0.8306f, 0.9623f, 1f);
				((ColorBlock)(ref colors)).selectedColor = new Color(0.9608f, 0.9608f, 0.9608f, 1f);
				((ColorBlock)(ref colors)).disabledColor = new Color(0.2941f, 0.6863f, 0.8824f, 1f);
				((ColorBlock)(ref colors)).colorMultiplier = 1f;
				((ColorBlock)(ref colors)).fadeDuration = 0f;
				((Selectable)sendButton).colors = colors;
				((UnityEventBase)SendButton.onClick).RemoveAllListeners();
				((UnityEvent)SendButton.onClick).AddListener(UnityAction.op_Implicit((Action)Send));
				((Graphic)((Component)SendButton).GetComponent<Image>()).color = Color.white;
				GameObject val = Object.Instantiate<GameObject>(GameObject.Find("UI/ItemUIManager/AmountSelector/Slider"), Content);
				((Object)val).name = "Slider";
				RectTransform component2 = val.GetComponent<RectTransform>();
				component2.anchoredPosition = Vector2.zero;
				component2.sizeDelta = new Vector2(280f, 40f);
				Slider = val.GetComponent<Slider>();
				Slider.maxValue = 1f;
				Slider.minValue = 0f;
				Slider.wholeNumbers = false;
				Slider.normalizedValue = 0.5f;
				((UnityEventBase)Slider.onValueChanged).RemoveAllListeners();
				((UnityEvent<float>)(object)Slider.onValueChanged).AddListener(UnityAction<float>.op_Implicit((Action<float>)OnValueChanged));
				RectTransform component3 = ((Component)((Transform)component2).Find("Handle Slide Area/Handle")).GetComponent<RectTransform>();
				component3.anchoredPosition = new Vector2(0f, 0f);
				component3.sizeDelta = new Vector2(40f, 0f);
				RectTransform component4 = ((Component)((Transform)component2).Find("Fill Area/Fill")).GetComponent<RectTransform>();
				component4.anchoredPosition = new Vector2(0f, 0f);
				component4.sizeDelta = new Vector2(40f, 0f);
				val.SetActive(true);
				Object.Destroy((Object)(object)((Component)array[1]).gameObject);
				Logger.Debug("NegotiationPopup", "Negotiation popup UI created");
				UICreated = true;
			}
		}
	}
	public static class UIBuilder
	{
		public static bool HasBuild { get; private set; }

		public static SettingsPopup SettingsPopup { get; private set; }

		public static SliderPopup SliderPopup { get; private set; }

		public static DeadDropSelector ProductDeadDropSelector { get; private set; }

		public static DeadDropSelector CashDeadDropSelector { get; private set; }

		public static CustomersScrollView CustomersScrollView { get; private set; }

		public static CustomerSelector CustomerSelector { get; private set; }

		public static void Build()
		{
			if (!HasBuild)
			{
				if (SettingsPopup == null)
				{
					SettingsPopup = new SettingsPopup();
				}
				if (SliderPopup == null)
				{
					SliderPopup = new SliderPopup();
				}
				if (CustomersScrollView == null)
				{
					CustomersScrollView = new CustomersScrollView();
				}
				if (ProductDeadDropSelector == null)
				{
					ProductDeadDropSelector = new DeadDropSelector(DeadDropPurpose.ProductPickup);
				}
				if (CashDeadDropSelector == null)
				{
					CashDeadDropSelector = new DeadDropSelector(DeadDropPurpose.CashDelivery);
				}
				if (CustomerSelector == null)
				{
					CustomerSelector = new CustomerSelector();
				}
				MelonCoroutines.Start(CreateUI());
			}
			static IEnumerator CreateUI()
			{
				yield return (object)new WaitUntil(Func<bool>.op_Implicit((Func<bool>)(() => !Singleton<LoadManager>.Instance.IsLoading && Singleton<LoadManager>.Instance.IsGameLoaded)));
				SettingsPopup.BuildUI();
				SliderPopup.BuildUI();
				CustomersScrollView.BuildUI();
				ProductDeadDropSelector.BuildUI();
				CashDeadDropSelector.BuildUI();
				if (ModConfig.CustomersSearchAndSort)
				{
					CustomerSelector.BuildUI();
				}
				Logger.Msg("UI elements created");
				HasBuild = true;
			}
		}

		public static void Reset()
		{
			SettingsPopup = null;
			SliderPopup = null;
			CustomersScrollView = null;
			ProductDeadDropSelector = null;
			CashDeadDropSelector = null;
			CustomerSelector = null;
			HasBuild = false;
		}
	}
}
namespace AdvancedDealing.Persistence
{
	public struct DataWrapper
	{
		public string SaveName;

		public List<DealerData> Dealers;

		public List<DeadDropData> DeadDrops;
	}
	public class NetworkSynchronizer
	{
		public SessionData SessionData;

		protected Callback<LobbyChatMsg_t> LobbyChatMsgCallback;

		protected Callback<LobbyDataUpdate_t> LobbyDataUpdateCallback;

		private readonly string _prefix = Hashing.GetStableHashU16("AdvancedDealing").ToString();

		private CSteamID _lobbySteamID;

		private bool _isSyncing;

		private bool _isHost;

		public static NetworkSynchronizer Instance { get; private set; }

		public static bool IsSyncing => Instance._isSyncing;

		public static bool IsNoSyncOrHost => !IsSyncing || (IsSyncing && Instance._isHost);

		public static bool IsHost => Instance._isHost;

		public static CSteamID LocalSteamID => Singleton<Lobby>.Instance.LocalPlayerID;

		public NetworkSynchronizer()
		{
			if (Instance == null)
			{
				Lobby instance = Singleton<Lobby>.Instance;
				instance.onLobbyChange += Action.op_Implicit((Action)OnLobbyChange);
				LobbyChatMsgCallback = Callback<LobbyChatMsg_t>.Create(DispatchDelegate<LobbyChatMsg_t>.op_Implicit((Action<LobbyChatMsg_t>)OnLobbyMessage));
				Instance = this;
			}
		}

		private void StartSyncing()
		{
			//IL_000e: 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)
			_isHost = false;
			_lobbySteamID = Singleton<Lobby>.Instance.LobbySteamID;
			_isSyncing = true;
			Logger.Msg("NetworkSynchronizer", "Synchronization started");
		}

		private void StopSyncing()
		{
			//IL_0009: 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)
			_isHost = false;
			_lobbySteamID = CSteamID.Nil;
			_isSyncing = false;
			SessionData = null;
			Logger.Msg("NetworkSynchronizer", "Synchronization stopped");
		}

		public void SetAsHost()
		{
			_isHost = true;
			Logger.Debug("NetworkSynchronizer", "Set as host");
		}

		public void SendData(DataBase data)
		{
			SendData(data.DataType, data.Identifier, JsonConvert.SerializeObject((object)data, FileSerializer.JsonSerializerSettings));
		}

		public void SendData(string dataType, string identifier, string dataString)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			if (IsSyncing)
			{
				string text = $"{_prefix}_{dataType}_{identifier}";
				SteamMatchmaking.SetLobbyMemberData(_lobbySteamID, text, dataString);
				SendMessage(text);
				Logger.Debug("NetworkSynchronizer", "Data synced with lobby: " + text);
			}
		}

		public void SendMessage(string text, string identifier = null)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			text = _prefix + "__" + text;
			if (identifier != null)
			{
				text = text + "__" + identifier;
			}
			Il2CppStructArray<byte> bytes = Encoding.UTF8.GetBytes(text);
			SteamMatchmaking.SendLobbyChatMsg(_lobbySteamID, bytes, ((Il2CppArrayBase<byte>)(object)bytes).Length);
		}

		public void FetchData(CSteamID steamId, string key)
		{
			//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)
			string lobbyMemberData = SteamMatchmaking.GetLobbyMemberData(_lobbySteamID, steamId, key);
			bool flag = false;
			if (lobbyMemberData != null)
			{
				string[] array = key.Split("_");
				if (array[1] != null && array[2] != null)
				{
					string text = array[1];
					string guid = array[2];
					if (text == "DealerData")
					{
						DealerExtension dealer = DealerExtension.GetDealer(guid);
						if (dealer != null)
						{
							DealerData data = JsonConvert.DeserializeObject<DealerData>(lobbyMemberData);
							dealer.PatchData(data);
							flag = true;
						}
					}
					else if (text == "SessionData" && !_isHost)
					{
						SessionData = JsonConvert.DeserializeObject<SessionData>(lobbyMemberData);
						flag = true;
					}
				}
			}
			if (flag)
			{
				Logger.Debug("NetworkSynchronizer", "Data from lobby fetched: " + key);
			}
			else
			{
				Logger.Debug("NetworkSynchronizer", "Could not fetch data from lobby: " + key);
			}
		}

		private void OnLobbyMessage(LobbyChatMsg_t res)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			if (!IsSyncing)
			{
				return;
			}
			Il2CppStructArray<byte> val = Il2CppStructArray<byte>.op_Implicit(new byte[4096]);
			CSteamID val2 = default(CSteamID);
			EChatEntryType val3 = default(EChatEntryType);
			SteamMatchmaking.GetLobbyChatEntry(_lobbySteamID, (int)res.m_iChatID, ref val2, val, ((Il2CppArrayBase<byte>)(object)val).Length, ref val3);
			if (val2 == LocalSteamID)
			{
				return;
			}
			string text = Encoding.UTF8.GetString(val);
			text = text.TrimEnd(new char[1]);
			string[] array = text.Split("__");
			if (!(array[0] == _prefix))
			{
				return;
			}
			Logger.Debug("NetworkSynchronizer", "Received msg: " + array[1]);
			string text2 = array[1];
			string text3 = text2;
			if (!(text3 == "data_request"))
			{
				if (text3 == "dealer_fired")
				{
					DealerExtension.GetDealer(array[2])?.Fire();
				}
				else
				{
					FetchData(val2, array[1]);
				}
			}
			else
			{
				if (!_isHost)
				{
					return;
				}
				SendData(SessionData);
				foreach (DealerData item in DealerExtension.FetchAllDealerDatas())
				{
					SendData(item);
				}
			}
		}

		private void OnLobbyChange()
		{
			//IL_001a: 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_0038: 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)
			if (Singleton<Lobby>.Instance.IsInLobby && _isSyncing && Singleton<Lobby>.Instance.LobbySteamID != _lobbySteamID)
			{
				_lobbySteamID = Singleton<Lobby>.Instance.LobbySteamID;
			}
			else if (Singleton<Lobby>.Instance.IsInLobby && !_isSyncing)
			{
				StartSyncing();
			}
			else if (!Singleton<Lobby>.Instance.IsInLobby && _isSyncing)
			{
				StopSyncing();
			}
		}
	}
	public class SaveModifier
	{
		public static SaveModifier Instance { get; private set; }

		public DataWrapper SaveData { get; private set; }

		public bool SavegameLoaded { get; private set; }

		private static string FilePath => Path.Combine(Singleton<LoadManager>.Instance.ActiveSaveInfo.SavePath, "AdvancedDealing.json");

		public SaveModifier()
		{
			if (Instance == null)
			{
				Singleton<SaveManager>.Instance.onSaveComplete.AddListener(UnityAction.op_Implicit((Action)OnSaveComplete));
				Instance = this;
			}
		}

		public void LoadModifications()
		{
			Logger.Msg("Preparing savegame modifications...");
			if (Singleton<Lobby>.Instance.IsInLobby && !Singleton<Lobby>.Instance.IsHost)
			{
				LoadModificationsAsClient();
			}
			else
			{
				MelonCoroutines.Start(LoadRoutine());
			}
			IEnumerator LoadRoutine()
			{
				if (!FileSerializer.LoadFromFile<DataWrapper>(FilePath, out var data))
				{
					SaveData = new DataWrapper
					{
						SaveName = $"SaveGame_{Singleton<LoadManager>.Instance.ActiveSaveInfo.SaveSlotNumber}",
						Dealers = new List<DealerData>(),
						DeadDrops = new List<DeadDropData>()
					};
				}
				else
				{
					SaveData = new DataWrapper
					{
						SaveName = $"SaveGame_{Singleton<LoadManager>.Instance.ActiveSaveInfo.SaveSlotNumber}",
						Dealers = (data.Dealers ?? new List<DealerData>()),
						DeadDrops = (data.DeadDrops ?? new List<DeadDropData>())
					};
				}
				DeadDropExtension.Initialize();
				DealerExtension.Initialize();
				if (NetworkSynchronizer.IsSyncing)
				{
					NetworkSynchronizer.Instance.SetAsHost();
					NetworkSynchronizer.Instance.SessionData = new SessionData(((object)Singleton<Lobby>.Instance.LobbySteamID/*cast due to .constrained prefix*/).ToString())
					{
						AccessInventory = ModConfig.AccessInventory,
						SettingsMenu = ModConfig.SettingsMenu,
						NegotiationModifier = ModConfig.NegotiationModifier
					};
				}
				yield return (object)new WaitForSecondsRealtime(2f);
				SavegameLoaded = true;
				UIBuilder.Build();
				Logger.Msg("Savegame modifications successfully injected");
			}
		}

		private void LoadModificationsAsClient()
		{
			MelonCoroutines.Start(ClientLoadRoutine());
			IEnumerator ClientLoadRoutine()
			{
				SaveData = new DataWrapper
				{
					SaveName = "temporary",
					Dealers = new List<DealerData>()
				};
				DeadDropExtension.Initialize();
				DealerExtension.Initialize();
				yield return (object)new WaitForSecondsRealtime(2f);
				SavegameLoaded = true;
				NetworkSynchronizer.Instance.SendMessage("data_request");
				UIBuilder.Build();
				Logger.Msg("Savegame modifications successfully injected");
			}
		}

		public void ClearModifications()
		{
			UIBuilder.Reset();
			List<DealerExtension> allDealers = DealerExtension.GetAllDealers();
			for (int num = allDealers.Count - 1; num >= 0; num--)
			{
				allDealers[num].Destroy();
			}
			SavegameLoaded = false;
			Logger.Msg("Savegame modifications cleared");
		}

		private void OnSaveComplete()
		{
			if (NetworkSynchronizer.IsNoSyncOrHost)
			{
				DataWrapper data = new DataWrapper
				{
					SaveName = $"SaveGame_{Singleton<LoadManager>.Instance.ActiveSaveInfo.SaveSlotNumber}",
					Dealers = DealerExtension.FetchAllDealerDatas(),
					DeadDrops = DeadDropExtension.FetchAllDeadDropDatas()
				};
				Logger.Msg("Data for " + data.SaveName + " saved");
				FileSerializer.SaveToFile(FilePath, data);
			}
		}
	}
}
namespace AdvancedDealing.Persistence.IO
{
	public static class FileSerializer
	{
		public static readonly JsonSerializerSettings JsonSerializerSettings = new JsonSerializerSettings
		{
			NullValueHandling = (NullValueHandling)0,
			MissingMemberHandling = (MissingMemberHandling)0,
			Formatting = (Formatting)1
		};

		public static Type LastLoadedDataType { get; private set; }

		public static string LastLoadedDataString { get; private set; }

		public static bool LoadFromFile<T>(string filePath, out T data) where T : struct
		{
			if (File.Exists(filePath))
			{
				string text = File.ReadAllText(filePath);
				data = JsonConvert.DeserializeObject<T>(text, JsonSerializerSettings);
				LastLoadedDataType = data.GetType();
				LastLoadedDataString = text;
				Logger.Debug("Loaded from file: " + filePath);
				return true;
			}
			data = default(T);
			return false;
		}

		public static void SaveToFile<T>(string filePath, T data) where T : struct
		{
			string contents = JsonConvert.SerializeObject((object)data, JsonSerializerSettings);
			File.WriteAllText(filePath, contents);
			Logger.Debug("Saved to file: " + filePath);
		}
	}
}
namespace AdvancedDealing.Persistence.Datas
{
	public abstract class DataBase
	{
		public string DataType;

		public string ModVersion;

		public string Identifier;

		public DataBase(string identifier)
		{
			DataType = GetType().Name;
			ModVersion = "1.5.1";
			Identifier = identifier;
		}

		public virtual bool IsEqual(object other)
		{
			if (!GetType().Equals(other.GetType()))
			{
				throw new Exception($"Tried to compare {GetType()} with {other.GetType()}");
			}
			bool result = true;
			FieldInfo[] fields = GetType().GetFields();
			FieldInfo[] array = fields;
			foreach (FieldInfo fieldInfo in array)
			{
				if (fieldInfo.GetValue(this) != fieldInfo.GetValue(other))
				{
					result = false;
					break;
				}
			}
			return result;
		}

		public virtual void Merge(DataBase other)
		{
			FieldInfo[] fields = GetType().GetFields();
			FieldInfo[] array = fields;
			foreach (FieldInfo fieldInfo in array)
			{
				if (fieldInfo.GetValue(other) == null || fieldInfo.GetValue(this) != fieldInfo.GetValue(other))
				{
					fieldInfo.SetValue(this, fieldInfo.GetValue(other));
				}
			}
		}
	}
	public class DeadDropData : DataBase
	{
		public string CashCollectionQuest;

		public string RefillProductsQuest;

		public DeadDropData(string identifier, bool loadDefaults = false)
			: base(identifier)
		{
			if (loadDefaults)
			{
				LoadDefaults();
			}
		}

		public void LoadDefaults()
		{
		}
	}
	public class DealerData : DataBase
	{
		public string DeadDrop;

		public string ProductDeadDrop;

		public string CashDeadDrop;

		public int MaxCustomers;

		public int ItemSlots;

		public float Cut;

		public float SpeedMultiplier;

		public bool DeliverCash;

		public bool PickupProducts;

		public float CashThreshold;

		public int ProductThreshold;

		public int DaysUntilNextNegotiation;

		public DealerData(string identifier, bool loadDefaults = false)
			: base(identifier)
		{
			if (loadDefaults)
			{
				LoadDefaults();
			}
		}

		public void LoadDefaults()
		{
			DeadDrop = null;
			ProductDeadDrop = null;
			CashDeadDrop = null;
			MaxCustomers = 8;
			ItemSlots = 5;
			Cut = 0.2f;
			SpeedMultiplier = 1f;
			DeliverCash = false;
			PickupProducts = false;
			CashThreshold = 1500f;
			ProductThreshold = 20;
			DaysUntilNextNegotiation = 0;
		}

		public bool MigrateLegacyDeadDrop()
		{
			bool result = false;
			if (!string.IsNullOrWhiteSpace(DeadDrop))
			{
				if (string.IsNullOrWhiteSpace(ProductDeadDrop))
				{
					ProductDeadDrop = DeadDrop;
					result = true;
				}
				if (string.IsNullOrWhiteSpace(CashDeadDrop))
				{
					CashDeadDrop = DeadDrop;
					result = true;
				}
				DeadDrop = null;
				result = true;
			}
			if (ModVersion != "1.5.1")
			{
				ModVersion = "1.5.1";
				result = true;
			}
			return result;
		}
	}
	public class SessionData : DataBase
	{
		public bool AccessInventory;

		public bool SettingsMenu;

		public float NegotiationModifier;

		public SessionData(string identifier)
			: base(identifier)
		{
		}
	}
}
namespace AdvancedDealing.Patches
{
	[HarmonyPatch(typeof(CustomerSelector))]
	public class CustomerSelectorPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("Open")]
		public static void OpenPostfix()
		{
			if (UIBuilder.CustomerSelector.UICreated)
			{
				UIBuilder.CustomerSelector.SortCustomers();
				UIBuilder.CustomerSelector.Searchbar.text = string.Empty;
			}
		}
	}
	[HarmonyPatch(typeof(DealerManagementApp))]
	public class DealerManagementAppPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("SetDisplayedDealer")]
		public static void SetDisplayedDealerPostfix(DealerManagementApp __instance, Dealer dealer)
		{
			if (SaveModifier.Instance.SavegameLoaded && UIBuilder.HasBuild)
			{
				DealerExtension dealer2 = DealerExtension.GetDealer(dealer);
				if (dealer2 != null)
				{
					UIBuilder.ProductDeadDropSelector.ButtonLabel.text = ResolveDeadDropName(dealer2.ProductDeadDrop, UIBuilder.ProductDeadDropSelector.EmptySelectionLabel);
					UIBuilder.CashDeadDropSelector.ButtonLabel.text = ResolveDeadDropName(dealer2.CashDeadDrop, UIBuilder.CashDeadDropSelector.EmptySelectionLabel);
					UIBuilder.CustomersScrollView.TitleLabel.text = LocalizationManager.Get("ui.customers.assigned_title", dealer2.Dealer.AssignedCustomers.Count, dealer2.MaxCustomers);
					UIBuilder.CustomersScrollView.AssignButton.SetActive(dealer2.Dealer.AssignedCustomers.Count < dealer2.MaxCustomers);
				}
			}
		}

		private static string ResolveDeadDropName(string guid, string fallback)
		{
			if (string.IsNullOrWhiteSpace(guid))
			{
				return fallback;
			}
			DeadDropExtension deadDrop = DeadDropExtension.GetDeadDrop(guid);
			object obj;
			if (deadDrop == null)
			{
				obj = null;
			}
			else
			{
				DeadDrop deadDrop2 = deadDrop.DeadDrop;
				obj = ((deadDrop2 != null) ? deadDrop2.DeadDropName : null);
			}
			if (obj == null)
			{
				obj = fallback;
			}
			return (string)obj;
		}
	}
	[HarmonyPatch(typeof(Dealer))]
	public class DealerPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("OnTick")]
		public static bool OnTickPrefix(Dealer __instance)
		{
			if (DealerExtension.DealerExists(__instance))
			{
				DealerExtension dealer = DealerExtension.GetDealer(__instance);
				if (dealer.HasActiveBehaviour)
				{
					dealer.Dealer.UpdatePotentialDealerPoI();
					return false;
				}
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(App<MessagesApp>))]
	public class MessagesAppPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("SetOpen")]
		public static void SetOpenPostfix()
		{
			if (!SaveModifier.Instance.SavegameLoaded)
			{
				return;
			}
			foreach (Conversation allConversation in Conversation.GetAllConversations())
			{
				allConversation.PatchSendableMessages();
			}
		}
	}
	[HarmonyPatch(typeof(NPCBehaviour))]
	public class NPCBehaviourPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("Update")]
		public static bool UpdatePrefix(NPCBehaviour __instance)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (DealerExtension.DealerExists(((object)__instance.Npc.GUID/*cast due to .constrained prefix*/).ToString()))
			{
				DealerExtension dealer = DealerExtension.GetDealer(((object)__instance.Npc.GUID/*cast due to .constrained prefix*/).ToString());
				if (dealer.HasActiveBehaviour)
				{
					return false;
				}
			}
			return true;
		}
	}
}
namespace AdvancedDealing.NPCs.Behaviour
{
	public abstract class DealerBehaviour
	{
		public const int MAX_CONSECUTIVE_PATHING_FAILURES = 5;

		public int Priority;

		protected int ConsecutivePathingFailures;

		protected DealerExtension Dealer;

		private Vector3 _lastDestination;

		private bool _enableScheduleOnEnd = false;

		public virtual string Name => "Behaviour";

		public virtual bool IsEnabled { get; protected set; }

		public bool IsActive { get; protected set; }

		public bool HasStarted { get; protected set; }

		protected NPCMovement Movement => ((NPC)Dealer.Dealer).Movement;

		private Behaviour activeBehaviour
		{
			get
			{
				NPCBehaviour behaviour = ((NPC)Dealer.Dealer).Behaviour;
				return (behaviour != null) ? behaviour.activeBehaviour : null;
			}
		}

		private NPCScheduleManager schedule => ((Component)Dealer.Dealer).GetComponentInChildren<NPCScheduleManager>();

		public DealerBehaviour(DealerExtension dealer)
		{
			Dealer = dealer;
			((NPC)dealer.Dealer).Health.onKnockedOut.AddListener(UnityAction.op_Implicit((Action)OnKnockOutOrDie));
			((NPC)dealer.Dealer).Health.onDie.AddListener(UnityAction.op_Implicit((Action)OnKnockOutOrDie));
			((NPC)dealer.Dealer).Health.onRevive.AddListener(UnityAction.op_Implicit((Action)OnRevive));
		}

		public virtual void Enable()
		{
			IsEnabled = true;
			Logger.Debug("DealerBehaviour", "Behaviour for " + ((NPC)Dealer.Dealer).fullName + " enabled: " + Name);
		}

		public void Disable()
		{
			IsEnabled = false;
			if (HasStarted)
			{
				End();
			}
			Logger.Debug("DealerBehaviour", "Behaviour for " + ((NPC)Dealer.Dealer).fullName + " disabled: " + Name);
		}

		public virtual void Start()
		{
			if (Movement.IsMoving)
			{
				Movement.Stop();
			}
			HasStarted = true;
			IsActive = true;
			Dealer.SetActiveBehaviour(this);
			Behaviour obj = activeBehaviour;
			if (obj != null)
			{
				obj.Pause();
			}
			if ((Object)(object)schedule != (Object)null && schedule.ScheduleEnabled)
			{
				schedule.DisableSchedule();
				_enableScheduleOnEnd = true;
			}
			Logger.Debug("DealerBehaviour", "Behaviour for " + ((NPC)Dealer.Dealer).fullName + " started: " + Name);
		}

		public virtual void End()
		{
			HasStarted = false;
			IsActive = false;
			Disable();
			Dealer.SetActiveBehaviour(null);
			if (_enableScheduleOnEnd && (Object)(object)schedule != (Object)null)
			{
				schedule.EnableSchedule();
			}
			Logger.Debug("DealerBehaviour", "Behaviour for " + ((NPC)Dealer.Dealer).fullName + " ended: " + Name);
		}

		public virtual void Pause()
		{
			IsActive = false;
			if (_enableScheduleOnEnd && (Object)(object)schedule != (Object)null)
			{
				schedule.EnableSchedule();
			}
			Logger.Debug("DealerBehaviour", "Behaviour for " + ((NPC)Dealer.Dealer).fullName + " paused: " + Name);
		}

		public virtual void Resume()
		{
			IsActive = true;
			if ((Object)(object)schedule != (Object)null && schedule.ScheduleEnabled)
			{
				schedule.DisableSchedule();
				_enableScheduleOnEnd = true;
			}
			Logger.Debug("DealerBehaviour", "Behaviour for " + ((NPC)Dealer.Dealer).fullName + " resumed: " + Name);
		}

		public virtual void OnActiveTick()
		{
			Behaviour obj = activeBehaviour;
			if (obj != null)
			{
				obj.Pause();
			}
		}

		protected virtual void SetDestination(Vector3 position, bool teleportIfFail = true, float successThreshold = 1f)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			if (InstanceFinder.IsServer)
			{
				if (teleportIfFail && ConsecutivePathingFailures >= 5 && !Movement.CanGetTo(position, 1f))
				{
					Logger.Debug("DealerBehaviour", $"Too many pathing failures for {((NPC)Dealer.Dealer).fullName}. Warping to {position}.");
					NavMeshHit val = default(NavMeshHit);
					NavMeshUtility.SamplePosition(position, ref val, 5f, -1, true);
					position = ((NavMeshHit)(ref val)).position;
					Movement.Warp(position);
					WalkCallback((WalkResult)4);
				}
				else
				{
					_lastDestination = position;
					Movement.SetDestination(position, Action<WalkResult>.op_Implicit((Action<WalkResult>)WalkCallback), successThreshold, 0.1f);
				}
			}
		}

		protected bool IsAtDestination()
		{
			//IL_0007: 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)
			return Vector3.Distance(Movement.FootPosition, _lastDestination) < 2f;
		}

		protected virtual void WalkCallback(WalkResult res)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			if (IsActive)
			{
				if ((int)res == 0)
				{
					ConsecutivePathingFailures++;
				}
				else
				{
					ConsecutivePathingFailures = 0;
				}
			}
		}

		private void OnKnockOutOrDie()
		{
			if (IsEnabled && HasStarted)
			{
				Pause();
			}
		}

		private void OnRevive()
		{
			if (IsEnabled && HasStarted)
			{
				Resume();
			}
		}
	}
	public class DeliverCashDealerBehaviour : DealerBehaviour
	{
		private DeadDropExtension _deadDrop;

		private object _deliveryRoutine;

		private bool _deadDropIsFull = false;

		public override string Name => "Deliver cash";

		public DeliverCashDealerBehaviour(DealerExtension dealer)
			: base(dealer)
		{
			Priority = 1;
		}

		public override void Start()
		{
			_deadDrop = DeadDropExtension.GetDeadDrop(Dealer.CashDeadDrop);
			if (_deadDrop == null)
			{
				Disable();
				Logger.Warning("DeliverCashDealerBehaviour", "Cash delivery for " + ((NPC)Dealer.Dealer).fullName + " was not started because no valid cash dead drop is assigned.");
			}
			else if (!_deadDropIsFull || !_deadDrop.IsFull())
			{
				_deadDropIsFull = false;
				base.Start();
			}
		}

		public override void End()
		{
			base.End();
			StopRoutines();
		}

		public override void OnActiveTick()
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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)
			if (!base.IsActive)
			{
				return;
			}
			base.OnActiveTick();
			if (_deadDrop == null)
			{
				End();
			}
			else if (ModConfig.SkipMovement)
			{
				BeginDelivery();
			}
			else if (Dealer.Dealer.Cash < Dealer.CashThreshold || (_deadDrop != null && ((object)_deadDrop.DeadDrop.GUID/*cast due to .constrained prefix*/).ToString() != Dealer.CashDeadDrop) || !Dealer.DeliverCash)
			{
				End();
			}
			else if (_deliveryRoutine == null && !base.Movement.IsMoving)
			{
				if (IsAtDestination())
				{
					BeginDelivery();
				}
				else
				{
					SetDestination(_deadDrop.GetPosition(), teleportIfFail: true, 2f);
				}
			}
		}

		private void BeginDelivery()
		{
			if (_deliveryRoutine == null)
			{
				_deliveryRoutine = MelonCoroutines.Start(DeliveryRoutine());
			}
			IEnumerator DeliveryRoutine()
			{
				float cash = Dealer.Dealer.Cash;
				base.Movement.FaceDirection(_deadDrop.GetPosition(), 0.5f);
				yield return (object)new WaitForSeconds(2f);
				((NPC)Dealer.Dealer).SetAnimationTrigger("GrabItem");
				if (_deadDrop.IsFull())
				{
					_deadDropIsFull = true;
					Dealer.SendMessage(LocalizationManager.Get("notifications.cash.no_space", _deadDrop.DeadDrop.DeadDropName), ModConfig.NotifyOnAction);
					Logger.Debug("Cash delivery for " + ((NPC)Dealer.Dealer).fullName + " failed: Dead drop is full");
				}
				else
				{
					((StorageEntity)_deadDrop.DeadDrop.Storage).InsertItem((ItemInstance)(object)NetworkSingleton<MoneyManager>.Instance.GetCashInstance(cash), true);
					Dealer.SendMessage(LocalizationManager.Get("notifications.cash.delivered", cash, _deadDrop.DeadDrop.DeadDropName), ModConfig.NotifyOnAction);
					if (ModConfig.NotifyOnAction)
					{
					}
					Dealer.Dealer.ChangeCash(0f - cash);
					Logger.Debug("Cash from " + ((NPC)Dealer.Dealer).fullName + " delivered successfully");
					yield return (object)new WaitUntil(Func<bool>.op_Implicit((Func<bool>)(() => Dealer.Dealer.Cash < Dealer.CashThreshold)));
				}
				End();
			}
		}

		private void StopRoutines()
		{
			if (_deliveryRoutine != null)
			{
				MelonCoroutines.Stop(_deliveryRoutine);
				_deliveryRoutine = null;
			}
		}
	}
	public class PickupProductsDealerBehaviour : DealerBehaviour
	{
		private DeadDropExtension _deadDrop;

		private object _pickupRoutine;

		private bool _deadDropIsEmpty = false;

		public override string Name => "Pickup products";

		public PickupProductsDealerBehaviour(DealerExtension dealer)
			: base(dealer)
		{
			Priority = 2;
		}

		public override void Start()
		{
			_deadDrop = DeadDropExtension.GetDeadDrop(Dealer.ProductDeadDrop);
			if (!_deadDropIsEmpty || _deadDrop == null || _deadDrop.GetAllProducts().Count > 0)
			{
				_deadDropIsEmpty = false;
				base.Start();
			}
		}

		public override void End()
		{
			base.End();
			StopRoutines();
		}

		public override void OnActiveTick()
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			if (!base.IsActive)
			{
				return;
			}
			base.OnActiveTick();
			if (_deadDrop == null)
			{
				End();
			}
			else if (ModConfig.SkipMovement)
			{
				BeginPickup();
			}
			else if ((_deadDrop != null && ((object)_deadDrop.DeadDrop.GUID/*cast due to .constrained prefix*/).ToString() != Dealer.ProductDeadDrop) || !Dealer.PickupProducts)
			{
				End();
			}
			else if (_pickupRoutine == null && !base.Movement.IsMoving)
			{
				if (IsAtDestination())
				{
					BeginPickup();
				}
				else
				{
					SetDestination(_deadDrop.GetPosition(), teleportIfFail: true, 2f);
				}
			}
		}

		private void BeginPickup()
		{
			if (_pickupRoutine == null)
			{
				_pickupRoutine = MelonCoroutines.Start(PickupRoutine());
			}
			IEnumerator PickupRoutine()
			{
				base.Movement.FaceDirection(_deadDrop.GetPosition(), 0.5f);
				yield return (object)new WaitForSeconds(2f);
				((NPC)Dealer.Dealer).SetAnimationTrigger("GrabItem");
				bool shouldNotify = true;
				if (_deadDrop.GetAllProducts().Count > 0)
				{
					Dictionary<ProductItemInstance, ItemSlot> products = _deadDrop.GetAllProducts();
					foreach (KeyValuePair<ProductItemInstance, ItemSlot> product in products)
					{
						if (Dealer.IsInventoryFull(out var freeSlots) || freeSlots <= 1)
						{
							break;
						}
						((NPC)Dealer.Dealer).Inventory.InsertItem((ItemInstance)(object)product.Key, true);
						product.Value.ChangeQuantity(-((BaseItemInstance)product.Key).Quantity, false);
					}
					Dealer.GetAllProducts(out var totalAmount);
					if (totalAmount <= Dealer.ProductThreshold && !Dealer.IsInventoryFull(out var freeSlots2) && freeSlots2 > 1)
					{
						shouldNotify = true;
					}
					else
					{
						shouldNotify = false;
						Logger.Debug("Product pickup for " + ((NPC)Dealer.Dealer).fullName + " was successfull");
					}
				}
				if (shouldNotify)
				{
					Dealer.SendMessage(LocalizationManager.Get("notifications.products.empty", _deadDrop.DeadDrop.DeadDropName), ModConfig.NotifyOnAction);
					_deadDropIsEmpty = true;
					if (ModConfig.NotifyOnAction)
					{
					}
					Logger.Debug("Product pickup for " + ((NPC)Dealer.Dealer).fullName + " failed: Dead drop is empty");
				}
				yield return (object)new WaitForSeconds(2f);
				End();
			}
		}

		private void StopRoutines()
		{
			if (_pickupRoutine != null)
			{
				MelonCoroutines.Stop(_pickupRoutine);
				_pickupRoutine = null;
			}
		}
	}
}
namespace AdvancedDealing.Messaging
{
	public class Conversation
	{
		public readonly NPC NPC;

		public bool UIPatched;

		private static readonly List<Conversation> cache = new List<Conversation>();

		private readonly List<MessageBase> _sendableMessages = new List<MessageBase>();

		private readonly List<MessageBase> _patchedMessages = new List<MessageBase>();

		public MSGConversation S1Conversation => NPC.MSGConversation;

		public Conversation(NPC npc)
		{
			NPC = npc;
			Logger.Debug("Conversation", "Conversation created: " + npc.fullName);
			cache.Add(this);
		}

		public void PatchSendableMessages()
		{
			if ((Object)(object)NPC == (Object)null || S1Conversation == null)
			{
				return;
			}
			foreach (MessageBase msg in _sendableMessages)
			{
				bool flag = S1Conversation.Sendables.Exists(Predicate<SendableMessage>.op_Implicit((Func<SendableMessage, bool>)((SendableMessage x) => x.Text == msg.Text)));
				if (!_patchedMessages.Contains(msg) && !flag)
				{
					SendableMessage val = S1Conversation.CreateSendableMessage(msg.Text);
					val.ShouldShowCheck = BoolCheck.op_Implicit((Func<SendableMessage, bool>)msg.ShouldShowCheck);
					val.disableDefaultSendBehaviour = msg.DisableDefaultSendBehaviour;
					val.onSelected = Action.op_Implicit((Action)msg.OnSelected);
					val.onSent = Action.op_Implicit((Action)msg.OnSent);
					_patchedMessages.Add(msg);
				}
			}
			if (!UIPatched)
			{
				NPC.ConversationCanBeHidden = false;
				S1Conversation.EnsureUIExists();
				S1Conversation.SetEntryVisibility(true);
				UIPatched = true;
			}
		}

		public void Destroy()
		{
			if ((Object)(object)NPC != (Object)null)
			{
				NPC.ConversationCanBeHidden = true;
			}
			UIPatched = false;
			cache.Remove(this);
		}

		public void AddSendableMessage(MessageBase message)
		{
			Type type = message.GetType();
			if (!_sendableMessages.Exists((MessageBase a) => a.GetType() == type))
			{
				message.SetReferences(NPC, this);
				_sendableMessages.Add(message);
			}
		}

		public static Conversation GetConversation(string npcGuid)
		{
			Conversation conversation = cache.Find((Conversation x) => ((object)x.NPC.GUID/*cast due to .constrained prefix*/).ToString().Contains(npcGuid));
			if (conversation == null)
			{
				Logger.Error("Conversation", "Could not find conversation for: " + npcGuid);
				return null;
			}
			return conversation;
		}

		public static List<Conversation> GetAllConversations()
		{
			return cache;
		}

		public static void ClearAll()
		{
			cache.Clear();
			Logger.Debug("Conversation", "Conversations deinitialized");
		}

		public static bool ConversationExists(string npcName)
		{
			Conversation conversation = cache.Find((Conversation x) => ((Object)x.NPC).name.Contains(npcName));
			return conversation != null;
		}
	}
}
namespace AdvancedDealing.Messaging.Messages
{
	public class AccessInventoryMessage(DealerExtension dealerExtension) : MessageBase()
	{
		private readonly DealerExtension _dealer = dealerExtension;

		public override string Text => LocalizationManager.Get("messages.access_inventory.option");

		public override bool DisableDefaultSendBehaviour => true;

		public override bool ShouldShowCheck(SendableMessage sMsg)
		{
			if (dealerExtension.Dealer.IsRecruited && ModConfig.AccessInventory)
			{
				return true;
			}
			return false;
		}

		public override void OnSelected()
		{
			Singleton<GameplayMenu>.Instance.SetIsOpen(false);
			dealerExtension.Dealer.TradeItems();
		}
	}
	public class AdjustSettingsMessage(DealerExtension dealerExtension) : MessageBase()
	{
		private readonly DealerExtension _dealer = dealerExtension;

		public override string Text => LocalizationManager.Get("messages.adjust_settings.option");

		public override bool DisableDefaultSendBehaviour => true;

		public override bool ShouldShowCheck(SendableMessage sMsg)
		{
			if (dealerExtension.Dealer.IsRecruited && ModConfig.SettingsMenu)
			{
				return true;
			}
			return false;
		}

		public override void OnSelected()
		{
			UIBuilder.SettingsPopup.Open(dealerExtension);
		}
	}
	public class DisableDeliverCashMessage(DealerExtension dealerExtension) : MessageBase()
	{
		private readonly DealerExtension _dealer = dealerExtension;

		public override string Text => LocalizationManager.Get("messages.cash.disable.option");

		public override bool DisableDefaultSendBehaviour => true;

		public override bool ShouldShowCheck(SendableMessage sMsg)
		{
			if (dealerExtension.Dealer.IsRecruited && dealerExtension.DeliverCash)
			{
				return true;
			}
			return false;
		}

		public override void OnSelected()
		{
			dealerExtension.DeliverCash = false;
			dealerExtension.SendPlayerMessage(LocalizationManager.Get("messages.cash.disable.player"));
			dealerExtension.SendMessage(LocalizationManager.Get("messages.cash.disable.dealer"), notify: false, network: true, 2f);
		}
	}
	internal class DisableProductPickupMessage(DealerExtension dealerExtension) : MessageBase()
	{
		private readonly DealerExtension _dealer = dealerExtension;

		public override string Text => LocalizationManager.Get("messages.products.disable.option");

		public override bool DisableDefaultSendBehaviour => true;

		public override bool ShouldShowCheck(SendableMessage sMsg)
		{
			if (dealerExtension.Dealer.IsRecruited && dealerExtension.PickupProducts)
			{
				return true;
			}
			return false;
		}

		public override void OnSelected()
		{
			dealerExtension.PickupProducts = false;
			dealerExtension.SendPlayerMessage(LocalizationManager.Get("messages.products.disable.player"));
			dealerExtension.SendMessage(LocalizationManager.Get("messages.products.disable.dealer"), notify: false, network: true, 2f);
		}
	}
	public class EnableDeliverCashMessage(DealerExtension dealerExtension) : MessageBase()
	{
		private readonly DealerExtension _dealer = dealerExtension;

		public override string Text => LocalizationManager.Get("messages.cash.enable.option");

		public override bool DisableDefaultSendBehaviour => true;

		public override bool ShouldShowCheck(SendableMessage sMsg)
		{
			if (dealerExtension.Dealer.IsRecruited && !dealerExtension.DeliverCash && !string.IsNullOrWhiteSpace(dealerExtension.CashDeadDrop))
			{
				return true;
			}
			return false;
		}

		public override void OnSelected()
		{
			UIBuilder.SliderPopup.Open(LocalizationManager.Get("ui.slider.cash_threshold_title", ((Object)dealerExtension.Dealer).name), null, dealerExtension.CashThreshold, 100f, 10000f, 50f, 0, OnSend, null, LocalizationManager.Get("formats.cash"));
		}

		private void OnSend(float value)
		{
			dealerExtension.DeliverCash = true;
			dealerExtension.CashThreshold = value;
			dealerExtension.SendPlayerMessage(LocalizationManager.Get("messages.cash.enable.player", value));
			dealerExtension.SendMessage(LocalizationManager.Get("messages.cash.enable.dealer"), notify: false, network: true, 2f);
		}
	}
	public class EnableProductPickupMessage(DealerExtension dealerExtension) : MessageBase()
	{
		private readonly DealerExtension _dealer = dealerExtension;

		public override string Text => LocalizationManager.Get("messages.products.enable.option");

		public override bool DisableDefaultSendBehaviour => true;

		public override bool ShouldShowCheck(SendableMessage sMsg)
		{
			if (dealerExtension.Dealer.IsRecruited && !dealerExtension.PickupProducts)
			{
				return true;
			}
			return false;
		}

		public override void OnSelected()
		{
			UIBuilder.SliderPopup.Open(LocalizationManager.Get("ui.slider.product_threshold_title", ((Object)dealerExtension.Dealer).name), null, dealerExtension.ProductThreshold, 0f, 1000f, 10f, 0, OnSend, null, LocalizationManager.Get("formats.products"));
		}

		private void OnSend(float value)
		{
			dealerExtension.PickupProducts = true;
			dealerExtension.ProductThreshold = (int)value;
			dealerExtension.SendPlayerMessage(LocalizationManager.Get("messages.products.enable.player", value));
			dealerExtension.SendMessage(LocalizationManager.Get("messages.products.enable.dealer"), notify: false, network: true, 2f);
		}
	}
	public class FiredMessage(DealerExtension dealerExtension) : MessageBase()
	{
		private readonly DealerExtension _dealer = dealerExtension;

		public override string Text => LocalizationManager.Get("messages.fire.option");

		public override bool DisableDefaultSendBehaviour => true;

		public override bool ShouldShowCheck(SendableMessage sMsg)
		{
			if (dealerExtension.Dealer.IsRecruited)
			{
				return true;
			}
			return false;
		}

		public override void OnSelected()
		{
			PlayerSingleton<MessagesApp>.Instance.ConfirmationPopup.Open(LocalizationManager.Get("messages.fire.confirm_title"), LocalizationManager.Get("messages.fire.confirm_body"), base.S1Conversation, Action<EResponse>.op_Implicit((Action<EResponse>)OnConfirmationResponse));
		}

		private void OnConfirmationResponse(EResponse response)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			if ((int)response == 0)
			{
				dealerExtension.Fire();
				dealerExtension.SendPlayerMessage(LocalizationManager.Get("messages.fire.player"));
				dealerExtension.SendMessage(LocalizationManager.Get("messages.fire.dealer"), notify: false, network: true, 0.5f);
			}
		}
	}
	public abstract class MessageBase
	{
		protected NPC NPC;

		protected Conversation Conversation;

		public virtual string Text => "Text";

		protected MSGConversation S1Conversation => NPC.MSGConversation;

		public virtual bool DisableDefaultSendBehaviour => false;

		public virtual void SetReferences(NPC npc, Conversation conversation)
		{
			NPC = npc;
			Conversation = conversation;
		}

		public virtual bool ShouldShowCheck(SendableMessage sMsg)
		{
			return true;
		}

		public virtual void OnSelected()
		{
		}

		public virtual void OnSent()
		{
		}
	}
	public class NegotiateCutMessage(DealerExtension dealerExtension) : MessageBase()
	{
		private readonly DealerExtension _dealer = dealerExtension;

		public override string Text => LocalizationManager.Get("messages.negotiation.option");

		public override bool DisableDefaultSendBehaviour => true;

		public override bool ShouldShowCheck(SendableMessage sMsg)
		{
			if (dealerExtension.Dealer.IsRecruited && dealerExtension.DaysUntilNextNegotiation <= 0)
			{
				return true;
			}
			return false;
		}

		public override void OnSelected()
		{
			float num = (float)Math.Round(dealerExtension.Cut, 2);
			UIBuilder.SliderPopup.Open(LocalizationManager.Get("ui.slider.negotiation_title", ((Object)dealerExtension.Dealer).name), LocalizationManager.Get("ui.slider.current", num), num, 0f, 1f, 0.01f, 2, OnSend, null, LocalizationManager.Get("formats.percent"));
		}

		private void OnSend(float value)
		{
			dealerExtension.SendPlayerMessage(LocalizationManager.Get("messages.negotiation.player_offer", value));
			if (value == dealerExtension.Cut)
			{
				dealerExtension.SendMessage(LocalizationManager.Get("messages.negotiation.same"), notify: false, network: true, 2f);
				return;
			}
			if (value > dealerExtension.Cut)
			{
				dealerExtension.SendMessage(LocalizationManager.Get("messages.negotiation.higher"), notify: false, network: true, 2f);
			}
			else
			{
				if (!CalculateResponse(dealerExtension.Cut, value))
				{
					dealerExtension.SendMessage(LocalizationManager.Get("messages.negotiation.rejected"), notify: false, network: true, 2f);
					dealerExtension.DaysUntilNextNegotiation = 3;
					if (NetworkSynchronizer.IsSyncing)
					{
						NetworkSynchronizer.Instance.SendData(dealerExtension.FetchData());
					}
					return;
				}
				dealerExtension.SendMessage(LocalizationManager.Get("messages.negotiation.accepted"), notify: false, network: true, 2f);
			}
			dealerExtension.Cut = value;
			dealerExtension.DaysUntilNextNegotiation = 7;
			dealerExtension.HasChanged = true;
			if (NetworkSynchronizer.IsSyncing)
			{
				NetworkSynchronizer.Instance.SendData(dealerExtension.FetchData());
			}
		}

		private static bool CalculateResponse(float oldCut, float newCut)
		{
			float negotiationModifier = ModConfig.NegotiationModifier;
			float num = negotiationModifier - (1f - newCut * 100f / oldCut / 100f);
			return Random.value <= num;
		}
	}
}
namespace AdvancedDealing.Localization
{
	public static class LocalizationManager
	{
		public const string DefaultLanguage = "en-US";

		private static readonly StringComparer KeyComparer = StringComparer.OrdinalIgnoreCase;

		private static Dictionary<string, string> _fallback = new Dictionary<string, string>(KeyComparer);

		private static Dictionary<string, string> _translations = new Dictionary<string, string>(KeyComparer);

		private static CultureInfo _formatCulture = CultureInfo.InvariantCulture;

		public static string CurrentLanguage { get; private set; } = "en-US";

		public static string LocalizationDirectory => Path.Combine(MelonEnvironment.UserDataDirectory, "AdvancedDealing", "Localization");

		public static void Initialize(string configuredLanguage)
		{
			try
			{
				Directory.CreateDirectory(LocalizationDirectory);
				EnsureBundledLanguageFile("en-US");
				EnsureBundledLanguageFile("ru-RU");
				_fallback = LoadLanguage("en-US", allowBundledFallback: true);
				CurrentLanguage = ResolveLanguage(configuredLanguage);
				_formatCulture = ResolveCulture(CurrentLanguage);
				_translations = (CurrentLanguage.Equals("en-US", StringComparison.OrdinalIgnoreCase) ? new Dictionary<string, string>(_fallback, KeyComparer) : LoadLanguage(CurrentLanguage, allowBundledFallback: false));
				if (_translations.Count == 0 && !CurrentLanguage.Equals("en-US", StringComparison.OrdinalIgnoreCase))
				{
					Logger.Warning("Localization", $"Language '{CurrentLanguage}' could not be loaded. Falling back to {"en-US"}.");
					CurrentLanguage = "en-US";
					_formatCulture = ResolveCulture("en-US");
					_translations = new Dictionary<string, string>(_fallback, KeyComparer);
				}
				Logger.Msg("Localization", "Loaded language: " + CurrentLanguage + ". Files: " + LocalizationDirectory);
			}
			catch (Exception ex)
			{
				CurrentLanguage = "en-US";
				_formatCulture = CultureInfo.InvariantCulture;
				_fallback = LoadBundledLanguage("en-US");
				_translations = new Dictionary<string, string>(_fallback, KeyComparer);
				Logger.Error("Localization", "Localization initialization failed. Embedded English fallback will be used.", ex);
			}
		}

		public static string Get(string key, params object[] arguments)
		{
			if (string.IsNullOrWhiteSpace(key))
			{
				return string.Empty;
			}
			if (!_translations.TryGetValue(key, out var value) && !_fallback.TryGetValue(key, out value))
			{
				Logger.Warning("Localization", "Missing localization key: " + key);
				return "[" + key + "]";
			}
			if (arguments == null || arguments.Length == 0)
			{
				return value;
			}
			try
			{
				return string.Format(_formatCulture, value, arguments);
			}
			catch (FormatException ex)
			{
				Logger.Error("Localization", "Invalid format string for key '" + key + "': " + value, ex);
				return value;
			}
		}

		public static string Format(string format, params object[] arguments)
		{
			if (string.IsNullOrEmpty(format))
			{
				return string.Empty;
			}
			try
			{
				return string.Format(_formatCulture, format, arguments);
			}
			catch (FormatException ex)
			{
				Logger.Error("Localization", "Invalid runtime format string: " + format, ex);
				return format;
			}
		}

		private static string ResolveLanguage(string configuredLanguage)
		{
			string text = configuredLanguage;
			if (string.IsNullOrWhiteSpace(text) || text.Equals("auto", StringComparison.OrdinalIgnoreCase))
			{
				text = CultureInfo.CurrentUICulture?.Name;
			}
			if (string.IsNullOrWhiteSpace(text))
			{
				return "en-US";
			}
			text = text.Trim();
			if (text.Equals("ru", StringComparison.OrdinalIgnoreCase))
			{
				text = "ru-RU";
			}
			else if (text.Equals("en", StringComparison.OrdinalIgnoreCase))
			{
				text = "en-US";
			}
			string languageFilePath = GetLanguageFilePath(text);
			if (File.Exists(languageFilePath))
			{
				return text;
			}
			string value = text.Split('-', '_')[0];
			string text2 = null;
			string[] files = Directory.GetFiles(LocalizationDirectory, "*.json", SearchOption.TopDirectoryOnly);
			foreach (string path in files)
			{
				string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path);
				string text3 = fileNameWithoutExtension.Split('-', '_')[0];
				if (text3.Equals(value, StringComparison.OrdinalIgnoreCase))
				{
					text2 = fileNameWithoutExtension;
					break;
				}
			}
			return text2 ?? "en-US";
		}

		private static CultureInfo ResolveCulture(string language)
		{
			try
			{
				return CultureInfo.GetCultureInfo(language);
			}
			catch (CultureNotFoundException)
			{
				return CultureInfo.InvariantCulture;
			}
		}

		private static Dictionary<string, string> LoadLanguage(string language, bool allowBundledFallback)
		{
			string languageFilePath = GetLanguageFilePath(language);
			if (!File.Exists(languageFilePath))
			{
				Logger.Warning("Localization", "Localization file not found: " + languageFilePath);
				return allowBundledFallback ? LoadBundledLanguage(language) : new Dictionary<string, string>(KeyComparer);
			}
			try
			{
				string text = File.ReadAllText(languageFilePath, Encoding.UTF8);
				Dictionary<string, string> dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(text);
				return (dictionary == null) ? new Dictionary<string, string>(KeyComparer) : new Dictionary<string, string>(dictionary, KeyComparer);
			}
			catch (Exception ex)
			{
				Logger.Error("Localization", "Failed to load localization file: " + languageFilePath, ex);
				return allowBundledFallback ? LoadBundledLanguage(language) : new Dictionary<string, string>(KeyComparer);
			}
		}

		private static Dictionary<string, string> LoadBundledLanguage(string language)
		{
			string resourceName = GetResourceName(language);
			try
			{
				using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName);
				if (stream == null)
				{
					Logger.Error("Localization", "Embedded localization resource not found: " + resourceName);
					return new Dictionary<string, string>(KeyComparer);
				}
				using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8, detectEncodingFromByteOrderMarks: true);
				string text = streamReader.ReadToEnd();
				Dictionary<string, string> dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(text);
				return (dictionary == null) ? new Dictionary<string, string>(KeyComparer) : new Dictionary<string, string>(dictionary, KeyComparer);
			}
			catch (Exception ex)
			{
				Logger.Error("Localization", "Failed to load embedded localization resource: " + resourceName, ex);
				return new Dictionary<string, string>(KeyComparer);
			}
		}

		private static void EnsureBundledLanguageFile(string language)
		{
			string languageFilePath = GetLanguageFilePath(language);
			Dictionary<string, string> dictionary = LoadBundledLanguage(language);
			if (dictionary.Count == 0)
			{
				return;
			}
			if (!File.Exists(languageFilePath))
			{
				WriteLanguageFile(languageFilePath, dictionary);
				return;
			}
			try
			{
				string text = File.ReadAllText(languageFilePath, Encoding.UTF8);
				Dictionary<string, string> dictionary2 = JsonConvert.DeserializeO