Decompiled source of EasyDeals v0.0.2

easy_deals.dll

Decompiled 3 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Threading.Tasks;
using HarmonyLib;
using Il2CppScheduleOne.DevUtilities;
using Il2CppScheduleOne.Economy;
using Il2CppScheduleOne.GameTime;
using Il2CppScheduleOne.ItemFramework;
using Il2CppScheduleOne.Messaging;
using Il2CppScheduleOne.Product;
using Il2CppScheduleOne.Quests;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using MelonLoader;
using TestingClass;
using UnityEngine;
using easy_deals;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(MainHandler), "EasyDeals", "0.0.1", "Omar Ahmed", null)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: AssemblyTitle("easy_deals")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("easy_deals")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("3a228b8d-b72a-44dc-96c4-530d3e296a3b")]
[assembly: AssemblyFileVersion("0.1")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("0.1.0.0")]
namespace TestingClass
{
	internal static class TestingClass
	{
		private static ProductDefinition cachedProduct;

		public static void GenerateRandomQuests(int numberOfQuests)
		{
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Expected O, but got Unknown
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: 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_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Expected O, but got Unknown
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Expected O, but got Unknown
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Expected O, but got Unknown
			List<Customer> val = new List<Customer>();
			Enumerator<Customer> enumerator = Customer.UnlockedCustomers.GetEnumerator();
			while (enumerator.MoveNext())
			{
				Customer current = enumerator.Current;
				val.Add(current);
			}
			MelonLogger.Msg("we have : " + val.Count);
			if (val == null || val.Count == 0)
			{
				return;
			}
			Random random = new Random();
			while (numberOfQuests > 0 && val.Count != 0)
			{
				int num = random.Next(0, val.Count);
				Customer val2 = val[num];
				if ((Object)(object)val2 == (Object)null || val2.offeredContractInfo != null || (Object)(object)val2.DefaultDeliveryLocation == (Object)null)
				{
					val.RemoveAt(num);
					continue;
				}
				List<ProductDefinition> orderableProducts = val2.OrderableProducts;
				if ((Object)(object)cachedProduct == (Object)null && orderableProducts.Count > 0)
				{
					cachedProduct = orderableProducts[0];
				}
				ProductDefinition val3 = null;
				if (orderableProducts.Count > 0)
				{
					val3 = orderableProducts[random.Next(0, orderableProducts.Count)];
				}
				else if ((Object)(object)cachedProduct != (Object)null)
				{
					val3 = cachedProduct;
				}
				if ((Object)(object)val3 == (Object)null)
				{
					val.RemoveAt(num);
					continue;
				}
				ProductList val4 = new ProductList();
				val4.entries = new List<Entry>();
				Entry val5 = new Entry
				{
					ProductID = ((ItemDefinition)val3).ID,
					Quantity = 2,
					Quality = (EQuality)2
				};
				val4.entries.Add(val5);
				QuestWindowConfig val6 = new QuestWindowConfig
				{
					WindowStartTime = 0,
					WindowEndTime = 600
				};
				Guid gUID = val2.DefaultDeliveryLocation.GUID;
				string text = ((object)(Guid)(ref gUID)).ToString();
				ContractInfo val7 = new ContractInfo(100f, val4, text, val6, true, 900, numberOfQuests, false);
				val2.OfferContract(val7);
				val.RemoveAt(num);
				numberOfQuests--;
			}
		}
	}
}
namespace easy_deals
{
	public static class KeyBindings
	{
		public static KeyCode OpenMenuKey = (KeyCode)280;

		public static KeyCode AcceptContractKey = (KeyCode)279;

		public static KeyCode NextPeriodKey = (KeyCode)273;

		public static KeyCode PreviousPeriodKey = (KeyCode)274;

		public static KeyCode NextProductKey = (KeyCode)275;

		public static KeyCode PreviousProductKey = (KeyCode)276;

		public static KeyCode IncreasePrice = (KeyCode)43;

