Decompiled source of ExpiryItemManager v1.0.2

BepInEx/plugins/OldMarket.ExpiryItemManager.dll

Decompiled a month ago
using System;
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 BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Localization;
using UnityEngine.Localization.Settings;
using UnityEngine.Localization.Tables;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("OldMarket.RottenUtil")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("OldMarket.RottenUtil")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("d1173fe2-e39d-489d-b10d-f2b8bebd55b6")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
[HarmonyPatch(typeof(UIManager), "OpenJournal")]
public static class UIManager_OpenJournal_RottenStockPatch
{
	private static void Postfix(UIManager __instance)
	{
		try
		{
			IEnumerable<Item> source = from x in Object.FindObjectsOfType<Item>()
				where (Object)(object)x != (Object)null && x.itemSO is ProductSO
				select x;
			var enumerable = from <>h__TransparentIdentifier0 in source.Select(delegate(Item item)
				{
					ItemSO itemSO3 = item.itemSO;
					return new
					{
						item = item,
						product = (ProductSO)(object)((itemSO3 is ProductSO) ? itemSO3 : null)
					};
				})
				group item by item.itemSO.id into g
				let itemSO = GameManager.Instance.GetItemById(g.Key)
				orderby itemSO.GetLocalizedName()
				select new
				{
					ItemId = g.Key,
					StackCount = g.Count(delegate(Item it)
					{
						ItemSO itemSO2 = it.itemSO;
						ProductSO val4 = (ProductSO)(object)((itemSO2 is ProductSO) ? itemSO2 : null);
						return (Object)(object)val4 == (Object)null || val4.maxDays <= 0 || !RottenUtil.IsExpired(val4, it.dayCounter.Value);
					}),
					TotalAmount = g.Sum(delegate(Item it)
					{
						ItemSO itemSO = it.itemSO;
						ProductSO val3 = (ProductSO)(object)((itemSO is ProductSO) ? itemSO : null);
						return (!((Object)(object)val3 != (Object)null) || val3.maxDays <= 0 || !RottenUtil.IsExpired(val3, it.dayCounter.Value)) ? it.amount.Value : 0;
					})
				};
			Transform listInventory = __instance.listInventory;
			for (int num = listInventory.childCount - 1; num >= 0; num--)
			{
				Object.Destroy((Object)(object)((Component)listInventory.GetChild(num)).gameObject);
			}
			foreach (var item in enumerable)
			{
				if (item.StackCount <= 0 && item.TotalAmount <= 0)
				{
					continue;
				}
				ItemSO itemById = GameManager.Instance.GetItemById(item.ItemId);
				string localizedName = itemById.GetLocalizedName();
				GameObject val = Object.Instantiate<GameObject>(__instance.prefabInventoryTile, listInventory);
				MonoBehaviour[] components = val.GetComponents<MonoBehaviour>();
				MonoBehaviour[] array = components;
				foreach (MonoBehaviour val2 in array)
				{
					Type type = ((object)val2).GetType();
					if (type.Name.Contains("InventoryTile"))
					{
						MethodInfo method = type.GetMethod("SetData", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						if (!(method == null))
						{
							method.Invoke(val2, new object[3] { localizedName, item.StackCount, item.TotalAmount });
							break;
						}
					}
				}
			}
		}
		catch (Exception arg)
		{
			ManualLogSource log = RottenItemManager.Log;
			if (log != null)
			{
				log.LogError((object)$"[JournalStock] OpenJournal postfix failed: {arg}");
			}
		}
	}
}
[HarmonyPatch(typeof(UIManager), "Update")]
public static class UIManager_Update_RottenOutlineHotkey_Patch
{
	private static void Postfix()
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (Keyboard.current != null)
			{
				Key value = RottenItemManager.OutlineToggleKey.Value;
				KeyControl val = Keyboard.current[value];
				if (val != null && ((ButtonControl)val).wasPressedThisFrame)
				{
					RottenOutlineController.ToggleOutlineForExpiringItems();
				}
			}
		}
		catch (Exception arg)
		{
			ManualLogSource log = RottenItemManager.Log;
			if (log != null)
			{
				log.LogError((object)$"[RottenOutline] UIManager.Update hotkey patch failed: {arg}");
			}
		}
	}
}
public static class RottenOutlineController
{
	private static bool _enabled = false;

