Decompiled source of RyLib v1.0.0
BepInEx/plugins/RyLib/RyLib.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using HighlightPlus; using HoldfastGame; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.SceneManagement; using UnityEngine.TextCore; 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: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyVersion("1.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 RyLib { internal sealed class Driver : MonoBehaviour { internal RyLibPlugin Owner; internal static Driver Attach(RyLibPlugin owner) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown GameObject val = new GameObject("RyLib_Driver"); Object.DontDestroyOnLoad((Object)(object)val); Driver driver = val.AddComponent<Driver>(); driver.Owner = owner; return driver; } private void Update() { if (Owner != null) { Owner.Tick(); } } } internal static class GameView { public static Camera ActiveCamera { get { ClientComponentReferenceManager clientInstance = ClientComponentReferenceManager.ClientInstance; if ((Object)(object)clientInstance != (Object)null && (Object)(object)clientInstance.ownerCameraManager != (Object)null) { Camera val = clientInstance.ownerCameraManager.ActiveCamera; if ((Object)(object)val == (Object)null) { val = clientInstance.ownerCameraManager.ownerCamera; } if ((Object)(object)val != (Object)null) { return val; } } return Camera.main; } } } internal static class Log { private static readonly ManualLogSource Source = Logger.CreateLogSource("RyLib"); public static void Info(string message) { Source.LogInfo((object)message); } public static void Warn(string message) { Source.LogWarning((object)message); } public static void Error(string message) { Source.LogError((object)message); } } internal static class Owners { public static bool Valid(string owner, string call) { if (!string.IsNullOrEmpty(owner)) { return true; } Log.Warn(call + " was called without an owner GUID, so it was ignored. Pass your plugin's GUID."); return false; } public static bool Same(string left, string right) { return string.Equals(left, right, StringComparison.OrdinalIgnoreCase); } public static void Run(string owner, string what, Action action) { try { action(); } catch (Exception ex) { Log.Error(owner + ": " + what + " threw " + ex.GetType().Name + ": " + ex.Message); } } public static string Say(string owner, string what, Func<string> text, string fallback) { if (text == null) { return fallback; } try { return text() ?? fallback; } catch (Exception ex) { Log.Error(owner + ": " + what + " threw " + ex.GetType().Name + ": " + ex.Message); return fallback; } } public static bool Ask(string owner, string what, Func<bool> question, bool fallback) { if (question == null) { return fallback; } try { return question(); } catch (Exception ex) { Log.Error(owner + ": " + what + " threw " + ex.GetType().Name + ": " + ex.Message); return fallback; } } } [BepInPlugin("com.ryannlt.rylib", "RyLib", "1.0.0")] public class RyLibPlugin : BaseUnityPlugin { public const string Guid = "com.ryannlt.rylib"; private Driver _driver; private void Awake() { GlowStyle.Bind(((BaseUnityPlugin)this).Config); MapStyle.Bind(((BaseUnityPlugin)this).Config); SceneManager.sceneLoaded += OnSceneLoaded; EnsureDriver(); try { Harmony.CreateAndPatchAll(typeof(RyLibPlugin).Assembly, "com.ryannlt.rylib"); } catch (Exception ex) { Log.Error("patches could not be applied: " + ex.Message); } Log.Info("Ready."); } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { EnsureDriver(); } private void EnsureDriver() { if (!((Object)(object)_driver != (Object)null)) { _driver = Driver.Attach(this); } } internal void Tick() { GlowStyle.Poll(); Menu.Tick(); PlayerRow.Tick(); World.Tick(); Minimap.Tick(); MapView.TickAll(); KeyHints.Tick(); } } internal sealed class ControlSpec { public string Owner; public string Key; public string Icon; public Func<string> Text; public Func<bool> IsOn; public Action Click; public Action RightClick; } internal sealed class RightClickRelay : MonoBehaviour, IPointerClickHandler, IEventSystemHandler { internal Action Clicked; public void OnPointerClick(PointerEventData eventData) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 if ((int)eventData.button == 1 && Clicked != null) { Clicked(); } } } internal sealed class Control { public ControlSpec Spec; public GameObject Root; public TMP_Text Label; public Image Icon; } internal static class Controls { private static readonly List<Control> Live = new List<Control>(); private static Color _labelOn = new Color(1f, 1f, 1f, 0.588f); private static Color _labelOff = new Color(0.855f, 0.753f, 0.612f, 1f); private static Color _iconOn = new Color(1f, 1f, 1f, 0.588f); private static Color _iconOff = new Color(0.859f, 0f, 0f, 1f); public static void SetPalette(UIRoundPlayersControlPanel players) { //IL_000f: 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_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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)players == (Object)null)) { _labelOn = players.enabledOptionColor; _labelOff = players.disabledOptionColor; _iconOn = players.voipUnmutedColor; _iconOff = players.voipMutedColor; } } public static ControlSpec Toggle(string owner, string label, ConfigEntry<bool> entry, string icon) { ControlSpec controlSpec = new ControlSpec(); controlSpec.Owner = owner; controlSpec.Key = label; controlSpec.Icon = icon; controlSpec.Text = () => label + (entry.Value ? " On" : " Off"); controlSpec.IsOn = () => entry.Value; controlSpec.Click = delegate { entry.Value = !entry.Value; }; return controlSpec; } public static ControlSpec Cycle<T>(string owner, string label, ConfigEntry<T> entry, Func<T, string> text, Func<T, bool> isOn, string icon) where T : struct, Enum { Array values = Enum.GetValues(typeof(T)); ControlSpec controlSpec = new ControlSpec(); controlSpec.Owner = owner; controlSpec.Key = label; controlSpec.Icon = icon; controlSpec.Text = () => (text != null) ? text(entry.Value) : (label + " " + entry.Value); controlSpec.IsOn = () => isOn == null || isOn(entry.Value); controlSpec.Click = delegate { entry.Value = Next(values, entry.Value); }; return controlSpec; } public static ControlSpec Button(string owner, string label, Action onClick, string icon) { ControlSpec controlSpec = new ControlSpec(); controlSpec.Owner = owner; controlSpec.Key = label; controlSpec.Icon = icon; controlSpec.Text = () => label; controlSpec.IsOn = () => true; controlSpec.Click = onClick; return controlSpec; } public static ControlSpec Stepper(string owner, string label, ConfigEntry<float> entry, float step, string format, string icon) { ControlSpec controlSpec = new ControlSpec(); controlSpec.Owner = owner; controlSpec.Key = label; controlSpec.Icon = icon; controlSpec.Text = () => label + " " + entry.Value.ToString(format); controlSpec.IsOn = () => true; controlSpec.Click = delegate { Nudge(entry, step); }; controlSpec.RightClick = delegate { Nudge(entry, 0f - step); }; return controlSpec; } private static void Nudge(ConfigEntry<float> entry, float delta) { float num = (float)Math.Round(entry.Value + delta, 3); AcceptableValueBase acceptableValues = ((ConfigEntryBase)entry).Description.AcceptableValues; entry.Value = ((acceptableValues != null) ? ((float)acceptableValues.Clamp((object)num)) : num); GlowStyle.Saved(); } private static T Next<T>(Array values, T current) { int num = Array.IndexOf(values, current); return (T)values.GetValue((num + 1) % values.Length); } public static Control Make(ControlSpec spec, Transform parent, GameObject template) { //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Expected O, but got Unknown if ((Object)(object)template == (Object)null || (Object)(object)parent == (Object)null) { return null; } GameObject val = Object.Instantiate<GameObject>(template, parent); ((Object)val).name = "RyLib_" + spec.Owner + "_" + spec.Key; UiClone.Strip(val); Button componentInChildren = val.GetComponentInChildren<Button>(true); if ((Object)(object)componentInChildren == (Object)null) { Object.Destroy((Object)(object)val); Log.Warn(spec.Owner + ": the control template carried no button, so '" + spec.Key + "' was skipped."); return null; } Control control = new Control(); control.Spec = spec; control.Root = val; control.Label = val.GetComponentInChildren<TMP_Text>(true); control.Icon = FindIcon(val.transform); UiClone.Mute((UnityEventBase)(object)componentInChildren.onClick); ((UnityEvent)componentInChildren.onClick).AddListener((UnityAction)delegate { Owners.Run(spec.Owner, spec.Key, spec.Click); Refresh(control); }); if (spec.RightClick != null) { RightClickRelay rightClickRelay = ((Component)componentInChildren).gameObject.AddComponent<RightClickRelay>(); rightClickRelay.Clicked = delegate { Owners.Run(spec.Owner, spec.Key, spec.RightClick); Refresh(control); }; } if (!string.IsNullOrEmpty(spec.Icon) && (Object)(object)control.Icon != (Object)null) { Sprite val2 = Sprites.Find(spec.Icon, Menu.SpriteRoot); if ((Object)(object)val2 != (Object)null) { control.Icon.sprite = val2; } } val.SetActive(true); Live.Add(control); Refresh(control); return control; } public static void Refresh(Control control) { //IL_009a: 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_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) if (control != null && !((Object)(object)control.Root == (Object)null)) { ControlSpec spec = control.Spec; bool flag = Owners.Ask(spec.Owner, spec.Key + " state", spec.IsOn, fallback: true); if ((Object)(object)control.Label != (Object)null) { control.Label.text = Owners.Say(spec.Owner, spec.Key + " text", spec.Text, spec.Key); ((Graphic)control.Label).color = (flag ? _labelOn : _labelOff); } if ((Object)(object)control.Icon != (Object)null) { ((Graphic)control.Icon).color = (flag ? _iconOn : _iconOff); } } } public static void RefreshVisible() { for (int num = Live.Count - 1; num >= 0; num--) { Control control = Live[num]; if ((Object)(object)control.Root == (Object)null) { Live.RemoveAt(num); } else if (control.Root.activeInHierarchy) { Refresh(control); } } } private static Image FindIcon(Transform root) { Transform val = root.Find("Icon"); if ((Object)(object)val != (Object)null) { return ((Component)val).GetComponent<Image>(); } Image[] componentsInChildren = ((Component)root).GetComponentsInChildren<Image>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if (((Object)componentsInChildren[i]).name.IndexOf("Icon", StringComparison.OrdinalIgnoreCase) >= 0) { return componentsInChildren[i]; } } return null; } } public static class KeyHints { private sealed class Host { public string Name; public Func<GameObject> Find; public Func<GameObject, TMP_Text> Keys; public bool AtEnd; public GameObject Template; public TMP_Text KeySource; } private sealed class Copy { public GameObject Root; public TMP_Text Bind; public string Signature; } private sealed class Entry { public string Owner; public string Label; public Func<KeyCode[]> Keys; public Func<bool> Visible; public Copy[] Copies; public bool[] Skipped; } private const float RefreshSeconds = 0.5f; private const float SearchSeconds = 5f; private const float MaxSkew = 0.22f; private const float LooseGap = 40f; private const string Prefix = "RyLib_Hint_"; private static readonly Regex SpriteIndex = new Regex("<sprite index=(\\d+)", RegexOptions.Compiled); private static readonly List<Entry> Entries = new List<Entry>(); private static readonly List<Transform> Roots = new List<Transform>(); private static readonly Host[] Hosts = new Host[2] { new Host { Name = "free roam", Find = FreeRoamTemplate, Keys = FirstBind }, new Host { Name = "spectating", Find = SpectateTemplate, Keys = SquareBind, AtEnd = true } }; private static UISpectatingPanel _spectating; private static GameObject _spectateEntry; private static float _nextSearch; private static float _nextRefresh; private static bool _warned; private static bool _dumped; public static bool Add(string owner, string label, Func<KeyCode[]> keys, Func<bool> visible = null) { if (!Owners.Valid(owner, "KeyHints.Add")) { return false; } if (string.IsNullOrEmpty(label) || keys == null) { Log.Warn(owner + ": KeyHints.Add needs a label and its keys."); return false; } for (int i = 0; i < Entries.Count; i++) { if (Owners.Same(Entries[i].Owner, owner) && Owners.Same(Entries[i].Label, label)) { Log.Warn(owner + ": key hint '" + label + "' is already registered, so the second one was ignored."); return false; } } Entry entry = new Entry(); entry.Owner = owner; entry.Label = label; entry.Keys = keys; entry.Visible = visible; entry.Copies = new Copy[Hosts.Length]; entry.Skipped = new bool[Hosts.Length]; Entries.Add(entry); Log.Info(owner + " added key hint '" + label + "'."); return true; } internal static void Tick() { if (Entries.Count == 0 || Time.unscaledTime < _nextRefresh) { return; } _nextRefresh = Time.unscaledTime + 0.5f; try { for (int i = 0; i < Hosts.Length; i++) { Refresh(i); } } catch (Exception ex) { if (!_warned) { _warned = true; Log.Error("key hints failed: " + ex.Message); } } } private static GameObject FreeRoamTemplate() { ClientComponentReferenceManager clientInstance = ClientComponentReferenceManager.ClientInstance; if ((Object)(object)clientInstance == (Object)null || (Object)(object)clientInstance.clientFreeflightCameraManager == (Object)null) { return null; } return clientInstance.clientFreeflightCameraManager.AdminRaygunHotkey; } private static GameObject SpectateTemplate() { if ((Object)(object)_spectateEntry != (Object)null) { return _spectateEntry; } if (Time.unscaledTime < _nextSearch) { return null; } _nextSearch = Time.unscaledTime + 5f; List<Transform> list = SpectateRoots(); _spectateEntry = EntryFor(list, (PlayerInputAction)45); if ((Object)(object)_spectateEntry == (Object)null) { _spectateEntry = EntryFor(list, (PlayerInputAction)58); } if ((Object)(object)_spectateEntry == (Object)null && list.Count > 0 && !_dumped) { _dumped = true; Log.Warn("the spectating panel has no labelled key entry to copy, so key hints are skipped there."); for (int i = 0; i < list.Count; i++) { Probe.Dump(list[i], 6, "spectating panel"); } } return _spectateEntry; } private static List<Transform> SpectateRoots() { ClientComponentReferenceManager clientInstance = ClientComponentReferenceManager.ClientInstance; CanvasGroup val = (((Object)(object)clientInstance == (Object)null || (Object)(object)clientInstance.clientSpectatorManager == (Object)null) ? null : clientInstance.clientSpectatorManager.SpectatePanel); if ((Object)(object)_spectating == (Object)null) { if ((Object)(object)val != (Object)null) { _spectating = ((Component)val).GetComponentInChildren<UISpectatingPanel>(true); if ((Object)(object)_spectating == (Object)null) { _spectating = ((Component)val).GetComponentInParent<UISpectatingPanel>(); } } if ((Object)(object)_spectating == (Object)null) { _spectating = Object.FindObjectOfType<UISpectatingPanel>(true); } } Roots.Clear(); if ((Object)(object)_spectating != (Object)null) { AddRoot(((Component)_spectating).transform); if ((Object)(object)_spectating.spectatingPanelRootTransform != (Object)null) { AddRoot((Transform)(object)_spectating.spectatingPanelRootTransform); } } if ((Object)(object)val != (Object)null) { AddRoot(((Component)val).transform); } return Roots; } private static void AddRoot(Transform root) { for (int num = Roots.Count - 1; num >= 0; num--) { if (root.IsChildOf(Roots[num])) { return; } if (Roots[num].IsChildOf(root)) { Roots.RemoveAt(num); } } Roots.Add(root); } private static GameObject EntryFor(List<Transform> roots, PlayerInputAction action) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < roots.Count; i++) { Hotkey[] componentsInChildren = ((Component)roots[i]).GetComponentsInChildren<Hotkey>(true); for (int j = 0; j < componentsInChildren.Length; j++) { if (Bound(componentsInChildren[j], action)) { GameObject val = EntryOf(((Component)componentsInChildren[j]).transform, roots[i]); if ((Object)(object)val != (Object)null) { return val; } } } } return null; } private unsafe static bool Bound(Hotkey hotkey, PlayerInputAction action) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Invalid comparison between Unknown and I4 //IL_000f: 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) if ((int)hotkey.Type == 0) { return hotkey.PlayerAction == action; } return (int)hotkey.Type == 1 && !string.IsNullOrEmpty(hotkey.ActionName) && Flatten(hotkey.ActionName) == Flatten(((object)(*(PlayerInputAction*)(&action))/*cast due to .constrained prefix*/).ToString()); } private static GameObject EntryOf(Transform bind, Transform root) { Transform val = bind; TMP_Text val2 = null; while ((Object)(object)val2 == (Object)null && (Object)(object)val.parent != (Object)null && (Object)(object)val.parent != (Object)(object)root) { val = val.parent; val2 = LabelIn(val, null, null); } if ((Object)(object)val2 == (Object)null) { return null; } string same = val2.text.Trim(); while ((Object)(object)val.parent != (Object)null && (Object)(object)val.parent != (Object)(object)root && (Object)(object)LabelIn(val.parent, val, same) == (Object)null) { val = val.parent; } return ((Component)val).gameObject; } private static TMP_Text LabelIn(Transform node, Transform skip, string same) { TMP_Text[] componentsInChildren = ((Component)node).GetComponentsInChildren<TMP_Text>(true); foreach (TMP_Text val in componentsInChildren) { if (IsLabel(val) && (!((Object)(object)skip != (Object)null) || !val.transform.IsChildOf(skip)) && (same == null || !(val.text.Trim() == same))) { return val; } } return null; } private static bool IsLabel(TMP_Text text) { if ((Object)(object)text == (Object)null || text.text == null || (Object)(object)((Component)text).GetComponent<Hotkey>() != (Object)null) { return false; } return text.text.Trim().Length > 2 && text.text.IndexOf("<sprite", StringComparison.Ordinal) < 0; } private static TMP_Text SquareBind(GameObject template) { List<Transform> list = SpectateRoots(); TMP_Text result = null; float num = 0.22f; for (int i = 0; i < list.Count; i++) { Hotkey[] componentsInChildren = ((Component)list[i]).GetComponentsInChildren<Hotkey>(true); for (int j = 0; j < componentsInChildren.Length; j++) { TMP_Text component = ((Component)componentsInChildren[j]).GetComponent<TMP_Text>(); float num2 = Skew(component); if (!(num2 > num)) { num = num2; result = component; } } } return result; } private static float Skew(TMP_Text text) { //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)text == (Object)null || !((Component)text).gameObject.activeInHierarchy || (Object)(object)text.spriteAsset == (Object)null || string.IsNullOrEmpty(text.text)) { return float.MaxValue; } MatchCollection matchCollection = SpriteIndex.Matches(text.text); if (matchCollection.Count != 1) { return float.MaxValue; } int num = int.Parse(matchCollection[0].Groups[1].Value); List<TMP_SpriteCharacter> spriteCharacterTable = text.spriteAsset.spriteCharacterTable; if (spriteCharacterTable == null || num >= spriteCharacterTable.Count || spriteCharacterTable[num] == null || ((TMP_TextElement)spriteCharacterTable[num]).glyph == null) { return float.MaxValue; } GlyphRect glyphRect = ((TMP_TextElement)spriteCharacterTable[num]).glyph.glyphRect; if (((GlyphRect)(ref glyphRect)).width <= 0 || ((GlyphRect)(ref glyphRect)).height <= 0) { return float.MaxValue; } return Mathf.Abs(Mathf.Log((float)((GlyphRect)(ref glyphRect)).width / (float)((GlyphRect)(ref glyphRect)).height)); } private static void Refresh(int index) { Host host = Hosts[index]; GameObject val = host.Find(); if ((Object)(object)val != (Object)(object)host.Template) { host.Template = val; host.KeySource = null; for (int i = 0; i < Entries.Count; i++) { Entries[i].Copies[index] = null; Entries[i].Skipped[index] = false; } } if ((Object)(object)host.Template == (Object)null) { return; } bool flag = host.Template.activeInHierarchy && ClientRemoteConsoleAccessManager.loggedOn; if (flag && (Object)(object)host.KeySource == (Object)null) { host.KeySource = host.Keys(host.Template); } for (int j = 0; j < Entries.Count; j++) { Entry entry = Entries[j]; if (entry.Skipped[index]) { continue; } Copy copy = entry.Copies[index]; if (copy == null || (Object)(object)copy.Root == (Object)null) { copy = Build(host, entry); entry.Copies[index] = copy; if (copy == null) { entry.Skipped[index] = true; continue; } } bool flag2 = flag && Owners.Ask(entry.Owner, entry.Label + " visibility", entry.Visible, fallback: true); if (copy.Root.activeSelf != flag2) { copy.Root.SetActive(flag2); } if (flag2) { UpdateKeys(host, entry, copy); } } } private static TMP_Text FirstBind(GameObject root) { if ((Object)(object)root == (Object)null) { return null; } Hotkey[] componentsInChildren = root.GetComponentsInChildren<Hotkey>(true); for (int i = 0; i < componentsInChildren.Length; i++) { TMP_Text component = ((Component)componentsInChildren[i]).GetComponent<TMP_Text>(); if ((Object)(object)component != (Object)null) { return component; } } return null; } private static Copy Build(Host host, Entry entry) { GameObject val = Object.Instantiate<GameObject>(host.Template, host.Template.transform.parent); ((Object)val).name = "RyLib_Hint_" + entry.Label; List<TMP_Text> list = new List<TMP_Text>(); Hotkey[] componentsInChildren = val.GetComponentsInChildren<Hotkey>(true); for (int i = 0; i < componentsInChildren.Length; i++) { TMP_Text component = ((Component)componentsInChildren[i]).GetComponent<TMP_Text>(); if ((Object)(object)component != (Object)null) { list.Add(component); } Object.DestroyImmediate((Object)(object)componentsInChildren[i]); } UiClone.Strip(val); TMP_Text val2 = null; TMP_Text[] componentsInChildren2 = val.GetComponentsInChildren<TMP_Text>(true); for (int j = 0; j < componentsInChildren2.Length; j++) { if (!list.Contains(componentsInChildren2[j]) && componentsInChildren2[j].text != null && componentsInChildren2[j].text.Trim().Length > 2) { val2 = componentsInChildren2[j]; break; } } TMP_Text val3 = ((list.Count > 0) ? list[0] : null); if ((Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null) { Log.Warn("the " + host.Name + " panel's key entry has no label or key to copy, so hint '" + entry.Label + "' was skipped there."); Probe.Dump(host.Template.transform, 4, host.Name + " key entry"); Object.Destroy((Object)(object)val); return null; } for (int k = 0; k < componentsInChildren2.Length; k++) { if ((Object)(object)componentsInChildren2[k] != (Object)(object)val2 && (Object)(object)componentsInChildren2[k] != (Object)(object)val3) { Collapse(val.transform, componentsInChildren2[k].transform, val2.transform, val3.transform); } } ((Component)val2).gameObject.SetActive(true); ((Component)val3).gameObject.SetActive(true); val2.text = entry.Label; Place(host, val); Copy copy = new Copy(); copy.Root = val; copy.Bind = val3; val.SetActive(false); return copy; } private static void Place(Host host, GameObject clone) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_0149: 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) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0186: 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_018d: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) Transform transform = clone.transform; Transform parent = transform.parent; if (host.AtEnd) { transform.SetAsLastSibling(); } else { transform.SetSiblingIndex(host.Template.transform.GetSiblingIndex() + 1); } if ((Object)(object)parent == (Object)null || (Object)(object)((Component)parent).GetComponent<LayoutGroup>() != (Object)null) { return; } Transform val = null; Transform val2 = null; for (int i = 0; i < parent.childCount; i++) { Transform child = parent.GetChild(i); if (!((Object)(object)child == (Object)(object)transform)) { if ((Object)(object)val == (Object)null || child.localPosition.x > val.localPosition.x) { val2 = val; val = child; } else if ((Object)(object)val2 == (Object)null || child.localPosition.x > val2.localPosition.x) { val2 = child; } } } if (!((Object)(object)val == (Object)null)) { Vector3 val3 = (Vector3)(((Object)(object)val2 == (Object)null) ? new Vector3(Width(val) + 40f, 0f, 0f) : (val.localPosition - val2.localPosition)); if (val3.x <= 0f) { ((Vector3)(ref val3))..ctor(Width(val) + 40f, 0f, 0f); } transform.localPosition = val.localPosition + val3; Log.Info("the " + host.Name + " key bar has no layout group, so hints are placed by hand."); Probe.Dump(parent, 2, host.Name + " key bar"); } } private static float Width(Transform node) { //IL_0012: 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) RectTransform val = (RectTransform)(object)((node is RectTransform) ? node : null); float result; if (!((Object)(object)val == (Object)null)) { Rect rect = val.rect; result = ((Rect)(ref rect)).width; } else { result = 0f; } return result; } private static void Collapse(Transform root, Transform node, Transform title, Transform bind) { Transform val = node; while ((Object)(object)val.parent != (Object)null && (Object)(object)val.parent != (Object)(object)root && !title.IsChildOf(val.parent) && !bind.IsChildOf(val.parent)) { val = val.parent; } if (!title.IsChildOf(val) && !bind.IsChildOf(val)) { ((Component)val).gameObject.SetActive(false); } } private static void UpdateKeys(Host host, Entry entry, Copy copy) { KeyCode[] keys = null; Owners.Run(entry.Owner, entry.Label + " keys", delegate { keys = entry.Keys(); }); if (keys == null) { keys = (KeyCode[])(object)new KeyCode[0]; } string text = (((Object)(object)host.KeySource == (Object)null) ? string.Empty : host.KeySource.text); string text2 = text + "|" + string.Join(",", Array.ConvertAll(keys, Name)); if (text2 == copy.Signature) { return; } copy.Signature = text2; TMP_SpriteAsset val = (((Object)(object)host.KeySource == (Object)null) ? null : host.KeySource.spriteAsset); Match match = SpriteIndex.Match(text); int sourceIndex = (match.Success ? int.Parse(match.Groups[1].Value) : (-1)); StringBuilder stringBuilder = new StringBuilder(); bool flag = false; for (int num = 0; num < keys.Length; num++) { if (num > 0) { stringBuilder.Append(" / "); } string text3 = Token(val, sourceIndex, text, keys[num]); if (text3 == null) { stringBuilder.Append(Character(keys[num])); continue; } stringBuilder.Append(text3); flag = true; } if (flag) { copy.Bind.spriteAsset = val; } copy.Bind.text = stringBuilder.ToString(); } private static string Token(TMP_SpriteAsset icons, int sourceIndex, string pattern, KeyCode key) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)icons == (Object)null || sourceIndex < 0) { return null; } int num = Glyph(icons, key); if (num >= 0) { return SpriteIndex.Replace(pattern, "<sprite index=" + num, 1); } string text = KeyCaps.Name(icons, sourceIndex, key); return (text == null) ? null : SpriteIndex.Replace(pattern, "<sprite name=\"" + text + "\"", 1); } private unsafe static int Glyph(TMP_SpriteAsset icons, KeyCode key) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) List<TMP_SpriteCharacter> spriteCharacterTable = icons.spriteCharacterTable; if (spriteCharacterTable == null) { return -1; } string value = Flatten(((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString()); string text = Flatten(Character(key)); for (int i = 0; i < spriteCharacterTable.Count; i++) { TMP_SpriteCharacter val = spriteCharacterTable[i]; if (val != null && !string.IsNullOrEmpty(val.name)) { string text2 = Flatten(val.name); if (text2.EndsWith(value, StringComparison.Ordinal) || text2 == text) { return i; } } } return -1; } private static string Flatten(string text) { return text.Replace(" ", string.Empty).Replace("_", string.Empty).Replace("-", string.Empty) .ToLowerInvariant(); } private unsafe static string Name(KeyCode key) { return ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString(); } private unsafe static string Character(KeyCode key) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Invalid comparison between Unknown and I4 //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected I4, but got Unknown //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected I4, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Invalid comparison between Unknown and I4 KeyCode val = key; KeyCode val2 = val; if ((int)val2 <= 59) { switch (val2 - 39) { default: if ((int)val2 != 59) { break; } return ";"; case 0: return "'"; case 5: return ","; case 7: return "."; case 8: return "/"; case 6: return "-"; case 1: case 2: case 3: case 4: break; } } else { if ((int)val2 == 61) { return "="; } switch (val2 - 91) { case 0: return "["; case 2: return "]"; case 1: return "\\"; case 5: return "`"; } } return ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString(); } } public static class KillLog { private sealed class Request { public string Owner; public Func<bool> Visible; } private static readonly List<Request> Requests = new List<Request>(); internal static bool Requested => Requests.Count > 0; internal static bool ActionsOn { get { for (int i = 0; i < Requests.Count; i++) { if (Owners.Ask(Requests[i].Owner, "kill log actions visibility", Requests[i].Visible, fallback: true)) { return true; } } return false; } } public static bool EnableActions(string owner, Func<bool> visible = null) { if (!Owners.Valid(owner, "KillLog.EnableActions")) { return false; } for (int i = 0; i < Requests.Count; i++) { if (Owners.Same(Requests[i].Owner, owner)) { Log.Warn(owner + " already turned on the kill log actions, so the second call was ignored."); return false; } } Request request = new Request(); request.Owner = owner; request.Visible = visible; Requests.Add(request); Log.Info(owner + " turned on the kill log actions."); return true; } } internal sealed class KillLogRowClick : MonoBehaviour, IPointerClickHandler, IEventSystemHandler { internal UIAdminPlayerKillLogPanelRow Row; public void OnPointerClick(PointerEventData eventData) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) if ((int)eventData.button != 0 || (Object)(object)Row == (Object)null) { return; } try { KillLogRows.Toggle(Row); } catch (Exception ex) { Log.Error("the kill log actions could not be opened: " + ex.Message); } } } internal static class KillLogRows { private sealed class Half { public TMP_Text Title; public RectTransform Grid; public int Buttons; } private const float ButtonWidth = 160f; private const float ButtonHeight = 36f; private const float Spacing = 6f; private const float Padding = 10f; private const float TitleHeight = 26f; private const float ArmSeconds = 4f; private const int Columns = 3; private static readonly Color PanelColour = new Color(0.04f, 0.05f, 0.06f, 0.94f); private static readonly Color Clear = new Color(0f, 0f, 0f, 0f); private static KillLogInfo _open; private static UIAdminPlayerKillLogPanel _log; private static GameObject _panel; private static LayoutElement _size; private static Half _killer; private static Half _victim; private static int _armedPlayer = -1; private static string _armedAction; private static float _armedUntil; internal static void Attach(UIAdminPlayerKillLogPanelRow row) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)row == (Object)null) && KillLog.Requested && !((Object)(object)((Component)row).GetComponent<KillLogRowClick>() != (Object)null)) { if ((Object)(object)((Component)row).GetComponent<Graphic>() == (Object)null) { Image val = ((Component)row).gameObject.AddComponent<Image>(); ((Graphic)val).color = Clear; } ((Component)row).gameObject.AddComponent<KillLogRowClick>().Row = row; } } internal static void Toggle(UIAdminPlayerKillLogPanelRow row) { if (!ClientRemoteConsoleAccessManager.loggedOn || !KillLog.ActionsOn) { return; } KillLogInfo currentInfo = row.CurrentInfo; if (currentInfo == null) { return; } if (_open == currentInfo && (Object)(object)_panel != (Object)null && _panel.activeSelf) { Close(); return; } _log = ((Component)row).GetComponentInParent<UIAdminPlayerKillLogPanel>(); _open = currentInfo; _armedPlayer = -1; if (!Ensure(row)) { _open = null; return; } Fill(currentInfo); Place(); } internal static void Place() { if ((Object)(object)_panel == (Object)null) { return; } UIAdminPlayerKillLogPanelRow val = ((_open == null || !KillLog.ActionsOn) ? null : FindRow(_open)); if ((Object)(object)val == (Object)null || !((Component)val).gameObject.activeSelf) { Hide(); return; } Transform parent = ((Component)val).transform.parent; if ((Object)(object)_panel.transform.parent != (Object)(object)parent) { _panel.transform.SetParent(parent, false); } int siblingIndex = ((Component)val).transform.GetSiblingIndex(); int siblingIndex2 = _panel.transform.GetSiblingIndex(); _panel.transform.SetSiblingIndex((siblingIndex2 < siblingIndex) ? siblingIndex : (siblingIndex + 1)); if (!_panel.activeSelf) { _panel.SetActive(true); } } internal static void Close() { _open = null; _armedPlayer = -1; Hide(); } private static void Hide() { if ((Object)(object)_panel != (Object)null && _panel.activeSelf) { _panel.SetActive(false); } } private static UIAdminPlayerKillLogPanelRow FindRow(KillLogInfo info) { if ((Object)(object)_log == (Object)null || (Object)(object)_log.rowsRootTransform == (Object)null) { return null; } Transform rowsRootTransform = _log.rowsRootTransform; for (int i = 0; i < rowsRootTransform.childCount; i++) { UIAdminPlayerKillLogPanelRow component = ((Component)rowsRootTransform.GetChild(i)).GetComponent<UIAdminPlayerKillLogPanelRow>(); if ((Object)(object)component != (Object)null && component.CurrentInfo == info) { return component; } } return null; } private static bool Ensure(UIAdminPlayerKillLogPanelRow row) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009d: 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_00b5: 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_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Expected O, but got Unknown if ((Object)(object)_panel != (Object)null) { return true; } if ((Object)(object)Menu.ControlTemplate == (Object)null) { return false; } GameObject val = new GameObject("RyLib_KillLogActions", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(((Component)row).transform.parent, false); RectTransform val2 = (RectTransform)val.transform; RectTransform val3 = (RectTransform)((Component)row).transform; val2.anchorMin = val3.anchorMin; val2.anchorMax = val3.anchorMax; val2.pivot = val3.pivot; val2.sizeDelta = new Vector2(val3.sizeDelta.x, val2.sizeDelta.y); Image val4 = val.AddComponent<Image>(); ((Graphic)val4).color = PanelColour; _size = val.AddComponent<LayoutElement>(); _size.flexibleHeight = 0f; _size.flexibleWidth = 1f; HorizontalLayoutGroup val5 = val.AddComponent<HorizontalLayoutGroup>(); ((LayoutGroup)val5).padding = new RectOffset(10, 10, 10, 10); ((HorizontalOrVerticalLayoutGroup)val5).spacing = 20f; ((LayoutGroup)val5).childAlignment = (TextAnchor)0; ((HorizontalOrVerticalLayoutGroup)val5).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)val5).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)val5).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)val5).childForceExpandHeight = true; _killer = BuildHalf(val2, "Killer"); _victim = BuildHalf(val2, "Victim"); _panel = val; val.SetActive(false); return true; } private static Half BuildHalf(RectTransform parent, string name) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Expected O, but got Unknown //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Expected O, but got Unknown GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent((Transform)(object)parent, false); VerticalLayoutGroup val2 = val.AddComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)val2).spacing = 6f; ((LayoutGroup)val2).childAlignment = (TextAnchor)0; ((HorizontalOrVerticalLayoutGroup)val2).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)val2).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)val2).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)val2).childForceExpandHeight = false; GameObject val3 = new GameObject("Title", new Type[1] { typeof(RectTransform) }); val3.transform.SetParent(val.transform, false); TextMeshProUGUI val4 = val3.AddComponent<TextMeshProUGUI>(); if ((Object)(object)Menu.FontAsset != (Object)null) { ((TMP_Text)val4).font = Menu.FontAsset; } ((TMP_Text)val4).fontSize = 18f; ((Graphic)val4).color = Color.white; ((TMP_Text)val4).alignment = (TextAlignmentOptions)4097; ((TMP_Text)val4).enableWordWrapping = false; ((TMP_Text)val4).overflowMode = (TextOverflowModes)0; ((Graphic)val4).raycastTarget = false; LayoutElement val5 = val3.AddComponent<LayoutElement>(); val5.minHeight = 26f; val5.preferredHeight = 26f; GameObject val6 = new GameObject("Actions", new Type[1] { typeof(RectTransform) }); val6.transform.SetParent(val.transform, false); GridLayoutGroup val7 = val6.AddComponent<GridLayoutGroup>(); val7.cellSize = new Vector2(160f, 36f); val7.spacing = new Vector2(6f, 6f); val7.startCorner = (Corner)0; val7.startAxis = (Axis)0; ((LayoutGroup)val7).childAlignment = (TextAnchor)0; val7.constraint = (Constraint)1; val7.constraintCount = 3; Half half = new Half(); half.Title = (TMP_Text)(object)val4; half.Grid = (RectTransform)val6.transform; return half; } private static void Fill(KillLogInfo info) { //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) ClientRoundPlayer player = (info.KillerIsVictim ? null : info.Killer); SetHalf(_killer, info.KillerIsVictim ? "Killer: suicide" : ("Killer: " + Name(info.KillerName, player)), player); SetHalf(_victim, "Victim: " + Name(info.VictimName, info.Victim), info.Victim); int num = Mathf.Max(1, Mathf.CeilToInt((float)Mathf.Max(_killer.Buttons, _victim.Buttons) / 3f)); float num2 = 52f + (float)num * 36f + (float)(num - 1) * 6f; _size.minHeight = num2; _size.preferredHeight = num2; RectTransform val = (RectTransform)_panel.transform; val.sizeDelta = new Vector2(val.sizeDelta.x, num2); } private static string Name(string shown, ClientRoundPlayer player) { if (!string.IsNullOrEmpty(shown)) { return shown; } return (player == null) ? "none" : ("Player " + ((RoundPlayer)player).NetworkPlayerID); } private static void SetHalf(Half half, string title, ClientRoundPlayer player) { for (int num = ((Transform)half.Grid).childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)((Transform)half.Grid).GetChild(num)).gameObject); } half.Title.text = title; half.Buttons = 0; if (player == null) { return; } int id = ((RoundPlayer)player).NetworkPlayerID; Add(half, "Spectate", "hui-p-players-unspawned", delegate { PlayerActions.Spectate(id); }); Add(half, "Go To", "hui-p-tab-maps", delegate { PlayerActions.GoTo(id); }); Add(half, "Bring", "hui-p-tab-players", delegate { PlayerActions.Bring(id); }); Confirmed(half, id, "Slay", "hui-p-slay", PlayerActions.Slay); Add(half, "Revive", "hui-p-revive", delegate { PlayerActions.Revive(id); }); Add(half, "Heal", "hui-p-heal", delegate { PlayerActions.Heal(id); }); Confirmed(half, id, "Slap", "hui-p-slap", PlayerActions.Slap); Confirmed(half, id, "Kick", "hui-p-kick", PlayerActions.Kick); for (int num2 = 0; num2 < PlayerRow.ActionCount; num2++) { if (PlayerRow.ActionVisible(num2)) { int index = num2; Add(half, PlayerRow.ActionLabel(num2), "hui-p-tab-admin", delegate { PlayerRow.RunAction(index, id); }, PlayerRow.ActionOwner(num2)); } } } private static void Add(Half half, string label, string icon, Action click, string owner = null) { Make(half, Controls.Button(owner ?? "com.ryannlt.rylib", label, click, icon)); } private static void Confirmed(Half half, int id, string action, string icon, Action<int> run) { ControlSpec controlSpec = Controls.Button("com.ryannlt.rylib", action, delegate { if (Armed(id, action)) { _armedPlayer = -1; run(id); } else { _armedPlayer = id; _armedAction = action; _armedUntil = Time.unscaledTime + 4f; } }, icon); controlSpec.Text = () => Armed(id, action) ? ("Confirm " + action) : action; Make(half, controlSpec); } private static bool Armed(int id, string action) { return _armedPlayer == id && _armedAction == action && Time.unscaledTime <= _armedUntil; } private static void Make(Half half, ControlSpec spec) { Control control = Controls.Make(spec, (Transform)(object)half.Grid, Menu.ControlTemplate); if (control != null) { half.Buttons++; if (!((Object)(object)control.Label == (Object)null)) { control.Label.enableWordWrapping = false; control.Label.fontSizeMax = control.Label.fontSize; control.Label.fontSizeMin = 9f; control.Label.enableAutoSizing = true; } } } } [HarmonyPatch(typeof(UIAdminPlayerKillLogPanelRow), "Setup")] internal static class KillLogRowSetupPatch { private static void Postfix(UIAdminPlayerKillLogPanelRow __instance) { try { KillLogRows.Attach(__instance); } catch (Exception ex) { Log.Error("kill log row actions could not be attached: " + ex.Message); } } } [HarmonyPatch(typeof(UIAdminPlayerKillLogPanel), "PopulateKillLogRows")] internal static class KillLogPopulatePatch { private static void Postfix() { KillLogRows.Place(); } } [HarmonyPatch(typeof(UIAdminPlayerKillLogPanel), "UpdateFilteredPlayers")] internal static class KillLogFilterPlacePatch { private static void Postfix() { KillLogRows.Place(); } } [HarmonyPatch(typeof(UIAdminPlayerKillLogPanel), "_ResetObject")] internal static class KillLogResetClosePatch { private static void Postfix() { KillLogRows.Close(); } } [HarmonyPatch(typeof(UIAdminPlayerKillLogPanel), "_ToggleShowing")] internal static class KillLogHideClosePatch { private static void Postfix(bool show) { if (!show) { KillLogRows.Close(); } } } internal static class Menu { private struct Anchoring { public Vector2 Min; public Vector2 Max; public Vector2 Size; public Vector2 Position; } private const float RefreshSeconds = 0.25f; private const int FirstTabType = 100; private const float StripSpacing = 70f; private const float StripOffset = -25f; private const float HeaderFont = 18f; private const float MinHeaderFont = 12f; private const float HeaderPadding = 8f; private const float NavWidth = 240f; private const float NavGap = 20f; private const float NavButtonHeight = 48f; private static readonly PMenuTabType[] StockOrder; internal static readonly List<HeaderTab> Headers; private static readonly FieldRef<PMenuPanel, Dictionary<PMenuTabType, PMenuPanelTabBase>> TabsField; private static readonly MethodInfo SwitchTabMethod; private static readonly Dictionary<PMenuTabType, PMenuTabButton> StockHeaders; private static readonly List<HeaderTab> Visible; private static readonly List<Page> VisiblePages; private static readonly Dictionary<TMP_Text, Vector2> LabelHomes; private static PMenuPanel _panel; private static bool _dirty; private static bool _failed; private static bool _refreshFailed; private static float _nextRefresh; private static int _nextType; private static string _layout; private static RectTransform _banner; private static RectTransform _players; private static RectTransform _rules; private static RectTransform _adminTabs; private static Anchoring _playersHome; private static Anchoring _rulesHome; private static Anchoring _adminHome; private static GameObject _headerTemplate; private static GameObject _stripTemplate; private static GameObject _childTemplate; private static GameObject _headerBackground; private static GameObject _scrollView; private static GameObject _controlTemplate; private static Canvas _panelCanvas; private static TMP_FontAsset _font; internal static Transform SpriteRoot => ((Object)(object)_panel == (Object)null) ? null : ((Component)_panel).transform; internal static GameObject ControlTemplate => _controlTemplate; internal static Canvas PanelCanvas => _panelCanvas; internal static TMP_FontAsset FontAsset => _font; private static bool AdminTabsShowing => (Object)(object)_adminTabs != (Object)null && ((Component)_adminTabs).gameObject.activeSelf; internal static void MarkDirty() { _dirty = true; } internal static HeaderTab FindHeader(string name) { for (int i = 0; i < Headers.Count; i++) { if (Owners.Same(Headers[i].Name, name)) { return Headers[i]; } } return null; } internal static void Tick() { PMenuPanel val = CurrentPanel(); if ((Object)(object)val != (Object)(object)_panel) { Forget(); _panel = val; _dirty = true; _failed = false; _refreshFailed = false; } if ((Object)(object)_panel == (Object)null) { return; } if (_dirty && !_failed && Ready(_panel)) { _dirty = false; try { Build(); } catch (Exception ex) { _failed = true; Log.Error("P menu extensions could not be built: " + ex); } } if (Time.unscaledTime < _nextRefresh) { return; } _nextRefresh = Time.unscaledTime + 0.25f; try { Refresh(); } catch (Exception ex2) { if (!_refreshFailed) { _refreshFailed = true; Log.Error("P menu refresh failed: " + ex2); } } } private static PMenuPanel CurrentPanel() { ClientComponentReferenceManager clientInstance = ClientComponentReferenceManager.ClientInstance; if ((Object)(object)clientInstance == (Object)null) { return null; } PMenuPanel pMenuPanel = clientInstance.pMenuPanel; return ((Object)(object)pMenuPanel == (Object)null) ? null : pMenuPanel; } private static bool Ready(PMenuPanel panel) { if ((Object)(object)panel.tabButtonsRootTransform == (Object)null || (Object)(object)panel.tabsRootTransform == (Object)null) { return false; } Dictionary<PMenuTabType, PMenuPanelTabBase> dictionary = TabsField.Invoke(panel); return dictionary != null && dictionary.Count > 0; } private static void Forget() { for (int i = 0; i < Headers.Count; i++) { HeaderTab headerTab = Headers[i]; headerTab.Root = null; headerTab.Rect = null; headerTab.Switch = null; headerTab.Label = null; headerTab.Strip = null; headerTab.StripGroup = null; for (int j = 0; j < headerTab.Pages.Count; j++) { Page page = headerTab.Pages[j]; page.Root = null; page.Tab = null; page.Button = null; page.Switch = null; page.Content = null; page.TitleTemplate = null; page.Map = null; page.Nav = null; page.Scroller = null; for (int k = 0; k < page.Sections.Count; k++) { page.Sections[k].Built = false; } for (int l = 0; l < page.ModTabs.Count; l++) { ModTab modTab = page.ModTabs[l]; modTab.Content = null; modTab.Button = null; for (int m = 0; m < modTab.Sections.Count; m++) { modTab.Sections[m].Built = false; } } } } PlayersBar.Forget(); StockHeaders.Clear(); LabelHomes.Clear(); _banner = null; _players = null; _rules = null; _adminTabs = null; _headerTemplate = null; _stripTemplate = null; _childTemplate = null; _headerBackground = null; _scrollView = null; _controlTemplate = null; _panelCanvas = null; _layout = null; } private static void Build() { if ((Object)(object)_banner == (Object)null) { Capture(); } if ((Object)(object)_controlTemplate != (Object)null) { PlayersBar.Build(_controlTemplate); } for (int i = 0; i < Headers.Count; i++) { HeaderTab headerTab = Headers[i]; if ((Object)(object)headerTab.Root == (Object)null && !BuildHeader(headerTab)) { continue; } for (int j = 0; j < headerTab.Pages.Count; j++) { Page page = headerTab.Pages[j]; if (!((Object)(object)page.Root == (Object)null) || BuildPage(headerTab, page)) { if (page.Kind == PageKind.Mods) { BuildModTabs(page); } else { BuildSections(page); } } } } _layout = null; Refresh(); } private static void Capture() { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Invalid comparison between Unknown and I4 //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Invalid comparison between Unknown and I4 //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Invalid comparison between Unknown and I4 //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Invalid comparison between Unknown and I4 _banner = _panel.tabButtonsRootTransform; Transform val = (Transform)(object)_banner; while ((Object)(object)val != (Object)null) { Canvas component = ((Component)val).GetComponent<Canvas>(); if ((Object)(object)component != (Object)null) { _panelCanvas = component; } val = val.parent; } TMP_Text componentInChildren = ((Component)_panel.tabsRootTransform).GetComponentInChildren<TMP_Text>(true); if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.font != (Object)null) { _font = componentInChildren.font; } PMenuTabButton[] componentsInChildren = ((Component)_banner).GetComponentsInChildren<PMenuTabButton>(true); foreach (PMenuTabButton val2 in componentsInChildren) { StockHeaders[val2.tabType] = val2; if ((int)val2.tabType == 0) { Transform transform = ((Component)val2).transform; _players = (RectTransform)(object)((transform is RectTransform) ? transform : null); } else if ((int)val2.tabType == 1) { Transform transform2 = ((Component)val2).transform; _rules = (RectTransform)(object)((transform2 is RectTransform) ? transform2 : null); } else if ((int)val2.tabType == 2) { Transform parent = ((Component)val2).transform.parent; _adminTabs = (RectTransform)(object)((parent is RectTransform) ? parent : null); } if ((Object)(object)val2.toggle != (Object)null && !val2.toggle.isOn && ((Object)(object)_headerTemplate == (Object)null || (int)val2.tabType == 1)) { _headerTemplate = ((Component)val2).gameObject; } } if ((Object)(object)_players != (Object)null) { _playersHome = Save(_players); } if ((Object)(object)_rules != (Object)null) { _rulesHome = Save(_rules); } if ((Object)(object)_adminTabs != (Object)null && (Object)(object)_adminTabs != (Object)(object)_banner) { _adminHome = Save(_adminTabs); } else { _adminTabs = null; } if ((Object)(object)_panel.playerChildTabButtonsRoot != (Object)null) { _stripTemplate = _panel.playerChildTabButtonsRoot; PMenuChildTabButton[] componentsInChildren2 = _stripTemplate.GetComponentsInChildren<PMenuChildTabButton>(true); for (int j = 0; j < componentsInChildren2.Length; j++) { if (!((Object)(object)componentsInChildren2[j].toggle != (Object)null) || !componentsInChildren2[j].toggle.isOn) { _childTemplate = ((Component)componentsInChildren2[j]).gameObject; break; } } } UIRoundPlayersControlPanel componentInChildren2 = ((Component)_panel.tabsRootTransform).GetComponentInChildren<UIRoundPlayersControlPanel>(true); if ((Object)(object)componentInChildren2 != (Object)null && (Object)(object)componentInChildren2.adminRaygunToggleButton != (Object)null) { Transform transform3 = ((Component)componentInChildren2.adminRaygunToggleButton).transform; _controlTemplate = (((Object)(object)transform3.parent != (Object)null) ? ((Component)transform3.parent).gameObject : ((Component)transform3).gameObject); Controls.SetPalette(componentInChildren2); } UIAdminPlayerKillLogPanel componentInChildren3 = ((Component)_panel.tabsRootTransform).GetComponentInChildren<UIAdminPlayerKillLogPanel>(true); if ((Object)(object)componentInChildren3 != (Object)null) { Transform val3 = ((Component)componentInChildren3).transform.Find("Header Background"); Transform val4 = ((Component)componentInChildren3).transform.Find("Scroll View"); _headerBackground = (((Object)(object)val3 == (Object)null) ? null : ((Component)val3).gameObject); _scrollView = (((Object)(object)val4 == (Object)null) ? null : ((Component)val4).gameObject); } StringBuilder stringBuilder = new StringBuilder(); if ((Object)(object)_headerTemplate == (Object)null) { stringBuilder.Append(" header"); } if ((Object)(object)_stripTemplate == (Object)null || (Object)(object)_childTemplate == (Object)null) { stringBuilder.Append(" child-tab"); } if ((Object)(object)_controlTemplate == (Object)null) { stringBuilder.Append(" raygun"); } if ((Object)(object)_headerBackground == (Object)null || (Object)(object)_scrollView == (Object)null) { stringBuilder.Append(" page-frame"); } if ((Object)(object)_players == (Object)null || (Object)(object)_rules == (Object)null) { stringBuilder.Append(" stock-headers"); } if (stringBuilder.Length > 0) { Log.Warn("P menu templates not found:" + stringBuilder?.ToString() + ". Those parts of the UI are skipped."); } } private static bool BuildHeader(HeaderTab header) { if ((Object)(object)_headerTemplate == (Object)null || (Object)(object)_banner == (Object)null) { return false; } GameObject val = Object.Instantiate<GameObject>(_headerTemplate, (Transform)(object)_banner); ((Object)val).name = "RyLib_Header_" + header.Name; DropTabData(val); UiClone.Strip(val); Toggle component = val.GetComponent<Toggle>(); if ((Object)(object)component == (Object)null) { Object.Destroy((Object)(object)val); return false; } UiClone.Mute((UnityEventBase)(object)component.onValueChanged); component.SetIsOnWithoutNotify(false); TMP_Text componentInChildren = val.GetComponentInChildren<TMP_Text>(true); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.text = header.Name; } SetIcon(val.transform, header.IconName); HeaderTab captured = header; ((UnityEvent<bool>)(object)component.onValueChanged).AddListener((UnityAction<bool>)delegate(bool on) { HeaderToggled(captured, on); }); header.Root = val; ref RectTransform rect = ref header.Rect; Transform transform = val.transform; rect = (RectTransform)(object)((transform is RectTransform) ? transform : null); header.Switch = component; header.Label = componentInChildren; if ((Object)(object)_stripTemplate != (Object)null) { GameObject val2 = Object.Instantiate<GameObject>(_stripTemplate, (Transform)(object)_banner); ((Object)val2).name = "RyLib_Strip_" + header.Name; for (int num = val2.transform.childCount - 1; num >= 0; num--) { Object.DestroyImmediate((Object)(object)((Component)val2.transform.GetChild(num)).gameObject); } ToggleGroup val3 = val2.GetComponent<ToggleGroup>(); if ((Object)(object)val3 == (Object)null) { val3 = val2.AddComponent<ToggleGroup>(); } val3.allowSwitchOff = false; val2.SetActive(false); header.Strip = val2; header.StripGroup = val3; } return true; } private static bool BuildPage(HeaderTab header, Page page) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Expected O, but got Unknown //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Expected O, but got Unknown //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_02f4: Unknown result type (might be due to invalid IL or missing references) //IL_047d: Unknown result type (might be due to invalid IL or missing references) //IL_0484: Expected O, but got Unknown //IL_0486: Unknown result type (might be due to invalid IL or missing references) //IL_0493: Unknown result type (might be due to invalid IL or missing references) //IL_04a7: Unknown result type (might be due to invalid IL or missing references) //IL_04be: Unknown result type (might be due to invalid IL or missing references) //IL_0387: Unknown result type (might be due to invalid IL or missing references) //IL_038e: Expected O, but got Unknown //IL_03a9: Unknown result type (might be due to invalid IL or missing references) //IL_03b0: Expected O, but got Unknown //IL_03bc: Unknown result type (might be due to invalid IL or missing references) //IL_03d3: Unknown result type (might be due to invalid IL or missing references) //IL_03ea: Unknown result type (might be due to invalid IL or missing references) //IL_0401: Unknown result type (might be due to invalid IL or missing references) //IL_0418: Unknown result type (might be due to invalid IL or missing references) //IL_0580: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_headerBackground == (Object)null || (Object)(object)_scrollView == (Object)null || (Object)(object)header.Strip == (Object)null || (Object)(object)_childTemplate == (Object)null) { return false; } if (!page.HasType) { page.Type = (PMenuTabType)(_nextType++); page.HasType = true; } GameObject val = Object.Instantiate<GameObject>(_childTemplate, header.Strip.transform); ((Object)val).name = "RyLib_PageButton_" + page.Name; DropTabData(val); UiClone.Strip(val); Toggle component = val.GetComponent<Toggle>(); if ((Object)(object)component != (Object)null) { UiClone.Mute((UnityEventBase)(object)component.onValueChanged); component.group = header.StripGroup; component.SetIsOnWithoutNotify(false); Page captured = page; ((UnityEvent<bool>)(object)component.onValueChanged).AddListener((UnityAction<bool>)delegate(bool on) { if (on) { OpenPage(captured); } }); } SetIcon(val.transform, page.IconName); val.SetActive(true); GameObject val2 = new GameObject("RyLib_Page_" + header.Name + "_" + page.Name, new Type[1] { typeof(RectTransform) }); val2.SetActive(false); val2.transform.SetParent((Transform)(object)_panel.tabsRootTransform, false); RectTransform val3 = (RectTransform)val2.transform; val3.anchorMin = Vector2.zero; val3.anchorMax = Vector2.one; val3.offsetMin = Vector2.zero; val3.offsetMax = Vector2.zero; val2.AddComponent<Canvas>(); val2.AddComponent<GraphicRaycaster>(); PageTab pageTab = val2.AddComponent<PageTab>(); ((PMenuPanelTabBase)pageTab).TabType = page.Type; pageTab.Page = page; ((PMenuPanelTabBase)pageTab).ObjectToSelectOnOpen = header.Root; GameObject val4 = Object.Instantiate<GameObject>(_headerBackground, val2.transform); ((Object)val4).name = "Header Background"; Transform val5 = val4.transform.Find("Search"); TMP_InputField val6 = null; if ((Object)(object)val5 != (Object)null && page.Kind == PageKind.Map) { val6 = ((Component)val5).GetComponentInChildren<TMP_InputField>(true); } if ((Object)(object)val5 != (Object)null && (Object)(object)val6 == (Object)null) { Object.DestroyImmediate((Object)(object)((Component)val5).gameObject); } UiClone.Strip(val4); Transform val7 = val4.transform.Find("Title"); TMP_Text val8 = (((Object)(object)val7 == (Object)null) ? val4.GetComponentInChildren<TMP_Text>(true) : ((Component)val7).GetComponent<TMP_Text>()); if ((Object)(object)val8 != (Object)null) { val8.text = page.Name; } if (page.Kind == PageKind.Map) { page.Map = new MapView(page, val3, val8, val6); TabsField.Invoke(_panel)[page.Type] = (PMenuPanelTabBase)(object)pageTab; page.Root = val2; page.Tab = pageTab; page.Button = val; page.Switch = component; page.TitleTemplate = val8; return true; } GameObject val9 = Object.Instantiate<GameObject>(_scrollView, val2.transform); ((Object)val9).name = "Scroll View"; UiClone.Strip(val9); float num = 25f; if (page.Kind == PageKind.Mods) { GameObject val10 = new GameObject("Mod Tabs", new Type[1] { typeof(RectTransform) }); val10.transform.SetParent(val2.transform, false); RectTransform val11 = (RectTransform)val10.transform; val11.anchorMin = new Vector2(0f, 0f); val11.anchorMax = new Vector2(0f, 1f); val11.pivot = new Vector2(0f, 1f); val11.offsetMin = new Vector2(25f, 25f); val11.offsetMax = new Vector2(265f, -135f); VerticalLayoutGroup val12 = val10.AddComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)val12).spacing = 8f; ((LayoutGroup)val12).childAlignment = (TextAnchor)0; ((HorizontalOrVerticalLayoutGroup)val12).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)val12).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)val12).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)val12).childForceExpandHeight = false; page.Nav = val11; num = 285f; } RectTransform val13 = (RectTransform)val9.transform; val13.anchorMin = Vector2.zero; val13.anchorMax = Vector2.one; val13.offsetMin = new Vector2(num, 25f); val13.offsetMax = new Vector2(-25f, -135f); ScrollRect val14 = (page.Scroller = val9.GetComponent<ScrollRect>()); RectTransform val15 = (((Object)(object)val14 == (Object)null) ? null : val14.content); if ((Object)(object)val15 == (Object)null) { Object.Destroy((Object)(object)val2); Object.Destroy((Object)(object)val); Log.Warn("the page frame has no scroll content, so page '" + page.Name + "' was skipped."); return false; } for (int num2 = ((Transform)val15).childCount - 1; num2 >= 0; num2--) { Object.DestroyImmediate((Object)(object)((Component)((Transform)val15).GetChild(num2)).gameObject); } PrepareContent(val15); TabsField.Invoke(_panel)[page.Type] = (PMenuPanelTabBase)(object)pageTab; page.Root = val2; page.Tab = pageTab; page.Button = val; page.Switch = component; page.Content = val15; page.TitleTemplate = val8; return true; } private static void PrepareContent(RectTransform content) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown LayoutGroup component = ((Component)content).GetComponent<LayoutGroup>(); if ((Object)(object)component != (Object)null && !(component is VerticalLayoutGroup)) { Object.DestroyImmediate((Object)(object)component); } VerticalLayoutGroup val = ((Component)content).GetComponent<VerticalLayoutGroup>(); if ((Object)(object)val == (Object)null) { val = ((Component)content).gameObject.AddComponent<VerticalLayoutGroup>(); } ((LayoutGroup)val).padding = new RectOffset(10, 10, 10, 10); ((HorizontalOrVerticalLayoutGroup)val).spacing = 20f; ((LayoutGroup)val).childAlignment = (TextAnchor)0; ((HorizontalOrVerticalLayoutGroup)val).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)val).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)val).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)val).childForceExpandHeight = false; ContentSizeFitter val2 = ((Component)content).GetComponent<ContentSizeFitter>(); if ((Object)(object)val2 == (Object)null) { val2 = ((Component)content).gameObject.AddComponent<ContentSizeFitter>(); } val2.horizontalFit = (FitMode)0; val2.verticalFit = (FitMode)2; } private static void BuildSections(Page page) { if (page.Kind == PageKind.Sections && !((Object)(object)page.Content == (Object)null) && !((Object)(object)_controlTemplate == (Object)null)) { BuildSectionList(page, page.Sections, page.Content, 3); } } private static void BuildModTabs(Page page) { //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Expected O, but got Unknown if (page.Kind != PageKind.Mods || (Object)(object)page.Content == (Object)null || (Object)(object)page.Nav == (Object)null || (Object)(object)_controlTemplate == (Object)null) { return; } for (int i = 0; i < page.ModTabs.Count; i++) { ModTab modTab = page.ModTabs[i]; if ((Object)(object)modTab.Content == (Object)null) { GameObject val = new GameObject("RyLib_ModTab_" + modTab.Name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent((Transform)(object)page.Content, false); VerticalLayoutGroup val2 = val.AddComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)val2).spacing = 20f; ((LayoutGroup)val2).childAlignment = (TextAnchor)0; ((HorizontalOrVerticalLayoutGroup)val2).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)val2).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)val2).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)val2).childForceExpandHeight = false; modTab.Content = (RectTransform)val.transform; ModTab captured = modTab; ControlSpec controlSpec = Controls.Button(modTab.Creator, modTab.Name, delegate { SelectModTab(page, captured); }, modTab.IconName ?? "hui-p-tab-admin"); controlSpec.IsOn = () => page.CurrentModTab == captured; modTab.Button = Controls.Make(controlSpec, (Transform)(object)page.Nav, _controlTemplate); if (modTab.Button != null) { LayoutElement val3 = modTab.Button.Root.GetComponent<LayoutElement>(); if ((Object)(object)val3 == (Object)null) { val3 = modTab.Button.Root.AddComponent<LayoutElement>(); } val3.minHeight = 48f; val3.preferredHeight = 48f; val3.flexibleHeight = 0f; val3.minWidth = -1f; val3.preferredWidth = -1f; val3.flexibleWidth = 1f; } } BuildSectionList(page, modTab.Sections, modTab.Content, 2); } RefreshModTabs(page); } private static void SelectModTab(Page page, ModTab tab) { page.CurrentModTab = tab; ShowModTab(page); } private static void RefreshModTabs(Page page) { if (page.Kind != PageKind.Mods || (Object)(object)page.Nav == (Object)null) { return; } ModTab modTab = null; for (int i = 0; i < page.ModTabs.Count; i++) { ModTab modTab2 = page.ModTabs[i]; bool visible = modTab2.Visible; if (visible && modTab == null) { modTab = modTab2; } if (modTab2.Button != null && (Object)(object)modTab2.Button.Root != (Object)null && modTab2.Button.Root.activeSelf != visible) { modTab2.Button.Root.SetActive(visible); } } if (page.CurrentModTab == null || !page.CurrentModTab.Visible) { page.CurrentModTab = modTab; ShowModTab(page); } } private static void ShowModTab(Page page) { for (int i = 0; i < page.ModTabs.Count; i++) { ModTab modTab = page.ModTabs[i]; bool flag = modTab == page.CurrentModTab; if ((Object)(object)modTab.Content != (Object)null && ((Component)modTab.Content).gameObject.activeSelf != flag) { ((Component)modTab.Content).gameObject.SetActive(flag); } if (modTab.Button != null) { Controls.Refresh(modTab.Button); } } if ((Object)(object)page.Scroller != (Object)null) { page.Scroller.verticalNormalizedPosition = 1f; } } private static void BuildSectionList(Page page, List<SectionSpec> sections, RectTransform parent, int columns) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Expected O, but got Unknown //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < sections.Count; i++) { SectionSpec spec = sections[i]; if (spec.Built) { continue; } spec.Built = true; GameObject val = new GameObject("RyLib_Section_" + spec.Owner + "_" + spec.Title, new Type[1] { typeof(RectTransform) }); val.transform.SetParent((Transform)(object)parent, false); VerticalLayoutGroup val2 = val.AddComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)val2).spacing = 10f; ((LayoutGroup)val2).childAlignment = (TextAnchor)0; ((HorizontalOrVerticalLayoutGroup)val2).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)val2).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)val2).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)val2).childForceExpandHeight = false; if ((Object)(object)page.TitleTemplate != (Object)null) { TMP_Text val3 = Object.Instantiate<TMP_Text>(page.TitleTemplate, val.transform); ((Object)val3).name = "Heading"; val3.text = spec.Title; val3.fontSize = 24f; val3.enableAutoSizing = false; val3.alignment = (TextAlignmentOptions)4097; LayoutElement val4 = ((Component)val3).gameObject.AddComponent<LayoutElement>(); val4.preferredHeight = 34f; } GameObject val5 = new GameObject("Controls", new Type[1] { typeof(RectTransform) }); val5.transform.SetParent(val.transform, false); GridLayoutGroup val6 = val5.AddComponent<GridLayoutGroup>(); val6.cellSize = new Vector2(330f, 48f); val6.spacing = new Vector2(15f, 10f); val6.startCorner = (Corner)0; val6.startAxis = (Axis)0; ((LayoutGroup)val6).childAlignment = (TextAnchor)0; val6.constraint = (Constraint)1; val6.constraintCount = columns; Section builder = new Section(spec.Owner, val5.transform); Owners.Run(spec.Owner, "section '" + spec.Title + "'", delegate { spec.Build(builder); }); if (builder.First != null && (Object)(object)page.Tab != (Object)null && (Object)(object)((PMenuPanelTabBase)page.Tab).ObjectToSelectOnOpen == (Object)(object)page.Header.Root) { Button componentInChildren = builder.First.Root.GetComponentInChildren<Button>(true); if ((Object)(object)componentInChildren != (Object)null) { ((PMenuPanelTabBase)page.Tab).ObjectToSelectOnOpen = ((Component)componentInChildren).gameObject; } } } } private static void HeaderToggled(HeaderTab header, bool on) { if (on) { Page page = header.Selected; if (page == null || (Object)(object)page.Tab == (Object)null || !page.Visible) { page = FirstVisible(header); } if (page != null) { OpenPage(page); } } UpdateStrip(header); } private static Page FirstVisible(HeaderTab header) { for (int i = 0; i < header.Pages.Count; i++) { Page page = header.Pages[i]; if ((Object)(object)page.Tab != (Object)null && page.Visible) { return page; } } return null; } private static void OpenPage(Page page) { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_panel == (Object)null || (Object)(object)page.Tab == (Object)null || SwitchTabMethod == null) { return; } HeaderTab header = page.Header; header.Selected = page; for (int i = 0; i < header.Pages.Count; i++) { Toggle val = header.Pages[i].Switch; if ((Object)(object)val != (Object)null) { val.SetIsOnWithoutNotify(header.Pages[i] == page); } } SwitchTabMethod.Invoke(_panel, new object[1] { page.Type }); UpdateStrip(header); } private static void Refresh() { Visible.Clear(); for (int i = 0; i < Headers.Count; i++) { HeaderTab headerTab = Headers[i]; if (!((Object)(object)headerTab.Root == (Object)null)) { bool flag = FirstVisible(headerTab) != null; if (headerTab.Root.activeSelf != flag) { headerTab.Root.SetActive(flag); } if (flag) { Visible.Add(headerTab); } } } string text = Key(); if (text != _layout) { _layout = text; Layout(); } for (int j = 0; j < Headers.Count; j++) { UpdateStrip(Headers[j]); List<Page> pages = Headers[j].Pages; for (int k = 0; k < pages.Count; k++) { RefreshModTabs(pages[k]); } } PlayersBar.Refresh(_controlTemplate); Controls.RefreshVisible(); } private static string Key() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(AdminTabsShowing ? 'A' : 'a'); for (int i = 0; i < Visible.Count; i++) { stringBuilder.Append('|').Append(Visible[i].Name); } return stringBuilder.ToString(); } private static void Layout() { if ((Object)(object)_banner == (Object)null || (Object)(object)_players == (Object)null || (Object)(object)_rules == (Object)null) { return; } if (Visible.Count == 0) { Load(_players, _playersHome); Load(_rules, _rulesHome); if ((Object)(object)_adminTabs != (Object)null) { Load(_adminTabs, _adminHome); } RestoreLabels(); return; } bool adminTabsShowing = AdminTabsShowing; int num = (adminTabsShowing ? 6 : 2); int count = num + Visible.Count; Place(_players, 0, 1, count); Place(_rules, 1, 1, count); if (adminTabsShowing) { Place(_adminTabs, 2, 4, count); } for (int i = 0; i < Visible.Count; i++) { Place(Visible[i].Rect, num + i, 1, count); } foreach (KeyValuePair<PMenuTabType, PMenuTabButton> stockHeader in StockHeaders) { if (!((Object)(object)stockHeader.Value == (Object)null)) { Transform transform = ((Component)stockHeader.Value).transform; FitHeader((RectTransform)(object)((transform is RectTransform) ? transform : null), ((Component)stockHeader.Value).GetComponentInChildren<TMP_Text>(true)); } } for (int j = 0; j < Visible.Count; j++) { FitHeader(Visible[j].Rect, Visible[j].Label); } } private static void Place(RectTransform rect, int start, int span, int count) { //IL_003b: 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_0059: 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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)rect == (Object)null)) { float num = ((start == 0) ? 0f : 1f); float num2 = ((start + span >= count) ? 0f : 1f); rect.anchorMin = new Vector2((float)start / (float)count, rect.anchorMin.y); rect.anchorMax = new Vector2((float)(start + span) / (float)count, rect.anchorMax.y); rect.sizeDelta = new Vector2(0f - (num + num2), rect.sizeDelta.y); rect.anchoredPosition = new Vector2(num * (1f - rect.pivot.x) - num2 * rect.pivot.x, rect.anchoredPosition.y); } } private static void FitHeader(RectTransform button, TMP_Text label) { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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_0098: 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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0124: 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_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)button == (Object)null || (Object)(object)label == (Object)null) { return; } RectTransform rectTransform = label.rectTransform; if (!LabelHomes.TryGetValue(label, out var value)) { ((Vector2)(ref value))..ctor(Mathf.Min(label.fontSize, 18f), rectTransform.anchoredPosition.x); LabelHomes[label] = value; } rectTransform.anchoredPosition = new Vector2(value.y, rectTransform.anchoredPosition.y); RectTransform icon = HeaderIcon(label, button); Rect rect = button.rect; float num = ((Rect)(ref rect)).width - 16f; float num2 = value.x; label.enableAutoSizing = false; float left; float right; while (true) { label.fontSize = num2; Extent(label, icon, out left, out right); if (right - left <= num || num2 <= 12f) { break; } num2 -= 1f; } float x = ((Transform)button).InverseTransformPoint(((Transform)rectTransform).position).x; float num3 = 0.5f - button.pivot.x; rect = button.rect; float num4 = num3 * ((Rect)(ref rect)).width; float num5 = num4 - (x + (left + right) * 0.5f); rectTransform.anchoredPosition = new Vector2(value.y + num5, rectTransform.anchoredPosition.y); } private static void Extent(TMP_Text label, RectTransform icon, out float left, out float right) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007d: 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_009c: 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_00b6: Unknown result type (might be due to invalid IL or missing references) RectTransform rectTransform = label.rectTransform; float x = label.GetPreferredValues(label.text).x; left = (0f - rectTransform.pivot.x) * x; right = (1f - rectTransform.pivot.x) * x; if (!((Object)(object)icon == (Object)null) && ((Component)icon).gameObject.activeSelf && !((Object)(object)((Transform)icon).parent != (Object)(object)rectTransform)) { Rect rect = icon.rect; float width = ((Rect)(ref rect)).width; float num = (icon.anchorMin.x + icon.anchorMax.x) * 0.5f; float num2 = (num - rectTransform.pivot.x) * x + icon.anchoredPosition.x - icon.pivot.x * width; left = Mathf.Min(left, num2); right = Mathf.Max(right, num2 + width); } } private static RectTransform HeaderIcon(TMP_Text label, RectTransform button) { Transform val = label.transform.Find("Icon"); if ((Object)(object)val == (Object)null) { val = ((Transform)button).Find("Icon"); } return (RectTransform)(object)((val is RectTransform) ? val : null); } private static void RestoreLabels() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //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) foreach (KeyValuePair<TMP_Text, Vector2> labelHome in LabelHomes) { if (!((Object)(object)labelHome.Key == (Object)null)) { labelHome.Key.fontSize = labelHome.Value.x; RectTransform rectTransform = labelHome.Key.rectTransform; rectTransform.anchoredPosition = new Vector2(labelHome.Value.y, rectTransform.anchoredPosition.y); } } } private static void UpdateStrip(HeaderTab header) { //IL_00f8: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)header.Strip == (Object)null) { return; } VisiblePages.Clear(); for (int i = 0; i < header.Pages.Count; i++) { Page page = header.Pages[i]; if (!((Object)(object)page.Button == (Object)null)) { bool visible = page.Visible; if (page.Button.activeSelf != visible) { page.Button.SetActive(visible); } if (visible) { VisiblePages.Add(page); } } } for (int j = 0; j < VisiblePages.Count; j++) { Transform transform = VisiblePages[j].Button.transform; RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null); if (!((Object)(object)val == (Object)null)) { val.anchoredPosition = new Vector2(-25f - 70f * (float)(VisiblePages.Count - 1 - j), 0f); } } bool flag = (Object)(object)header.Root != (Object)null && header.Root.activeSelf && (Object)(object)header.Switch != (Object)null && header.Switch.isOn && VisiblePages.Count > 1; if (header.Strip.activeSelf != flag) { header.Strip.SetActive(flag); } } internal static bool Cycle(PMenuPanel panel, bool next) { //IL_0100: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)panel == (Object)null || (Object)(object)panel != (Object)(object)_panel || !panel.CurrentlyShowing) { return false; } Visible.Clear(); for (int i = 0; i < Headers.Count; i++) { if ((Object)(object)Headers[i].Root != (Object)null && Headers[i].Root.activeSelf && (Object)(object)Headers[i].Switch != (Object)null) { Visible.Add(Headers[i]); } } if (Visible.Count == 0) { return false; } bool currentlyAdminMode = panel.currentlyAdminMode; int num = (currentlyAdminMode ? 6 : 2); int num2 = num + Visible.Count; int num3 = Slot(panel.CurrentActiveTabType, currentlyAdminMode, num); if (num3 < 0) { return false; } int num4 = (num3 + (next ? 1 : (num2 - 1))) % num2; if (num4 >= num) { Visible[num4 - num].Switch.isOn = true; return true; } if (!StockHeaders.TryGetValue(StockOrder[num4], out var value) || (Object)(object)value == (Object)null || (Object)(object)value.toggle == (Object)null) { return false; } value.toggle.isOn = true; return true; } private static int Slot(PMenuTabType type, bool admin, int stock) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Invalid comparison between Unknown and I4 //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Invalid comparison between I4 and Unknown //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) if ((int)type == 0 || (int)type == 6 || (int)type == 7 || (int)type == 8) { return 0; } if ((int)type == 1) { return 1; } if (admin) { for (int i = 2; i < StockOrder.Length; i++) { if ((int)StockOrder[i] == (int)type) { return i; } } } for (int j = 0; j < Visible.Count; j++) { List<Page> pages = Visible[j].Pages; for (int k = 0; k < pages.Count; k++) { if (pages[k].HasType && pages[k].Type == type) { return stock + j; } } } return -1; } private static void SetIcon(Transform root, string sprite) { if (string.IsNullOrEmpty(sprite)) { return; } Image val = null; Image[] componentsInChildren = ((Component)root).GetComponentsInChildren<Image>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if (!(((Object)componentsInChildren[i]).name != "Icon")) { val = componentsInChildren[i]; break; } } if (!((Object)(object)val == (Object)null)) { Sprite val2 = Sprites.Find(sprite, SpriteRoot); if ((Object)(object)val2 != (Object)null) { val.sprite = val2; } } } private static void DropTabData(GameObject root) { PMenuTabButton component = root.GetComponent<PMenuTabButton>(); if ((Object)(object)component != (Object)null) { Object.DestroyImmediate((Object)(object)component); } PMenuChildTabButton component2 = root.GetComponent<PMenuChildTabButton>(); if ((Object)(object)component2 != (Object)null) { Object.DestroyImmediate((Object)(object)component2); } } private static Anchoring Save(RectTransform rect) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) Anchoring result = default(Anchoring); result.Min = rect.anchorMin; result.Max = rect.anchorMax; result.Size = rect.sizeDelta; result.Position = rect.anchoredPosition; return result; } private static void Load(RectTransform rect, Anchoring anchoring) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)rect == (Object)null)) { rect.anchorMin = anchoring.Min; rect.anchorMax = anchoring.Max; rect.sizeDelta = anchoring.Size; rect.anchoredPosition = anchoring.Position; } } static Menu() { PMenuTabType[] array = new PMenuTabType[6]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); StockOrder = (PMenuTabType[])(object)array; Headers = new List<HeaderTab>(); TabsField = AccessTools.FieldRefAccess<PMenuPanel, Dictionary<PMenuTabType, PMenuPanelTabBase>>("tabs"); SwitchTabMethod = AccessTools.Method(typeof(PMenuPanel), "SwitchTab", new Type[1] { typeof(PMenuTabType) }, (Type[])null); StockHeaders = new Dictionary<PMenuTabType, PMenuTabButton>(); Visible = new List<HeaderTab>(); VisiblePages = new List<Page>(); LabelHomes = new Dictionary<TMP_Text, Vector2>(); _dirty = true; _nextType = 100; } } [HarmonyPatch(typeof(PMenuPanel), "SwitchToNextTab")] internal static class NextTabPatch { private static bool Prefix(PMenuPanel __instance) { return !Safe(__instance, next: true); } internal static bool Safe(PMenuPanel panel, bool next) { try { return Menu.Cycle(panel, next); } catch (Exception ex) { Log.Error("tab cycling failed: " + ex.Message); return false; } } } [HarmonyPatch(typeof(PMenuPanel), "SwitchToPreviousTab")] internal static class PreviousTabPatch { private static bool Prefix(PMenuPanel __instance) { return !NextTabPatch.Safe(__instance, next: false); } } internal sealed class PageTab : PMenuPanelTabBase { internal Page Page; public override void _InitializeOnMap(RoundGameDetails roundGameDetails) { if (Page != null && Page.Map != null) { Page.Map.Invalidate(); } } public override void _Awake() { } public override void _ResetObject() { if (Page != null && Page.Map != null) { Page.Map.Invalidate(); } } public override void _OnDestroy() { } public override void _ToggleShowing(bool show) { if (Page != null && Page.Map != null) { Page.Map.Show(show); } if (show) { Controls.RefreshVisible(); } } } internal static class PlayerActions { private const int GroundMask = 8705; private const int HealAmount = 100; private static ClientComponentReferenceManager Client => ClientComponentReferenceManager.ClientInstance; internal static void Spectate(int id) { ClientComponentReferenceManager client = Client; if ((Object)(object)client != (Object)null && (Object)(object)client.clientSpectatorManager != (Object)null) { client.clientSpectatorManager.SpectateStartRequest(id); } } internal static void Slay(int id) { ClientComponentReferenceManager client = Client; if ((Object)(object)client != (Object)null && (Object)(object)client.clientBannedPlayersManager != (Object)null) { client.clientBannedPlayersManager.RequestPlayerSlay(id, string.Empty); } } internal static void Revive(int id) { ClientComponentReferenceManager client = Client; if ((Object)(object)client != (Object)null && (Object)(object)client.clientBannedPlayersManager != (Object)null) { client.clientBannedPlayersManager.RequestPlayerRevive(id, string.Empty); } } internal static void Heal(int id) { ClientComponentReferenceManager client = Client; if ((Object)(object)client != (Object)null && (Object)(object)client.clientBannedPlayersManager != (Object)null) { client.clientBannedPlayersManager.RequestPlayerSlap(id, string.Empty, -100); } } internal static void