		public static KeyCode DecreasePrice = (KeyCode)45;
	}
	public class ContractManager
	{
		private static readonly object _lock = new object();

		private static ContractManager _instance;

		private readonly List<PendingContract> _pendingContracts = new List<PendingContract>();

		private readonly Queue<PendingContract> _contractPool = new Queue<PendingContract>();

		private bool _isProcessing = false;

		private readonly Dictionary<string, float> _potentialGains = new Dictionary<string, float>();

		private readonly Dictionary<string, int> _totalQuantities = new Dictionary<string, int>();

		private readonly List<string> _offeredProducts = new List<string> { "All" };

		private bool _productsChanged = false;

		public static ContractManager Instance
		{
			get
			{
				lock (_lock)
				{
					return _instance ?? (_instance = new ContractManager());
				}
			}
		}

		public float OverallPriceModifier { get; set; } = 10f;


		private ContractManager()
		{
			_potentialGains["All"] = 0f;
			_totalQuantities["All"] = 0;
			MelonLogger.Msg("ContractManager initialized with default 'All' values");
		}

		public void AddContract(ProductDefinition product, int quantity, float payment, Customer customer)
		{
			if ((Object)(object)product == (Object)null || string.IsNullOrEmpty(((ItemDefinition)product).Name))
			{
				MelonLogger.Warning("AddContract failed: Product is null or has no name");
				return;
			}
			PendingContract contract = GetContract(product, quantity, payment, customer);
			_pendingContracts.Add(contract);
			_potentialGains.TryGetValue("All", out var value);
			_potentialGains["All"] = value + payment + OverallPriceModifier;
			_totalQuantities.TryGetValue("All", out var value2);
			_totalQuantities["All"] = value2 + quantity;
			_potentialGains.TryGetValue(((ItemDefinition)product).Name, out var value3);
			_potentialGains[((ItemDefinition)product).Name] = value3 + payment + OverallPriceModifier;
			_totalQuantities.TryGetValue(((ItemDefinition)product).Name, out var value4);
			_totalQuantities[((ItemDefinition)product).Name] = value4 + quantity;
			if (!_offeredProducts.Contains(((ItemDefinition)product).Name))
			{
				_offeredProducts.Add(((ItemDefinition)product).Name);
				_offeredProducts.Sort();
			}
			MelonLogger.Msg($"Contract added: Product={((ItemDefinition)product).Name}, Quantity={quantity}, Payment={payment}, TotalContracts={_pendingContracts.Count}");
			_productsChanged = true;
		}

		public void ProcessContracts(EDealWindow dealWindow, string productName = "All")
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if (_pendingContracts.Count == 0)
			{
				MelonLogger.Msg("No contracts to process");
				return;
			}
			if (_isProcessing)
			{
				MelonLogger.Msg("Already processing contracts");
				return;
			}
			_isProcessing = true;
			MelonCoroutines.Start(ExecuteContracts(dealWindow, productName));
		}