	private static readonly List<Outline> _createdOutlines = new List<Outline>();

	public static bool IsEnabled => _enabled;

	public static int LastExpiringCount { get; private set; }

	public static int LastRottenCount { get; private set; }

	public static void ToggleOutlineForExpiringItems()
	{
		_enabled = !_enabled;
		if (_enabled)
		{
			EnableOutline();
		}
		else
		{
			DisableOutline();
		}
	}

	private static void EnableOutline()
	{
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			_createdOutlines.RemoveAll((Outline o) => (Object)(object)o == (Object)null);
			List<Item> worldItemsExpiringTomorrow = RottenScan.GetWorldItemsExpiringTomorrow();
			List<Item> worldRottenItems = RottenScan.GetWorldRottenItems();
			LastExpiringCount = worldItemsExpiringTomorrow.Count;
			LastRottenCount = worldRottenItems.Count;
			foreach (Item item in worldItemsExpiringTomorrow)
			{
				AddOutlineIfPossible(item, Color.yellow);
			}
			foreach (Item item2 in worldRottenItems)
			{
				AddOutlineIfPossible(item2, Color.red);
			}
		}
		catch (Exception arg)
		{
			ManualLogSource log = RottenItemManager.Log;
			if (log != null)
			{
				log.LogError((object)$"[RottenOutline] EnableOutline failed: {arg}");
			}
		}
	}

	private static void AddOutlineIfPossible(Item item, Color color)
	{
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)item == (Object)null || (Object)(object)((Component)item).GetComponent<Outline>() != (Object)null)
		{
			return;
		}
		try
		{
			Outline val = ((Component)item).gameObject.AddComponent<Outline>();
			val.OutlineMode = (Mode)0;
			val.OutlineWidth = 4f;
			val.OutlineColor = color;
			_createdOutlines.Add(val);
		}
		catch (Exception arg)
		{
			ManualLogSource log = RottenItemManager.Log;
			if (log != null)
			{
				log.LogError((object)$"[RottenOutline] Failed to add outline to {((Object)item).name}: {arg}");
			}
		}
	}

	private static void DisableOutline()
	{
		try
		{
			foreach (Outline createdOutline in _createdOutlines)
			{
				if ((Object)(object)createdOutline == (Object)null)
				{
					continue;
				}
				try
				{
					Object.Destroy((Object)(object)createdOutline);
				}
				catch (Exception arg)
				{
					ManualLogSource log = RottenItemManager.Log;
					if (log != null)
					{
						log.LogError((object)$"[RottenOutline] Failed to destroy outline: {arg}");
					}
				}
			}
			_createdOutlines.Clear();
			LastExpiringCount = 0;
			LastRottenCount = 0;
		}
		catch (Exception arg2)
		{
			ManualLogSource log2 = RottenItemManager.Log;
			if (log2 != null)
			{
				log2.LogError((object)$"[RottenOutline] DisableOutline failed: {arg2}");
			}
		}
	}
}
[HarmonyPatch(typeof(ItemSlot), "UpdateSlot")]
public static class ItemSlot_UpdateSlot_RottenPatch
{
	private static readonly Dictionary<TextMeshProUGUI, Color> DefaultTmpColor = new Dictionary<TextMeshProUGUI, Color>();

	private static readonly Dictionary<Text, Color> DefaultTextColor = new Dictionary<Text, Color>();

	private static readonly Dictionary<Image, Color> DefaultImageColor = new Dictionary<Image, Color>();

