Decompiled source of OrderDeskFilter v1.6.2

plugins/OrderDeskFilter.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("OrderDeskFilter")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("OrderDeskFilter")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("47d1e841-b7e4-461d-9115-c204dbedcb41")]
[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")]
namespace OrderDeskFilterMod;

[BepInPlugin("travyryans.aleandtale.orderdeskfilter", "Order desk filter", "1.6.2")]
public class OrderDeskFilterPlugin : BaseUnityPlugin
{
	internal enum FilterMode
	{
		All,
		Drinks,
		Food
	}

	private class PopupOverlay
	{
		private Type _tmpType;

		private object _tmpComp;

		private GameObject _go;

		private bool _triedCreate;

		public void SetVisible(bool visible)
		{
			EnsureCreated();
			if ((Object)(object)_go != (Object)null)
			{
				_go.SetActive(visible);
			}
		}

		public void SetText(string text)
		{
			EnsureCreated();
			if (_tmpComp != null && !(_tmpType == null))
			{
				PropertyInfo property = _tmpType.GetProperty("text", BindingFlags.Instance | BindingFlags.Public);
				if (property != null)
				{
					property.SetValue(_tmpComp, text, null);
				}
			}
		}

		private void EnsureCreated()
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_go != (Object)null || _triedCreate)
			{
				return;
			}
			_triedCreate = true;
			_tmpType = AccessTools.TypeByName("TMPro.TextMeshProUGUI");
			if (_tmpType == null)
			{
				return;
			}
			Canvas val = Object.FindObjectOfType<Canvas>();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			_go = new GameObject("OrderDeskFilterPopup");
			_go.transform.SetParent(((Component)val).transform, false);
			_tmpComp = _go.AddComponent(_tmpType);
			RectTransform component = _go.GetComponent<RectTransform>();
			if ((Object)(object)component != (Object)null)
			{
				component.anchorMin = new Vector2(0.5f, 0.15f);
				component.anchorMax = new Vector2(0.5f, 0.15f);
				component.pivot = new Vector2(0.5f, 0.5f);
				component.anchoredPosition = Vector2.zero;
				component.sizeDelta = new Vector2(800f, 120f);
			}
			PropertyInfo property = _tmpType.GetProperty("fontSize", BindingFlags.Instance | BindingFlags.Public);
			if (property != null)
			{
				property.SetValue(_tmpComp, 22f, null);
			}
			PropertyInfo property2 = _tmpType.GetProperty("alignment", BindingFlags.Instance | BindingFlags.Public);
			if (property2 != null)
			{
				try
				{
					object value = Enum.Parse(property2.PropertyType, "Center");
					property2.SetValue(_tmpComp, value, null);
				}
				catch
				{
				}
			}
			_go.SetActive(false);
		}
	}

	public const string GUID = "travyryans.aleandtale.orderdeskfilter";

	public const string NAME = "Order desk filter";

	public const string VERSION = "1.6.2";

	private static ConfigEntry<KeyCode> ToggleKey;

	private static ConfigEntry<float> RayDistance;

	private static readonly Dictionary<int, FilterMode> DeskModes = new Dictionary<int, FilterMode>();

	private Camera _cam;

	private bool _aimingDesk;

	private object _aimedDesk;

	private int _aimedDeskKey;

	private PopupOverlay _overlay;

	private void Awake()
	{
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		ToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "ToggleKey", (KeyCode)101, "Key to cycle order desk filter");
		RayDistance = ((BaseUnityPlugin)this).Config.Bind<float>("General", "RayDistance", 3f, "Raycast distance for detecting order desk");
		_overlay = new PopupOverlay();
		new Harmony("travyryans.aleandtale.orderdeskfilter").PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Order desk filter loaded.");
	}

	private void Update()
	{
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_cam == (Object)null)
		{
			_cam = Camera.main;
		}
		_aimingDesk = false;
		_aimedDesk = null;
		_aimedDeskKey = 0;
		object desk = null;
		if ((Object)(object)_cam != (Object)null && TryGetAimedDesk(_cam, out desk))
		{
			_aimingDesk = true;
			_aimedDesk = desk;
			_aimedDeskKey = GetDeskKey(desk);
			FilterMode deskMode = GetDeskMode(_aimedDeskKey);
			_overlay.SetVisible(visible: true);
			_overlay.SetText("Press \"E\" to change filter\nCurrent filter: " + FilterLabel(deskMode));
			if (Input.GetKeyDown(ToggleKey.Value))
			{
				CycleDeskFilter(_aimedDeskKey);
				FilterMode deskMode2 = GetDeskMode(_aimedDeskKey);
				ApplyFilter(desk, deskMode2);
				_overlay.SetText("Press \"E\" to change filter\nCurrent filter: " + FilterLabel(deskMode2));
			}
		}
		else
		{
			_overlay.SetVisible(visible: false);
		}
	}

	private static FilterMode GetDeskMode(int deskKey)
	{
		if (!DeskModes.TryGetValue(deskKey, out var value))
		{
			return FilterMode.All;
		}
		return value;
	}

	private static void SetDeskMode(int deskKey, FilterMode mode)
	{
		DeskModes[deskKey] = mode;
	}

	private static void CycleDeskFilter(int deskKey)
	{
		FilterMode deskMode = GetDeskMode(deskKey);
		FilterMode mode = (FilterMode)((int)(deskMode + 1) % 3);
		SetDeskMode(deskKey, mode);
	}

	private static string FilterLabel(FilterMode mode)
	{
		return mode switch
		{
			FilterMode.Drinks => "Show Drinks Only", 
			FilterMode.Food => "Show Food Only", 
			_ => "Show All", 
		};
	}

	private static int GetDeskKey(object desk)
	{
		PropertyInfo property = desk.GetType().GetProperty("gameObject", BindingFlags.Instance | BindingFlags.Public);
		if (property == null)
		{
			return desk.GetHashCode();
		}
		object? value = property.GetValue(desk, null);
		GameObject val = (GameObject)((value is GameObject) ? value : null);
		if ((Object)(object)val == (Object)null)
		{
			return desk.GetHashCode();
		}
		return ((Object)val).GetInstanceID();
	}

	private static bool TryGetAimedDesk(Camera cam, out object desk)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		desk = null;
		Ray val = default(Ray);
		((Ray)(ref val))..ctor(((Component)cam).transform.position, ((Component)cam).transform.forward);
		RaycastHit val2 = default(RaycastHit);
		if (!Physics.Raycast(val, ref val2, RayDistance.Value, -1, (QueryTriggerInteraction)1))
		{
			return false;
		}
		Type type = AccessTools.TypeByName("OrderStickersDesk");
		if (type == null)
		{
			return false;
		}
		MethodInfo method = typeof(Component).GetMethod("GetComponentInParent", new Type[1] { typeof(Type) });
		if (method == null)
		{
			return false;
		}
		desk = method.Invoke(((RaycastHit)(ref val2)).collider, new object[1] { type });
		return desk != null;
	}

	private static void ApplyFilter(object desk, FilterMode mode)
	{
		FieldInfo fieldInfo = AccessTools.Field(desk.GetType(), "orderStickers");
		if (fieldInfo == null || !(fieldInfo.GetValue(desk) is IList list))
		{
			return;
		}
		for (int i = 0; i < list.Count; i++)
		{
			object obj = list[i];
			if (obj == null)
			{
				continue;
			}
			bool active = PassesFilter(obj, mode);
			PropertyInfo property = obj.GetType().GetProperty("gameObject", BindingFlags.Instance | BindingFlags.Public);
			if (!(property == null))
			{
				object? value = property.GetValue(obj, null);
				GameObject val = (GameObject)((value is GameObject) ? value : null);
				if ((Object)(object)val != (Object)null)
				{
					val.SetActive(active);
				}
			}
		}
	}

	private static bool PassesFilter(object sticker, FilterMode mode)
	{
		if (mode == FilterMode.All)
		{
			return true;
		}
		FieldInfo field = sticker.GetType().GetField("itemDataId", BindingFlags.Instance | BindingFlags.Public);
		if (field == null)
		{
			return true;
		}
		ushort itemId = (ushort)field.GetValue(sticker);
		if (!TryResolveItemData(itemId, out var itemData))
		{
			return true;
		}
		FieldInfo field2 = itemData.GetType().GetField("type", BindingFlags.Instance | BindingFlags.Public);
		if (field2 == null)
		{
			return true;
		}
		string text = field2.GetValue(itemData).ToString();
		bool flag = text == "Drink";
		bool flag2 = text == "FoodSpoon" || text == "FoodFork" || text == "Recipe";
		return mode switch
		{
			FilterMode.Drinks => flag, 
			FilterMode.Food => flag2, 
			_ => true, 
		};
	}

	private static bool TryResolveItemData(ushort itemId, out object itemData)
	{
		itemData = null;
		Type type = AccessTools.TypeByName("ItemManager");
		if (type == null)
		{
			return false;
		}
		FieldInfo field = type.GetField("Instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
		object obj = ((field != null) ? field.GetValue(null) : null);
		if (obj == null)
		{
			return false;
		}
		MethodInfo methodInfo = null;
		MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		foreach (MethodInfo methodInfo2 in methods)
		{
			if (!(methodInfo2.Name != "GetItemData"))
			{
				ParameterInfo[] parameters = methodInfo2.GetParameters();
				if (parameters.Length == 2 && !(parameters[0].ParameterType != typeof(uint)) && parameters[1].IsOut)
				{
					methodInfo = methodInfo2;
					break;
				}
			}
		}
		if (methodInfo == null)
		{
			return false;
		}
		object[] array = new object[2]
		{
			(uint)itemId,
			null
		};
		bool flag = (bool)methodInfo.Invoke(obj, array);
		itemData = array[1];
		return flag && itemData != null;
	}

	internal static FilterMode GetModeForDeskInstance(object desk)
	{
		int deskKey = GetDeskKey(desk);
		return GetDeskMode(deskKey);
	}
}
[HarmonyPatch]
public static class Patch_OrderStickersDesk_OnOrderAdded
{
	private static MethodBase TargetMethod()
	{
		Type type = AccessTools.TypeByName("OrderStickersDesk");
		if (type == null)
		{
			return null;
		}
		return AccessTools.Method(type, "OnOrderAdded", (Type[])null, (Type[])null);
	}