		private IEnumerator ExecuteContracts(EDealWindow dealWindow, string productName)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			List<PendingContract> contractsToProcess = ((productName == "All") ? _pendingContracts.ToList() : _pendingContracts.Where((PendingContract c) => c.ProductName == productName).ToList());
			int processedCount = 0;
			_pendingContracts.RemoveAll((PendingContract c) => contractsToProcess.Contains(c));
			RemoveContracts(contractsToProcess);
			List<IGrouping<string, PendingContract>> groupedContracts = (from c in contractsToProcess
				group c by c.CustomerName).ToList();
			foreach (IGrouping<string, PendingContract> group in groupedContracts)
			{
				List<PendingContract> contracts = group.ToList();
				for (int i = 0; i < contracts.Count; i += 3)
				{
					List<PendingContract> batch = contracts.Skip(i).Take(3).ToList();
					yield return MelonCoroutines.Start(ProcessContractBatch(dealWindow, batch, 300));
					processedCount += batch.Count;
					MelonLogger.Msg($"Processed batch of {batch.Count} contracts, total processed: {processedCount}/{contractsToProcess.Count}");
					yield return (object)new WaitForSeconds(3f);
				}
			}
			foreach (PendingContract contract in contractsToProcess)
			{
				ReturnContract(contract);
			}
			_isProcessing = false;
			MelonLogger.Msg($"Completed processing {processedCount} contracts for {productName}");
			_productsChanged = true;
		}

		private IEnumerator ProcessContractBatch(EDealWindow dealWindow, List<PendingContract> contracts, int delayBetweenContracts)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			foreach (PendingContract contract in contracts)
			{
				bool taskCompleted = false;
				float timeout = Time.time + 10f;
				MelonLogger.Msg("Processing contract for " + contract.ProductName);
				contract.Execute(dealWindow).ContinueWith(delegate(Task t)
				{
					taskCompleted = true;
					if (t.IsFaulted)
					{
						MelonLogger.Error("Contract execution failed: " + t.Exception?.InnerException?.Message);
					}
				});
				while (!taskCompleted && Time.time < timeout)
				{
					yield return null;
				}
				yield return (object)new WaitForSeconds((float)delayBetweenContracts / 1000f);
			}
		}

		private void RemoveContracts(List<PendingContract> contracts)
		{
			foreach (PendingContract contract in contracts)
			{
				_potentialGains.TryGetValue("All", out var value);
				_potentialGains["All"] = value - (contract.Payment + OverallPriceModifier);
				_totalQuantities.TryGetValue("All", out var value2);
				_totalQuantities["All"] = value2 - contract.Quantity;
				_potentialGains.TryGetValue(contract.ProductName, out var value3);
				_potentialGains[contract.ProductName] = value3 - (contract.Payment + OverallPriceModifier);
				_totalQuantities.TryGetValue(contract.ProductName, out var value4);
				_totalQuantities[contract.ProductName] = value4 - contract.Quantity;
				if (!_pendingContracts.Any((PendingContract c) => c.ProductName == contract.ProductName))
				{
					_potentialGains.Remove(contract.ProductName);
					_totalQuantities.Remove(contract.ProductName);
					_offeredProducts.Remove(contract.ProductName);
				}
			}
		}

		public void UpdateGainsForModifierChange()
		{
			_potentialGains.Clear();
			_potentialGains["All"] = _pendingContracts.Sum((PendingContract c) => c.Payment + OverallPriceModifier);
			foreach (string productName in _offeredProducts.Where((string n) => n != "All"))
			{
				_potentialGains[productName] = _pendingContracts.Where((PendingContract c) => c.ProductName == productName).Sum((PendingContract c) => c.Payment + OverallPriceModifier);
			}
		}

		public List<string> GetOfferedProductNames()
		{
			return _offeredProducts;
		}

		public bool HasProductsChanged()
		{
			return _productsChanged;
		}

		public void ResetProductsChanged()
		{
			_productsChanged = false;
		}

		public float GetPotentialGain(string productName = "All")
		{
			_potentialGains.TryGetValue(productName, out var value);
			return value;
		}

		public int GetTotalQuantity(string productName = "All")
		{
			_totalQuantities.TryGetValue(productName, out var value);
			return value;
		}

		public List<PendingContract> GetPendingContracts()
		{
			return _pendingContracts;
		}

		private PendingContract GetContract(ProductDefinition product, int quantity, float payment, Customer customer)
		{
			PendingContract pendingContract;
			if (_contractPool.Count > 0)
			{
				pendingContract = _contractPool.Dequeue();
				pendingContract.Reset(product, quantity, payment, customer);
			}
			else
			{
				pendingContract = new PendingContract(product, quantity, payment, customer);
			}
			return pendingContract;
		}

		private void ReturnContract(PendingContract contract)
		{
			_contractPool.Enqueue(contract);
		}
	}
	public class PendingContract
	{
		private ProductDefinition _product;

		private int _quantity;

		private float _payment;

		private Customer _customer;

		public string ProductName => ((Object)(object)_product != (Object)null) ? ((ItemDefinition)_product).Name : "Null Product";

		public float Payment => _payment;

		public int Quantity => _quantity;

		public string CustomerName => ((Object)(object)_customer != (Object)null) ? ((Object)_customer).name : "Null Customer";

		public ProductDefinition Product => _product;

		public PendingContract(ProductDefinition product, int quantity, float payment, Customer customer)
		{
			Reset(product, quantity, payment, customer);
		}

		public void Reset(ProductDefinition product, int quantity, float payment, Customer customer)
		{
			_product = product;
			_quantity = quantity;
			_payment = payment;
			_customer = customer;
		}

		public async Task Execute(EDealWindow dealWindow)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_customer == (Object)null || (Object)(object)_product == (Object)null)
			{
				MelonLogger.Warning("Skipping contract execution: Invalid customer or product");
				return;
			}
			float finalPrice = _payment + ContractManager.Instance.OverallPriceModifier;
			int maxRetries = 2;
			int currentRetry = 0;
			while (currentRetry <= maxRetries)
			{
				try
				{
					MelonLogger.Msg($"Step 1: EvaluateCounteroffer for {ProductName} (attempt {currentRetry + 1})");
					Task<bool> task1 = RunOnMainThread(delegate
					{
						_customer.EvaluateCounteroffer(_product, _quantity, finalPrice);
						return true;
					});
					if (await Task.WhenAny(new Task[2]
					{
						task1,
						Task.Delay(5000)
					}) == task1)
					{
						await task1;
						await Task.Delay(200);
						MelonLogger.Msg("Step 2: SendCounteroffer for " + ProductName);
						Task<bool> task2 = RunOnMainThread(delegate
						{
							_customer.SendCounteroffer(_product, _quantity, finalPrice);
							return true;
						});
						if (await Task.WhenAny(new Task[2]
						{
							task2,
							Task.Delay(5000)
						}) == task2)
						{
							await task2;
							await Task.Delay(1500);
							MelonLogger.Msg("Step 3: PlayerAcceptedContract for " + ProductName);
							Task<bool> task3 = RunOnMainThread(delegate
							{
								//IL_000d: Unknown result type (might be due to invalid IL or missing references)
								_customer.PlayerAcceptedContract(dealWindow);
								_customer.NPC.MSGConversation.ClearResponses(true);
								return true;
							});
							if (await Task.WhenAny(new Task[2]
							{
								task3,
								Task.Delay(5000)
							}) != task3)
							{
								throw new TimeoutException("PlayerAcceptedContract timed out");
							}
							MelonLogger.Msg("Contract successfully executed for " + ProductName);
							break;
						}
						throw new TimeoutException("SendCounteroffer timed out");
					}
					throw new TimeoutException("EvaluateCounteroffer timed out");
				}
				catch (Exception ex)
				{
					currentRetry++;
					MelonLogger.Error($"Contract execution attempt {currentRetry} failed for {ProductName}: {ex.Message}");
					if (currentRetry > maxRetries)
					{
						MelonLogger.Error($"Failed to execute contract after {maxRetries + 1} attempts");
						break;
					}
					await Task.Delay(1000);
				}
			}
		}

		private Task<T> RunOnMainThread<T>(Func<T> action)
		{
			TaskCompletionSource<T> taskCompletionSource = new TaskCompletionSource<T>();
			MelonCoroutines.Start(ExecuteOnMainThread(action, taskCompletionSource));
			return taskCompletionSource.Task;
		}

		private IEnumerator ExecuteOnMainThread<T>(Func<T> action, TaskCompletionSource<T> tcs)
		{
			yield return null;
			try
			{
				T result = action();
				tcs.SetResult(result);
			}
			catch (Exception ex)
			{
				tcs.SetException(ex);
			}
		}
	}
	public class MainHandler : MelonMod
	{
		private MessagingManager _messagingManager;

		private ContractManager _contractManager = ContractManager.Instance;

		private TimeManager _timeManager;

		private float _sliderTextTimer = 0f;

		private bool _showSliderText = false;

		private bool _isMenuOpen = false;

		private int _selectedPeriodIndex = 0;

		private int _selectedProductIndex = 0;

		private readonly EDealWindow[] _dealPeriods;

		private List<string> _offeredProducts;

		public override void OnSceneWasInitialized(int buildIndex, string sceneName)
		{
			if (sceneName == "Main")
			{
				_messagingManager = NetworkSingleton<MessagingManager>.instance;
				_timeManager = NetworkSingleton<TimeManager>.instance;
				MelonLogger.Msg("Mod initialized in Main scene");
			}
		}

		public EDealWindow GetTimePeriod(int time)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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)
			int num = time % 2400;
			if (num >= 600 && num < 1200)
			{
				return (EDealWindow)0;
			}
			if (num >= 1200 && num < 1800)
			{
				return (EDealWindow)1;
			}
			if (num >= 1800 && num < 2400)
			{
				return (EDealWindow)2;
			}
			return (EDealWindow)3;
		}

		private (int start, int end) GetPeriodTimes(EDealWindow period)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected I4, but got Unknown
			return (int)period switch
			{
				0 => (600, 1200), 
				1 => (1200, 1800), 
				2 => (1800, 2400), 
				3 => (0, 600), 
				_ => (0, 600), 
			};
		}

		private string FormatGameTime(int ticks)
		{
			float num = (float)ticks / 100f;
			return (num >= 1f) ? $"{num:F1} hours" : $"{ticks:F0} minutes";
		}

		private string FormatGameTimeForCurrent(int ticks)
		{
			float num = (float)(ticks % 2400) / 100f;
			int num2 = (int)num;
			int num3 = (int)((num - (float)num2) * 100f);
			return $"{num2:D2}:{num3:D2}";
		}

		private string GetSliderDisplayText()
		{
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_timeManager == (Object)null)
			{
				return "Time not available";
			}
			if (_offeredProducts == null || _offeredProducts.Count == 0)
			{
				return "No products available";
			}
			if (_selectedProductIndex < 0 || _selectedProductIndex >= _offeredProducts.Count)
			{
				return "Invalid product selection";
			}
			if (_selectedPeriodIndex < 0 || _selectedPeriodIndex >= _dealPeriods.Length)
			{
				return "Invalid period selection";
			}
			int time = _timeManager.GetDateTime().time;
			int num = time % 2400;
			EDealWindow val = _dealPeriods[_selectedPeriodIndex];
			string text = ((val == GetTimePeriod(time)) ? $"{val} (current)" : ((object)(EDealWindow)(ref val)).ToString());
			(int start, int end) periodTimes = GetPeriodTimes(val);
			int item = periodTimes.start;
			int item2 = periodTimes.end;
			string text2 = _offeredProducts[_selectedProductIndex];
			int totalQuantity = _contractManager.GetTotalQuantity(text2);
			float potentialGain = _contractManager.GetPotentialGain(text2);
			int ticks = ((item2 > num) ? (item2 - num) : (2400 - num + item2));
			int ticks2 = ((item > num) ? (item - num) : (2400 - num + item));
			return "Period: <color=#00FFFF>" + text + "</color>\n" + $"Product: <color=#FFFF00>{text2} [{totalQuantity} units]</color>\n" + $"Potential Gain: <color=#800080>${potentialGain:F2}</color>\n" + $"Extra Price: <color=#00FF00>${_contractManager.OverallPriceModifier:F2}</color>\n" + "Current Time: <color=#FFFFFF>" + FormatGameTimeForCurrent(time) + "</color>\nStarts in: <color=#FFA500>" + FormatGameTime(ticks2) + "</color>\nEnds in: <color=#FF0000>" + FormatGameTime(ticks) + "</color>";
		}

		public override void OnUpdate()
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_0371: Unknown result type (might be due to invalid IL or missing references)
			if (_contractManager.HasProductsChanged())
			{
				_offeredProducts = _contractManager.GetOfferedProductNames();
				if (_offeredProducts.Count == 0)
				{
					_offeredProducts.Add("All");
					_selectedProductIndex = 0;
				}
				else if (_selectedProductIndex >= _offeredProducts.Count)
				{
					_selectedProductIndex = _offeredProducts.Count - 1;
				}
				_contractManager.ResetProductsChanged();
			}
			if (Input.GetKeyDown(KeyBindings.OpenMenuKey))
			{
				_isMenuOpen = !_isMenuOpen;
				_showSliderText = _isMenuOpen;
				if (!_isMenuOpen)
				{
					_sliderTextTimer = 0f;
				}
			}
			if (Input.GetKeyDown(KeyBindings.PreviousPeriodKey))
			{
				_selectedPeriodIndex = (_selectedPeriodIndex - 1 + _dealPeriods.Length) % _dealPeriods.Length;
				if (!_isMenuOpen)
				{
					_showSliderText = true;
					_sliderTextTimer = 2.5f;
				}
			}
			else if (Input.GetKeyDown(KeyBindings.NextPeriodKey))
			{
				_selectedPeriodIndex = (_selectedPeriodIndex + 1) % _dealPeriods.Length;
				if (!_isMenuOpen)
				{
					_showSliderText = true;
					_sliderTextTimer = 2.5f;
				}
			}
			if (_offeredProducts.Count > 1)
			{
				if (Input.GetKeyDown(KeyBindings.PreviousProductKey))
				{
					_selectedProductIndex = (_selectedProductIndex - 1 + _offeredProducts.Count) % _offeredProducts.Count;
					if (!_isMenuOpen)
					{
						_showSliderText = true;
						_sliderTextTimer = 2.5f;
					}
				}
				else if (Input.GetKeyDown(KeyBindings.NextProductKey))
				{
					_selectedProductIndex = (_selectedProductIndex + 1) % _offeredProducts.Count;
					if (!_isMenuOpen)
					{
						_showSliderText = true;
						_sliderTextTimer = 2.5f;
					}
				}
			}
			if (Input.GetKeyDown(KeyBindings.AcceptContractKey))
			{
				string productName = _offeredProducts[_selectedProductIndex];
				_contractManager.ProcessContracts(_dealPeriods[_selectedPeriodIndex], productName);
				if (!_isMenuOpen)
				{
					_showSliderText = true;
					_sliderTextTimer = 2.5f;
				}
			}
			if (Input.GetKeyDown(KeyBindings.IncreasePrice) || Input.GetKeyDown((KeyCode)61))
			{
				_contractManager.OverallPriceModifier += 5f;
				_contractManager.UpdateGainsForModifierChange();
				if (!_isMenuOpen)
				{
					_showSliderText = true;
					_sliderTextTimer = 2.5f;
				}
			}
			if (Input.GetKeyDown(KeyBindings.DecreasePrice))
			{
				_contractManager.OverallPriceModifier -= 5f;
				_contractManager.UpdateGainsForModifierChange();
				if (!_isMenuOpen)
				{
					_showSliderText = true;
					_sliderTextTimer = 2.5f;
				}
			}
			if (Input.GetKeyDown((KeyCode)258))
			{
				int time = _timeManager.GetDateTime().time;
				_timeManager.SetTime(time + 100, false);
			}
			if (Input.GetKeyDown((KeyCode)259))
			{
				try
				{
					global::TestingClass.TestingClass.GenerateRandomQuests(10);
				}
				catch (Exception ex)
				{
					MelonLogger.Error((object)ex);
				}
			}
			if (_showSliderText && !_isMenuOpen)
			{
				_sliderTextTimer -= Time.deltaTime;
				if (_sliderTextTimer <= 0f)
				{
					_showSliderText = false;
				}
			}
		}

		public override void OnGUI()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			if (_showSliderText || _isMenuOpen)
			{
				GUI.color = new Color(0f, 0f, 0f, 0.7f);
				GUI.Box(new Rect((float)(Screen.width / 2 - 160), (float)(Screen.height / 2 - 120), 320f, 240f), "");
				GUI.color = Color.white;
				GUI.skin.label.alignment = (TextAnchor)4;
				GUI.skin.label.fontSize = 22;
				GUI.skin.label.richText = true;
				GUI.Label(new Rect((float)(Screen.width / 2 - 150), (float)(Screen.height / 2 - 110), 300f, 220f), GetSliderDisplayText());
			}
		}

		public MainHandler()
		{
			EDealWindow[] array = new EDealWindow[4];
			RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			_dealPeriods = (EDealWindow[])(object)array;
			_offeredProducts = new List<string> { "All" };
			((MelonMod)this)..ctor();
		}
	}
	public static class DealsTracker
	{
		private static readonly Dictionary<string, ProductDefinition> _productCache = new Dictionary<string, ProductDefinition>();

		public static void AddDealToList(Customer customer)
		{
			ContractInfo offeredContractInfo = customer.offeredContractInfo;
			object obj;
			if (offeredContractInfo == null)
			{
				obj = null;
			}
			else
			{
				ProductList products = offeredContractInfo.Products;
				obj = ((products != null) ? products.entries : null);
			}
			if (obj == null || offeredContractInfo.Products.entries.Count == 0)
			{
				MelonLogger.Warning("AddDealToList failed for " + ((Object)customer).name + ": No valid contract info");
				return;
			}
			Entry val = offeredContractInfo.Products.entries[0];
			string productId = val.ProductID;
			string customerName = ((Object)customer).name;
			if (ContractManager.Instance.GetPendingContracts().Any((PendingContract c) => c.CustomerName == customerName && ((ItemDefinition)c.Product).ID == productId))
			{
				MelonLogger.Msg("Contract already exists for " + customerName + ", ProductID=" + productId);
				return;
			}
			if (!_productCache.TryGetValue(productId, out var value))
			{
				Enumerator<ProductDefinition> enumerator = customer.OrderableProducts.GetEnumerator();
				while (enumerator.MoveNext())
				{
					ProductDefinition current = enumerator.Current;
					if (((ItemDefinition)current).ID == productId)
					{
						value = current;
						_productCache[productId] = value;
						break;
					}
				}
				if ((Object)(object)value == (Object)null)
				{
					MelonLogger.Warning("No matching product found for ProductID=" + productId + " in " + customerName + "'s OrderableProducts");
					return;
				}
			}
			MelonLogger.Msg($"Adding contract: Product={((ItemDefinition)value).Name}, Quantity={val.Quantity}, Payment={offeredContractInfo.Payment}, Customer={customerName}");
			ContractManager.Instance.AddContract(value, val.Quantity, offeredContractInfo.Payment, customer);
		}
	}
	[HarmonyPatch(typeof(Customer), "OfferContract")]
	public static class CustomerPatch
	{
		private static void Postfix(Customer __instance)
		{
			MelonLogger.Msg("Customer.OfferContract patch triggered");
			DealsTracker.AddDealToList(__instance);
		}
	}
	[HarmonyPatch(typeof(Customer), "RpcReader___Observers_SetOfferedContract_4277245194")]
	public static class CustomerClientPatch
	{
		private static void Postfix(Customer __instance)
		{
			MelonLogger.Msg("Customer.RpcReader_SetOfferedContract patch triggered");
			DealsTracker.AddDealToList(__instance);
		}
	}
	[HarmonyPatch(typeof(Customer), "Load")]
	public static class CustomerStartPatch
	{
		private static void Postfix(Customer __instance)
		{
			try
			{
				if ((Object)(object)__instance != (Object)null && __instance.offeredContractInfo != null)
				{
					MelonLogger.Msg("CustomerStartPatch: Found active contract for " + ((Object)__instance).name);
					DealsTracker.AddDealToList(__instance);
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("Error in CustomerStartPatch for " + (((Object)(object)__instance != (Object)null) ? ((Object)__instance).name : "unknown") + ": " + ex.Message);
			}
		}
	}
}