	private static void Postfix(ItemSlot __instance, InventorySlot inventorySlot)
	{
		//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_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_0129: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_01be: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dc: 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_01fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0210: Unknown result type (might be due to invalid IL or missing references)
		//IL_0217: Unknown result type (might be due to invalid IL or missing references)
		//IL_018b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0284: Unknown result type (might be due to invalid IL or missing references)
		//IL_0232: Unknown result type (might be due to invalid IL or missing references)
		//IL_0237: Unknown result type (might be due to invalid IL or missing references)
		//IL_0249: Unknown result type (might be due to invalid IL or missing references)
		//IL_0250: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			TextMeshProUGUI val = null;
			TextMeshProUGUI[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<TextMeshProUGUI>(true);
			foreach (TextMeshProUGUI val2 in componentsInChildren)
			{
				if (int.TryParse(((TMP_Text)val2).text, out var _))
				{
					val = val2;
					break;
				}
			}
			Text val3 = null;
			if ((Object)(object)val == (Object)null)
			{
				Text[] componentsInChildren2 = ((Component)__instance).GetComponentsInChildren<Text>(true);
				foreach (Text val4 in componentsInChildren2)
				{
					if (int.TryParse(val4.text, out var _))
					{
						val3 = val4;
						break;
					}
				}
			}
			Image componentInChildren = ((Component)__instance).GetComponentInChildren<Image>();
			if ((Object)(object)val != (Object)null && !DefaultTmpColor.ContainsKey(val))
			{
				DefaultTmpColor[val] = ((Graphic)val).color;
			}
			if ((Object)(object)val3 != (Object)null && !DefaultTextColor.ContainsKey(val3))
			{
				DefaultTextColor[val3] = ((Graphic)val3).color;
			}
			if ((Object)(object)componentInChildren != (Object)null && !DefaultImageColor.ContainsKey(componentInChildren))
			{
				DefaultImageColor[componentInChildren] = ((Graphic)componentInChildren).color;
			}
			bool flag = false;
			if (inventorySlot.itemId != -1 && inventorySlot.amount > 0)
			{
				ItemSO itemById = GameManager.Instance.GetItemById(inventorySlot.itemId);
				ProductSO val5 = (ProductSO)(object)((itemById is ProductSO) ? itemById : null);
				if ((Object)(object)val5 != (Object)null && val5.maxDays > 0 && RottenUtil.IsExpired(val5, inventorySlot.dayCounter))
				{
					flag = true;
				}
			}
			if (flag)
			{
				if ((Object)(object)val != (Object)null)
				{
					Color color = ((Graphic)val).color;
					((Graphic)val).color = new Color(0.7f, 0.7f, 0.7f, color.a);
				}
				else if ((Object)(object)val3 != (Object)null)
				{
					Color color2 = ((Graphic)val3).color;
					((Graphic)val3).color = new Color(0.7f, 0.7f, 0.7f, color2.a);
				}
				if ((Object)(object)componentInChildren != (Object)null)
				{
					Color color3 = ((Graphic)componentInChildren).color;
					((Graphic)componentInChildren).color = new Color(0.7f, 0.7f, 0.7f, color3.a);
				}
			}
			else
			{
				if ((Object)(object)val != (Object)null && DefaultTmpColor.TryGetValue(val, out var value))
				{
					((Graphic)val).color = value;
				}
				if ((Object)(object)val3 != (Object)null && DefaultTextColor.TryGetValue(val3, out var value2))
				{
					((Graphic)val3).color = value2;
				}
				if ((Object)(object)componentInChildren != (Object)null && DefaultImageColor.TryGetValue(componentInChildren, out var value3))
				{
					((Graphic)componentInChildren).color = value3;
				}
			}
		}
		catch (Exception arg)
		{
			ManualLogSource log = RottenItemManager.Log;
			if (log != null)
			{
				log.LogError((object)$"ItemSlot_UpdateSlot_RottenPatch failed: {arg}");
			}
		}
	}
}
[HarmonyPatch(typeof(UIManager), "OpenSleepWarningPanel")]
public static class UIManager_OpenSleepWarningPanel_RottenPatch
{
	private static void Postfix(UIManager __instance)
	{
		try
		{
			if (RottenScan.HasItemsExpiringTomorrow())
			{
				TextMeshProUGUI componentInChildren = __instance.panelSleepWarning.GetComponentInChildren<TextMeshProUGUI>(true);
				if (!((Object)(object)componentInChildren == (Object)null))
				{
					string text = BuildLocalizedWarningMessage();
					((TMP_Text)componentInChildren).text = ((TMP_Text)componentInChildren).text + "\n" + text;
				}
			}
		}
		catch (Exception arg)
		{
			ManualLogSource log = RottenItemManager.Log;
			if (log != null)
			{
				log.LogError((object)$"[SleepWarning] Postfix failed: {arg}");
			}
		}
	}

