Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of AdvancedDealingCommunity v1.5.2
Mods/AdvancedDealing.Il2Cpp.dll
Decompiled 3 days ago
The result has been truncated due to the large size, download it to view full contents!
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