using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using TMPro;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace BoardRoles
{
internal class Boards
{
private static readonly FieldInfo StickersFI = AccessTools.Field(typeof(OrderStickersDesk), "orderStickers");
private static readonly FieldInfo PanelFI = AccessTools.Field(typeof(OrderStickersDesk), "stickersPanel");
private static readonly FieldInfo PrefabFI = AccessTools.Field(typeof(OrderStickersDesk), "orderStickerPrefab");
private static readonly FieldInfo BgFI = AccessTools.Field(typeof(OrderSticker), "bgImage");
private static readonly FieldInfo TextFI = AccessTools.Field(typeof(OrderSticker), "stickerText");
private static readonly MethodInfo OnOrderAddedMI = AccessTools.Method(typeof(OrderStickersDesk), "OnOrderAdded", (Type[])null, (Type[])null);
private readonly Plugin _p;
private readonly HashSet<OrderStickersDesk> _desks = new HashSet<OrderStickersDesk>();
private readonly Dictionary<OrderStickersDesk, TextMeshProUGUI> _plates = new Dictionary<OrderStickersDesk, TextMeshProUGUI>();
private readonly Dictionary<ushort, Role> _itemRole = new Dictionary<ushort, Role>();
private string _lastSig = string.Empty;
private float _nextTick;
private bool _rebuilding;
private Role _claimed;
private Role _onMenu;
private List<string> _present = new List<string>();
private readonly Vector3[] _corners = (Vector3[])(object)new Vector3[4];
public IEnumerable<OrderStickersDesk> Desks => _desks.Where((OrderStickersDesk d) => (Object)(object)d != (Object)null);
public Role UnclaimedOnMenu => _onMenu & ~_claimed;
public Boards(Plugin p)
{
_p = p;
}
private static List<OrderSticker> StickersRef(OrderStickersDesk o)
{
if ((Object)(object)o == (Object)null || StickersFI == null)
{
return null;
}
return (List<OrderSticker>)StickersFI.GetValue(o);
}
private static Transform PanelRef(OrderStickersDesk o)
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Expected O, but got Unknown
if ((Object)(object)o == (Object)null || PanelFI == null)
{
return null;
}
return (Transform)PanelFI.GetValue(o);
}
private static OrderSticker PrefabRef(OrderStickersDesk o)
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Expected O, but got Unknown
if ((Object)(object)o == (Object)null || PrefabFI == null)
{
return null;
}
return (OrderSticker)PrefabFI.GetValue(o);
}
private static Image BgRef(OrderSticker o)
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Expected O, but got Unknown
if ((Object)(object)o == (Object)null || BgFI == null)
{
return null;
}
return (Image)BgFI.GetValue(o);
}
private static TextMeshProUGUI TextRef(OrderSticker o)
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Expected O, but got Unknown
if ((Object)(object)o == (Object)null || TextFI == null)
{
return null;
}
return (TextMeshProUGUI)TextFI.GetValue(o);
}
public void OnDeskSpawn(OrderStickersDesk d)
{
_desks.Add(d);
_lastSig = string.Empty;
}
public void OnDeskDespawn(OrderStickersDesk d)
{
_desks.Remove(d);
if (_plates.TryGetValue(d, out var value))
{
if ((Object)(object)value != (Object)null)
{
Object.Destroy((Object)(object)((Component)value).gameObject);
}
_plates.Remove(d);
}
}
public static string KeyOf(OrderStickersDesk d)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
Vector3 position = ((Component)d).transform.position;
return Mathf.Round(position.x * 10f) / 10f + "," + Mathf.Round(position.y * 10f) / 10f + "," + Mathf.Round(position.z * 10f) / 10f;
}
public void Tick()
{
if (Time.unscaledTime < _nextTick)
{
return;
}
_nextTick = Time.unscaledTime + 0.5f;
_desks.RemoveWhere((OrderStickersDesk d) => (Object)(object)d == (Object)null);
if ((Object)(object)GameStatus.Instance == (Object)null)
{
_itemRole.Clear();
return;
}
_present = Net.PresentPlayers();
_claimed = Role.None;
foreach (string item in _present)
{
_claimed |= _p.State.RolesOf(item);
}
_onMenu = MenuRoles();
string[] obj = new string[7]
{
_p.State.Version.ToString(),
"|",
string.Join(",", _present.ToArray()),
"|",
null,
null,
null
};
int onMenu = (int)_onMenu;
obj[4] = onMenu.ToString();
obj[5] = "|";
obj[6] = _desks.Count.ToString();
string text = string.Concat(obj);
if (text != _lastSig)
{
_lastSig = text;
foreach (OrderStickersDesk desk in Desks)
{
Rebuild(desk);
}
}
foreach (OrderStickersDesk desk2 in Desks)
{
PlacePlate(desk2);
}
}
public Role RoleOfItem(ushort itemId)
{
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
if (_itemRole.TryGetValue(itemId, out var value))
{
return value;
}
value = Role.None;
try
{
RecipeData val = default(RecipeData);
if ((Object)(object)RecipeManager.Instance != (Object)null && RecipeManager.Instance.GetRecipeDataByProductItemDataId(itemId, ref val) && (Object)(object)val != (Object)null)
{
value = Roles.FromRecipeType(val.type);
}
}
catch
{
}
if ((Object)(object)RecipeManager.Instance != (Object)null)
{
_itemRole[itemId] = value;
}
return value;
}
private Role MenuRoles()
{
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
Role role = Role.None;
try
{
RecipeManager instance = RecipeManager.Instance;
if ((Object)(object)instance == (Object)null || instance.menuRecipes == null)
{
return role;
}
for (int i = 0; i < instance.menuRecipes.Count; i++)
{
RecipeData recipeDataById = instance.GetRecipeDataById(instance.menuRecipes[i]);
if ((Object)(object)recipeDataById != (Object)null)
{
role |= Roles.FromRecipeType(recipeDataById.type);
}
}
}
catch
{
}
return role;
}
private string Owner(OrderStickersDesk d)
{
return _p.State.BoardOwner(KeyOf(d));
}
public bool ShouldShow(OrderStickersDesk d, ushort itemId, out bool unclaimed)
{
Role role = RoleOfItem(itemId);
unclaimed = role != Role.None && (_claimed & role) == 0;
string text = Owner(d);
if (text == null || !_present.Contains(text))
{
return true;
}
if ((role == Role.None) | unclaimed)
{
return true;
}
return (_p.State.RolesOf(text) & role) != 0;
}
public void TintLast(OrderStickersDesk d)
{
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
if (!_p.TintUnclaimed.Value)
{
return;
}
List<OrderSticker> list = StickersRef(d);
if (list == null || list.Count == 0)
{
return;
}
OrderSticker val = list[list.Count - 1];
if (!((Object)(object)val == (Object)null))
{
Image val2 = BgRef(val);
if ((Object)(object)val2 != (Object)null)
{
((Graphic)val2).color = new Color(1f, 0.62f, 0.55f, ((Graphic)val2).color.a);
}
}
}
public List<OrderSticker> StickersOf(OrderStickersDesk d)
{
return StickersRef(d);
}
private void Rebuild(OrderStickersDesk d)
{
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
if (_rebuilding || (Object)(object)d == (Object)null || (Object)(object)OrdersManager.Instance == (Object)null || OnOrderAddedMI == null)
{
return;
}
_rebuilding = true;
try
{
List<OrderSticker> list = StickersRef(d);
if (list != null)
{
foreach (OrderSticker item in list)
{
if ((Object)(object)item != (Object)null)
{
Object.Destroy((Object)(object)((Component)item).gameObject);
}
}
list.Clear();
}
NetworkList<V3Ushort> clientOrders = OrdersManager.Instance.clientOrders;
for (int i = 0; i < clientOrders.Count; i++)
{
V3Ushort val = clientOrders[i];
OnOrderAddedMI.Invoke(d, new object[2]
{
val.y,
val.z != 0
});
}
UpdatePlate(d);
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("Rebuild failed: " + ex));
}
finally
{
_rebuilding = false;
}
}
private void UpdatePlate(OrderStickersDesk d)
{
TextMeshProUGUI plate = GetPlate(d);
if ((Object)(object)plate == (Object)null)
{
return;
}
string text = Owner(d);
StringBuilder stringBuilder = new StringBuilder();
if (text == null)
{
stringBuilder.Append("<size=75%>Everyone</size>");
}
else
{
bool num = _present.Contains(text);
stringBuilder.Append("<b>").Append(text).Append("</b>");
if (!num)
{
stringBuilder.Append(" <size=70%>(not here, showing all)</size>");
}
stringBuilder.Append("\n<size=70%>").Append(Roles.List(_p.State.RolesOf(text))).Append("</size>");
}
Role unclaimedOnMenu = UnclaimedOnMenu;
if (unclaimedOnMenu != Role.None)
{
stringBuilder.Append("\n<color=#FF6A50><size=70%>Nobody is on: ").Append(Roles.List(unclaimedOnMenu)).Append("</size></color>");
}
((TMP_Text)plate).text = stringBuilder.ToString();
}
private TextMeshProUGUI GetPlate(OrderStickersDesk d)
{
//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: 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_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
if (_plates.TryGetValue(d, out var value) && (Object)(object)value != (Object)null)
{
return value;
}
Transform val = PanelRef(d);
if ((Object)(object)val == (Object)null || (Object)(object)val.parent == (Object)null)
{
return null;
}
GameObject val2 = new GameObject("BoardRolesNameplate", new Type[1] { typeof(RectTransform) });
val2.transform.SetParent(val.parent, false);
val2.layer = ((Component)val).gameObject.layer;
val2.AddComponent<LayoutElement>().ignoreLayout = true;
value = val2.AddComponent<TextMeshProUGUI>();
((TMP_Text)value).alignment = (TextAlignmentOptions)1026;
((TMP_Text)value).enableWordWrapping = false;
((TMP_Text)value).overflowMode = (TextOverflowModes)0;
((Graphic)value).raycastTarget = false;
TextMeshProUGUI val3 = null;
try
{
OrderSticker val4 = PrefabRef(d);
if ((Object)(object)val4 != (Object)null)
{
val3 = TextRef(val4);
}
}
catch
{
}
if ((Object)(object)val3 != (Object)null)
{
((TMP_Text)value).font = ((TMP_Text)val3).font;
((TMP_Text)value).fontSharedMaterial = ((TMP_Text)val3).fontSharedMaterial;
((Graphic)value).color = ((Graphic)val3).color;
((TMP_Text)value).fontSize = ((TMP_Text)val3).fontSize * _p.NameplateTextScale.Value;
}
else
{
((TMP_Text)value).fontSize = 36f;
}
_plates[d] = value;
PlacePlate(d);
return value;
}
private void PlacePlate(OrderStickersDesk d)
{
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: 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_0100: 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_0104: Unknown result type (might be due to invalid IL or missing references)
//IL_010e: Unknown result type (might be due to invalid IL or missing references)
//IL_012d: 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_013d: Unknown result type (might be due to invalid IL or missing references)
//IL_0147: Unknown result type (might be due to invalid IL or missing references)
if (_plates.TryGetValue(d, out var value) && !((Object)(object)value == (Object)null))
{
Transform val = PanelRef(d);
RectTransform val2 = ((!((Object)(object)val != (Object)null)) ? null : ((Component)val).GetComponent<RectTransform>());
Transform parent = ((Transform)((TMP_Text)value).rectTransform).parent;
if (!((Object)(object)val2 == (Object)null) && !((Object)(object)parent == (Object)null))
{
val2.GetWorldCorners(_corners);
Vector3 val3 = parent.InverseTransformPoint(_corners[1]);
Vector3 val4 = parent.InverseTransformPoint(_corners[2]);
RectTransform rectTransform = ((TMP_Text)value).rectTransform;
Vector2 val5 = default(Vector2);
((Vector2)(ref val5))..ctor(0.5f, 0.5f);
rectTransform.anchorMax = val5;
Vector2 anchorMin = val5;
rectTransform.anchorMin = anchorMin;
rectTransform.pivot = new Vector2(0.5f, 0f);
rectTransform.sizeDelta = new Vector2(Mathf.Max(100f, Mathf.Abs(val4.x - val3.x)), 10f);
((Transform)rectTransform).localPosition = (val3 + val4) * 0.5f + new Vector3(0f, _p.NameplateOffset.Value, 0f);
((Transform)rectTransform).localRotation = Quaternion.identity;
((Transform)rectTransform).localScale = Vector3.one;
}
}
}
public OrderStickersDesk FindLookedAtDesk()
{
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: 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)
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
Camera main = Camera.main;
if ((Object)(object)main == (Object)null)
{
return null;
}
OrderStickersDesk result = null;
float num = _p.InteractAngle.Value;
foreach (OrderStickersDesk desk in Desks)
{
Vector3 val = ((Component)desk).transform.position;
Transform val2 = PanelRef(desk);
RectTransform val3 = ((!((Object)(object)val2 != (Object)null)) ? null : ((Component)val2).GetComponent<RectTransform>());
if ((Object)(object)val3 != (Object)null)
{
val3.GetWorldCorners(_corners);
val = (_corners[0] + _corners[2]) * 0.5f;
}
Vector3 val4 = val - ((Component)main).transform.position;
if (!(((Vector3)(ref val4)).magnitude > _p.InteractDistance.Value))
{
float num2 = Vector3.Angle(((Component)main).transform.forward, val4);
if (num2 < num)
{
num = num2;
result = desk;
}
}
}
return result;
}
}
[HarmonyPatch(typeof(OrderStickersDesk), "OnNetworkSpawn")]
internal static class DeskSpawnPatch
{
private static void Postfix(OrderStickersDesk __instance)
{
Plugin.Inst.Boards.OnDeskSpawn(__instance);
}
}
[HarmonyPatch(typeof(OrderStickersDesk), "OnNetworkDespawn")]
internal static class DeskDespawnPatch
{
private static void Prefix(OrderStickersDesk __instance)
{
Plugin.Inst.Boards.OnDeskDespawn(__instance);
}
}
[HarmonyPatch(typeof(OrderStickersDesk), "OnOrderAdded")]
internal static class OrderAddedPatch
{
private static bool Prefix(OrderStickersDesk __instance, ushort itemId, ref int __state)
{
__state = -1;
try
{
if (!Plugin.Inst.Boards.ShouldShow(__instance, itemId, out var unclaimed))
{
return false;
}
if (unclaimed)
{
__state = Plugin.Inst.Boards.StickersOf(__instance)?.Count ?? (-1);
}
return true;
}
catch (Exception ex)
{
Plugin.Log.LogError((object)ex);
return true;
}
}
private static void Postfix(OrderStickersDesk __instance, int __state)
{
if (__state < 0)
{
return;
}
try
{
List<OrderSticker> list = Plugin.Inst.Boards.StickersOf(__instance);
if (list != null && list.Count > __state)
{
Plugin.Inst.Boards.TintLast(__instance);
}
}
catch (Exception ex)
{
Plugin.Log.LogError((object)ex);
}
}
}
internal class Net
{
private const string MsgReq = "BoardRoles/Req";
private const string MsgRoles = "BoardRoles/SetRoles";
private const string MsgBoard = "BoardRoles/SetBoard";
private const string MsgState = "BoardRoles/State";
private readonly Plugin _p;
private NetworkManager _registeredOn;
private bool _inSession;
private float _reqSentAt;
private bool _gotHostState;
private string _tavern;
private bool _hostChanged;
private float _nextNameCheck;
private int _reqTries;
public bool LocalOnly { get; private set; }
private static NetworkManager NM => NetworkManager.Singleton;
public bool IsHost
{
get
{
if ((Object)(object)NM != (Object)null)
{
return NM.IsServer;
}
return false;
}
}
public bool Ready
{
get
{
if ((Object)(object)NM != (Object)null && NM.IsListening && NM.CustomMessagingManager != null && (Object)(object)GameStatus.Instance != (Object)null)
{
return (Object)(object)PlayerManager.Instance != (Object)null;
}
return false;
}
}
public Net(Plugin p)
{
_p = p;
}
public void Tick()
{
if (!Ready)
{
if (_inSession)
{
EndSession();
}
return;
}
if (!_inSession || (Object)(object)_registeredOn != (Object)(object)NM)
{
StartSession();
}
if (!IsHost && !_gotHostState && !LocalOnly && Time.unscaledTime - _reqSentAt > 3f)
{
if (_reqTries >= 3)
{
LocalOnly = true;
Plugin.Log.LogWarning((object)"Host didn't answer. The host probably doesn't have Board Roles, so assignments stay on this computer only.");
}
else
{
SendReq();
}
}
if (IsHost && !_hostChanged && Time.unscaledTime > _nextNameCheck)
{
_nextNameCheck = Time.unscaledTime + 2f;
string text = TavernName();
if (text != _tavern)
{
_tavern = text;
_p.State.LoadFor(_tavern);
Broadcast();
}
}
}
private void StartSession()
{
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
//IL_00ab: Expected O, but got Unknown
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
//IL_00c2: Expected O, but got Unknown
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Expected O, but got Unknown
//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
//IL_00f0: Expected O, but got Unknown
_inSession = true;
_registeredOn = NM;
_gotHostState = false;
LocalOnly = false;
_reqSentAt = 0f;
_reqTries = 0;
_hostChanged = false;
_nextNameCheck = 0f;
CustomMessagingManager customMessagingManager = NM.CustomMessagingManager;
string[] array = new string[4] { "BoardRoles/Req", "BoardRoles/SetRoles", "BoardRoles/SetBoard", "BoardRoles/State" };
foreach (string text in array)
{
try
{
customMessagingManager.UnregisterNamedMessageHandler(text);
}
catch
{
}
}
customMessagingManager.RegisterNamedMessageHandler("BoardRoles/Req", new HandleNamedMessageDelegate(OnReq));
customMessagingManager.RegisterNamedMessageHandler("BoardRoles/SetRoles", new HandleNamedMessageDelegate(OnSetRoles));
customMessagingManager.RegisterNamedMessageHandler("BoardRoles/SetBoard", new HandleNamedMessageDelegate(OnSetBoard));
customMessagingManager.RegisterNamedMessageHandler("BoardRoles/State", new HandleNamedMessageDelegate(OnState));
if (IsHost)
{
_tavern = TavernName();
_p.State.LoadFor(_tavern);
}
else
{
_p.State.Replace(new Assignments());
}
}
private void EndSession()
{
_inSession = false;
_registeredOn = null;
_p.State.Replace(new Assignments());
}
public void RequestSetRoles(Role mask)
{
string player = LocalName();
if (IsHost || LocalOnly)
{
ApplyRoles(player, mask);
return;
}
int num = (int)mask;
Send("BoardRoles/SetRoles", num.ToString(), 0uL);
}
public void RequestSetBoard(string key, string player)
{
if (IsHost || LocalOnly)
{
ApplyBoard(key, player);
}
else
{
Send("BoardRoles/SetBoard", key + "|" + (player ?? string.Empty), 0uL);
}
}
private void ApplyRoles(string player, Role mask)
{
_p.State.SetRoles(player, mask);
AfterHostChange();
}
private void ApplyBoard(string key, string player)
{
_p.State.SetBoard(key, player);
AfterHostChange();
}
private void AfterHostChange()
{
if (IsHost)
{
_hostChanged = true;
_p.State.SaveFor(_tavern);
Broadcast();
}
}
public void Broadcast()
{
if (IsHost && Ready)
{
string payload = JsonConvert.SerializeObject((object)_p.State.Current);
List<ulong> list = NM.ConnectedClientsIds.Where((ulong id) => id != NM.LocalClientId).ToList();
if (list.Count > 0)
{
Send("BoardRoles/State", payload, list);
}
}
}
private void OnReq(ulong sender, FastBufferReader r)
{
if (IsHost)
{
Send("BoardRoles/State", JsonConvert.SerializeObject((object)_p.State.Current), sender);
}
}
private void OnSetRoles(ulong sender, FastBufferReader r)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
if (IsHost && int.TryParse(Read(r), out var result))
{
ApplyRoles(NameOf(sender), (Role)result);
}
}
private void OnSetBoard(ulong sender, FastBufferReader r)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
if (IsHost)
{
string text = Read(r);
int num = text.LastIndexOf('|');
if (num > 0)
{
ApplyBoard(text.Substring(0, num), text.Substring(num + 1));
}
}
}
private void OnState(ulong sender, FastBufferReader r)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
if (IsHost)
{
return;
}
try
{
_p.State.Replace(JsonConvert.DeserializeObject<Assignments>(Read(r)));
_gotHostState = true;
LocalOnly = false;
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("Bad state from host: " + ex.Message));
}
}
private void SendReq()
{
_reqSentAt = Time.unscaledTime;
_reqTries++;
Send("BoardRoles/Req", string.Empty, 0uL);
}
private static string Read(FastBufferReader r)
{
string text = default(string);
((FastBufferReader)(ref r)).ReadValueSafe(ref text, false);
return text ?? string.Empty;
}
private unsafe static void Send(string msg, string payload, ulong to)
{
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
try
{
int num = FastBufferWriter.GetWriteSize(payload, false) + 16;
FastBufferWriter val = default(FastBufferWriter);
((FastBufferWriter)(ref val))..ctor(num, (Allocator)2, Math.Max(num, 65536));
try
{
((FastBufferWriter)(ref val)).WriteValueSafe(payload, false);
NM.CustomMessagingManager.SendNamedMessage(msg, to, val, (NetworkDelivery)4);
}
finally
{
((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose();
}
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("Send " + msg + " failed: " + ex.Message));
}
}
private unsafe static void Send(string msg, string payload, List<ulong> to)
{
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
try
{
int num = FastBufferWriter.GetWriteSize(payload, false) + 16;
FastBufferWriter val = default(FastBufferWriter);
((FastBufferWriter)(ref val))..ctor(num, (Allocator)2, Math.Max(num, 65536));
try
{
((FastBufferWriter)(ref val)).WriteValueSafe(payload, false);
NM.CustomMessagingManager.SendNamedMessage(msg, (IReadOnlyList<ulong>)to, val, (NetworkDelivery)4);
}
finally
{
((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose();
}
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("Send " + msg + " failed: " + ex.Message));
}
}
public static string NameOf(ulong clientId)
{
try
{
return PlayerManager.Instance.GetPlayerName(clientId);
}
catch
{
return "Player " + clientId;
}
}
public static string LocalName()
{
if ((Object)(object)NM != (Object)null)
{
return NameOf(NM.LocalClientId);
}
return null;
}
public static List<string> PresentPlayers()
{
List<string> list = new List<string>();
try
{
foreach (ulong item in PlayerManager.Instance.players.Keys.OrderBy((ulong k) => k))
{
string text = NameOf(item);
if (!string.IsNullOrEmpty(text) && !list.Contains(text))
{
list.Add(text);
}
}
}
catch
{
}
return list;
}
private static string TavernName()
{
try
{
FieldInfo field = typeof(GameStatus).GetField("tavernName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
object obj = ((!(field != null)) ? null : field.GetValue(GameStatus.Instance));
if (obj == null)
{
return string.Empty;
}
PropertyInfo property = obj.GetType().GetProperty("Value");
object obj2 = ((!(property != null)) ? obj : property.GetValue(obj, null));
return (obj2 == null) ? string.Empty : obj2.ToString();
}
catch
{
return string.Empty;
}
}
}
[BepInPlugin("aletale.boardroles", "Board Roles", "1.2.1")]
public class Plugin : BaseUnityPlugin
{
public const string Guid = "aletale.boardroles";
public const string Name = "Board Roles";
public const string Version = "1.2.1";
internal static Plugin Inst;
internal static ManualLogSource Log;
internal ConfigEntry<KeyCode> InteractKey;
internal ConfigEntry<KeyCode> RolesKey;
internal ConfigEntry<float> InteractDistance;
internal ConfigEntry<float> InteractAngle;
internal ConfigEntry<float> NameplateOffset;
internal ConfigEntry<float> NameplateTextScale;
internal ConfigEntry<bool> TintUnclaimed;
internal RolesState State;
internal Net Net;
internal Boards Boards;
internal RolesUI UI;
private void Awake()
{
//IL_0150: Unknown result type (might be due to invalid IL or missing references)
Inst = this;
Log = ((BaseUnityPlugin)this).Logger;
InteractKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Keys", "BoardKey", (KeyCode)101, "Press while looking at an order board to assign it.");
RolesKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Keys", "RolesKey", (KeyCode)288, "Open the roles window from anywhere.");
InteractDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Board", "InteractDistance", 4f, "How close you need to be to an order board (meters).");
InteractAngle = ((BaseUnityPlugin)this).Config.Bind<float>("Board", "InteractAngle", 15f, "How directly you need to look at the board (degrees).");
NameplateOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Board", "NameplateOffset", 30f, "Gap between the top of the stickers and the name, in board units. Raise it if the name overlaps stickers.");
NameplateTextScale = ((BaseUnityPlugin)this).Config.Bind<float>("Board", "NameplateTextScale", 1.4f, "Name text size relative to sticker text.");
TintUnclaimed = ((BaseUnityPlugin)this).Config.Bind<bool>("Board", "TintUnclaimed", true, "Tint stickers for orders nobody has a role for.");
State = new RolesState(Path.Combine(Paths.ConfigPath, "BoardRoles_saved.json"));
Net = new Net(this);
Boards = new Boards(this);
UI = new RolesUI(this);
new Harmony("aletale.boardroles").PatchAll(typeof(Plugin).Assembly);
Log.LogInfo((object)"Board Roles 1.2.1 loaded");
}
private void Update()
{
//IL_009d: 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_0068: Unknown result type (might be due to invalid IL or missing references)
try
{
Net.Tick();
Boards.Tick();
if (!UI.IsOpen)
{
if (!RolesUI.PlayerIsFree())
{
return;
}
if (Input.GetKeyDown(InteractKey.Value))
{
OrderStickersDesk val = Boards.FindLookedAtDesk();
if ((Object)(object)val != (Object)null)
{
UI.OpenForBoard(val);
}
}
else if (Input.GetKeyDown(RolesKey.Value) && (Object)(object)Game.Instance != (Object)null)
{
UI.OpenRoles();
}
}
else if (Input.GetKeyDown((KeyCode)27) || Input.GetKeyDown(RolesKey.Value))
{
UI.Close();
}
}
catch (Exception ex)
{
Log.LogError((object)ex);
}
}
private void LateUpdate()
{
UI.LateUpdate();
}
private void OnGUI()
{
UI.Draw();
}
}
internal class RolesUI
{
private readonly Plugin _p;
private OrderStickersDesk _desk;
private bool _open;
private Rect _win = new Rect(0f, 0f, 420f, 10f);
private CursorLockMode _prevLock;
private bool _prevVisible;
private GUIStyle _h;
private GUIStyle _small;
private GUIStyle _warn;
private GUIStyle _sel;
private bool _wasBoard;
private bool _blocking;
private bool _restorePending;
public bool IsOpen => _open;
public RolesUI(Plugin p)
{
//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)
_p = p;
}
public void OpenForBoard(OrderStickersDesk d)
{
_desk = d;
Open();
}
public void OpenRoles()
{
_desk = null;
Open();
}
internal static bool PlayerIsFree()
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Invalid comparison between Unknown and I4
PlayerInventory instance = PlayerInventory.Instance;
if (!((Object)(object)instance == (Object)null))
{
return (int)instance.state == 0;
}
return true;
}
private void Open()
{
//IL_001a: 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_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
_open = true;
_wasBoard = (Object)(object)_desk != (Object)null;
_prevLock = Cursor.lockState;
_prevVisible = Cursor.visible;
_win = new Rect((float)Screen.width / 2f - 210f, (float)Screen.height / 2f - 200f, 420f, 10f);
_restorePending = false;
_blocking = false;
PlayerInventory instance = PlayerInventory.Instance;
if ((Object)(object)instance != (Object)null && (int)instance.state == 0)
{
instance.SetState((State)1);
_blocking = true;
}
}
public void Close()
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
_open = false;
_desk = null;
Cursor.lockState = _prevLock;
Cursor.visible = _prevVisible;
if (_blocking)
{
_restorePending = true;
}
_blocking = false;
}
public void LateUpdate()
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Invalid comparison between Unknown and I4
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Invalid comparison between Unknown and I4
if (_restorePending)
{
_restorePending = false;
PlayerInventory instance = PlayerInventory.Instance;
if ((Object)(object)instance != (Object)null && (int)instance.state == 1)
{
instance.SetState((State)0);
}
}
if (!_open)
{
return;
}
if ((Object)(object)Game.Instance == (Object)null || ((Object)(object)_desk == (Object)null && _wasBoard))
{
Close();
return;
}
if (_blocking)
{
PlayerInventory instance2 = PlayerInventory.Instance;
if ((Object)(object)instance2 == (Object)null || (int)instance2.state != 1)
{
_blocking = false;
Close();
return;
}
}
Cursor.lockState = (CursorLockMode)0;
Cursor.visible = true;
}
public void Draw()
{
//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
//IL_00f8: 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)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Expected O, but got Unknown
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Expected O, but got Unknown
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Expected O, but got Unknown
//IL_0089: 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)
//IL_00af: Expected O, but got Unknown
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
//IL_0121: Expected O, but got Unknown
//IL_011c: Unknown result type (might be due to invalid IL or missing references)
//IL_0121: Unknown result type (might be due to invalid IL or missing references)
if (_open)
{
if (_h == null)
{
_h = new GUIStyle(GUI.skin.label)
{
fontSize = 15,
fontStyle = (FontStyle)1
};
_small = new GUIStyle(GUI.skin.label)
{
fontSize = 12,
wordWrap = true
};
_warn = new GUIStyle(_small);
_warn.normal.textColor = new Color(1f, 0.5f, 0.42f);
_sel = new GUIStyle(GUI.skin.button)
{
fontStyle = (FontStyle)1
};
_sel.normal.textColor = new Color(1f, 0.85f, 0.4f);
}
_wasBoard = (Object)(object)_desk != (Object)null;
_win = GUILayout.Window(723501, _win, new WindowFunction(Window), (!((Object)(object)_desk != (Object)null)) ? "Kitchen roles" : "Order board", Array.Empty<GUILayoutOption>());
}
}
private void Window(int id)
{
//IL_0379: Unknown result type (might be due to invalid IL or missing references)
List<string> list = Net.PresentPlayers();
string text = Net.LocalName();
if ((Object)(object)_desk != (Object)null)
{
string key = Boards.KeyOf(_desk);
string text2 = _p.State.BoardOwner(key);
GUILayout.Label("Whose board is this?", _h, Array.Empty<GUILayoutOption>());
GUILayout.Label("The board shows that player's orders, plus anything nobody has a role for.", _small, Array.Empty<GUILayoutOption>());
if (GUILayout.Button("Everyone (show all orders)", (text2 != null) ? GUI.skin.button : _sel, Array.Empty<GUILayoutOption>()))
{
_p.Net.RequestSetBoard(key, null);
}
foreach (string item in list)
{
if (GUILayout.Button(item + " (" + Roles.List(_p.State.RolesOf(item)) + ")", (!(item == text2)) ? GUI.skin.button : _sel, Array.Empty<GUILayoutOption>()))
{
_p.Net.RequestSetBoard(key, item);
}
}
if (text2 != null && !list.Contains(text2))
{
GUILayout.Label("Currently assigned to " + text2 + ", who isn't in the game. It shows all orders until they're back.", _small, Array.Empty<GUILayoutOption>());
}
GUILayout.Space(10f);
}
GUILayout.Label("Your roles" + ((!string.IsNullOrEmpty(text)) ? (" (" + text + ")") : string.Empty), _h, Array.Empty<GUILayoutOption>());
GUILayout.Label("Pick any number. Two people can share a role.", _small, Array.Empty<GUILayoutOption>());
Role role = _p.State.RolesOf(text);
Role[] all = Roles.All;
foreach (Role role2 in all)
{
bool flag = (role & role2) != 0;
bool flag2 = GUILayout.Toggle(flag, " " + Roles.Label(role2) + " (" + Roles.Hint(role2) + ")", Array.Empty<GUILayoutOption>());
if (flag2 != flag)
{
_p.Net.RequestSetRoles((!flag2) ? (role & ~role2) : (role | role2));
}
}
GUILayout.Space(8f);
GUILayout.Label("Everyone", _h, Array.Empty<GUILayoutOption>());
foreach (string item2 in list)
{
GUILayout.Label(item2 + ": " + Roles.List(_p.State.RolesOf(item2)), _small, Array.Empty<GUILayoutOption>());
}
Role unclaimedOnMenu = _p.Boards.UnclaimedOnMenu;
if (unclaimedOnMenu != Role.None)
{
GUILayout.Label("Nobody is on: " + Roles.List(unclaimedOnMenu) + ". Those orders go to every board.", _warn, Array.Empty<GUILayoutOption>());
}
if (_p.Net.LocalOnly)
{
GUILayout.Label("The host doesn't have Board Roles, so these settings only apply on your screen.", _warn, Array.Empty<GUILayoutOption>());
}
GUILayout.Space(6f);
if (GUILayout.Button("Close (Esc)", Array.Empty<GUILayoutOption>()))
{
Close();
}
GUI.DragWindow(new Rect(0f, 0f, 10000f, 22f));
}
}
[Flags]
public enum Role
{
None = 0,
FryCook = 1,
SoupCook = 2,
Baker = 4,
Bartender = 8,
Grinder = 0x10
}
public static class Roles
{
public static readonly Role[] All = new Role[5]
{
Role.FryCook,
Role.SoupCook,
Role.Baker,
Role.Bartender,
Role.Grinder
};
public static string Label(Role r)
{
return r switch
{
Role.FryCook => "Fry cook",
Role.SoupCook => "Soup cook",
Role.Baker => "Baker",
Role.Bartender => "Bartender",
Role.Grinder => "Grinder",
_ => r.ToString(),
};
}
public static string Hint(Role r)
{
return r switch
{
Role.FryCook => "fried dishes",
Role.SoupCook => "soups, stews, boiled dishes",
Role.Baker => "breads, pies, baked dishes",
Role.Bartender => "drinks",
Role.Grinder => "tartars, applesauce, candies",
_ => string.Empty,
};
}
public static string List(Role mask)
{
string[] array = All.Where((Role r) => (mask & r) != 0).Select(Label).ToArray();
if (array.Length == 0)
{
return "no roles";
}
return string.Join(", ", array);
}
public static Role FromRecipeType(Type t)
{
//IL_0000: 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_001c: Expected I4, but got Unknown
return (t - 1) switch
{
1 => Role.FryCook,
0 => Role.SoupCook,
2 => Role.Baker,
3 => Role.Bartender,
4 => Role.Grinder,
_ => Role.None,
};
}
}
public class Assignments
{
public Dictionary<string, string> Boards = new Dictionary<string, string>();
public Dictionary<string, int> Roles = new Dictionary<string, int>();
}
public class RolesState
{
public Assignments Current = new Assignments();
public int Version;
private readonly string _path;
private Dictionary<string, Assignments> _saved = new Dictionary<string, Assignments>();
public RolesState(string path)
{
_path = path;
try
{
if (File.Exists(path))
{
_saved = JsonConvert.DeserializeObject<Dictionary<string, Assignments>>(File.ReadAllText(path)) ?? _saved;
}
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("Could not read saved roles: " + ex.Message));
}
}
public Role RolesOf(string player)
{
if (player == null || !Current.Roles.TryGetValue(player, out var value))
{
return Role.None;
}
return (Role)value;
}
public string BoardOwner(string key)
{
if (key != null && Current.Boards.TryGetValue(key, out var value))
{
return value;
}
return null;
}
public void SetRoles(string player, Role mask)
{
if (!string.IsNullOrEmpty(player))
{
Current.Roles[player] = (int)mask;
Version++;
}
}
public void SetBoard(string key, string player)
{
if (!string.IsNullOrEmpty(key))
{
if (string.IsNullOrEmpty(player))
{
Current.Boards.Remove(key);
}
else
{
Current.Boards[key] = player;
}
Version++;
}
}
public void Replace(Assignments a)
{
Current = a ?? new Assignments();
Version++;
}
public void LoadFor(string tavern)
{
Current = ((!_saved.TryGetValue(tavern ?? string.Empty, out var value)) ? new Assignments() : value);
Version++;
}
public void SaveFor(string tavern)
{
_saved[tavern ?? string.Empty] = Current;
try
{
string text = _path + ".tmp";
File.WriteAllText(text, JsonConvert.SerializeObject((object)_saved, (Formatting)1));
if (File.Exists(_path))
{
File.Delete(_path);
}
File.Move(text, _path);
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("Could not save roles: " + ex.Message));
}
}
}
}