	private static string BuildLocalizedWarningMessage()
	{
		//IL_0018: 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_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		string text = "DAYS LEFT";
		string text2 = "en";
		try
		{
			text = LocalizationSettings.StringDatabase.GetLocalizedString(TableReference.op_Implicit("Translations"), TableEntryReference.op_Implicit("days_left"), (Locale)null, (FallbackBehavior)0, Array.Empty<object>());
			Locale selectedLocale = LocalizationSettings.SelectedLocale;
			if ((Object)(object)selectedLocale != (Object)null)
			{
				LocaleIdentifier identifier = selectedLocale.Identifier;
				text2 = ((LocaleIdentifier)(ref identifier)).Code;
			}
		}
		catch (Exception arg)
		{
			ManualLogSource log = RottenItemManager.Log;
			if (log != null)
			{
				log.LogError((object)$"[SleepWarning] Localization failed: {arg}");
			}
			text = "DAYS LEFT";
			text2 = "en";
		}
		Key val = (Key)((RottenItemManager.OutlineToggleKey == null) ? 101 : ((int)RottenItemManager.OutlineToggleKey.Value));
		string text3 = ((object)(Key)(ref val)).ToString();
		string text4 = ((!text2.StartsWith("ja")) ? ("There are items with 1 " + text + " (" + text3 + " to highlight)") : ("1" + text + "の商品があります(" + text3 + "で表示)"));
		return "<color=#FF4444>" + text4 + "</color>";
	}
}
public static class RottenScan
{
	public static List<Item> GetWorldItemsExpiringTomorrow()
	{
		List<Item> list = new List<Item>();
		try
		{
			Item[] array = Object.FindObjectsOfType<Item>();
			Item[] array2 = array;
			foreach (Item val in array2)
			{
				if (!((Object)(object)val == (Object)null) && val.amount.Value > 0 && !val.IsInFreezer())
				{
					ItemSO itemSO = val.itemSO;
					ProductSO val2 = (ProductSO)(object)((itemSO is ProductSO) ? itemSO : null);
					if (!((Object)(object)val2 == (Object)null) && val2.maxDays > 0 && !RottenUtil.IsExpired(val2, val.dayCounter.Value) && RottenUtil.IsExpireTomorrow(val2, val.dayCounter.Value))
					{
						list.Add(val);
					}
				}
			}
		}
		catch (Exception arg)
		{
			ManualLogSource log = RottenItemManager.Log;
			if (log != null)
			{
				log.LogError((object)$"[RottenScan] GetWorldItemsExpiringTomorrow failed: {arg}");
			}
		}
		return list;
	}

