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;
}
}