	private static void Postfix(object __instance)
	{
		if (__instance == null)
		{
			return;
		}
		OrderDeskFilterPlugin.FilterMode modeForDeskInstance = OrderDeskFilterPlugin.GetModeForDeskInstance(__instance);
		FieldInfo fieldInfo = AccessTools.Field(__instance.GetType(), "orderStickers");
		if (fieldInfo == null || !(fieldInfo.GetValue(__instance) is IList list) || list.Count == 0)
		{
			return;
		}
		object obj = list[list.Count - 1];
		if (obj == null)
		{
			return;
		}
		bool active = true;
		if (modeForDeskInstance.ToString() != "All")
		{
			FieldInfo field = obj.GetType().GetField("itemDataId", BindingFlags.Instance | BindingFlags.Public);
			if (field != null)
			{
				ushort itemId = (ushort)field.GetValue(obj);
				if (TryResolveItemData_Static(itemId, out var itemData))
				{
					FieldInfo field2 = itemData.GetType().GetField("type", BindingFlags.Instance | BindingFlags.Public);
					if (field2 != null)
					{
						string text = field2.GetValue(itemData).ToString();
						bool flag = text == "Drink";
						bool flag2 = text == "FoodSpoon" || text == "FoodFork" || text == "Recipe";
						if (modeForDeskInstance.ToString() == "Drinks")
						{
							active = flag;
						}
						else if (modeForDeskInstance.ToString() == "Food")
						{
							active = flag2;
						}
					}
				}
			}
		}
		PropertyInfo property = obj.GetType().GetProperty("gameObject", BindingFlags.Instance | BindingFlags.Public);
		if (!(property == null))
		{
			object? value = property.GetValue(obj, null);
			GameObject val = (GameObject)((value is GameObject) ? value : null);
			if ((Object)(object)val != (Object)null)
			{
				val.SetActive(active);
			}
		}
	}

	private static bool TryResolveItemData_Static(ushort itemId, out object itemData)
	{
		itemData = null;
		Type type = AccessTools.TypeByName("ItemManager");
		if (type == null)
		{
			return false;
		}
		FieldInfo field = type.GetField("Instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
		object obj = ((field != null) ? field.GetValue(null) : null);
		if (obj == null)
		{
			return false;
		}
		MethodInfo methodInfo = null;
		MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		foreach (MethodInfo methodInfo2 in methods)
		{
			if (!(methodInfo2.Name != "GetItemData"))
			{
				ParameterInfo[] parameters = methodInfo2.GetParameters();
				if (parameters.Length == 2 && !(parameters[0].ParameterType != typeof(uint)) && parameters[1].IsOut)
				{
					methodInfo = methodInfo2;
					break;
				}
			}
		}
		if (methodInfo == null)
		{
			return false;
		}
		object[] array = new object[2]
		{
			(uint)itemId,
			null
		};
		bool flag = (bool)methodInfo.Invoke(obj, array);
		itemData = array[1];
		return flag && itemData != null;
	}
}