	public static List<Item> GetWorldRottenItems()
	{
		List<Item> list = new List<Item>();
		try
		{
			Item[] array = Object.FindObjectsOfType<Item>();
			Item[] array2 = array;
			foreach (Item val in array2)
			{
				if (!((Object)(object)val == (Object)null) && val.amount.Value > 0)
				{
					ItemSO itemSO = val.itemSO;
					ProductSO val2 = (ProductSO)(object)((itemSO is ProductSO) ? itemSO : null);
					if (!((Object)(object)val2 == (Object)null) && val2.maxDays > 0 && RottenUtil.IsExpired(val2, val.dayCounter.Value))
					{
						list.Add(val);
					}
				}
			}
		}
		catch (Exception arg)
		{
			ManualLogSource log = RottenItemManager.Log;
			if (log != null)
			{
				log.LogError((object)$"[RottenScan] GetWorldRottenItems failed: {arg}");
			}
		}
		return list;
	}

	public static bool HasItemsExpiringTomorrow()
	{
		List<Item> worldItemsExpiringTomorrow = GetWorldItemsExpiringTomorrow();
		return worldItemsExpiringTomorrow != null && worldItemsExpiringTomorrow.Count > 0;
	}
}
[HarmonyPatch(typeof(PlayerInventory), "GetItemCount")]
public static class PlayerInventory_GetItemCount_RottenPatch
{
	private static void Postfix(PlayerInventory __instance, ItemSO itemSO, ref int __result)
	{
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			ProductSO val = (ProductSO)(object)((itemSO is ProductSO) ? itemSO : null);
			if ((Object)(object)val == (Object)null || val.maxDays <= 0)
			{
				return;
			}
			int num = 0;
			NetworkList<InventorySlot> slots = __instance.slots;
			for (int i = 0; i < slots.Count; i++)
			{
				InventorySlot val2 = slots[i];
				if (val2.itemId == itemSO.id && val2.amount > 0)
				{
					ItemSO itemById = GameManager.Instance.GetItemById(val2.itemId);
					ProductSO val3 = (ProductSO)(object)((itemById is ProductSO) ? itemById : null);
					if (!((Object)(object)val3 == (Object)null) && !RottenUtil.IsExpired(val3, val2.dayCounter))
					{
						num += val2.amount;
					}
				}
			}
			__result = num;
		}
		catch (Exception arg)
		{
			ManualLogSource log = RottenItemManager.Log;
			if (log != null)
			{
				log.LogError((object)$"PlayerInventory_GetItemCount_RottenPatch failed: {arg}");
			}
		}
	}
}
[BepInPlugin("com.example.oldmarket.expiryitemmanager", "Old Market Expiry Item Manager", "1.0.2")]
public class RottenItemManager : BaseUnityPlugin
{
	public const string PluginGuid = "com.example.oldmarket.expiryitemmanager";

	public const string PluginName = "Old Market Expiry Item Manager";

	public const string PluginVersion = "1.0.2";

	internal static ManualLogSource Log;

	internal static ConfigEntry<Key> OutlineToggleKey;

	internal static TextMeshProUGUI OutlineStatusText;

	private void Awake()
	{
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		OutlineToggleKey = ((BaseUnityPlugin)this).Config.Bind<Key>("Hotkeys", "OutlineToggleKey", (Key)101, "Key to toggle outline for expiring/rotten items.");
		Harmony val = new Harmony("com.example.oldmarket.expiryitemmanager");
		val.PatchAll();
	}
}
[HarmonyPatch(typeof(PlayerInteraction))]
internal static class RottenOutlineUI_Patches
{
	private static bool _lastEnabled;

	private static int _lastExpiring;

	private static int _lastRotten;

