using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Shared;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("PingSystem")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+d0b18f487bc4ec855fd3a19ba360d2e089f76d81")]
[assembly: AssemblyProduct("PingSystem")]
[assembly: AssemblyTitle("PingSystem")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.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 Shared
{
public static class AccessTools
{
public static Type TypeByName(string name)
{
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
for (int i = 0; i < assemblies.Length; i++)
{
Type type = assemblies[i].GetType(name);
if (type != null)
{
return type;
}
}
return null;
}
public static MethodInfo Method(Type type, string name)
{
return type?.GetMethod(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
}
public static FieldInfo Field(Type type, string name)
{
return type?.GetField(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
}
public static PropertyInfo Property(Type type, string name)
{
return type?.GetProperty(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
}
}
public static class FuzzyMatcher
{
public static float CalculateScore(string target, string query)
{
if (string.IsNullOrEmpty(query))
{
return 0f;
}
if (string.IsNullOrEmpty(target))
{
return 0f;
}
string text = target.ToLowerInvariant();
string text2 = query.ToLowerInvariant();
if (text.StartsWith(text2))
{
return 2f;
}
if (IsAcronymMatch(text, text2))
{
return 1.5f;
}
if (text.Contains(text2))
{
return 0.5f;
}
return 0f;
}
private static bool IsAcronymMatch(string target, string query)
{
if (query.Length == 0)
{
return false;
}
if (target.Length == 0)
{
return false;
}
if (target[0] != query[0])
{
return false;
}
int i = 0;
int num = 0;
for (; i < target.Length; i++)
{
if (num >= query.Length)
{
break;
}
if (target[i] == query[num])
{
num++;
}
}
return num == query.Length;
}
public static IEnumerable<T> Filter<T>(IEnumerable<T> items, Func<T, string> selector, string query)
{
if (string.IsNullOrEmpty(query))
{
return items;
}
return from item in items
select new
{
Item = item,
Score = CalculateScore(selector(item), query)
} into x
where x.Score > 0f
orderby x.Score descending, selector(x.Item)
select x.Item;
}
}
}
namespace PingSystem
{
public static class CommandHelper
{
public static void Register(string name, string category, Action<string[]> handler, string desc)
{
try
{
Type type = Type.GetType("CommandAPI.CommandRegistry, CommandAPI");
if (type == null)
{
return;
}
Type type2 = Type.GetType("CommandAPI.Parameter, CommandAPI");
Type type3 = Type.GetType("CommandAPI.ParameterType, CommandAPI");
if (type2 == null || type3 == null)
{
return;
}
ConstructorInfo constructorInfo = type2.GetConstructors()[0];
ParameterInfo[] parameters = constructorInfo.GetParameters();
object[] array = new object[parameters.Length];
array[0] = "args";
array[1] = Enum.Parse(type3, "String");
for (int i = 2; i < parameters.Length; i++)
{
if (parameters[i].ParameterType == typeof(bool) && i == 2)
{
array[i] = false;
}
else if (parameters[i].HasDefaultValue)
{
array[i] = parameters[i].DefaultValue;
}
else
{
array[i] = null;
}
}
object value = constructorInfo.Invoke(array);
Array array2 = Array.CreateInstance(type2, 1);
array2.SetValue(value, 0);
type.GetMethod("Register", new Type[5]
{
typeof(string),
typeof(string),
typeof(Action<string[]>),
typeof(string),
array2.GetType()
})?.Invoke(null, new object[5] { name, category, handler, desc, array2 });
}
catch (Exception ex)
{
Debug.LogWarning((object)("[PingSystem] Failed to register /" + name + ": " + ex.Message));
}
}
public static void Notify(string message)
{
try
{
Type type = Type.GetType("CommandAPI.Utilities, CommandAPI");
if (!(type == null))
{
type.GetMethod("Notify", new Type[1] { typeof(string) })?.Invoke(null, new object[1] { message });
}
}
catch
{
}
}
}
public class MentionDropdown : MonoBehaviour
{
private GameObject dropdownPanel;
private GameObject contentContainer;
private List<GameObject> itemPool = new List<GameObject>();
private List<string> currentMatches = new List<string>();
private int selectedIndex = -1;
private TMP_InputField chatInput;
private RectTransform chatInputRect;
private const int MAX_VISIBLE_ITEMS = 8;
private const float MAX_DROPDOWN_HEIGHT = 600f;
private const float ITEM_HEIGHT = 55f;
private const float DROPDOWN_GAP = 20f;
private static readonly Color BACKGROUND_COLOR = new Color(0.96f, 0.9f, 0.84f, 1f);
private static readonly Color BORDER_COLOR = new Color(0.42f, 0.3f, 0.32f, 1f);
private static readonly Color HIGHLIGHT_COLOR = new Color(0.83f, 0.65f, 0.45f, 0.9f);
private static readonly Color TEXT_COLOR = new Color(0.29f, 0.22f, 0.16f, 1f);
private static readonly Color MENTION_COLOR = new Color(1f, 0.84f, 0f, 1f);
private Sprite roundedSprite;
private ScrollRect scrollRect;
private float _nextScrollTime;
private const float SCROLL_REPEAT_DELAY = 0.4f;
private const float SCROLL_REPEAT_RATE = 0.08f;
private bool _isScrolling;
private KeyCode _scrollDirection;
public bool IsVisible
{
get
{
GameObject obj = dropdownPanel;
if (obj == null)
{
return false;
}
return obj.activeSelf;
}
}
public int SelectedIndex => selectedIndex;
public void Initialize(TMP_InputField input)
{
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Expected O, but got Unknown
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_00da: Unknown result type (might be due to invalid IL or missing references)
//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
//IL_0105: Unknown result type (might be due to invalid IL or missing references)
//IL_0153: Unknown result type (might be due to invalid IL or missing references)
//IL_0159: Expected O, but got Unknown
//IL_0177: Unknown result type (might be due to invalid IL or missing references)
//IL_0182: Unknown result type (might be due to invalid IL or missing references)
//IL_0197: Unknown result type (might be due to invalid IL or missing references)
//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
//IL_0210: Unknown result type (might be due to invalid IL or missing references)
//IL_0217: Expected O, but got Unknown
//IL_0232: Unknown result type (might be due to invalid IL or missing references)
//IL_023d: Unknown result type (might be due to invalid IL or missing references)
//IL_0252: Unknown result type (might be due to invalid IL or missing references)
//IL_0266: Unknown result type (might be due to invalid IL or missing references)
//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
//IL_02d0: Expected O, but got Unknown
//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0311: Unknown result type (might be due to invalid IL or missing references)
//IL_0327: Unknown result type (might be due to invalid IL or missing references)
//IL_033d: Unknown result type (might be due to invalid IL or missing references)
//IL_0375: Unknown result type (might be due to invalid IL or missing references)
//IL_037f: Expected O, but got Unknown
//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
//IL_03c6: Unknown result type (might be due to invalid IL or missing references)
//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
//IL_0454: Unknown result type (might be due to invalid IL or missing references)
//IL_045b: Expected O, but got Unknown
//IL_0481: Unknown result type (might be due to invalid IL or missing references)
//IL_0496: Unknown result type (might be due to invalid IL or missing references)
//IL_04ab: Unknown result type (might be due to invalid IL or missing references)
//IL_04bf: Unknown result type (might be due to invalid IL or missing references)
//IL_04d4: Unknown result type (might be due to invalid IL or missing references)
//IL_0519: Unknown result type (might be due to invalid IL or missing references)
//IL_051e: Unknown result type (might be due to invalid IL or missing references)
//IL_0531: Unknown result type (might be due to invalid IL or missing references)
//IL_0538: Unknown result type (might be due to invalid IL or missing references)
//IL_0543: Unknown result type (might be due to invalid IL or missing references)
//IL_0558: Unknown result type (might be due to invalid IL or missing references)
//IL_056c: Unknown result type (might be due to invalid IL or missing references)
//IL_058f: Unknown result type (might be due to invalid IL or missing references)
//IL_05c2: Unknown result type (might be due to invalid IL or missing references)
//IL_05c9: Expected O, but got Unknown
//IL_05e5: Unknown result type (might be due to invalid IL or missing references)
//IL_05f0: Unknown result type (might be due to invalid IL or missing references)
//IL_0605: Unknown result type (might be due to invalid IL or missing references)
//IL_0619: Unknown result type (might be due to invalid IL or missing references)
//IL_063b: Unknown result type (might be due to invalid IL or missing references)
//IL_0640: Unknown result type (might be due to invalid IL or missing references)
//IL_0653: Unknown result type (might be due to invalid IL or missing references)
//IL_065d: Unknown result type (might be due to invalid IL or missing references)
//IL_0684: Unknown result type (might be due to invalid IL or missing references)
chatInput = input;
chatInputRect = ((Component)input).GetComponent<RectTransform>();
Image component = ((Component)input).GetComponent<Image>();
if ((Object)(object)component != (Object)null)
{
roundedSprite = component.sprite;
}
Canvas componentInParent = ((Component)input).GetComponentInParent<Canvas>();
Canvas val = ((componentInParent != null) ? componentInParent.rootCanvas : null);
if (!((Object)(object)val == (Object)null))
{
dropdownPanel = new GameObject("MentionDropdown", new Type[1] { typeof(RectTransform) });
dropdownPanel.transform.SetParent(((Component)val).transform, false);
Canvas obj = dropdownPanel.AddComponent<Canvas>();
obj.overrideSorting = true;
obj.sortingOrder = 30001;
dropdownPanel.AddComponent<GraphicRaycaster>();
RectTransform component2 = dropdownPanel.GetComponent<RectTransform>();
component2.pivot = new Vector2(0f, 0f);
component2.anchorMin = Vector2.zero;
component2.anchorMax = Vector2.zero;
component2.sizeDelta = new Vector2(300f, 600f);
Image val2 = dropdownPanel.AddComponent<Image>();
((Graphic)val2).color = BORDER_COLOR;
if ((Object)(object)roundedSprite != (Object)null)
{
val2.sprite = roundedSprite;
val2.type = (Type)1;
val2.pixelsPerUnitMultiplier = 4f;
}
GameObject val3 = new GameObject("Background", new Type[1] { typeof(RectTransform) });
val3.transform.SetParent(dropdownPanel.transform, false);
RectTransform component3 = val3.GetComponent<RectTransform>();
component3.anchorMin = Vector2.zero;
component3.anchorMax = Vector2.one;
component3.offsetMin = new Vector2(5f, 5f);
component3.offsetMax = new Vector2(-5f, -5f);
Image val4 = val3.AddComponent<Image>();
((Graphic)val4).color = BACKGROUND_COLOR;
if ((Object)(object)roundedSprite != (Object)null)
{
val4.sprite = roundedSprite;
val4.type = (Type)1;
val4.pixelsPerUnitMultiplier = 4f;
}
GameObject val5 = new GameObject("ScrollView", new Type[1] { typeof(RectTransform) });
val5.transform.SetParent(val3.transform, false);
RectTransform component4 = val5.GetComponent<RectTransform>();
component4.anchorMin = Vector2.zero;
component4.anchorMax = Vector2.one;
component4.offsetMin = new Vector2(5f, 5f);
component4.offsetMax = new Vector2(-5f, -5f);
scrollRect = val5.AddComponent<ScrollRect>();
scrollRect.horizontal = false;
scrollRect.vertical = true;
scrollRect.scrollSensitivity = 20f;
scrollRect.movementType = (MovementType)2;
GameObject val6 = new GameObject("Viewport", new Type[1] { typeof(RectTransform) });
val6.transform.SetParent(val5.transform, false);
RectTransform component5 = val6.GetComponent<RectTransform>();
component5.anchorMin = Vector2.zero;
component5.anchorMax = Vector2.one;
component5.pivot = new Vector2(0f, 1f);
component5.offsetMin = new Vector2(0f, 5f);
component5.offsetMax = new Vector2(-6f, -5f);
val6.AddComponent<RectMask2D>();
scrollRect.viewport = component5;
contentContainer = new GameObject("Content", new Type[1] { typeof(RectTransform) });
contentContainer.transform.SetParent(val6.transform, false);
RectTransform component6 = contentContainer.GetComponent<RectTransform>();
component6.anchorMin = new Vector2(0f, 1f);
component6.anchorMax = new Vector2(1f, 1f);
component6.pivot = new Vector2(0f, 1f);
VerticalLayoutGroup obj2 = contentContainer.AddComponent<VerticalLayoutGroup>();
((HorizontalOrVerticalLayoutGroup)obj2).spacing = 2f;
((LayoutGroup)obj2).childAlignment = (TextAnchor)0;
((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true;
((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true;
((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = true;
((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false;
contentContainer.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
scrollRect.content = component6;
GameObject val7 = new GameObject("Scrollbar Vertical", new Type[1] { typeof(RectTransform) });
val7.transform.SetParent(val5.transform, false);
RectTransform component7 = val7.GetComponent<RectTransform>();
component7.anchorMin = new Vector2(1f, 0f);
component7.anchorMax = new Vector2(1f, 1f);
component7.pivot = new Vector2(1f, 1f);
component7.sizeDelta = new Vector2(5f, 0f);
Image val8 = val7.AddComponent<Image>();
((Graphic)val8).color = Color.black;
if ((Object)(object)roundedSprite != (Object)null)
{
val8.sprite = roundedSprite;
val8.type = (Type)1;
}
GameObject val9 = new GameObject("Track", new Type[1] { typeof(RectTransform) });
val9.transform.SetParent(val7.transform, false);
RectTransform component8 = val9.GetComponent<RectTransform>();
component8.anchorMin = Vector2.zero;
component8.anchorMax = Vector2.one;
component8.offsetMin = new Vector2(1f, 1f);
component8.offsetMax = new Vector2(-1f, -1f);
((Graphic)val9.AddComponent<Image>()).color = new Color(0.3f, 0.22f, 0.2f, 0.3f);
Scrollbar val10 = val7.AddComponent<Scrollbar>();
val10.direction = (Direction)2;
GameObject val11 = new GameObject("Sliding Area", new Type[1] { typeof(RectTransform) });
val11.transform.SetParent(val7.transform, false);
RectTransform component9 = val11.GetComponent<RectTransform>();
component9.anchorMin = Vector2.zero;
component9.anchorMax = Vector2.one;
component9.offsetMin = new Vector2(1f, 1f);
component9.offsetMax = new Vector2(-1f, -1f);
GameObject val12 = new GameObject("Handle", new Type[1] { typeof(RectTransform) });
val12.transform.SetParent(val11.transform, false);
RectTransform component10 = val12.GetComponent<RectTransform>();
component10.sizeDelta = Vector2.zero;
Image val13 = val12.AddComponent<Image>();
((Graphic)val13).color = new Color(1f, 1f, 1f, 0.9f);
if ((Object)(object)roundedSprite != (Object)null)
{
val13.sprite = roundedSprite;
val13.type = (Type)1;
}
val10.handleRect = component10;
((Selectable)val10).targetGraphic = (Graphic)(object)val13;
scrollRect.verticalScrollbar = val10;
scrollRect.verticalScrollbarVisibility = (ScrollbarVisibility)1;
for (int i = 0; i < 8; i++)
{
itemPool.Add(CreateDropdownItem());
}
dropdownPanel.SetActive(false);
}
}
private void Update()
{
if ((Object)(object)chatInput == (Object)null || !IsVisible || !chatInput.isFocused)
{
_isScrolling = false;
return;
}
if (!Input.GetKey((KeyCode)273) && !Input.GetKey((KeyCode)274))
{
_isScrolling = false;
}
HandleKeyboardInput();
}
private void HandleKeyboardInput()
{
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_0125: 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_015a: Invalid comparison between Unknown and I4
if (Input.GetKeyDown((KeyCode)9))
{
int caretPosition = chatInput.caretPosition;
string text = chatInput.text;
int num = text.LastIndexOf('@', Mathf.Max(0, caretPosition - 1));
string currentQuery = ((num >= 0) ? text.Substring(num + 1, caretPosition - num - 1) : "");
if (TryAutocomplete(currentQuery))
{
EventSystem.current.SetSelectedGameObject(((Component)chatInput).gameObject);
}
}
else if (Input.GetKeyDown((KeyCode)273))
{
_isScrolling = true;
_scrollDirection = (KeyCode)273;
_nextScrollTime = Time.realtimeSinceStartup + 0.4f;
NavigateUp();
EventSystem.current.SetSelectedGameObject(((Component)chatInput).gameObject);
chatInput.MoveTextEnd(false);
}
else if (Input.GetKeyDown((KeyCode)274))
{
_isScrolling = true;
_scrollDirection = (KeyCode)274;
_nextScrollTime = Time.realtimeSinceStartup + 0.4f;
NavigateDown();
EventSystem.current.SetSelectedGameObject(((Component)chatInput).gameObject);
chatInput.MoveTextEnd(false);
}
else if (_isScrolling && Input.GetKey(_scrollDirection) && Time.realtimeSinceStartup >= _nextScrollTime)
{
_nextScrollTime = Time.realtimeSinceStartup + 0.08f;
if ((int)_scrollDirection == 273)
{
NavigateUp();
}
else
{
NavigateDown();
}
EventSystem.current.SetSelectedGameObject(((Component)chatInput).gameObject);
chatInput.MoveTextEnd(false);
}
else
{
if (Input.GetKeyDown((KeyCode)13) || Input.GetKeyDown((KeyCode)271))
{
Hide();
}
if (Input.GetKeyDown((KeyCode)27))
{
Hide();
}
}
}
private void UpdateDropdownPosition()
{
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: 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_00d0: Unknown result type (might be due to invalid IL or missing references)
//IL_00da: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)chatInputRect == (Object)null) && !((Object)(object)dropdownPanel == (Object)null))
{
RectTransform component = dropdownPanel.GetComponent<RectTransform>();
component.pivot = new Vector2(0f, 0f);
component.anchorMin = Vector2.zero;
component.anchorMax = Vector2.zero;
Vector3[] array = (Vector3[])(object)new Vector3[4];
chatInputRect.GetWorldCorners(array);
float num = array[1].y + 20f;
((Transform)component).position = new Vector3(array[1].x, num, 0f);
float num2 = Vector3.Distance(array[0], array[3]);
float x = ((Transform)component).lossyScale.x;
if (Mathf.Abs(x) > 0.001f)
{
float num3 = num2 / x;
component.sizeDelta = new Vector2(num3, component.sizeDelta.y);
}
ClampToScreen(component);
}
}
private void ClampToScreen(RectTransform dropdownRect)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
float y = ((Transform)dropdownRect).lossyScale.y;
if (!(Mathf.Abs(y) < 0.001f))
{
float y2 = ((Transform)dropdownRect).position.y;
float num = ((float)Screen.height - y2) / y;
if (dropdownRect.sizeDelta.y > num)
{
float num2 = 120f;
dropdownRect.sizeDelta = new Vector2(dropdownRect.sizeDelta.x, Mathf.Max(num, num2));
}
}
}
private GameObject CreateDropdownItem()
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Expected O, but got Unknown
//IL_0068: 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_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_0134: Unknown result type (might be due to invalid IL or missing references)
//IL_0139: Unknown result type (might be due to invalid IL or missing references)
//IL_014b: 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_015d: Unknown result type (might be due to invalid IL or missing references)
//IL_0172: 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_01a2: 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)
GameObject val = new GameObject("Item", new Type[1] { typeof(RectTransform) });
val.transform.SetParent(contentContainer.transform, false);
LayoutElement obj = val.AddComponent<LayoutElement>();
obj.minHeight = 55f;
obj.flexibleHeight = 0f;
GameObject val2 = new GameObject("Highlight", new Type[1] { typeof(RectTransform) });
val2.transform.SetParent(val.transform, false);
RectTransform component = val2.GetComponent<RectTransform>();
component.anchorMin = Vector2.zero;
component.anchorMax = Vector2.one;
component.offsetMin = new Vector2(2f, 2f);
component.offsetMax = new Vector2(-2f, -2f);
Image val3 = val2.AddComponent<Image>();
((Graphic)val3).color = new Color(0f, 0f, 0f, 0f);
((Graphic)val3).raycastTarget = false;
if ((Object)(object)roundedSprite != (Object)null)
{
val3.sprite = roundedSprite;
val3.type = (Type)1;
val3.pixelsPerUnitMultiplier = 8f;
}
GameObject val4 = new GameObject("Text", new Type[1] { typeof(RectTransform) });
val4.transform.SetParent(val.transform, false);
RectTransform component2 = val4.GetComponent<RectTransform>();
component2.anchorMin = Vector2.zero;
component2.anchorMax = Vector2.one;
component2.offsetMin = new Vector2(8f, 2f);
component2.offsetMax = new Vector2(-6f, -2f);
TextMeshProUGUI val5 = val4.AddComponent<TextMeshProUGUI>();
((TMP_Text)val5).fontSize = 20f;
((Graphic)val5).color = TEXT_COLOR;
((TMP_Text)val5).alignment = (TextAlignmentOptions)4097;
((TMP_Text)val5).margin = new Vector4(4f, 0f, 4f, 0f);
((TMP_Text)val5).richText = true;
TMP_InputField obj2 = chatInput;
object obj3;
if (obj2 == null)
{
obj3 = null;
}
else
{
TMP_Text textComponent = obj2.textComponent;
obj3 = ((textComponent != null) ? textComponent.font : null);
}
if ((Object)obj3 != (Object)null)
{
((TMP_Text)val5).font = chatInput.textComponent.font;
}
((Graphic)val5).raycastTarget = false;
((TMP_Text)val5).enableWordWrapping = false;
((TMP_Text)val5).overflowMode = (TextOverflowModes)1;
MentionItem mentionItem = val.AddComponent<MentionItem>();
mentionItem.HighlightImage = val3;
mentionItem.TextMesh = val5;
val.SetActive(false);
return val;
}
public void Show(List<string> matches, string currentQuery)
{
//IL_018f: Unknown result type (might be due to invalid IL or missing references)
//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
currentMatches = matches;
selectedIndex = ((currentMatches.Count <= 0) ? (-1) : 0);
while (itemPool.Count < currentMatches.Count)
{
itemPool.Add(CreateDropdownItem());
}
TMP_InputField obj = chatInput;
object obj2;
if (obj == null)
{
obj2 = null;
}
else
{
TMP_Text textComponent = obj.textComponent;
obj2 = ((textComponent != null) ? textComponent.font : null);
}
TMP_FontAsset val = (TMP_FontAsset)obj2;
if ((Object)(object)val != (Object)null)
{
foreach (GameObject item in itemPool)
{
TextMeshProUGUI val2 = item.GetComponent<MentionItem>()?.TextMesh;
if ((Object)(object)val2 != (Object)null && (Object)(object)((TMP_Text)val2).font != (Object)(object)val)
{
((TMP_Text)val2).font = val;
}
}
}
for (int i = 0; i < itemPool.Count; i++)
{
if (i < currentMatches.Count)
{
itemPool[i].SetActive(true);
UpdateItemVisuals(itemPool[i], currentMatches[i], currentQuery, i == selectedIndex);
}
else
{
itemPool[i].SetActive(false);
}
}
int count = currentMatches.Count;
float num = 2f;
float num2 = 8f;
float num3 = (float)count * 55f + (float)((count > 1) ? (count - 1) : 0) * num + num2;
RectTransform component = dropdownPanel.GetComponent<RectTransform>();
component.sizeDelta = new Vector2(component.sizeDelta.x, Mathf.Min(num3 + 10f, 600f));
UpdateDropdownPosition();
if ((Object)(object)scrollRect != (Object)null)
{
scrollRect.verticalNormalizedPosition = 1f;
}
dropdownPanel.SetActive(true);
}
public bool TryAutocomplete(string currentQuery)
{
string selectedPlayer = GetSelectedPlayer();
if (selectedPlayer != null && (Object)(object)chatInput != (Object)null)
{
int caretPosition = chatInput.caretPosition;
string text = chatInput.text;
int num = text.LastIndexOf('@', Mathf.Max(0, caretPosition - 1));
if (num >= 0)
{
string text2 = text.Substring(0, num);
string text3 = text.Substring(caretPosition);
string text4 = "@" + selectedPlayer + " ";
chatInput.text = text2 + text4 + text3;
chatInput.caretPosition = text2.Length + text4.Length;
Hide();
return true;
}
}
return false;
}
public void SelectPrevious()
{
NavigateUp();
}
public void SelectNext()
{
NavigateDown();
}
private void UpdateItemVisuals(GameObject item, string playerName, string query, bool isSelected)
{
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
MentionItem component = item.GetComponent<MentionItem>();
if ((Object)(object)component?.HighlightImage != (Object)null)
{
((Graphic)component.HighlightImage).color = (Color)(isSelected ? HIGHLIGHT_COLOR : new Color(0f, 0f, 0f, 0f));
}
if ((Object)(object)component?.TextMesh != (Object)null)
{
((TMP_Text)component.TextMesh).text = HighlightMatch(playerName, query);
}
}
private string HighlightMatch(string text, string query)
{
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
if (string.IsNullOrEmpty(query))
{
return text;
}
if (text.StartsWith(query, StringComparison.OrdinalIgnoreCase))
{
string text2 = text.Substring(0, query.Length);
string text3 = text.Substring(query.Length);
return "<color=#" + ColorUtility.ToHtmlStringRGB(MENTION_COLOR) + ">" + text2 + "</color>" + text3;
}
return text;
}
public void Hide()
{
GameObject obj = dropdownPanel;
if (obj != null)
{
obj.SetActive(false);
}
selectedIndex = -1;
_isScrolling = false;
}
public bool NavigateUp()
{
if (currentMatches.Count == 0)
{
return false;
}
selectedIndex = (selectedIndex - 1 + currentMatches.Count) % currentMatches.Count;
RefreshSelection();
ScrollToSelected();
return true;
}
public bool NavigateDown()
{
if (currentMatches.Count == 0)
{
return false;
}
selectedIndex = (selectedIndex + 1) % currentMatches.Count;
RefreshSelection();
ScrollToSelected();
return true;
}
private void RefreshSelection()
{
//IL_0054: 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)
for (int i = 0; i < currentMatches.Count; i++)
{
MentionItem component = itemPool[i].GetComponent<MentionItem>();
if (!((Object)(object)component?.HighlightImage == (Object)null))
{
((Graphic)component.HighlightImage).color = (Color)((i == selectedIndex) ? HIGHLIGHT_COLOR : new Color(0f, 0f, 0f, 0f));
}
}
}
private void ScrollToSelected()
{
//IL_002c: 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_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)scrollRect == (Object)null || currentMatches.Count == 0)
{
return;
}
Canvas.ForceUpdateCanvases();
Rect rect = contentContainer.GetComponent<RectTransform>().rect;
float height = ((Rect)(ref rect)).height;
rect = scrollRect.viewport.rect;
float height2 = ((Rect)(ref rect)).height;
if (height <= height2)
{
return;
}
float num = height - height2;
if (!(num <= 0.001f))
{
float num2 = (float)selectedIndex * 55f;
float num3 = num2 + 55f;
float num4 = (1f - scrollRect.verticalNormalizedPosition) * num;
if (num2 < num4)
{
scrollRect.verticalNormalizedPosition = 1f - num2 / num;
}
else if (num3 > num4 + height2)
{
scrollRect.verticalNormalizedPosition = 1f - (num3 - height2) / num;
}
}
}
public string GetSelectedPlayer()
{
if (selectedIndex >= 0 && selectedIndex < currentMatches.Count)
{
return currentMatches[selectedIndex];
}
return null;
}
public void OnDestroy()
{
if ((Object)(object)dropdownPanel != (Object)null)
{
Object.Destroy((Object)(object)dropdownPanel);
}
}
}
public class MentionItem : MonoBehaviour
{
public Image HighlightImage { get; set; }
public TextMeshProUGUI TextMesh { get; set; }
}
public static class MentionHighlighter
{
public static string LocalPlayerName = "";
public static string MentionColor = "#FFD700";
public static string PingHighlightColor = "#9B59B6";
private static readonly Regex RichTextTagRegex = new Regex("<[^>]+>", RegexOptions.Compiled);
public static string GetLocalPlayerName()
{
if (!string.IsNullOrEmpty(LocalPlayerName))
{
return LocalPlayerName;
}
TextChannelManager i = NetworkSingleton<TextChannelManager>.I;
if ((Object)(object)i != (Object)null && !string.IsNullOrEmpty(i.UserName))
{
LocalPlayerName = RichTextTagRegex.Replace(i.UserName, "").Trim();
return LocalPlayerName;
}
DataManager i2 = MonoSingleton<DataManager>.I;
if ((Object)(object)i2 != (Object)null && i2.PlayerData != null && !string.IsNullOrEmpty(i2.PlayerData.Name))
{
LocalPlayerName = RichTextTagRegex.Replace(i2.PlayerData.Name, "").Trim().Trim('\0');
return LocalPlayerName;
}
return "";
}
public static void Initialize(Harmony harmony)
{
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Expected O, but got Unknown
harmony.Patch((MethodBase)AccessTools.Method(typeof(TextChannelManager), "AddMessageUI", (Type[])null, (Type[])null), new HarmonyMethod(typeof(MentionHighlighter), "AddMessageUI_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
private static void AddMessageUI_Prefix(ref string text, ref string userName, bool isLocal, int senderIndex)
{
if (string.IsNullOrEmpty(text) || text.StartsWith("/") || senderIndex < 0)
{
return;
}
if (!string.IsNullOrEmpty(userName))
{
string localPlayerName = GetLocalPlayerName();
if (!string.IsNullOrEmpty(localPlayerName) && userName.Equals(localPlayerName, StringComparison.OrdinalIgnoreCase))
{
LocalPlayerName = userName;
}
}
string localPlayerName2 = GetLocalPlayerName();
string cleanMyName = (string.IsNullOrEmpty(localPlayerName2) ? "" : RichTextTagRegex.Replace(localPlayerName2, "").Trim());
bool shouldPing = false;
List<string> validNames = PlayerListProvider.GetAllPlayers()?.Where((string p) => !string.IsNullOrEmpty(p)).ToList() ?? new List<string>();
Regex regex = new Regex("@(\\S+)", RegexOptions.IgnoreCase);
text = regex.Replace(text, delegate(Match match)
{
string value = match.Groups[1].Value;
foreach (string item in validNames)
{
string text2 = RichTextTagRegex.Replace(item, "").Trim();
if (FuzzyMatcher.CalculateScore(text2, value) > 0f)
{
if (!string.IsNullOrEmpty(cleanMyName) && (text2.IndexOf(cleanMyName, StringComparison.OrdinalIgnoreCase) >= 0 || cleanMyName.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0))
{
shouldPing = true;
}
return "<size=115%><b><color=" + MentionColor + ">@" + value + "</color></b></size>";
}
}
if (!string.IsNullOrEmpty(cleanMyName) && FuzzyMatcher.CalculateScore(cleanMyName, value) > 0f)
{
shouldPing = true;
return "<size=115%><b><color=" + MentionColor + ">@" + value + "</color></b></size>";
}
return match.Value;
});
if (shouldPing)
{
text = "<mark=" + PingHighlightColor + "30>" + text + "</mark>";
userName = "<b><color=" + MentionColor + ">" + userName + "</color></b>";
MentionManager.Instance?.PlayPing();
}
}
}
public class MentionManager : MonoBehaviour
{
[CompilerGenerated]
private sealed class <InitializeWhenReady>d__17 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public MentionManager <>4__this;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <InitializeWhenReady>d__17(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Expected O, but got Unknown
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Expected O, but got Unknown
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Expected O, but got Unknown
int num = <>1__state;
MentionManager mentionManager = <>4__this;
switch (num)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = (object)new WaitForEndOfFrame();
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(0.5f);
<>1__state = 2;
return true;
case 2:
<>1__state = -1;
break;
case 3:
<>1__state = -1;
break;
}
while (!mentionManager.isInitialized)
{
mentionManager.TryInitialize();
if (!mentionManager.isInitialized)
{
<>2__current = (object)new WaitForSeconds(1f);
<>1__state = 3;
return true;
}
}
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <LoadPingSound>d__14 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public MentionManager <>4__this;
private UnityWebRequest <uwr>5__2;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <LoadPingSound>d__14(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
int num = <>1__state;
if (num == -3 || num == 1)
{
try
{
}
finally
{
<>m__Finally1();
}
}
<uwr>5__2 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0068: 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_00a3: Invalid comparison between Unknown and I4
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: Invalid comparison between Unknown and I4
try
{
int num = <>1__state;
MentionManager mentionManager = <>4__this;
switch (num)
{
default:
return false;
case 0:
{
<>1__state = -1;
string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "ping.mp3");
<uwr>5__2 = UnityWebRequestMultimedia.GetAudioClip("file://" + text, (AudioType)13);
<>1__state = -3;
((DownloadHandlerAudioClip)<uwr>5__2.downloadHandler).streamAudio = false;
<>2__current = <uwr>5__2.SendWebRequest();
<>1__state = 1;
return true;
}
case 1:
<>1__state = -3;
if ((int)<uwr>5__2.result == 2 || (int)<uwr>5__2.result == 3)
{
Debug.LogError((object)("[PingSystem] Failed to load ping.mp3: " + <uwr>5__2.error));
}
else
{
mentionManager._pingClip = DownloadHandlerAudioClip.GetContent(<uwr>5__2);
}
<>m__Finally1();
<uwr>5__2 = null;
return false;
}
}
catch
{
//try-fault
((IDisposable)this).Dispose();
throw;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
private void <>m__Finally1()
{
<>1__state = -1;
if (<uwr>5__2 != null)
{
((IDisposable)<uwr>5__2).Dispose();
}
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private TMP_InputField chatInput;
private MentionDropdown dropdown;
private bool isInitialized;
private string currentQuery = "";
private AudioSource _audioSource;
private AudioClip _pingClip;
private float _nextScrollTime;
private const float SCROLL_REPEAT_DELAY = 0.4f;
private const float SCROLL_REPEAT_RATE = 0.08f;
private bool _isScrolling;
public static MentionManager Instance { get; private set; }
private void Awake()
{
if ((Object)(object)Instance == (Object)null)
{
Instance = this;
SceneManager.sceneLoaded += OnSceneLoaded;
SceneManager.sceneUnloaded += OnSceneUnloaded;
_audioSource = ((Component)this).gameObject.AddComponent<AudioSource>();
_audioSource.playOnAwake = false;
_audioSource.spatialBlend = 0f;
((MonoBehaviour)this).StartCoroutine(LoadPingSound());
}
else
{
Object.Destroy((Object)(object)((Component)this).gameObject);
}
}
private void OnDestroy()
{
if ((Object)(object)Instance == (Object)(object)this)
{
Instance = null;
}
SceneManager.sceneLoaded -= OnSceneLoaded;
SceneManager.sceneUnloaded -= OnSceneUnloaded;
Cleanup();
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
if (((Scene)(ref scene)).name == "Island")
{
((MonoBehaviour)this).StopAllCoroutines();
((MonoBehaviour)this).StartCoroutine(InitializeWhenReady());
}
}
private void OnSceneUnloaded(Scene scene)
{
if (((Scene)(ref scene)).name == "Island")
{
Cleanup();
}
}
[IteratorStateMachine(typeof(<LoadPingSound>d__14))]
private IEnumerator LoadPingSound()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <LoadPingSound>d__14(0)
{
<>4__this = this
};
}
public void PlayPing()
{
if ((Object)(object)_pingClip != (Object)null && (Object)(object)_audioSource != (Object)null)
{
_audioSource.PlayOneShot(_pingClip);
}
}
private void Cleanup()
{
((MonoBehaviour)this).StopAllCoroutines();
if ((Object)(object)chatInput != (Object)null)
{
((UnityEvent<string>)(object)chatInput.onValueChanged).RemoveListener((UnityAction<string>)OnChatInputChanged);
chatInput = null;
}
if ((Object)(object)dropdown != (Object)null)
{
Object.Destroy((Object)(object)dropdown);
dropdown = null;
}
isInitialized = false;
currentQuery = "";
}
[IteratorStateMachine(typeof(<InitializeWhenReady>d__17))]
private IEnumerator InitializeWhenReady()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <InitializeWhenReady>d__17(0)
{
<>4__this = this
};
}
private void Update()
{
if (isInitialized && !((Object)(object)chatInput == (Object)null) && !((Object)(object)dropdown == (Object)null) && chatInput.isFocused && dropdown.IsVisible)
{
HandleKeyboardInput();
}
}
private TMP_InputField GetChatInput()
{
Type type = AccessTools.TypeByName("MonoSingleton`1");
if (type == null)
{
return null;
}
Type type2 = AccessTools.TypeByName("UIManager");
if (type2 == null)
{
return null;
}
PropertyInfo property = type.MakeGenericType(type2).GetProperty("I", BindingFlags.Static | BindingFlags.Public);
if (property == null)
{
return null;
}
object value = property.GetValue(null);
if (value == null)
{
return null;
}
object? obj = type2.GetProperty("MessageInput")?.GetValue(value);
return (TMP_InputField)((obj is TMP_InputField) ? obj : null);
}
private bool TryInitialize()
{
if (isInitialized)
{
return true;
}
chatInput = GetChatInput();
if ((Object)(object)chatInput == (Object)null)
{
return false;
}
PlayerListProvider.Initialize();
dropdown = ((Component)this).gameObject.AddComponent<MentionDropdown>();
dropdown.Initialize(chatInput);
((UnityEvent<string>)(object)chatInput.onValueChanged).AddListener((UnityAction<string>)OnChatInputChanged);
isInitialized = true;
MentionHighlighter.GetLocalPlayerName();
return true;
}
private void OnChatInputChanged(string text)
{
if ((Object)(object)chatInput == (Object)null)
{
return;
}
int caretPosition = chatInput.caretPosition;
if (caretPosition <= 0 || caretPosition > text.Length)
{
dropdown.Hide();
return;
}
int num = text.LastIndexOf('@', caretPosition - 1);
if (num == -1)
{
dropdown.Hide();
return;
}
if (num > 0 && !char.IsWhiteSpace(text[num - 1]))
{
dropdown.Hide();
return;
}
currentQuery = text.Substring(num + 1, caretPosition - num - 1);
UpdateDropdown(currentQuery);
}
private void UpdateDropdown(string query)
{
List<string> list = FuzzyMatcher.Filter(PlayerListProvider.GetAllPlayers(), (string p) => p, query).ToList();
if (list.Count > 0)
{
dropdown.Show(list, query);
}
else
{
dropdown.Hide();
}
}
private void HandleKeyboardInput()
{
if (Input.GetKeyDown((KeyCode)9))
{
if (dropdown.TryAutocomplete(currentQuery))
{
EventSystem.current.SetSelectedGameObject(((Component)chatInput).gameObject);
}
}
else if (Input.GetKey((KeyCode)273) && dropdown.IsVisible)
{
if (Input.GetKeyDown((KeyCode)273))
{
_isScrolling = true;
_nextScrollTime = Time.realtimeSinceStartup + 0.4f;
NavigateUp();
}
else if (_isScrolling && Time.realtimeSinceStartup >= _nextScrollTime)
{
_nextScrollTime = Time.realtimeSinceStartup + 0.08f;
NavigateUp();
}
}
else if (Input.GetKey((KeyCode)274) && dropdown.IsVisible)
{
if (Input.GetKeyDown((KeyCode)274))
{
_isScrolling = true;
_nextScrollTime = Time.realtimeSinceStartup + 0.4f;
NavigateDown();
}
else if (_isScrolling && Time.realtimeSinceStartup >= _nextScrollTime)
{
_nextScrollTime = Time.realtimeSinceStartup + 0.08f;
NavigateDown();
}
}
else if (!Input.GetKey((KeyCode)273) && !Input.GetKey((KeyCode)274))
{
_isScrolling = false;
}
if (Input.GetKeyDown((KeyCode)13) || Input.GetKeyDown((KeyCode)271))
{
if (dropdown.IsVisible)
{
dropdown.TryAutocomplete(currentQuery);
dropdown.Hide();
}
}
else if (Input.GetKeyDown((KeyCode)27))
{
dropdown.Hide();
}
}
private void NavigateUp()
{
dropdown.SelectPrevious();
EventSystem.current.SetSelectedGameObject(((Component)chatInput).gameObject);
chatInput.MoveTextEnd(false);
}
private void NavigateDown()
{
dropdown.SelectNext();
EventSystem.current.SetSelectedGameObject(((Component)chatInput).gameObject);
chatInput.MoveTextEnd(false);
}
}
public static class PlayerListProvider
{
private static Type _playerPanelControllerType;
private static Type _networkSingletonBaseType;
private static Type _playerIdInfoType;
private static PropertyInfo _singletonInstanceProperty;
private static FieldInfo _idInfosField;
private static FieldInfo _playerIdInfoNameField;
private static readonly Regex RichTextTagRegex = new Regex("<[^>]+>", RegexOptions.Compiled);
private static bool _initialized;
private static bool _initFailed;
public static bool IsInitialized => _initialized;
public static bool IsInitFailed => _initFailed;
public static void Initialize()
{
if (_initialized)
{
return;
}
_initFailed = false;
try
{
_playerPanelControllerType = AccessTools.TypeByName("PlayerPanelController");
if (_playerPanelControllerType == null)
{
_initFailed = true;
return;
}
_networkSingletonBaseType = _playerPanelControllerType.BaseType;
if (_networkSingletonBaseType == null || !_networkSingletonBaseType.Name.StartsWith("NetworkSingleton"))
{
_initFailed = true;
return;
}
_singletonInstanceProperty = _networkSingletonBaseType.GetProperty("I", BindingFlags.Static | BindingFlags.Public);
if (_singletonInstanceProperty == null)
{
_initFailed = true;
return;
}
_idInfosField = _playerPanelControllerType.GetField("IDInfos", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (_idInfosField == null)
{
_initFailed = true;
return;
}
Type fieldType = _idInfosField.FieldType;
if (fieldType.IsGenericType)
{
Type[] genericArguments = fieldType.GetGenericArguments();
if (genericArguments.Length != 0)
{
_playerIdInfoType = genericArguments[0];
}
}
if ((object)_playerIdInfoType == null)
{
_playerIdInfoType = AccessTools.TypeByName("PlayerIDInfo");
}
if (_playerIdInfoType == null)
{
_initFailed = true;
return;
}
_playerIdInfoNameField = _playerIdInfoType.GetField("Name", BindingFlags.Instance | BindingFlags.Public);
if (_playerIdInfoNameField == null)
{
_initFailed = true;
}
else
{
_initialized = true;
}
}
catch (Exception)
{
_initFailed = true;
_initialized = false;
}
}
public static List<string> GetAllPlayers()
{
if (!_initialized || _initFailed)
{
Initialize();
if (!_initialized)
{
return new List<string>();
}
}
List<string> list = new List<string>();
try
{
object value = _singletonInstanceProperty.GetValue(null);
if (value == null)
{
return list;
}
object value2 = _idInfosField.GetValue(value);
if (value2 == null)
{
return list;
}
if (value2 is ICollection collection && collection.Count == 0)
{
return list;
}
List<object> list2 = new List<object>();
try
{
if (value2 is IEnumerable enumerable)
{
foreach (object item in enumerable)
{
if (item != null)
{
list2.Add(item);
}
}
}
}
catch
{
}
foreach (object item2 in list2)
{
try
{
object value3 = _playerIdInfoNameField.GetValue(item2);
string text = null;
if (value3 is string text2)
{
text = text2;
}
else if (value3 is byte[] array && array.Length != 0)
{
text = Encoding.Unicode.GetString(array).Trim('\0');
}
if (!string.IsNullOrEmpty(text))
{
text = text.Trim();
text = RichTextTagRegex.Replace(text, "").Trim();
if (!string.IsNullOrEmpty(text))
{
list.Add(text);
}
}
}
catch
{
}
}
}
catch (Exception ex)
{
Debug.LogError((object)("[PingSystem] GetAllPlayers: " + ex.Message));
}
return list;
}
public static int GetPlayerCount()
{
if (!_initialized)
{
Initialize();
if (!_initialized)
{
return 0;
}
}
try
{
object value = _singletonInstanceProperty.GetValue(null);
if (value == null)
{
return 0;
}
return (_idInfosField.GetValue(value) as ICollection)?.Count ?? 0;
}
catch
{
return 0;
}
}
}
[BepInPlugin("com.on-together-mods.playerpingmention", "PlayerPingMention", "1.1.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
private static ConfigEntry<string> _pingColorConfig;
private static readonly Regex HexColorRegex = new Regex("^#?([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$", RegexOptions.Compiled);
private void Awake()
{
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Expected O, but got Unknown
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Expected O, but got Unknown
_pingColorConfig = ((BaseUnityPlugin)this).Config.Bind<string>("Ping", "HighlightColorV2", "#9B59B6", "Hex color for pinged message highlights (default: soft purple)");
MentionHighlighter.PingHighlightColor = _pingColorConfig.Value;
MentionHighlighter.Initialize(new Harmony("com.on-together-mods.playerpingmention.highlight"));
GameObject val = new GameObject("MentionManager");
val.AddComponent<MentionManager>();
Object.DontDestroyOnLoad((Object)val);
RegisterCommands();
((BaseUnityPlugin)this).Logger.LogInfo((object)("PingSystem loaded. Color: " + _pingColorConfig.Value));
}
private void RegisterCommands()
{
CommandHelper.Register("setpingcolor", "Ping System", delegate(string[] args)
{
HandleSetPingColor(args);
}, "Usage: /setpingcolor <hex-color> e.g. FF0000 or #FF0000");
}
private void HandleSetPingColor(string[] args)
{
if (args.Length == 0)
{
CommandHelper.Notify("Current ping color: " + MentionHighlighter.PingHighlightColor);
return;
}
string text = args[0].Trim();
if (!HexColorRegex.IsMatch(text))
{
CommandHelper.Notify("Invalid hex color. Use format: #RRGGBB or #RGB");
return;
}
string text2 = (text.StartsWith("#") ? text : ("#" + text));
if (text2.Length == 4)
{
text2 = $"#{text2[1]}{text2[1]}{text2[2]}{text2[2]}{text2[3]}{text2[3]}";
}
text2 = (MentionHighlighter.PingHighlightColor = text2.ToUpper());
_pingColorConfig.Value = text2;
CommandHelper.Notify("Ping color set to <color=" + text2 + ">" + text2 + "</color>");
}
}
}