Decompiled source of TradersExtended v2.0.0

TradersExtended.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using AzuExtendedPlayerInventory;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using ConditionalConfigSync;
using ExtraSlots;
using GUIFramework;
using HarmonyLib;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using TMPro;
using TradersExtended.Compatibility;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using YamlDotNet.Serialization;

[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: ComVisible(false)]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyProduct("Traders Extended")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyDescription("")]
[assembly: Guid("6d6f243e-c80e-4a33-b2d0-a2657d3b9f7f")]
[assembly: AssemblyTitle("Traders Extended")]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CompilationRelaxations(8)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyFileVersion("2.0.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[<513676d6-9794-4182-bde6-312741b82216>Embedded]
	internal sealed class <513676d6-9794-4182-bde6-312741b82216>EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	[<513676d6-9794-4182-bde6-312741b82216>Embedded]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace TradersExtended
{
	internal static class AmountDialog
	{
		[HarmonyPatch(typeof(StoreGui), "OnSelectedItem")]
		public static class StoreGui_OnSelectedItem_SelectItem
		{
			private static void Postfix()
			{
				OnSelectedTradeableItemClick(sellDialog: false);
			}
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static UnityAction<float> <0>__OnSplitSliderChanged;

			public static UnityAction <1>__OnOkClick;

			public static UnityAction <2>__Close;
		}

		private static float clickTime;

		private static GameObject amountDialog;

		private static Slider sliderDialog;

		private static TMP_Text sliderTitle;

		private static TMP_Text sliderAmountText;

		private static TMP_Text sliderAmountCoinsText;

		private static TMP_Text sliderButtonOk;

		private static Image sliderImage;

		private static Image sliderCurrencyImage;

		private static string sliderTitleText;

		private static string sliderButtonText;

		private static StoreGui storeGui;

		private const float m_splitNumInputTimeoutSec = 0.5f;

		private static string m_splitInput = "";

		private static DateTime m_lastSplitInput;

		private static bool isSellDialog;

		public static GameObject Init(StoreGui store)
		{
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: 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_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: 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_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_036a: Unknown result type (might be due to invalid IL or missing references)
			//IL_036f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0375: Expected O, but got Unknown
			//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Expected O, but got Unknown
			storeGui = store;
			amountDialog = Object.Instantiate<GameObject>(((Component)InventoryGui.instance.m_splitPanel).gameObject, storeGui.m_rootPanel.transform.parent);
			((Object)amountDialog).name = "AmountDialog";
			Transform val = amountDialog.transform.Find("win_bkg");
			sliderTitle = ((Component)val.Find("Text")).GetComponent<TMP_Text>();
			sliderDialog = ((Component)val.Find("Slider")).GetComponent<Slider>();
			sliderAmountText = ((Component)val.Find("amount")).GetComponent<TMP_Text>();
			sliderImage = ((Component)val.Find("Icon_bkg/Icon")).GetComponent<Image>();
			sliderButtonOk = ((Component)val.Find("Button_ok/Text")).GetComponent<TMP_Text>();
			Transform val2 = val.Find("Icon_bkg");
			GameObject val3 = Object.Instantiate<GameObject>(((Component)val2).gameObject, val);
			((Object)val3).name = "Coins_bkg";
			val3.transform.SetSiblingIndex(val2.GetSiblingIndex() + 1);
			sliderCurrencyImage = ((Component)val3.transform.Find("Icon")).GetComponent<Image>();
			UpdateCurrencyIcon(storeGui.m_coinPrefab);
			RectTransform component = val3.GetComponent<RectTransform>();
			component.anchorMax += new Vector2(0.15f, 0f);
			component.anchorMin += new Vector2(0.15f, 0f);
			RectTransform component2 = ((Component)val2).GetComponent<RectTransform>();
			component2.anchorMax -= new Vector2(0.15f, 0f);
			component2.anchorMin -= new Vector2(0.15f, 0f);
			GameObject val4 = Object.Instantiate<GameObject>(((Component)sliderAmountText).gameObject, val);
			((Object)val4).name = "amount_coins";
			val4.transform.SetSiblingIndex(sliderAmountText.transform.GetSiblingIndex() + 1);
			sliderAmountCoinsText = val4.GetComponent<TMP_Text>();
			RectTransform component3 = ((Component)sliderAmountText).GetComponent<RectTransform>();
			component3.anchorMax -= new Vector2(0.15f, 0f);
			component3.anchorMin -= new Vector2(0.15f, 0f);
			RectTransform component4 = val4.GetComponent<RectTransform>();
			component4.anchorMax += new Vector2(0.15f, 0f);
			component4.anchorMin += new Vector2(0.15f, 0f);
			GameObject val5 = Object.Instantiate<GameObject>(((Component)sliderTitle).gameObject, val);
			((Object)val5).name = "equal";
			val5.transform.SetSiblingIndex(sliderTitle.transform.GetSiblingIndex() + 1);
			RectTransform component5 = val5.GetComponent<RectTransform>();
			component5.anchorMin -= new Vector2(0f, 0.5f);
			val5.GetComponent<TMP_Text>().SetText("=");
			((UnityEvent<float>)(object)sliderDialog.onValueChanged).AddListener((UnityAction<float>)OnSplitSliderChanged);
			ButtonClickedEvent onClick = ((Component)val.Find("Button_ok")).GetComponent<Button>().onClick;
			object obj = <>O.<1>__OnOkClick;
			if (obj == null)
			{
				UnityAction val6 = OnOkClick;
				<>O.<1>__OnOkClick = val6;
				obj = (object)val6;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj);
			ButtonClickedEvent onClick2 = ((Component)val.Find("Button_cancel")).GetComponent<Button>().onClick;
			object obj2 = <>O.<2>__Close;
			if (obj2 == null)
			{
				UnityAction val7 = Close;
				<>O.<2>__Close = val7;
				obj2 = (object)val7;
			}
			((UnityEvent)onClick2).AddListener((UnityAction)obj2);
			return amountDialog;
		}

		public static void UpdateCurrencyIcon(ItemDrop currency)
		{
			if ((Object)(object)sliderCurrencyImage != (Object)null && (Object)(object)currency != (Object)null)
			{
				sliderCurrencyImage.sprite = currency.m_itemData.GetIcon();
			}
		}

		public static void OnOkClick()
		{
			BuySelectedItem();
		}

		public static void SetSellState(bool sellDialog)
		{
			isSellDialog = sellDialog;
		}

		public static void OnSelectedTradeableItemClick(bool sellDialog)
		{
			SetSellState(sellDialog);
			if (Time.time - clickTime < 0.3f)
			{
				Open();
				clickTime = 0f;
			}
			else
			{
				clickTime = Time.time;
			}
		}

		public static bool IsOpen()
		{
			return (Object)(object)amountDialog != (Object)null && amountDialog.activeInHierarchy;
		}

		public static void Update()
		{
			if ((Object)(object)amountDialog == (Object)null)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || ((Character)localPlayer).InCutscene() || ((Character)localPlayer).IsTeleporting())
			{
				Close();
			}
			else
			{
				if ((Object)(object)sliderDialog == (Object)null || !((Component)sliderDialog).gameObject.activeInHierarchy)
				{
					return;
				}
				sliderTitle.SetText(sliderTitleText);
				sliderButtonOk.SetText(sliderButtonText);
				for (int i = 0; i < 10; i++)
				{
					if (ZInput.GetKeyDown((KeyCode)(256 + i), true) || ZInput.GetKeyDown((KeyCode)(48 + i), true))
					{
						if (m_lastSplitInput + TimeSpan.FromSeconds(0.5) < DateTime.Now)
						{
							m_splitInput = "";
						}
						m_lastSplitInput = DateTime.Now;
						m_splitInput += i;
						if (int.TryParse(m_splitInput, out var result))
						{
							sliderDialog.value = Mathf.Clamp((float)result, 1f, sliderDialog.maxValue);
							OnSplitSliderChanged();
						}
					}
				}
				if (ZInput.GetKeyDown((KeyCode)276, true) && sliderDialog.value > 1f)
				{
					Slider obj = sliderDialog;
					obj.value -= 1f;
					OnSplitSliderChanged();
				}
				if (ZInput.GetKeyDown((KeyCode)275, true) && sliderDialog.value < sliderDialog.maxValue)
				{
					Slider obj2 = sliderDialog;
					obj2.value += 1f;
					OnSplitSliderChanged();
				}
				if (ZInput.GetButtonDown("JoyLTrigger") && sliderDialog.value > 10f)
				{
					Slider obj3 = sliderDialog;
					obj3.value -= 10f;
					OnSplitSliderChanged();
				}
				if (ZInput.GetButtonDown("JoyRTrigger") && sliderDialog.value < sliderDialog.maxValue)
				{
					Slider obj4 = sliderDialog;
					obj4.value += 10f;
					OnSplitSliderChanged();
				}
				if (ZInput.GetButtonDown("JoyLBumper") && sliderDialog.value > 5f)
				{
					Slider obj5 = sliderDialog;
					obj5.value -= 5f;
					OnSplitSliderChanged();
				}
				if (ZInput.GetButtonDown("JoyRBumper") && sliderDialog.value < sliderDialog.maxValue)
				{
					Slider obj6 = sliderDialog;
					obj6.value += 5f;
					OnSplitSliderChanged();
				}
				if (ZInput.GetKeyDown((KeyCode)271, true) || ZInput.GetKeyDown((KeyCode)13, true))
				{
					BuySelectedItem();
				}
				if (((Object)(object)Chat.instance == (Object)null || !Chat.instance.HasFocus()) && !Console.IsVisible() && !Menu.IsVisible() && Object.op_Implicit((Object)(object)TextViewer.instance) && !TextViewer.instance.IsVisible() && !((Character)localPlayer).InCutscene() && (ZInput.GetButtonDown("JoyButtonB") || ZInput.GetKeyDown((KeyCode)27, true)))
				{
					ZInput.ResetButtonStatus("JoyButtonB");
					Close();
				}
			}
		}

		public static void Close()
		{
			GameObject obj = amountDialog;
			if (obj != null)
			{
				obj.SetActive(false);
			}
		}

		public static void Open()
		{
			if ((Object)(object)amountDialog == (Object)null)
			{
				return;
			}
			TradersExtended.LogInfo(isSellDialog);
			if (isSellDialog)
			{
				StorePanel.ItemToSell selectedItem = StorePanel.selectedItem;
				if (selectedItem == null || selectedItem.itemType != StorePanel.ItemToSell.ItemType.Combined || selectedItem.pricePerItem == 0 || !((Humanoid)Player.m_localPlayer).GetInventory().HaveItem(selectedItem.item.m_shared.m_name, true))
				{
					return;
				}
				int num = Math.Min(selectedItem.amount, selectedItem.item.m_shared.m_maxStackSize);
				if (TraderConfigManager.Get(storeGui.m_trader).TradersUseCoins)
				{
					num = GetMaximumAffordableSellAmount(TraderCoins.GetTraderCoins(), num);
					if (num < 1)
					{
						return;
					}
				}
				SetDialogAndOpen(selectedItem.item, num, selectedItem.currency ?? storeGui.m_coinPrefab);
			}
			else
			{
				if (!((Humanoid)Player.m_localPlayer).GetInventory().HaveEmptySlot())
				{
					return;
				}
				TradeItem selectedItem2 = storeGui.m_selectedItem;
				if (selectedItem2 != null && !StorePanel.ItemToSell.IsBuyBackItem(selectedItem2) && !((Object)(object)selectedItem2.m_prefab == (Object)null) && selectedItem2.m_price > 0)
				{
					int playerCurrencyAmount = TraderCurrency.GetPlayerCurrencyAmount(selectedItem2, storeGui);
					if (TradersExtended.TradeableItem.GetStackFromStack(selectedItem2.m_stack) == 1 && selectedItem2.m_prefab.m_itemData.m_shared.m_maxStackSize != 1 && playerCurrencyAmount >= selectedItem2.m_price)
					{
						SetDialogAndOpen(selectedItem2.m_prefab.m_itemData, playerCurrencyAmount / selectedItem2.m_price, TraderCurrency.GetCurrency(selectedItem2, storeGui));
					}
				}
			}
		}

		private static void SetDialogAndOpen(ItemData item, int maxValue, ItemDrop currency)
		{
			sliderTitleText = Localization.instance.Localize(item.m_shared.m_name);
			sliderButtonText = Localization.instance.Localize(isSellDialog ? "$store_sell" : "$store_buy");
			sliderDialog.value = 1f;
			sliderDialog.minValue = 1f;
			sliderDialog.maxValue = Math.Min(item.m_shared.m_maxStackSize, maxValue);
			sliderImage.sprite = item.GetIcon();
			UpdateCurrencyIcon(currency);
			OnSplitSliderChanged();
			amountDialog.SetActive(true);
		}

		public static void OnSplitSliderChanged(float value = 0f)
		{
			sliderAmountText.SetText(((int)sliderDialog.value).ToString());
			sliderAmountCoinsText.SetText(GetPrice().ToString());
		}

		private static void BuySelectedItem()
		{
			if (isSellDialog)
			{
				if (TraderCanAffordSelectedItem())
				{
					int amount = Mathf.CeilToInt(sliderDialog.value);
					int price = GetPrice();
					StorePanel.selectedItem.amount = amount;
					StorePanel.selectedItem.price = price;
					StorePanel.SellSelectedItem(storeGui);
				}
			}
			else if (CanAffordSelectedItem())
			{
				TradeItem selectedItem = storeGui.m_selectedItem;
				int stack = selectedItem.m_stack;
				int price2 = selectedItem.m_price;
				try
				{
					TradersExtended.TradeableItem.GetStackQualityFromStack(stack, out var _, out var quality);
					int num = Mathf.Min(Mathf.CeilToInt(sliderDialog.value), selectedItem.m_prefab.m_itemData.m_shared.m_maxStackSize);
					selectedItem.m_stack = TradersExtended.TradeableItem.GetStackFromStackQuality(num, quality);
					long num2 = (long)price2 * (long)num;
					selectedItem.m_price = (int)((num2 >= int.MaxValue) ? int.MaxValue : num2);
					storeGui.BuySelectedItem();
				}
				finally
				{
					selectedItem.m_stack = stack;
					selectedItem.m_price = price2;
				}
			}
			Close();
		}

		private static bool TraderCanAffordSelectedItem()
		{
			if (StorePanel.selectedItem == null)
			{
				return false;
			}
			return TraderCoins.CanSell(GetPrice());
		}

		private static bool CanAffordSelectedItem()
		{
			if (storeGui.m_selectedItem == null)
			{
				return false;
			}
			int playerCurrencyAmount = TraderCurrency.GetPlayerCurrencyAmount(storeGui.m_selectedItem, storeGui);
			return GetPrice() <= playerCurrencyAmount && ((Humanoid)Player.m_localPlayer).GetInventory().HaveEmptySlot();
		}

		private static int GetPricePerItem()
		{
			return isSellDialog ? StorePanel.selectedItem.pricePerItem : storeGui.m_selectedItem.m_price;
		}

		internal static int GetPrice()
		{
			return GetPriceForAmount(Mathf.CeilToInt(sliderDialog.value));
		}

		private static int GetPriceForAmount(int amount)
		{
			if (amount <= 0)
			{
				return 0;
			}
			if (isSellDialog)
			{
				return StorePanel.CalculateSellPrice(GetPricePerItem(), amount);
			}
			double num = (double)amount * (double)GetPricePerItem();
			if (double.IsNaN(num) || num >= 2147483647.0)
			{
				return int.MaxValue;
			}
			return Math.Max((int)Math.Ceiling(num), 1);
		}

		private static int GetMaximumAffordableSellAmount(int balance, int maximumAmount)
		{
			int num = 0;
			int num2 = Math.Max(maximumAmount, 0);
			while (num < num2)
			{
				int num3 = num + (num2 - num + 1) / 2;
				if (GetPriceForAmount(num3) <= balance)
				{
					num = num3;
				}
				else
				{
					num2 = num3 - 1;
				}
			}
			return num;
		}
	}
	internal static class BuybackManager
	{
		[Serializable]
		private sealed class BuybackSaveData
		{
			public Dictionary<string, Dictionary<string, BuybackRecord>> worlds = new Dictionary<string, Dictionary<string, BuybackRecord>>(StringComparer.OrdinalIgnoreCase);
		}

		[Serializable]
		private sealed class BuybackRecord
		{
			public double createdAt;

			public string itemData;

			public StorePanel.ItemToSell.ItemType itemType;

			public int stack;

			public int price;

			public int amount;

			public int quality;

			public string currency;
		}

		private const string CustomDataKey = "shudnal.TradersExtended.Buyback";

		private static BuybackSaveData cachedData;

		private static Player cachedPlayer;

		private static string cachedRawData;

		internal static StorePanel.ItemToSell Get(Trader trader)
		{
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Expected O, but got Unknown
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Expected O, but got Unknown
			if ((Object)(object)trader == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)ZNet.instance == (Object)null)
			{
				return null;
			}
			string text = TradersExtended.TraderName(trader);
			ResolvedTraderConfig resolvedTraderConfig = TraderConfigManager.Get(trader);
			if (!resolvedTraderConfig.EnableBuybackForLastItemSold)
			{
				return null;
			}
			Dictionary<string, BuybackRecord> worldRecords = GetWorldRecords(create: false);
			if (worldRecords == null || !worldRecords.TryGetValue(text, out var value))
			{
				return null;
			}
			int num = Math.Max(resolvedTraderConfig.BuybackLifetimeInWorldSeconds, 0);
			if (num > 0 && GetWorldTime() - value.createdAt >= (double)num)
			{
				worldRecords.Remove(text);
				Save();
				return null;
			}
			try
			{
				Inventory val = new Inventory("Traders Extended buyback", (Sprite)null, 1, 1);
				val.Load(new ZPackage(value.itemData));
				ItemData val2 = val.GetAllItems().FirstOrDefault();
				if (val2 == null)
				{
					worldRecords.Remove(text);
					Save();
					return null;
				}
				return new StorePanel.ItemToSell
				{
					itemType = value.itemType,
					item = val2,
					stack = value.stack,
					price = value.price,
					amount = value.amount,
					quality = value.quality,
					currency = TraderCurrency.GetCurrency(value.currency, StoreGui.instance)
				};
			}
			catch (Exception ex)
			{
				TradersExtended.LogWarning("Could not restore buyback for trader '" + text + "': " + ex.Message);
				worldRecords.Remove(text);
				Save();
				return null;
			}
		}

		internal static void Set(Trader trader, StorePanel.ItemToSell item)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			if ((Object)(object)trader == (Object)null || item?.item == null || (Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)ZNet.instance == (Object)null)
			{
				return;
			}
			try
			{
				ItemData val = item.item.Clone();
				val.m_equipped = false;
				val.m_gridPos = new Vector2i(0, 0);
				Inventory val2 = new Inventory("Traders Extended buyback", (Sprite)null, 1, 1);
				val2.m_inventory.Add(val);
				ZPackage val3 = new ZPackage();
				val2.Save(val3);
				Dictionary<string, BuybackRecord> worldRecords = GetWorldRecords(create: true);
				if (worldRecords != null)
				{
					worldRecords[TradersExtended.TraderName(trader)] = new BuybackRecord
					{
						createdAt = GetWorldTime(),
						itemData = val3.GetBase64(),
						itemType = item.itemType,
						stack = item.stack,
						price = item.price,
						amount = item.amount,
						quality = item.quality,
						currency = (((Object)(object)item.currency != (Object)null) ? Utils.GetPrefabName(((Component)item.currency).gameObject) : string.Empty)
					};
					Save();
				}
			}
			catch (Exception ex)
			{
				TradersExtended.LogWarning("Could not save buyback for trader '" + TradersExtended.TraderName(trader) + "': " + ex.Message);
			}
		}

		internal static void Remove(Trader trader)
		{
			Dictionary<string, BuybackRecord> worldRecords = GetWorldRecords(create: false);
			if (worldRecords != null && !((Object)(object)trader == (Object)null) && worldRecords.Remove(TradersExtended.TraderName(trader)))
			{
				Save();
			}
		}

		internal static void ResetCache()
		{
			cachedData = null;
			cachedPlayer = null;
			cachedRawData = null;
		}

		private static Dictionary<string, BuybackRecord> GetWorldRecords(bool create)
		{
			BuybackSaveData buybackSaveData = Load();
			if (buybackSaveData == null || (Object)(object)ZNet.instance == (Object)null)
			{
				return null;
			}
			string key = ZNet.instance.GetWorldUID().ToString(CultureInfo.InvariantCulture);
			if (!buybackSaveData.worlds.TryGetValue(key, out var value) && create)
			{
				value = new Dictionary<string, BuybackRecord>(StringComparer.OrdinalIgnoreCase);
				buybackSaveData.worlds[key] = value;
			}
			return value;
		}

		private static BuybackSaveData Load()
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return null;
			}
			localPlayer.m_customData.TryGetValue("shudnal.TradersExtended.Buyback", out var value);
			if ((Object)(object)cachedPlayer == (Object)(object)localPlayer && string.Equals(cachedRawData, value, StringComparison.Ordinal) && cachedData != null)
			{
				return cachedData;
			}
			cachedPlayer = localPlayer;
			cachedRawData = value;
			try
			{
				cachedData = (string.IsNullOrWhiteSpace(value) ? new BuybackSaveData() : (JsonConvert.DeserializeObject<BuybackSaveData>(value) ?? new BuybackSaveData()));
			}
			catch (Exception ex)
			{
				TradersExtended.LogWarning("Could not read saved buyback data: " + ex.Message);
				cachedData = new BuybackSaveData();
			}
			BuybackSaveData buybackSaveData = cachedData;
			if (buybackSaveData.worlds == null)
			{
				buybackSaveData.worlds = new Dictionary<string, Dictionary<string, BuybackRecord>>(StringComparer.OrdinalIgnoreCase);
			}
			return cachedData;
		}

		private static void Save()
		{
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null) && cachedData != null)
			{
				cachedRawData = JsonConvert.SerializeObject((object)cachedData, (Formatting)0);
				localPlayer.m_customData["shudnal.TradersExtended.Buyback"] = cachedRawData;
				cachedPlayer = localPlayer;
			}
		}

		private static double GetWorldTime()
		{
			return ((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetTimeSeconds() : 0.0;
		}
	}
	internal static class CoinsPatches
	{
		[HarmonyPatch(typeof(ObjectDB), "Awake")]
		public static class ObjectDB_Awake_CoinsPatch
		{
			[HarmonyPriority(0)]
			private static void Postfix()
			{
				UpdateCoinsPrefab();
			}
		}

		[HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")]
		public static class ObjectDB_CopyOtherDB_CoinsPatch
		{
			[HarmonyPriority(0)]
			private static void Postfix()
			{
				UpdateCoinsPrefab();
			}
		}

		[HarmonyPatch(typeof(Player), "AddKnownItem")]
		public static class Player_AddKnownItem_CoinsPatch
		{
			private static void Postfix(ref ItemData item)
			{
				if (item != null && !(item.m_shared.m_name != "$item_coins"))
				{
					PatchCoinsItemData(item);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "OnSpawned")]
		public class Player_OnSpawned_CoinsPatch
		{
			public static void Postfix(Player __instance)
			{
				if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
				{
					PatchCoinsInInventory(((Humanoid)__instance).GetInventory());
				}
			}
		}

		[HarmonyPatch(typeof(Inventory), "Load")]
		public class Inventory_Load_CoinsPatch
		{
			public static void Postfix(Inventory __instance)
			{
				PatchCoinsInInventory(__instance);
			}
		}

		[HarmonyPatch(typeof(Inventory), "AddItem", new Type[]
		{
			typeof(ItemData),
			typeof(int),
			typeof(int),
			typeof(int)
		})]
		private static class Inventory_AddItem_ItemData_amount_x_y_PatchCircletItemDataOnLoad
		{
			[HarmonyPriority(800)]
			private static void Prefix(ItemData item)
			{
				if (item != null && !(item.m_shared.m_name != "$item_coins"))
				{
					PatchCoinsItemData(item);
				}
			}
		}

		[HarmonyPatch(typeof(ItemDrop), "Start")]
		public static class ItemDrop_Start_CoinsPatch
		{
			private static void Postfix(ItemDrop __instance)
			{
				if (!(__instance.GetPrefabName(((Object)__instance).name) != "Coins"))
				{
					PatchCoinsItemData(__instance.m_itemData);
				}
			}
		}

		public const string itemNameCoins = "Coins";

		public const string itemDropNameCoins = "$item_coins";

		private static readonly List<ItemData> _itemDataList = new List<ItemData>();

		public static void PatchCoinsItemData(ItemData coins)
		{
			if (coins != null && TradersExtended.coinsPatch.Value)
			{
				coins.m_shared.m_weight = TradersExtended.coinsWeight.Value;
				coins.m_shared.m_maxStackSize = Math.Max(TradersExtended.coinsStackSize.Value, 1);
			}
		}

		public static void PatchCoinsInInventory(Inventory inventory)
		{
			if (inventory == null)
			{
				return;
			}
			_itemDataList.Clear();
			inventory.GetAllItems("$item_coins", _itemDataList);
			foreach (ItemData itemData in _itemDataList)
			{
				PatchCoinsItemData(itemData);
			}
		}

		public static void UpdateCoinsPrefab()
		{
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("Coins");
			if ((Object)(object)itemPrefab != (Object)null)
			{
				PatchCoinsItemData(itemPrefab.GetComponent<ItemDrop>()?.m_itemData);
			}
			Player localPlayer = Player.m_localPlayer;
			PatchCoinsInInventory((localPlayer != null) ? ((Humanoid)localPlayer).GetInventory() : null);
		}
	}
	internal sealed class ConfigEditor : IDisposable
	{
		private enum ItemSortColumn
		{
			Prefab,
			LocalizedName,
			Stack,
			Price,
			Quality,
			Currency,
			RequiredGlobalKey,
			BlockedGlobalKey,
			RequiredPlayerKey,
			BlockedPlayerKey
		}

		private enum ItemPickerSortColumn
		{
			Prefab,
			LocalizedName
		}

		private enum ItemRowAction
		{
			None,
			Delete,
			MoveUp,
			MoveDown
		}

		private enum KeyPickerKind
		{
			Global,
			Player
		}

		private sealed class ItemRowValidation
		{
			internal string Prefab = string.Empty;

			internal string Stack = string.Empty;

			internal string Price = string.Empty;

			internal string Quality = string.Empty;

			internal string Currency = string.Empty;

			internal string RequiredGlobalKey = string.Empty;

			internal string BlockedGlobalKey = string.Empty;

			internal string RequiredPlayerKey = string.Empty;

			internal string BlockedPlayerKey = string.Empty;

			internal bool HasErrors => !string.IsNullOrEmpty(Combined);

			internal string Combined => string.Join(" ", new string[9] { Prefab, Stack, Price, Quality, Currency, RequiredGlobalKey, BlockedGlobalKey, RequiredPlayerKey, BlockedPlayerKey }.Where((string value) => !string.IsNullOrWhiteSpace(value)).Distinct<string>(StringComparer.Ordinal));
		}

		private sealed class ItemSortValueComparer : IComparer<object>
		{
			internal static readonly ItemSortValueComparer Instance = new ItemSortValueComparer();

			public int Compare(object left, object right)
			{
				if (left == right)
				{
					return 0;
				}
				if (left == null)
				{
					return -1;
				}
				if (right == null)
				{
					return 1;
				}
				if (left is int num && right is int value)
				{
					return num.CompareTo(value);
				}
				return string.Compare(Convert.ToString(left, CultureInfo.CurrentCulture), Convert.ToString(right, CultureInfo.CurrentCulture), StringComparison.CurrentCultureIgnoreCase);
			}
		}

		private sealed class ItemOption
		{
			internal string Prefab { get; }

			internal string LocalizedName { get; }

			internal Sprite Icon { get; }

			internal bool VisibleByDefault { get; }

			internal ItemOption(string prefab, string localizedName, Sprite icon, bool visibleByDefault)
			{
				Prefab = prefab;
				LocalizedName = localizedName;
				Icon = icon;
				VisibleByDefault = visibleByDefault;
			}
		}

		private sealed class TraderOption
		{
			internal string Prefab { get; }

			internal string DisplayName { get; }

			internal TraderOption(string prefab, string displayName)
			{
				Prefab = prefab;
				DisplayName = displayName;
			}
		}

		private const int WindowId = 924617;

		private const int NewFileWindowId = 924618;

		private const int ItemPickerWindowId = 924619;

		private const int GlobalKeyWindowId = 924620;

		private const int ConfirmWindowId = 924621;

		private const float DefaultLeftPanelWidth = 382f;

		private const float MinimumLeftPanelWidth = 240f;

		private const float MaximumLeftPanelWidth = 800f;

		private const float ColumnSplitterWidth = 7f;

		private const float MinimumWidth = 1000f;

		private const float MinimumHeight = 600f;

		private const float TitleBarHeight = 22f;

		private const float ResizeEdgeHitSize = 4f;

		private const float ResizeHandleHitSize = 12f;

		private const float ResizeHandleVisualSize = 8f;

		private const float WindowBorderWidth = 1f;

		private const float LayoutSaveDelay = 0.5f;

		private const float CompactControlHeight = 20f;

		private const float CompactRowHeight = 22f;

		private const float ItemPickerControlHeight = 18f;

		private const float ItemPickerRowHeight = 20f;

		private const float ItemIconSize = 17f;

		private const float InlinePickerButtonWidth = 20f;

		private const float InlinePickerButtonHeight = 14f;

		private const float QuickDeleteButtonWidth = 18f;

		private const float ItemColumnSpacing = 3f;

		private const int ItemRowsPerPage = 100;

		private const float RequestTimeoutSeconds = 15f;

		private static readonly ItemSortColumn[] ItemColumnOrder = new ItemSortColumn[10]
		{
			ItemSortColumn.Prefab,
			ItemSortColumn.LocalizedName,
			ItemSortColumn.Stack,
			ItemSortColumn.Price,
			ItemSortColumn.Quality,
			ItemSortColumn.Currency,
			ItemSortColumn.RequiredGlobalKey,
			ItemSortColumn.BlockedGlobalKey,
			ItemSortColumn.RequiredPlayerKey,
			ItemSortColumn.BlockedPlayerKey
		};

		private readonly ConfigEditorCursor cursor = new ConfigEditorCursor();

		private readonly ConfigEditorGuiScale scale = new ConfigEditorGuiScale();

		private readonly ConfigEditorTheme theme = new ConfigEditorTheme();

		private readonly Dictionary<string, string> traderDisplayNames = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

		private readonly List<ItemOption> itemOptions = new List<ItemOption>();

		private readonly Dictionary<string, ItemOption> itemOptionsByPrefab = new Dictionary<string, ItemOption>(StringComparer.OrdinalIgnoreCase);

		private bool isOpen;

		private bool layoutLoaded;

		private bool resizing;

		private Vector2 resizeStartMouse;

		private Rect resizeStartRect;

		private bool resizeWidth;

		private bool resizeHeight;

		private bool layoutDirty;

		private bool splitterDragging;

		private Vector2 splitterDragStartMouse;

		private float splitterDragStartWidth;

		private float saveLayoutAfterRealtime;

		private Rect windowRect;

		private List<EditorFileInfo> files = new List<EditorFileInfo>();

		private EditorFileInfo activeFile;

		private ItemConfigDocument itemDocument;

		private TraderConfigDocument traderDocument;

		private string selectAfterList;

		private string fileSearch = string.Empty;

		private string itemSearch = string.Empty;

		private string statusText = string.Empty;

		private bool statusError;

		private bool requestInProgress;

		private float requestStartedAt;

		private Vector2 fileScroll;

		private Vector2 itemScroll;

		private int itemPage;

		private Vector2 settingsScroll;

		private bool showNewFile;

		private Rect newFileRect = new Rect(0f, 0f, 620f, 520f);

		private Vector2 newFileScroll;

		private EditorConfigKind newFileKind = EditorConfigKind.ItemList;

		private string newFileTrader = "common";

		private TradersExtended.ItemsListType newFileListType = TradersExtended.ItemsListType.Buy;

		private string newFileIdentifier = string.Empty;

		private string newFileExtension = "json";

		private bool showItemPicker;

		private Rect itemPickerRect = new Rect(0f, 0f, 572f, 650f);

		private string itemPickerSearch = string.Empty;

		private string itemPickerTitle = "Select item";

		private Vector2 itemPickerScroll;

		private int itemPickerPage;

		private ItemPickerSortColumn itemPickerSortColumn = ItemPickerSortColumn.Prefab;

		private bool itemPickerSortAscending = true;

		private Action<string> itemPickerCallback;

		private bool itemPickerMultiAdd;

		private bool showGlobalKeyPicker;

		private KeyPickerKind keyPickerKind = KeyPickerKind.Global;

		private string newPickerKey = string.Empty;

		private Rect globalKeyRect = new Rect(0f, 0f, 330f, 620f);

		private string globalKeySearch = string.Empty;

		private Vector2 globalKeyScroll;

		private HashSet<string> globalKeySelection = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		private Action<string> globalKeyCallback;

		private bool showConfirm;

		private Rect confirmRect = new Rect(0f, 0f, 360f, 112f);

		private string confirmMessage = string.Empty;

		private Action confirmAction;

		private GUISkin styleSourceSkin;

		private GUIStyle windowStyle;

		private GUIStyle panelStyle;

		private GUIStyle selectedFileStyle;

		private GUIStyle fileStyle;

		private GUIStyle headerStyle;

		private GUIStyle toolbarStyle;

		private GUIStyle rowStyle;

		private GUIStyle itemRowStyle;

		private GUIStyle mutedStyle;

		private GUIStyle rightMutedStyle;

		private GUIStyle errorStyle;

		private GUIStyle titleStyle;

		private GUIStyle smallButtonStyle;

		private GUIStyle centeredMutedStyle;

		private GUIStyle centeredMessageStyle;

		private GUIStyle singleLineMutedStyle;

		private GUIStyle itemPrefabTextFieldStyle;

		private GUIStyle invalidItemIconStyle;

		private GUIStyle fileNameStyle;

		private GUIStyle pickerPrefabStyle;

		private GUIStyle pickerNameStyle;

		private GUIStyle keyNameStyle;

		private GUIStyle keySelectedNameStyle;

		private GUIStyle selectedValueLabelStyle;

		private GUIStyle selectedValueStyle;

		private GUIStyle serverSourceStyle;

		private GUIStyle inlineButtonStyle;

		private GUIStyle splitterStyle;

		private bool stylesInitialized;

		private bool itemOptionsBuilt;

		private float itemPrefabColumnWidth = 150f;

		private bool itemPrefabColumnWidthDirty = true;

		private string lastGuiExceptionSignature = string.Empty;

		private bool focusPopupWindow;

		private readonly HashSet<ItemSortColumn> visibleItemColumns = new HashSet<ItemSortColumn>();

		private string visibleItemColumnsSource = string.Empty;

		private List<TraderOption> temporaryTraderOptions;

		internal static bool IsOpenGlobal => TradersExtended.configEditor != null && TradersExtended.configEditor.IsOpen;

		internal bool IsOpen => isOpen;

		internal static bool IsDrawing { get; private set; }

		internal ConfigEditor()
		{
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			ConfigEditorTransport.ResponseReceived += OnTransportResponse;
		}

		internal void MarkGameWindowReady()
		{
			scale.MarkGameWindowReady();
		}

		internal void Toggle()
		{
			SetOpen(!isOpen);
		}

		internal void Update()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (TradersExtended.configEditorShortcut != null)
			{
				KeyboardShortcut value = TradersExtended.configEditorShortcut.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					Toggle();
					return;
				}
			}
			if (isOpen && !AnyPopupOpen() && IsControlPressed() && UnityInput.Current.GetKeyDown((KeyCode)115))
			{
				if (activeFile != null && activeFile.Kind != EditorConfigKind.Unsupported && IsDirty() && !requestInProgress)
				{
					SaveActiveFile();
				}
				return;
			}
			if (isOpen && UnityInput.Current.GetKeyDown((KeyCode)27))
			{
				if (showConfirm)
				{
					showConfirm = false;
				}
				else if (showItemPicker)
				{
					CloseItemPicker();
				}
				else if (showGlobalKeyPicker)
				{
					showGlobalKeyPicker = false;
				}
				else if (showNewFile)
				{
					showNewFile = false;
				}
				else
				{
					RequestClose();
				}
			}
			if (requestInProgress && Time.realtimeSinceStartup - requestStartedAt > 15f)
			{
				requestInProgress = false;
				selectAfterList = null;
				SetStatus("The configuration request timed out. Check the server connection and mod version.", error: true);
			}
			if (resizing && !UnityInput.Current.GetKey((KeyCode)323))
			{
				ClearResizeState();
				MarkLayoutDirty();
			}
			if (splitterDragging && !UnityInput.Current.GetKey((KeyCode)323))
			{
				splitterDragging = false;
			}
			if (layoutDirty && Time.realtimeSinceStartup >= saveLayoutAfterRealtime)
			{
				SaveLayout();
			}
			cursor.Update(isOpen);
		}

		private bool AnyPopupOpen()
		{
			return showConfirm || showItemPicker || showGlobalKeyPicker || showNewFile;
		}

		private static bool IsControlPressed()
		{
			return UnityInput.Current.GetKey((KeyCode)306) || UnityInput.Current.GetKey((KeyCode)305);
		}

		internal void LateUpdate()
		{
			cursor.Update(isOpen);
		}

		internal void OnGUI()
		{
			//IL_0312: Unknown result type (might be due to invalid IL or missing references)
			//IL_0320: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Expected O, but got Unknown
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: 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)
			//IL_015b: Expected O, but got Unknown
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Expected O, but got Unknown
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Expected O, but got Unknown
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Expected O, but got Unknown
			//IL_0218: 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)
			if (!isOpen)
			{
				return;
			}
			Matrix4x4 matrix = GUI.matrix;
			GUISkin skin = GUI.skin;
			Color contentColor = GUI.contentColor;
			IsDrawing = true;
			try
			{
				GUI.matrix = scale.Matrix;
				GUI.skin = theme.Skin;
				GUI.contentColor = theme.TextColor;
				EnsureStyles();
				cursor.Update(active: true);
				ClampWindowToScreen();
				bool flag = showConfirm || showItemPicker || showGlobalKeyPicker || showNewFile;
				bool enabled = GUI.enabled;
				GUI.enabled = !flag;
				Rect left = windowRect;
				windowRect = GUI.Window(924617, windowRect, new WindowFunction(DrawWindow), "Traders Extended configuration editor", windowStyle);
				GUI.enabled = enabled;
				windowRect = ClampRect(windowRect);
				if (RectChanged(left, windowRect))
				{
					MarkLayoutDirty();
				}
				if (showConfirm)
				{
					CenterModal(ref confirmRect);
					confirmRect = GUI.Window(924621, confirmRect, new WindowFunction(DrawConfirmWindow), "Confirm", windowStyle);
					KeepPopupInFront(924621);
				}
				else if (showItemPicker)
				{
					CenterModal(ref itemPickerRect);
					itemPickerRect = GUI.Window(924619, itemPickerRect, new WindowFunction(DrawItemPickerWindow), itemPickerTitle, windowStyle);
					KeepPopupInFront(924619);
				}
				else if (showGlobalKeyPicker)
				{
					CenterModal(ref globalKeyRect);
					globalKeyRect = GUI.Window(924620, globalKeyRect, new WindowFunction(DrawGlobalKeyWindow), (keyPickerKind == KeyPickerKind.Global) ? "Select global keys" : "Select player keys", windowStyle);
					KeepPopupInFront(924620);
				}
				else if (showNewFile)
				{
					CenterModal(ref newFileRect);
					newFileRect = GUI.Window(924618, newFileRect, new WindowFunction(DrawNewFileWindow), "Create configuration", windowStyle);
					KeepPopupInFront(924618);
				}
				lastGuiExceptionSignature = string.Empty;
			}
			catch (Exception ex)
			{
				string a = ex.GetType().FullName + ": " + ex.Message;
				if (!string.Equals(a, lastGuiExceptionSignature, StringComparison.Ordinal))
				{
					lastGuiExceptionSignature = a;
					ManualLogSource logger = TradersExtended.logger;
					if (logger != null)
					{
						logger.LogError((object)$"Configuration editor GUI error: {ex}");
					}
				}
				SetStatus("Editor GUI error: " + ex.Message, error: true);
			}
			finally
			{
				GUI.contentColor = contentColor;
				GUI.skin = skin;
				GUI.matrix = matrix;
				IsDrawing = false;
			}
		}

		public void Dispose()
		{
			ConfigEditorTransport.ResponseReceived -= OnTransportResponse;
			cursor.Release();
			theme.Shutdown();
		}

		private void SetOpen(bool value)
		{
			if (isOpen == value)
			{
				return;
			}
			if (!value && IsDirty())
			{
				ShowConfirmation("Discard unsaved changes and close the editor?", delegate
				{
					SetOpenImmediate(value: false);
				});
			}
			else
			{
				SetOpenImmediate(value);
			}
		}

		private void SetOpenImmediate(bool value)
		{
			isOpen = value;
			if (value)
			{
				LoadLayout();
				traderDisplayNames.Clear();
				RefreshFiles();
				BuildItemOptions();
				return;
			}
			SaveLayout();
			showNewFile = false;
			showItemPicker = false;
			showGlobalKeyPicker = false;
			showConfirm = false;
			resizing = false;
			splitterDragging = false;
			itemOptions.Clear();
			itemOptionsByPrefab.Clear();
			itemOptionsBuilt = false;
			itemPrefabColumnWidthDirty = true;
			cursor.Release();
		}

		private void RequestClose()
		{
			SetOpen(value: false);
		}

		private void DrawWindow(int windowId)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			Event current = Event.current;
			Vector2 mousePosition = current.mousePosition;
			bool flag = TryApplyRealtimeMousePosition(current);
			try
			{
				HandleResizeInput();
				GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) });
				DrawFileColumn();
				DrawColumnSplitter();
				DrawEditorColumn();
				GUILayout.EndHorizontal();
				if (requestInProgress || !string.IsNullOrWhiteSpace(statusText))
				{
					GUILayout.BeginHorizontal(toolbarStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(26f) });
					GUILayout.Label(statusText ?? string.Empty, statusError ? errorStyle : mutedStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
					if (requestInProgress)
					{
						GUILayout.Label("Working...", mutedStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) });
					}
					GUILayout.EndHorizontal();
				}
				DrawWindowBorder();
				DrawResizeHandle();
				GUI.DragWindow(new Rect(0f, 0f, Mathf.Max(0f, ((Rect)(ref windowRect)).width - 4f), 22f));
			}
			finally
			{
				if (flag)
				{
					current.mousePosition = mousePosition;
				}
			}
		}

		private bool TryApplyRealtimeMousePosition(Event current)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Invalid comparison between Unknown and I4
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Invalid comparison between Unknown and I4
			//IL_002d: 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)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			if (current == null || ((int)current.type != 7 && (int)current.type != 8))
			{
				return false;
			}
			Vector2 val = scale.GetLogicalMousePosition() - ((Rect)(ref windowRect)).position;
			if (!IsFinite(val.x) || !IsFinite(val.y))
			{
				return false;
			}
			current.mousePosition = val;
			return true;
		}

		private static bool IsFinite(float value)
		{
			return !float.IsNaN(value) && !float.IsInfinity(value);
		}

		private static float GetHeaderToggleWidth(string text)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			return Mathf.Ceil(GUI.skin.label.CalcSize(new GUIContent(text)).x + 22f);
		}

		private void DrawFileColumn()
		{
			GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(GetLeftPanelWidth()),
				GUILayout.ExpandHeight(true)
			});
			DrawFilePanel();
			GUILayout.EndVertical();
		}

		private void DrawEditorColumn()
		{
			GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.ExpandWidth(true),
				GUILayout.ExpandHeight(true)
			});
			DrawEditorPanel();
			GUILayout.EndVertical();
		}

		private float GetLeftPanelWidth()
		{
			float num = TradersExtended.configEditorFileListWidth?.Value ?? 382f;
			float num2 = Mathf.Min(800f, Mathf.Max(240f, ((Rect)(ref windowRect)).width * 0.65f));
			return Mathf.Clamp(num, 240f, num2);
		}

		private void DrawColumnSplitter()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Invalid comparison between Unknown and I4
			//IL_00e1: 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_0138: Invalid comparison between Unknown and I4
			Rect rect = GUILayoutUtility.GetRect(7f, 1f, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(7f),
				GUILayout.ExpandHeight(true)
			});
			GUI.Box(rect, GUIContent.none, splitterStyle);
			Event current = Event.current;
			if ((int)current.type == 0 && current.button == 0 && ((Rect)(ref rect)).Contains(current.mousePosition))
			{
				splitterDragging = true;
				splitterDragStartMouse = current.mousePosition;
				splitterDragStartWidth = GetLeftPanelWidth();
				current.Use();
			}
			if (splitterDragging && (int)current.type == 3 && current.button == 0)
			{
				float num = Mathf.Min(800f, Mathf.Max(240f, ((Rect)(ref windowRect)).width * 0.65f));
				float value = Mathf.Clamp(splitterDragStartWidth + current.mousePosition.x - splitterDragStartMouse.x, 240f, num);
				if (TradersExtended.configEditorFileListWidth != null)
				{
					TradersExtended.configEditorFileListWidth.Value = value;
				}
				current.Use();
			}
			if (splitterDragging && (int)current.type == 1 && current.button == 0)
			{
				splitterDragging = false;
				current.Use();
			}
		}

		private void DrawFileActions()
		{
			GUI.enabled = !requestInProgress;
			if (GUILayout.Button("Refresh", smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(62f),
				GUILayout.Height(20f)
			}))
			{
				RefreshFiles();
			}
			if (GUILayout.Button("New", smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(42f),
				GUILayout.Height(20f)
			}))
			{
				OpenNewFileWindow();
			}
			GUI.enabled = activeFile != null && !requestInProgress;
			if (GUILayout.Button("Delete", smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(54f),
				GUILayout.Height(20f)
			}))
			{
				DeleteActiveFile();
			}
			GUI.enabled = true;
		}

		private void DrawEditorActions()
		{
			bool flag = (GUI.enabled = activeFile != null && activeFile.Kind != EditorConfigKind.Unsupported && IsDirty() && !requestInProgress);
			GUIStyle val = (flag ? theme.AccentButtonStyle : smallButtonStyle);
			if (GUILayout.Button("Save", val, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(48f),
				GUILayout.Height(20f)
			}))
			{
				SaveActiveFile();
			}
			if (GUILayout.Button("Cancel", smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(56f),
				GUILayout.Height(20f)
			}))
			{
				RevertActiveFile();
			}
			GUI.enabled = true;
		}

		private void DrawFilePanel()
		{
			//IL_0131: 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_014a: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.BeginVertical(panelStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.ExpandWidth(true),
				GUILayout.ExpandHeight(true)
			});
			GUIStyle val = (ConfigEditorTransport.UsesRemoteServer ? serverSourceStyle : singleLineMutedStyle);
			string text = (ConfigEditorTransport.UsesRemoteServer ? "SERVER CONFIGURATION DIRECTORY" : "Local configuration directory");
			GUILayout.Label(text, val, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.ExpandWidth(true),
				GUILayout.Height(20f)
			});
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Search", (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(50f),
				GUILayout.Height(20f)
			});
			fileSearch = GUILayout.TextField(fileSearch ?? string.Empty, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.ExpandWidth(true),
				GUILayout.Height(20f)
			});
			if (GUILayout.Button("×", smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(22f),
				GUILayout.Height(20f)
			}))
			{
				fileSearch = string.Empty;
			}
			GUILayout.EndHorizontal();
			GUILayout.Space(4f);
			fileScroll = GUILayout.BeginScrollView(fileScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) });
			List<EditorFileInfo> list = files.Where(FileMatchesSearch).ToList();
			DrawFileGroup("Buy items", list.Where((EditorFileInfo file) => file.Kind == EditorConfigKind.ItemList && file.ListType == TradersExtended.ItemsListType.Buy));
			DrawFileGroup("Sell items", list.Where((EditorFileInfo file) => file.Kind == EditorConfigKind.ItemList && file.ListType == TradersExtended.ItemsListType.Sell));
			DrawFileGroup("Trader Settings", list.Where((EditorFileInfo file) => file.Kind == EditorConfigKind.TraderSettings));
			DrawFileGroup("Other files", list.Where((EditorFileInfo file) => file.Kind == EditorConfigKind.Unsupported));
			if (list.Count == 0)
			{
				GUILayout.Label("No matching files.", mutedStyle, Array.Empty<GUILayoutOption>());
			}
			GUILayout.EndScrollView();
			GUILayout.Space(2f);
			GUILayout.BeginHorizontal(toolbarStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(24f) });
			DrawFileActions();
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
			GUILayout.EndVertical();
		}

		private void DrawFileGroup(string title, IEnumerable<EditorFileInfo> source)
		{
			List<EditorFileInfo> list = source.OrderBy<EditorFileInfo, string>((EditorFileInfo file) => file.Trader, StringComparer.OrdinalIgnoreCase).ThenBy<EditorFileInfo, string>((EditorFileInfo file) => GetFileListDisplayName(file), StringComparer.OrdinalIgnoreCase).ToList();
			if (list.Count == 0)
			{
				return;
			}
			GUILayout.Label(title, headerStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.ExpandWidth(true),
				GUILayout.Height(20f)
			});
			foreach (EditorFileInfo item in list)
			{
				DrawFileEntry(item);
			}
			GUILayout.Space(3f);
		}

		private void DrawFileEntry(EditorFileInfo file)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Expected O, but got Unknown
			GUIStyle val = ((activeFile != null && string.Equals(activeFile.Name, file.Name, StringComparison.OrdinalIgnoreCase)) ? selectedFileStyle : fileStyle);
			string fileListDisplayName = GetFileListDisplayName(file);
			float num = Mathf.Max(80f, GetLeftPanelWidth() - 28f);
			float num2 = Mathf.Max(titleStyle.lineHeight + 2f, fileNameStyle.CalcHeight(new GUIContent(fileListDisplayName), num));
			float num3 = Mathf.Max(30f, num2 + 10f);
			Rect rect = GUILayoutUtility.GetRect(0f, num3, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.ExpandWidth(true),
				GUILayout.Height(num3)
			});
			if (GUI.Button(rect, GUIContent.none, val))
			{
				SelectFile(file);
			}
			Rect val2 = default(Rect);
			((Rect)(ref val2))..ctor(((Rect)(ref rect)).x + 8f, ((Rect)(ref rect)).y + 5f, Mathf.Max(0f, ((Rect)(ref rect)).width - 16f), num2);
			GUI.Label(val2, new GUIContent(fileListDisplayName, file.Name), fileNameStyle);
		}

		private string GetFileListDisplayName(EditorFileInfo file)
		{
			if (file == null)
			{
				return string.Empty;
			}
			string text = (string.Equals(file.Trader, "common", StringComparison.OrdinalIgnoreCase) ? "Common" : (file.Trader ?? string.Empty));
			string text2 = Path.GetExtension(file.Name).TrimStart(new char[1] { '.' }).ToLowerInvariant();
			if (file.Kind == EditorConfigKind.ItemList && TradersExtended.TryParseConfigFileName(file.Name, out var _, out var _, out var identifier))
			{
				return string.IsNullOrWhiteSpace(identifier) ? (text + " · " + text2) : (text + " · " + identifier + " · " + text2);
			}
			if (file.Kind == EditorConfigKind.TraderSettings)
			{
				return text + " · " + text2;
			}
			return file.Name;
		}

		private void DrawEditorPanel()
		{
			GUILayout.BeginVertical(panelStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.ExpandWidth(true),
				GUILayout.ExpandHeight(true)
			});
			DrawEditorHeader();
			if (activeFile == null)
			{
				GUILayout.FlexibleSpace();
				GUILayout.Label("Select a configuration file or create a new one.", titleStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
				GUILayout.FlexibleSpace();
			}
			else if (activeFile.Kind == EditorConfigKind.Unsupported)
			{
				GUILayout.FlexibleSpace();
				GUILayout.Label("The file name does not match a supported Traders Extended configuration pattern.", errorStyle, Array.Empty<GUILayoutOption>());
				GUILayout.FlexibleSpace();
			}
			else if (itemDocument != null)
			{
				DrawItemEditor();
			}
			else if (traderDocument != null)
			{
				DrawTraderEditor();
			}
			else
			{
				GUILayout.FlexibleSpace();
				GUILayout.Label(requestInProgress ? "Loading configuration..." : "Configuration is not loaded.", mutedStyle, Array.Empty<GUILayoutOption>());
				GUILayout.FlexibleSpace();
			}
			GUILayout.EndVertical();
		}

		private void DrawEditorHeader()
		{
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Expected O, but got Unknown
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Expected O, but got Unknown
			float num = Mathf.Max(20f, titleStyle.lineHeight + 3f);
			float num2 = Mathf.Max(26f, num + 6f);
			GUILayout.BeginHorizontal(toolbarStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(num2) });
			string text = ((activeFile == null) ? "No file selected" : ((itemDocument != null) ? $"{GetTraderDisplayName(activeFile.Trader)} — {activeFile.ListType}" : ((traderDocument != null) ? (GetTraderDisplayName(traderDocument.Trader) + " (" + traderDocument.Trader + ")") : "Configuration")));
			float num3 = Mathf.Ceil(titleStyle.CalcSize(new GUIContent(text)).x * 1.2f + 4f);
			GUILayout.Label(text, titleStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(num3),
				GUILayout.Height(num)
			});
			GUILayout.Space(8f);
			DrawEditorActions();
			GUILayout.Space(8f);
			string text2 = ((activeFile == null) ? string.Empty : activeFile.Name);
			GUILayout.Label(text2, pickerNameStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.ExpandWidth(false),
				GUILayout.Height(num)
			});
			GUILayout.FlexibleSpace();
			bool flag = ConfigEditorGui.ToggleLayout(theme, TradersExtended.configEditorBlockGameInput?.Value ?? false, new GUIContent("Prevent input", "Block all Valheim gameplay input while the configuration editor is open."), GetHeaderToggleWidth("Prevent input"));
			if (TradersExtended.configEditorBlockGameInput != null && flag != TradersExtended.configEditorBlockGameInput.Value)
			{
				TradersExtended.configEditorBlockGameInput.Value = flag;
			}
			if (GUILayout.Button("Close", smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(52f),
				GUILayout.Height(20f)
			}))
			{
				RequestClose();
			}
			GUILayout.EndHorizontal();
		}

		private void DrawItemEditor()
		{
			//IL_04ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_055d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0562: Unknown result type (might be due to invalid IL or missing references)
			EnsureItemOptions();
			EnsureVisibleItemColumns();
			List<EditorItemRow> list = itemDocument.Rows.Where(ItemMatchesSearch).ToList();
			int num = Math.Max(1, (list.Count + 100 - 1) / 100);
			itemPage = Mathf.Clamp(itemPage, 0, num - 1);
			List<EditorItemRow> list2 = list.Skip(itemPage * 100).Take(100).ToList();
			GUILayout.BeginHorizontal(toolbarStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) });
			if (GUILayout.Button("Add item...", smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(88f),
				GUILayout.Height(20f)
			}))
			{
				OpenItemPicker("Add item", delegate(string prefab)
				{
					AddItemRow(prefab);
				}, multiAdd: false);
			}
			GUILayout.Space(2f);
			if (GUILayout.Button("Add items...", smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(92f),
				GUILayout.Height(20f)
			}))
			{
				OpenItemPicker("Add items", delegate(string prefab)
				{
					AddItemRow(prefab);
				}, multiAdd: true);
			}
			GUILayout.Space(2f);
			if (GUILayout.Button("Add blank", smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(76f),
				GUILayout.Height(20f)
			}))
			{
				itemDocument.Rows.Add(new EditorItemRow(new TradersExtended.TradeableItem()));
				itemDocument.Dirty = true;
			}
			GUILayout.Space(2f);
			if (GUILayout.Button("Select filtered", smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(100f),
				GUILayout.Height(20f)
			}))
			{
				foreach (EditorItemRow item in list)
				{
					item.Selected = true;
				}
			}
			GUILayout.Space(2f);
			if (GUILayout.Button("Clear selection", smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(100f),
				GUILayout.Height(20f)
			}))
			{
				foreach (EditorItemRow row in itemDocument.Rows)
				{
					row.Selected = false;
				}
			}
			GUILayout.Space(2f);
			int num2 = itemDocument.Rows.Count((EditorItemRow row) => row.Selected);
			GUI.enabled = num2 > 0;
			if (GUILayout.Button($"Delete selected ({num2})", smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(140f),
				GUILayout.Height(20f)
			}))
			{
				itemDocument.Rows.RemoveAll((EditorItemRow row) => row.Selected);
				itemDocument.Dirty = true;
			}
			GUI.enabled = true;
			GUILayout.Space(10f);
			GUILayout.Label("Search", (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(50f),
				GUILayout.Height(20f)
			});
			string a = GUILayout.TextField(itemSearch ?? string.Empty, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(150f),
				GUILayout.Height(20f)
			});
			if (!string.Equals(a, itemSearch, StringComparison.Ordinal))
			{
				itemSearch = a;
				itemPage = 0;
			}
			if (GUILayout.Button("×", smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(20f),
				GUILayout.Height(20f)
			}))
			{
				itemSearch = string.Empty;
				itemPage = 0;
			}
			GUILayout.FlexibleSpace();
			GUI.enabled = itemPage > 0;
			if (GUILayout.Button("◀", smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(28f),
				GUILayout.Height(20f)
			}))
			{
				itemPage--;
				itemScroll = Vector2.zero;
			}
			GUI.enabled = true;
			GUILayout.Label($"Page {itemPage + 1}/{num}", centeredMutedStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(75f),
				GUILayout.Height(20f)
			});
			GUI.enabled = itemPage + 1 < num;
			if (GUILayout.Button("▶", smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(28f),
				GUILayout.Height(20f)
			}))
			{
				itemPage++;
				itemScroll = Vector2.zero;
			}
			GUI.enabled = true;
			GUILayout.Label($"Rows: {itemDocument.Rows.Count}; filtered: {list.Count}", centeredMutedStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(180f),
				GUILayout.Height(20f)
			});
			GUILayout.EndHorizontal();
			itemScroll = GUILayout.BeginScrollView(itemScroll, true, true, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.ExpandWidth(true),
				GUILayout.ExpandHeight(true)
			});
			DrawItemHeader();
			EditorItemRow editorItemRow = null;
			ItemRowAction itemRowAction = ItemRowAction.None;
			foreach (EditorItemRow item2 in list2)
			{
				int rowIndex = itemDocument.Rows.IndexOf(item2);
				ItemRowAction itemRowAction2 = DrawItemRow(item2, rowIndex);
				if (itemRowAction2 != ItemRowAction.None)
				{
					editorItemRow = item2;
					itemRowAction = itemRowAction2;
				}
			}
			GUILayout.EndScrollView();
			if (editorItemRow != null)
			{
				int num3 = itemDocument.Rows.IndexOf(editorItemRow);
				if (itemRowAction == ItemRowAction.Delete)
				{
					itemDocument.Rows.Remove(editorItemRow);
				}
				else if (itemRowAction == ItemRowAction.MoveUp && num3 > 0)
				{
					MoveItemRow(num3, num3 - 1);
				}
				else if (itemRowAction == ItemRowAction.MoveDown && num3 >= 0 && num3 + 1 < itemDocument.Rows.Count)
				{
					MoveItemRow(num3, num3 + 1);
				}
				itemDocument.Dirty = true;
			}
			DrawItemSortControls();
			DrawItemColumnVisibilityControls();
		}

		private void AddItemRow(string prefab)
		{
			itemDocument.Rows.Add(new EditorItemRow(new TradersExtended.TradeableItem
			{
				prefab = prefab
			}));
			itemDocument.Dirty = true;
		}

		private void DrawItemHeader()
		{
			float width = GetItemPrefabColumnWidth();
			GUILayout.BeginHorizontal(headerStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(22f) });
			Header("", 22f);
			ItemColumnGap();
			Header("", 17f);
			ItemColumnGap();
			if (IsItemColumnVisible(ItemSortColumn.Prefab))
			{
				Header("Prefab", width);
				ItemColumnGap();
			}
			Header("", 18f);
			ItemColumnGap();
			Header("", 18f);
			ItemColumnGap();
			Header("", 18f);
			ItemColumnGap();
			if (IsItemColumnVisible(ItemSortColumn.LocalizedName))
			{
				Header("Localized name", 170f);
				ItemColumnGap();
			}
			Header("", 20f);
			ItemColumnGap();
			if (IsItemColumnVisible(ItemSortColumn.Stack))
			{
				Header("Stack", 55f);
				ItemColumnGap();
			}
			if (IsItemColumnVisible(ItemSortColumn.Price))
			{
				Header("Price", 60f);
				ItemColumnGap();
			}
			if (IsItemColumnVisible(ItemSortColumn.Quality))
			{
				Header("Quality", 55f);
				ItemColumnGap();
			}
			if (IsItemColumnVisible(ItemSortColumn.Currency))
			{
				Header("Currency", 140f);
				ItemColumnGap();
			}
			if (IsItemColumnVisible(ItemSortColumn.RequiredGlobalKey))
			{
				Header("Required global key", 155f);
				ItemColumnGap();
			}
			if (IsItemColumnVisible(ItemSortColumn.BlockedGlobalKey))
			{
				Header("Blocked global key", 155f);
				ItemColumnGap();
			}
			if (IsItemColumnVisible(ItemSortColumn.RequiredPlayerKey))
			{
				Header("Required player key", 150f);
				ItemColumnGap();
			}
			if (IsItemColumnVisible(ItemSortColumn.BlockedPlayerKey))
			{
				Header("Blocked player key", 150f);
			}
			GUILayout.EndHorizontal();
		}

		private ItemRowAction DrawItemRow(EditorItemRow row, int rowIndex)
		{
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Expected O, but got Unknown
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Expected O, but got Unknown
			//IL_04f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0514: Unknown result type (might be due to invalid IL or missing references)
			//IL_0524: Unknown result type (might be due to invalid IL or missing references)
			//IL_0531: Unknown result type (might be due to invalid IL or missing references)
			//IL_0540: Expected O, but got Unknown
			ItemRowValidation itemRowValidation = BuildItemRowValidation(row);
			row.ValidationError = itemRowValidation.Combined;
			float width = GetItemPrefabColumnWidth();
			ItemRowAction result = ItemRowAction.None;
			GUILayout.BeginHorizontal(itemRowStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(22f) });
			bool flag = ConfigEditorGui.ToggleLayout(theme, row.Selected, GUIContent.none, 22f, mutedStyle, 0f);
			if (flag != row.Selected)
			{
				row.Selected = flag;
			}
			ItemColumnGap();
			if (!string.IsNullOrEmpty(itemRowValidation.Prefab))
			{
				GUILayout.Label(new GUIContent("!", itemRowValidation.Prefab), invalidItemIconStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(17f),
					GUILayout.Height(17f)
				});
			}
			else
			{
				DrawItemIcon(row.Item.prefab, 17f);
			}
			ItemColumnGap();
			if (IsItemColumnVisible(ItemSortColumn.Prefab))
			{
				string text = DrawValidatedTextField(row.Item.prefab ?? string.Empty, itemPrefabTextFieldStyle, string.Empty, width, 20f);
				if (!string.Equals(text, row.Item.prefab, StringComparison.Ordinal))
				{
					row.Item.prefab = text;
					itemDocument.Dirty = true;
				}
				ItemColumnGap();
			}
			if (DrawQuickActionButton("×", "Delete row"))
			{
				result = ItemRowAction.Delete;
			}
			ItemColumnGap();
			GUI.enabled = rowIndex > 0;
			if (DrawQuickActionButton("↑", "Move row up"))
			{
				result = ItemRowAction.MoveUp;
			}
			GUI.enabled = true;
			ItemColumnGap();
			GUI.enabled = rowIndex >= 0 && rowIndex + 1 < itemDocument.Rows.Count;
			if (DrawQuickActionButton("↓", "Move row down"))
			{
				result = ItemRowAction.MoveDown;
			}
			GUI.enabled = true;
			ItemColumnGap();
			if (IsItemColumnVisible(ItemSortColumn.LocalizedName))
			{
				string itemDisplayName = GetItemDisplayName(row.Item.prefab);
				GUILayout.Label(new GUIContent(itemDisplayName, itemDisplayName), pickerNameStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(170f),
					GUILayout.Height(20f)
				});
				ItemColumnGap();
			}
			if (DrawInlinePickerButton())
			{
				OpenItemPicker("Select item prefab", delegate(string value)
				{
					row.Item.prefab = value;
					itemDocument.Dirty = true;
				}, multiAdd: false);
			}
			ItemColumnGap();
			if (IsItemColumnVisible(ItemSortColumn.Stack))
			{
				DrawIntegerField(ref row.StackText, delegate(int value)
				{
					row.Item.stack = value;
				}, 55f, itemRowValidation.Stack);
				ItemColumnGap();
			}
			if (IsItemColumnVisible(ItemSortColumn.Price))
			{
				DrawIntegerField(ref row.PriceText, delegate(int value)
				{
					row.Item.price = value;
				}, 60f, itemRowValidation.Price);
				ItemColumnGap();
			}
			if (IsItemColumnVisible(ItemSortColumn.Quality))
			{
				DrawIntegerField(ref row.QualityText, delegate(int value)
				{
					row.Item.quality = value;
				}, 55f, itemRowValidation.Quality);
				ItemColumnGap();
			}
			if (IsItemColumnVisible(ItemSortColumn.Currency))
			{
				DrawPrefabField(row.Item.currency, delegate(string value)
				{
					row.Item.currency = value;
				}, 140f, "Select currency item", itemRowValidation.Currency);
				ItemColumnGap();
			}
			if (IsItemColumnVisible(ItemSortColumn.RequiredGlobalKey))
			{
				DrawKeyField(row.Item.requiredGlobalKey, delegate(string value)
				{
					row.Item.requiredGlobalKey = value;
				}, 155f, KeyPickerKind.Global, itemRowValidation.RequiredGlobalKey);
				ItemColumnGap();
			}
			if (IsItemColumnVisible(ItemSortColumn.BlockedGlobalKey))
			{
				DrawKeyField(row.Item.notRequiredGlobalKey, delegate(string value)
				{
					row.Item.notRequiredGlobalKey = value;
				}, 155f, KeyPickerKind.Global, itemRowValidation.BlockedGlobalKey);
				ItemColumnGap();
			}
			if (IsItemColumnVisible(ItemSortColumn.RequiredPlayerKey))
			{
				DrawKeyField(row.Item.requiredPlayerKey, delegate(string value)
				{
					row.Item.requiredPlayerKey = value;
				}, 150f, KeyPickerKind.Player, itemRowValidation.RequiredPlayerKey);
				ItemColumnGap();
			}
			if (IsItemColumnVisible(ItemSortColumn.BlockedPlayerKey))
			{
				DrawKeyField(row.Item.notRequiredPlayerKey, delegate(string value)
				{
					row.Item.notRequiredPlayerKey = value;
				}, 150f, KeyPickerKind.Player, itemRowValidation.BlockedPlayerKey);
			}
			GUILayout.EndHorizontal();
			if (itemRowValidation.HasErrors)
			{
				Rect lastRect = GUILayoutUtility.GetLastRect();
				DrawOutline(lastRect, new Color(0.9f, 0.2f, 0.18f, 1f), 1f);
				GUI.Label(lastRect, new GUIContent(string.Empty, itemRowValidation.Combined), GUIStyle.none);
			}
			return result;
		}

		private void MoveItemRow(int sourceIndex, int destinationIndex)
		{
			if (sourceIndex >= 0 && destinationIndex >= 0 && sourceIndex < itemDocument.Rows.Count && destinationIndex < itemDocument.Rows.Count && sourceIndex != destinationIndex)
			{
				EditorItemRow item = itemDocument.Rows[sourceIndex];
				itemDocument.Rows.RemoveAt(sourceIndex);
				itemDocument.Rows.Insert(destinationIndex, item);
			}
		}

		private void DrawItemSortControls()
		{
			int num = itemDocument.Rows.Count((EditorItemRow row) => row.Selected);
			bool flag = num > 1;
			GUILayout.BeginHorizontal(toolbarStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(26f) });
			GUILayout.Label(flag ? "Sort selected by:" : "Sort by:", (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(flag ? 102f : 48f),
				GUILayout.Height(20f)
			});
			DrawItemSortCommand("Prefab", ItemSortColumn.Prefab, 48f, flag);
			DrawItemSortCommand("Name", ItemSortColumn.LocalizedName, 40f, flag);
			DrawItemSortCommand("Stack", ItemSortColumn.Stack, 40f, flag);
			DrawItemSortCommand("Price", ItemSortColumn.Price, 36f, flag);
			DrawItemSortCommand("Quality", ItemSortColumn.Quality, 46f, flag);
			DrawItemSortCommand("Currency", ItemSortColumn.Currency, 58f, flag);
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
		}

		private void DrawItemSortCommand(string label, ItemSortColumn column, float labelWidth, bool selectedOnly)
		{
			GUILayout.Label(label, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(labelWidth),
				GUILayout.Height(20f)
			});
			if (GUILayout.Button("↑", smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(22f),
				GUILayout.Height(20f)
			}))
			{
				SortItemRows(column, ascending: true, selectedOnly);
			}
			if (GUILayout.Button("↓", smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(22f),
				GUILayout.Height(20f)
			}))
			{
				SortItemRows(column, ascending: false, selectedOnly);
			}
			GUILayout.Space(5f);
		}

		private void DrawItemColumnVisibilityControls()
		{
			GUILayout.BeginHorizontal(toolbarStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(29f) });
			GUILayout.Label("Columns:", (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(58f),
				GUILayout.Height(20f)
			});
			DrawItemColumnToggle(ItemSortColumn.Prefab, "Prefab", 72f);
			DrawItemColumnToggle(ItemSortColumn.LocalizedName, "Name", 62f);
			DrawItemColumnToggle(ItemSortColumn.Stack, "Stack", 62f);
			DrawItemColumnToggle(ItemSortColumn.Price, "Price", 58f);
			DrawItemColumnToggle(ItemSortColumn.Quality, "Quality", 70f);
			DrawItemColumnToggle(ItemSortColumn.Currency, "Currency", 82f);
			DrawItemColumnToggle(ItemSortColumn.RequiredGlobalKey, "Req global", 96f);
			DrawItemColumnToggle(ItemSortColumn.BlockedGlobalKey, "Block global", 104f);
			DrawItemColumnToggle(ItemSortColumn.RequiredPlayerKey, "Req player", 96f);
			DrawItemColumnToggle(ItemSortColumn.BlockedPlayerKey, "Block player", 104f);
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
		}

		private void DrawItemColumnToggle(ItemSortColumn column, string label, float width)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			bool flag = IsItemColumnVisible(column);
			bool flag2 = ConfigEditorGui.ToggleLayout(theme, flag, new GUIContent(label), width, singleLineMutedStyle, 0f, 22f);
			if (flag2 != flag)
			{
				SetItemColumnVisible(column, flag2);
			}
		}

		private void DrawTraderEditor()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.Label("Enable Override for a field to store a trader-specific value. Disabled fields inherit the synchronized BepInEx configuration.", mutedStyle, Array.Empty<GUILayoutOption>());
			settingsScroll = GUILayout.BeginScrollView(settingsScroll, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.ExpandWidth(true),
				GUILayout.ExpandHeight(true)
			});
			foreach (IGrouping<string, TraderSettingState> item in from state in traderDocument.Settings
				group state by state.Definition.Section)
			{
				GUILayout.Label("— " + item.Key + " —", headerStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(20f) });
				foreach (TraderSettingState item2 in item)
				{
					DrawTraderSetting(item2);
				}
			}
			GUILayout.EndScrollView();
		}

		private void DrawTraderSetting(TraderSettingState state)
		{
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Expected O, but got Unknown
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.BeginVertical(rowStyle, Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			bool flag = ConfigEditorGui.ToggleLayout(theme, state.HasOverride, GUIContent.none, 22f, mutedStyle, 0f);
			if (flag != state.HasOverride)
			{
				state.HasOverride = flag;
				if (flag)
				{
					state.Value = state.Definition.Fallback(traderDocument.Trader);
					state.EditText = TraderConfigSchema.FormatEditText(state.Definition.Type, state.Value);
					state.ValidationError = string.Empty;
					if (state.Definition.Type == TraderSettingType.Vector2)
					{
						Vector2 val = ((state.Value is Vector2 val2) ? val2 : Vector2.zero);
						state.VectorXText = val.x.ToString("0.###", CultureInfo.InvariantCulture);
						state.VectorYText = val.y.ToString("0.###", CultureInfo.InvariantCulture);
					}
				}
				traderDocument.Dirty = true;
			}
			GUILayout.Label(new GUIContent(state.Definition.Name, state.Definition.Description), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(360f) });
			GUI.enabled = state.HasOverride;
			DrawTraderValue(state);
			GUI.enabled = true;
			if (!state.HasOverride)
			{
				GUILayout.Label("Inherited: " + FormatValue(state.Definition.Type, state.Definition.Fallback(traderDocument.Trader)), mutedStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(240f) });
			}
			GUILayout.EndHorizontal();
			if (state.HasOverride && !string.IsNullOrWhiteSpace(state.ValidationError))
			{
				GUILayout.Label(state.ValidationError, errorStyle, Array.Empty<GUILayoutOption>());
			}
			GUILayout.EndVertical();
		}

		private void DrawTraderValue(TraderSettingState state)
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_0540: Unknown result type (might be due to invalid IL or missing references)
			switch (state.Definition.Type)
			{
			case TraderSettingType.Boolean:
			{
				object value = state.Value;
				bool flag = default(bool);
				int num;
				if (value is bool)
				{
					flag = (bool)value;
					num = 1;
				}
				else
				{
					num = 0;
				}
				bool flag2 = (byte)((uint)num & (flag ? 1u : 0u)) != 0;
				bool flag3 = ConfigEditorGui.ToggleLayout(theme, flag2, new GUIContent(flag2 ? "Enabled" : "Disabled"), 150f);
				if (flag3 != flag2)
				{
					state.Value = flag3;
					state.ValidationError = string.Empty;
					traderDocument.Dirty = true;
				}
				break;
			}
			case TraderSettingType.Integer:
			{
				string text7 = GUILayout.TextField(state.EditText ?? string.Empty, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(150f) });
				if (!string.Equals(text7, state.EditText, StringComparison.Ordinal))
				{
					state.EditText = text7;
					if (int.TryParse(text7, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result3))
					{
						state.Value = result3;
						state.ValidationError = string.Empty;
						traderDocument.Dirty = true;
					}
					else
					{
						state.ValidationError = "Enter a valid integer.";
					}
				}
				break;
			}
			case TraderSettingType.Float:
			{
				string text8 = GUILayout.TextField(state.EditText ?? string.Empty, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(150f) });
				if (!string.Equals(text8, state.EditText, StringComparison.Ordinal))
				{
					state.EditText = text8;
					if (float.TryParse(text8, NumberStyles.Float, CultureInfo.InvariantCulture, out var result4))
					{
						state.Value = result4;
						state.ValidationError = string.Empty;
						traderDocument.Dirty = true;
					}
					else
					{
						state.ValidationError = "Enter a valid number using a dot as the decimal separator.";
					}
				}
				break;
			}
			case TraderSettingType.String:
			{
				string text5 = state.Value?.ToString() ?? string.Empty;
				string text6 = GUILayout.TextField(text5, (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.MinWidth(260f),
					GUILayout.ExpandWidth(true)
				});
				if (!string.Equals(text5, text6, StringComparison.Ordinal))
				{
					state.Value = text6;
					state.ValidationError = string.Empty;
					traderDocument.Dirty = true;
				}
				break;
			}
			case TraderSettingType.ItemPrefab:
			{
				string text3 = state.Value?.ToString() ?? string.Empty;
				string text4 = GUILayout.TextField(text3, (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(125f),
					GUILayout.Height(20f)
				});
				if (!string.Equals(text3, text4, StringComparison.Ordinal))
				{
					state.Value = text4;
					state.ValidationError = ValidateItemPrefab(text4);
					traderDocument.Dirty = true;
				}
				else
				{
					state.ValidationError = (state.HasOverride ? ValidateItemPrefab(text3) : string.Empty);
				}
				if (DrawInlinePickerButton())
				{
					OpenItemPicker("Select item prefab", delegate(string prefab)
					{
						state.Value = prefab;
						state.EditText = prefab;
						state.ValidationError = string.Empty;
						traderDocument.Dirty = true;
					}, multiAdd: false);
				}
				GUILayout.Label(GetItemDisplayName(state.Value?.ToString()), pickerNameStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(150f),
					GUILayout.Height(20f)
				});
				break;
			}
			case TraderSettingType.Vector2:
			{
				GUILayout.Label("x", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(12f) });
				string text = GUILayout.TextField(state.VectorXText ?? string.Empty, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(85f) });
				GUILayout.Label("y", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(12f) });
				string text2 = GUILayout.TextField(state.VectorYText ?? string.Empty, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(85f) });
				if (!string.Equals(text, state.VectorXText, StringComparison.Ordinal) || !string.Equals(text2, state.VectorYText, StringComparison.Ordinal))
				{
					state.VectorXText = text;
					state.VectorYText = text2;
					if (float.TryParse(text, NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && float.TryParse(text2, NumberStyles.Float, CultureInfo.InvariantCulture, out var result2))
					{
						state.Value = (object)new Vector2(result, result2);
						state.ValidationError = string.Empty;
						traderDocument.Dirty = true;
					}
					else
					{
						state.ValidationError = "Both x and y must be valid numbers using a dot as the decimal separator.";
					}
				}
				break;
			}
			}
		}

		private void DrawNewFileWindow(int windowId)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_048b: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
			newFileScroll = GUILayout.BeginScrollView(newFileScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) });
			GUILayout.Label("Configuration type", headerStyle, Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("Item list", (newFileKind == EditorConfigKind.ItemList) ? theme.AccentButtonStyle : smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
			{
				newFileKind = EditorConfigKind.ItemList;
			}
			if (GUILayout.Button("Trader settings", (newFileKind == EditorConfigKind.TraderSettings) ? theme.AccentButtonStyle : smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
			{
				newFileKind = EditorConfigKind.TraderSettings;
				if (string.Equals(newFileTrader, "common", StringComparison.OrdinalIgnoreCase))
				{
					newFileTrader = "Haldor";
				}
				if (newFileExtension == "csv")
				{
					newFileExtension = "json";
				}
			}
			GUILayout.EndHorizontal();
			GUILayout.Space(8f);
			GUILayout.Label("Trader prefab", headerStyle, Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			newFileTrader = GUILayout.TextField(newFileTrader ?? string.Empty, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
			if (GUILayout.Button("Select...", smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) }))
			{
				OpenTraderPicker();
			}
			GUILayout.EndHorizontal();
			GUILayout.Label(GetTraderDisplayName(newFileTrader), mutedStyle, Array.Empty<GUILayoutOption>());
			if (newFileKind == EditorConfigKind.ItemList)
			{
				GUILayout.Space(8f);
				GUILayout.Label("List type", headerStyle, Array.Empty<GUILayoutOption>());
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				if (GUILayout.Button("Buy", (newFileListType == TradersExtended.ItemsListType.Buy) ? theme.AccentButtonStyle : smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
				{
					newFileListType = TradersExtended.ItemsListType.Buy;
				}
				if (GUILayout.Button("Sell", (newFileListType == TradersExtended.ItemsListType.Sell) ? theme.AccentButtonStyle : smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
				{
					newFileListType = TradersExtended.ItemsListType.Sell;
				}
				GUILayout.EndHorizontal();
				GUILayout.Label("Optional dot-separated identifier", headerStyle, Array.Empty<GUILayoutOption>());
				newFileIdentifier = GUILayout.TextField(newFileIdentifier ?? string.Empty, Array.Empty<GUILayoutOption>());
			}
			GUILayout.Space(8f);
			GUILayout.Label("File format", headerStyle, Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			DrawFormatToggle("json");
			DrawFormatToggle("yaml");
			DrawFormatToggle("yml");
			if (newFileKind == EditorConfigKind.ItemList)
			{
				DrawFormatToggle("csv");
			}
			GUILayout.EndHorizontal();
			string text = BuildNewFileName();
			GUILayout.Space(8f);
			GUILayout.Label("File name", headerStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Label(text, panelStyle, Array.Empty<GUILayoutOption>());
			string text2 = ValidateNewFile(text);
			if (!string.IsNullOrEmpty(text2))
			{
				GUILayout.Label(text2, errorStyle, Array.Empty<GUILayoutOption>());
			}
			GUILayout.EndScrollView();
			GUILayout.BeginHorizontal(toolbarStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(34f) });
			GUI.enabled = string.IsNullOrEmpty(text2) && !requestInProgress;
			if (GUILayout.Button("Create", smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
			{
				CreateNewFile(text);
			}
			GUI.enabled = true;
			if (GUILayout.Button("Cancel", smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
			{
				showNewFile = false;
			}
			GUILayout.EndHorizontal();
			GUILayout.EndVertical();
			DrawModalBorder(((Rect)(ref newFileRect)).width, ((Rect)(ref newFileRect)).height);
			GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref newFileRect)).width, 22f));
		}

		private void DrawItemPickerWindow(int windowId)
		{
			//IL_00ba: 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_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Expected O, but got Unknown
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0696: Unknown result type (might be due to invalid IL or missing references)
			//IL_069b: Unknown result type (might be due to invalid IL or missing references)
			//IL_074d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0752: Unknown result type (might be due to invalid IL or missing references)
			//IL_07e5: Unknown result type (might be due to invalid IL or missing references)
			bool flag = temporaryTraderOptions != null;
			bool flag2 = false;
			string text = null;
			string value = null;
			GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(18f) });
			GUILayout.Label("Search", (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(49f),
				GUILayout.Height(18f)
			});
			string a = GUILayout.TextField(itemPickerSearch ?? string.Empty, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.ExpandWidth(true),
				GUILayout.Height(18f)
			});
			if (!string.Equals(a, itemPickerSearch, StringComparison.Ordinal))
			{
				itemPickerSearch = a;
				itemPickerPage = 0;
				itemPickerScroll = Vector2.zero;
			}
			if (GUILayout.Button("×", smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(20f),
				GUILayout.Height(18f)
			}))
			{
				itemPickerSearch = string.Empty;
				itemPickerPage = 0;
				itemPickerScroll = Vector2.zero;
			}
			if (!flag)
			{
				GUILayout.Space(3f);
				GUILayout.Label("Sort", (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(29f),
					GUILayout.Height(18f)
				});
				DrawItemPickerSortButton("Prefab", ItemPickerSortColumn.Prefab, 70f);
				DrawItemPickerSortButton("Name", ItemPickerSortColumn.LocalizedName, 64f);
				GUILayout.Space(3f);
				bool flag3 = ConfigEditorGui.ToggleLayout(theme, TradersExtended.configEditorShowAllItems?.Value ?? false, new GUIContent("Show all", "Include AI equipment and items without a normal user-facing name, description or icon."), 70f, singleLineMutedStyle, 0f);
				if (TradersExtended.configEditorShowAllItems != null && flag3 != TradersExtended.configEditorShowAllItems.Value)
				{
					TradersExtended.configEditorShowAllItems.Value = flag3;
					itemPickerPage = 0;
					itemPickerScroll = Vector2.zero;
				}
			}
			GUILayout.Space(3f);
			if (GUILayout.Button("Close", smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(52f),
				GUILayout.Height(18f)
			}))
			{
				flag2 = true;
			}
			GUILayout.EndHorizontal();
			GUILayout.Space(4f);
			itemPickerScroll = GUILayout.BeginScrollView(itemPickerScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) });
			int count;
			int num;
			if (flag)
			{
				List<TraderOption> list = temporaryTraderOptions.Where(TraderOptionMatchesSearch).ToList();
				count = list.Count;
				num = Math.Max(1, (count + 100 - 1) / 100);
				itemPickerPage = Mathf.Clamp(itemPickerPage, 0, num - 1);
				foreach (TraderOption item in list.Skip(itemPickerPage * 100).Take(100))
				{
					GUILayout.BeginHorizontal(rowStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(20f) });
					GUILayout.Label(item.DisplayName, pickerNameStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
					{
						GUILayout.ExpandWidth(true),
						GUILayout.Height(20f)
					});
					GUILayout.Space(3f);
					GUILayout.Label(item.Prefab, pickerPrefabStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
					{
						GUILayout.Width(214f),
						GUILayout.Height(20f)
					});
					GUILayout.Space(3f);
					if (GUILayout.Button("Select", smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
					{
						GUILayout.Width(56f),
						GUILayout.Height(17f)
					}))
					{
						value = item.Prefab;
					}
					GUILayout.EndHorizontal();
				}
			}
			else
			{
				bool showAll = TradersExtended.configEditorShowAllItems?.Value ?? false;
				List<ItemOption> list2 = SortItemPickerOptions(itemOptions.Where((ItemOption option) => (showAll || option.VisibleByDefault) && ItemOptionMatchesSearch(option)));
				count = list2.Count;
				num = Math.Max(1, (count + 100 - 1) / 100);
				itemPickerPage = Mathf.Clamp(itemPickerPage, 0, num - 1);
				foreach (ItemOption item2 in list2.Skip(itemPickerPage * 100).Take(100))
				{
					GUILayout.BeginHorizontal(rowStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(20f) });
					DrawSprite(item2.Icon, 17f);
					GUILayout.Space(3f);
					GUILayout.Label(item2.Prefab, pickerPrefabStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
					{
						GUILayout.Width(214f),
						GUILayout.Height(20f)
					});
					GUILayout.Space(3f);
					GUILayout.Label(item2.LocalizedName, pickerNameStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
					{
						GUILayout.ExpandWidth(true),
						GUILayout.Height(20f)
					});
					GUILayout.Space(3f);
					string text2 = (itemPickerMultiAdd ? "Add item" : "Select");
					float num2 = (itemPickerMultiAdd ? 65f : 59f);
					if (GUILayout.Button(text2, smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
					{
						GUILayout.Width(num2),
						GUILayout.Height(17f)
					}))
					{
						if (itemPickerMultiAdd)
						{
							itemPickerCallback?.Invoke(item2.Prefab);
						}
						else
						{
							text = item2.Prefab;
						}
					}
					GUILayout.EndHorizontal();
				}
			}
			GUILayout.EndScrollView();
			GUILayout.Space(4f);
			GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(18f) });
			GUI.enabled = itemPickerPage > 0;
			if (GUILayout.Button("Previous", smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(72f),
				GUILayout.Height(18f)
			}))
			{
				itemPickerPage--;
				itemPickerScroll = Vector2.zero;
			}
			GUI.enabled = true;
			GUILayout.Label($"Page {itemPickerPage + 1}/{num} — {count} result(s)", centeredMutedStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.ExpandWidth(true),
				GUILayout.Height(18f)
			});
			GUI.enabled = itemPickerPage + 1 < num;
			if (GUILayout.Button("Next", smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(60f),
				GUILayout.Height(18f)
			}))
			{
				itemPickerPage++;
				itemPickerScroll = Vector2.zero;
			}
			GUI.enabled = true;
			if (GUILayout.Button("Close", smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(58f),
				GUILayout.Height(18f)
			}))
			{
				flag2 = true;
			}
			GUILayout.EndHorizontal();
			GUILayout.Space(4f);
			GUILayout.EndVertical();
			DrawModalBorder(((Rect)(ref itemPickerRect)).width, ((Rect)(ref itemPickerRect)).height);
			GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref itemPickerRect)).width, 24f));
			if (!string.IsNullOrEmpty(value))
			{
				newFileTrader = value;
				CloseItemPicker();
			}
			else if (!string.IsNullOrEmpty(text))
			{
				Action<string> action = itemPickerCallback;
				CloseItemPicker();
				action?.Invoke(text);
			}
			else if (flag2)
			{
				CloseItemPicker();
			}
		}

		private void DrawGlobalKeyWindow(int windowId)
		{
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: 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_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing refe