	[HarmonyPostfix]
	[HarmonyPatch("Start")]
	private static void PlayerInteraction_Start_Postfix(PlayerInteraction __instance)
	{
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Expected O, but got Unknown
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (!((Object)(object)RottenItemManager.OutlineStatusText != (Object)null) && !((Object)(object)__instance.interactionUI == (Object)null))
			{
				Canvas componentInParent = __instance.interactionUI.GetComponentInParent<Canvas>();
				if (!((Object)(object)componentInParent == (Object)null))
				{
					GameObject val = new GameObject("OutlineStatusText");
					val.transform.SetParent(((Component)componentInParent).transform, false);
					RectTransform val2 = val.AddComponent<RectTransform>();
					val2.anchorMin = new Vector2(0f, 1f);
					val2.anchorMax = new Vector2(0f, 1f);
					val2.pivot = new Vector2(0f, 1f);
					val2.anchoredPosition = new Vector2(10f, -10f);
					val2.sizeDelta = new Vector2(800f, 24f);
					TextMeshProUGUI val3 = val.AddComponent<TextMeshProUGUI>();
					((TMP_Text)val3).fontSize = 18f;
					((TMP_Text)val3).alignment = (TextAlignmentOptions)257;
					((Graphic)val3).color = Color.white;
					((TMP_Text)val3).enableWordWrapping = false;
					((TMP_Text)val3).text = string.Empty;
					RottenItemManager.OutlineStatusText = val3;
					_lastEnabled = false;
					_lastExpiring = 0;
					_lastRotten = 0;
				}
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log = RottenItemManager.Log;
			if (log != null)
			{
				log.LogError((object)("[ExpiryItemManager] Failed to create OutlineStatusText: " + ex));
			}
		}
	}

	[HarmonyPostfix]
	[HarmonyPatch("Update")]
	private static void PlayerInteraction_Update_Postfix(PlayerInteraction __instance)
	{
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		TextMeshProUGUI outlineStatusText = RottenItemManager.OutlineStatusText;
		if ((Object)(object)outlineStatusText == (Object)null)
		{
			return;
		}
		bool isEnabled;
		int lastExpiringCount;
		int lastRottenCount;
		try
		{
			isEnabled = RottenOutlineController.IsEnabled;
			lastExpiringCount = RottenOutlineController.LastExpiringCount;
			lastRottenCount = RottenOutlineController.LastRottenCount;
		}
		catch (Exception ex)
		{
			ManualLogSource log = RottenItemManager.Log;
			if (log != null)
			{
				log.LogError((object)("[ExpiryItemManager] Failed to read RottenOutlineController: " + ex));
			}
			if (((Component)outlineStatusText).gameObject.activeSelf)
			{
				((Component)outlineStatusText).gameObject.SetActive(false);
			}
			return;
		}
		if (!isEnabled)
		{
			if (((Component)outlineStatusText).gameObject.activeSelf)
			{
				((Component)outlineStatusText).gameObject.SetActive(false);
			}
			_lastEnabled = false;
			_lastExpiring = lastExpiringCount;
			_lastRotten = lastRottenCount;
		}
		else if (_lastEnabled != isEnabled || _lastExpiring != lastExpiringCount || _lastRotten != lastRottenCount)
		{
			if (!((Component)outlineStatusText).gameObject.activeSelf)
			{
				((Component)outlineStatusText).gameObject.SetActive(true);
			}
			Key val = (Key)((RottenItemManager.OutlineToggleKey == null) ? 101 : ((int)RottenItemManager.OutlineToggleKey.Value));
			string arg = ((object)(Key)(ref val)).ToString();
			((TMP_Text)outlineStatusText).text = $"Outline({arg}): 1-day={lastExpiringCount}, rotten={lastRottenCount}";
			_lastEnabled = isEnabled;
			_lastExpiring = lastExpiringCount;
			_lastRotten = lastRottenCount;
		}
	}
}
public static class RottenUtil
{
	public static bool IsPerishable(ProductSO product)
	{
		return (Object)(object)product != (Object)null && product.maxDays > 0;
	}

	public static bool IsExpired(ProductSO product, int dayCounter)
	{
		return IsPerishable(product) && dayCounter >= product.maxDays;
	}

	public static bool IsExpireTomorrow(ProductSO product, int dayCounter)
	{
		if (!IsPerishable(product))
		{
			return false;
		}
		int num = product.maxDays - dayCounter;
		return num == 1;
	}
}