Decompiled source of PModeration v1.1.4

PModeration.dll

Decompiled 4 days ago
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.Security;
using System.Security.Permissions;
using AtlyssCommandLib.API;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mirror;
using Nessie.ATLYSS.EasySettings;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.Events;
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: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.PModeration.sftwre")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.1.4.0")]
[assembly: AssemblyInformationalVersion("1.1.4+99d511b41b553fe17cb66d918a089921a86b0b29")]
[assembly: AssemblyProduct("Player Moderation")]
[assembly: AssemblyTitle("PModeration")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.4.0")]
[module: UnverifiableCode]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 PModeration
{
	[BepInPlugin("com.PModeration.sftwre", "PModeration", "1.1.4")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static CommandCallback <>9__32_2;

			public static CommandCallback <>9__32_3;

			public static CommandCallback <>9__32_7;

			internal bool <RegisterModCommands>b__32_2(Caller c, string[] _)
			{
				//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_003c: 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)
				Utils.NotifyCaller(c, $"<color=orange>Blocked Users ({BlockedSteamIDs.Count}):</color>", Color.white);
				foreach (ulong blockedSteamID in BlockedSteamIDs)
				{
					Utils.NotifyCaller(c, $"- {blockedSteamID}", Color.white);
				}
				return true;
			}

			internal bool <RegisterModCommands>b__32_3(Caller c, string[] a)
			{
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				string text = ((a.Length != 0) ? a[0] : Path.Combine(Paths.ConfigPath, "PModeration_BlockList_Export.json"));
				File.WriteAllText(text, JsonConvert.SerializeObject((object)BlockedSteamIDs, (Formatting)1));
				Utils.NotifyCaller(c, "<color=green>[Export]</color> Blocklist saved to " + text, Color.white);
				return true;
			}

			internal bool <RegisterModCommands>b__32_7(Caller c, string[] _)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: 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_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: 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_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_005c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0067: 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_0078: 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_0089: Unknown result type (might be due to invalid IL or missing references)
				//IL_008f: Unknown result type (might be due to invalid IL or missing references)
				//IL_009a: 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)
				Utils.NotifyCaller(c, "<color=#ff8800>=== PModeration Commands (all client-side) ===</color>", Color.white);
				Utils.NotifyCaller(c, "<color=white>/block <name></color> — Hide player (model, nameplate, audio)", Color.white);
				Utils.NotifyCaller(c, "<color=white>/unblock <name or SteamID></color> — Unhide player", Color.white);
				Utils.NotifyCaller(c, "<color=cyan>/hideglobal <name></color> — Hide only @global name (RP title stays)", Color.white);
				Utils.NotifyCaller(c, "<color=cyan>/unhideglobal <name or SteamID></color> — Unhide @global name", Color.white);
				Utils.NotifyCaller(c, "<color=white>/blocklist</color> — List all blocked SteamIDs", Color.white);
				Utils.NotifyCaller(c, "<color=white>/blockexport [optional path]</color> — Save blocklist to JSON", Color.white);
				Utils.NotifyCaller(c, "<color=white>/blockimport <path></color> — Load blocklist from JSON", Color.white);
				Utils.NotifyCaller(c, "<color=gray>Tip: Use SteamID with /unblock or /unhideglobal if the player is hidden and name not visible.</color>", Color.gray);
				Utils.NotifyCaller(c, "<color=gray>Config: Edit BepInEx/config/PModeration.cfg or use Mod Settings menu.</color>", Color.gray);
				return true;
			}
		}

		public static Plugin Instance;

		internal static ManualLogSource Log;

		private readonly Harmony harmony = new Harmony("com.PModeration.sftwre");

		public static ConfigEntry<bool> CfgEnabled;

		public static ConfigEntry<bool> CfgHardBlock;

		public static ConfigEntry<bool> CfgCensorChat;

		public static ConfigEntry<string> CfgCensorReplacement;

		public static ConfigEntry<bool> CfgDebugMode;

		public static HashSet<ulong> BlockedSteamIDs = new HashSet<ulong>();

		public static HashSet<ulong> HiddenGlobalNameIDs = new HashSet<ulong>();

		private string blockListPath;

		private string globalNameListPath;

		private float visualRefreshTimer = 0f;

		private const string TARGET_GLOBAL_OBJ_NAME = "_text_playerGlobalName";

		private void Awake()
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			blockListPath = Path.Combine(Paths.ConfigPath, "PModeration_BlockList.json");
			globalNameListPath = Path.Combine(Paths.ConfigPath, "PModeration_GlobalNameHides.json");
			InitConfig();
			Settings.OnInitialized.AddListener(new UnityAction(AddSettings));
			Settings.OnApplySettings.AddListener((UnityAction)delegate
			{
				((BaseUnityPlugin)this).Config.Save();
				ForceRefreshAll();
			});
			LoadBlockList();
			LoadGlobalNameList();
			RegisterModCommands();
			harmony.PatchAll();
			Log.LogInfo((object)"PModeration v1.1.4 Loaded.");
		}

		private void Update()
		{
			if (CfgEnabled.Value)
			{
				visualRefreshTimer += Time.deltaTime;
				if (visualRefreshTimer >= 1f)
				{
					visualRefreshTimer = 0f;
					RefreshBlockedPlayersInScene();
				}
			}
		}

		private void ProcessPlayer(Player p)
		{
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Expected O, but got Unknown
			if ((Object)(object)p == (Object)null || ((NetworkBehaviour)p).isLocalPlayer || !ulong.TryParse(p._steamID, out var result))
			{
				return;
			}
			bool flag = BlockedSteamIDs.Contains(result) && CfgEnabled.Value;
			bool flag2 = HiddenGlobalNameIDs.Contains(result);
			if (CfgHardBlock.Value)
			{
				if (flag && ((Component)p).gameObject.activeSelf)
				{
					((Component)p).gameObject.SetActive(false);
				}
				else if (!flag && !((Component)p).gameObject.activeSelf)
				{
					((Component)p).gameObject.SetActive(true);
				}
			}
			else
			{
				if (!((Component)p).gameObject.activeSelf)
				{
					((Component)p).gameObject.SetActive(true);
				}
				Renderer[] componentsInChildren = ((Component)p).GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val in componentsInChildren)
				{
					val.forceRenderingOff = flag;
				}
				Canvas[] componentsInChildren2 = ((Component)p).GetComponentsInChildren<Canvas>(true);
				foreach (Canvas val2 in componentsInChildren2)
				{
					((Behaviour)val2).enabled = !flag;
				}
				AudioSource[] componentsInChildren3 = ((Component)p).GetComponentsInChildren<AudioSource>(true);
				foreach (AudioSource val3 in componentsInChildren3)
				{
					if (flag)
					{
						if (val3.isPlaying)
						{
							val3.Stop();
						}
						((Behaviour)val3).enabled = false;
					}
					else
					{
						((Behaviour)val3).enabled = true;
					}
				}
				foreach (Transform item in ((Component)p).transform)
				{
					Transform val4 = item;
					if (!((Object)val4).name.StartsWith("_"))
					{
						((Component)val4).gameObject.SetActive(!flag);
					}
				}
			}
			if (flag)
			{
				return;
			}
			Transform val5 = FindChildRecursive(((Component)p).transform, "_text_playerGlobalName");
			if ((Object)(object)val5 != (Object)null)
			{
				bool flag3 = !flag2;
				if (((Component)val5).gameObject.activeSelf != flag3)
				{
					((Component)val5).gameObject.SetActive(flag3);
				}
			}
		}

		private Transform FindChildRecursive(Transform parent, string name)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			foreach (Transform item in parent)
			{
				Transform val = item;
				if (((Object)val).name.Equals(name))
				{
					return val;
				}
				Transform val2 = FindChildRecursive(val, name);
				if ((Object)(object)val2 != (Object)null)
				{
					return val2;
				}
			}
			return null;
		}

		public void ForceRefreshAll()
		{
			Player[] array = Object.FindObjectsOfType<Player>();
			foreach (Player val in array)
			{
				if (!((Object)(object)val == (Object)null) && !((NetworkBehaviour)val).isLocalPlayer)
				{
					ProcessPlayer(val);
				}
			}
		}

		private void RefreshBlockedPlayersInScene()
		{
			ForceRefreshAll();
		}

		public void AddBlock(ulong steamID, string name = null)
		{
			if (BlockedSteamIDs.Add(steamID))
			{
				SaveBlockList();
				ForceRefreshAll();
				PModerationAPI.NotifyBlocked(steamID);
			}
		}

		public void RemoveBlock(ulong steamID)
		{
			if (BlockedSteamIDs.Remove(steamID))
			{
				SaveBlockList();
				ForceRefreshAll();
				PModerationAPI.NotifyUnblocked(steamID);
			}
		}

		public bool IsBlocked(ulong steamID)
		{
			return BlockedSteamIDs.Contains(steamID);
		}

		public bool IsGlobalNameHidden(ulong steamID)
		{
			return HiddenGlobalNameIDs.Contains(steamID);
		}

		public void HideGlobalName(ulong steamID)
		{
			if (HiddenGlobalNameIDs.Add(steamID))
			{
				SaveGlobalNameList();
				ForceRefreshAll();
			}
		}

		public void UnhideGlobalName(ulong steamID)
		{
			if (HiddenGlobalNameIDs.Remove(steamID))
			{
				SaveGlobalNameList();
				ForceRefreshAll();
			}
		}

		private void LoadBlockList()
		{
			if (!File.Exists(blockListPath))
			{
				return;
			}
			try
			{
				List<ulong> list = JsonConvert.DeserializeObject<List<ulong>>(File.ReadAllText(blockListPath));
				if (list != null)
				{
					BlockedSteamIDs = new HashSet<ulong>(list);
				}
			}
			catch
			{
			}
		}

		private void SaveBlockList()
		{
			File.WriteAllText(blockListPath, JsonConvert.SerializeObject((object)BlockedSteamIDs.ToList(), (Formatting)1));
		}

		private void LoadGlobalNameList()
		{
			if (!File.Exists(globalNameListPath))
			{
				return;
			}
			try
			{
				List<ulong> list = JsonConvert.DeserializeObject<List<ulong>>(File.ReadAllText(globalNameListPath));
				if (list != null)
				{
					HiddenGlobalNameIDs = new HashSet<ulong>(list);
				}
			}
			catch
			{
			}
		}

		private void SaveGlobalNameList()
		{
			File.WriteAllText(globalNameListPath, JsonConvert.SerializeObject((object)HiddenGlobalNameIDs.ToList(), (Formatting)1));
		}

		private void InitConfig()
		{
			CfgEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1. General", "Enabled", true, "Master switch");
			CfgHardBlock = ((BaseUnityPlugin)this).Config.Bind<bool>("2. Blocking", "Hard Block", false, "True = Disables GameObject. False = Hides Visuals.");
			CfgCensorChat = ((BaseUnityPlugin)this).Config.Bind<bool>("3. Chat", "Censor Chat", true, "Replace blocked players' chat.");
			CfgCensorReplacement = ((BaseUnityPlugin)this).Config.Bind<string>("3. Chat", "Replacement Text", "[BLOCKED]", "Text to show.");
			CfgDebugMode = ((BaseUnityPlugin)this).Config.Bind<bool>("4. Advanced", "Debug Mode", false, "Log details.");
		}

		private void AddSettings()
		{
			SettingsTab orAddCustomTab = Settings.GetOrAddCustomTab("PModeration");
			orAddCustomTab.AddHeader("General");
			orAddCustomTab.AddToggle(CfgEnabled);
			orAddCustomTab.AddHeader("Blocking");
			orAddCustomTab.AddToggle(CfgHardBlock);
			orAddCustomTab.AddHeader("Chat");
			orAddCustomTab.AddToggle(CfgCensorChat);
			orAddCustomTab.AddTextField(CfgCensorReplacement, "Text...");
			orAddCustomTab.AddHeader("Advanced");
			orAddCustomTab.AddToggle(CfgDebugMode);
		}

		private void RegisterModCommands()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			//IL_007f: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			//IL_00b4: 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)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Expected O, but got Unknown
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Expected O, but got Unknown
			//IL_0115: 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_0125: Expected O, but got Unknown
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Expected O, but got Unknown
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: 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_014f: Expected O, but got Unknown
			CommandOptions val = default(CommandOptions);
			((CommandOptions)(ref val))..ctor();
			val.chatCommand = (ChatCommandType)1;
			CommandOptions value = val;
			Utils.RegisterCommand("block", "Locally hides a player's visuals (and optionally chat).", (CommandCallback)delegate(Caller c, string[] a)
			{
				//IL_0078: Unknown result type (might be due to invalid IL or missing references)
				//IL_0089: Unknown result type (might be due to invalid IL or missing references)
				//IL_0053: Unknown result type (might be due to invalid IL or missing references)
				//IL_0069: Unknown result type (might be due to invalid IL or missing references)
				if (a.Length == 0)
				{
					return false;
				}
				string text7 = string.Join(" ", a);
				Player val8 = FindPlayerByName(text7);
				if ((Object)(object)val8 != (Object)null && ulong.TryParse(val8._steamID, out var result6))
				{
					AddBlock(result6, val8._nickname);
					Utils.NotifyCaller(c, "<color=red>[Block]</color> Hid " + val8._nickname + ".", Color.white);
				}
				else
				{
					Utils.NotifyCaller(c, "<color=yellow>[Block]</color> Player '" + text7 + "' not found.", Color.white);
				}
				return true;
			}, (CommandOptions?)value);
			Utils.RegisterCommand("unblock", "Unhides a player by name or SteamID.", (CommandCallback)delegate(Caller c, string[] a)
			{
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_004f: 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_00c0: Unknown result type (might be due to invalid IL or missing references)
				//IL_0095: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
				if (a.Length == 0)
				{
					return false;
				}
				string text6 = string.Join(" ", a);
				if (ulong.TryParse(text6, out var result4))
				{
					RemoveBlock(result4);
					ForceRefreshAll();
					Utils.NotifyCaller(c, $"<color=green>[Unblock]</color> Unblocked ID {result4}.", Color.white);
					return true;
				}
				Player val7 = FindPlayerByName(text6);
				if ((Object)(object)val7 != (Object)null && ulong.TryParse(val7._steamID, out var result5))
				{
					RemoveBlock(result5);
					ForceRefreshAll();
					Utils.NotifyCaller(c, "<color=green>[Unblock]</color> Unblocked " + val7._nickname + ".", Color.white);
				}
				else
				{
					Utils.NotifyCaller(c, "<color=yellow>[Unblock]</color> Player not found. Use SteamID if hidden.", Color.white);
				}
				return true;
			}, (CommandOptions?)value);
			object obj = <>c.<>9__32_2;
			if (obj == null)
			{
				CommandCallback val2 = delegate(Caller c, string[] _)
				{
					//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_003c: 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)
					Utils.NotifyCaller(c, $"<color=orange>Blocked Users ({BlockedSteamIDs.Count}):</color>", Color.white);
					foreach (ulong blockedSteamID in BlockedSteamIDs)
					{
						Utils.NotifyCaller(c, $"- {blockedSteamID}", Color.white);
					}
					return true;
				};
				<>c.<>9__32_2 = val2;
				obj = (object)val2;
			}
			Utils.RegisterCommand("blocklist", "Lists all blocked SteamIDs.", (CommandCallback)obj, (CommandOptions?)value);
			object obj2 = <>c.<>9__32_3;
			if (obj2 == null)
			{
				CommandCallback val3 = delegate(Caller c, string[] a)
				{
					//IL_002c: Unknown result type (might be due to invalid IL or missing references)
					//IL_0038: Unknown result type (might be due to invalid IL or missing references)
					string text5 = ((a.Length != 0) ? a[0] : Path.Combine(Paths.ConfigPath, "PModeration_BlockList_Export.json"));
					File.WriteAllText(text5, JsonConvert.SerializeObject((object)BlockedSteamIDs, (Formatting)1));
					Utils.NotifyCaller(c, "<color=green>[Export]</color> Blocklist saved to " + text5, Color.white);
					return true;
				};
				<>c.<>9__32_3 = val3;
				obj2 = (object)val3;
			}
			Utils.RegisterCommand("blockexport", "Exports blocklist to a file.", (CommandCallback)obj2, (CommandOptions?)value);
			Utils.RegisterCommand("blockimport", "Imports blocklist from a file.", (CommandCallback)delegate(Caller c, string[] a)
			{
				//IL_0067: 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_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				if (a.Length == 0)
				{
					return false;
				}
				string text3 = a[0];
				if (!File.Exists(text3))
				{
					Utils.NotifyCaller(c, "<color=red>[Import]</color> File not found: " + text3, Color.white);
					return true;
				}
				string text4 = File.ReadAllText(text3);
				List<ulong> list = JsonConvert.DeserializeObject<List<ulong>>(text4);
				BlockedSteamIDs.UnionWith(list);
				SaveBlockList();
				ForceRefreshAll();
				Utils.NotifyCaller(c, $"<color=green>[Import]</color> Imported {list.Count} IDs.", Color.white);
				return true;
			}, (CommandOptions?)value);
			Utils.RegisterCommand("hideglobal", "Hides only a player's @global name (does not hide model or RP title).", (CommandCallback)delegate(Caller c, string[] a)
			{
				//IL_0072: Unknown result type (might be due to invalid IL or missing references)
				//IL_0083: 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_0063: Unknown result type (might be due to invalid IL or missing references)
				if (a.Length == 0)
				{
					return false;
				}
				string text2 = string.Join(" ", a);
				Player val6 = FindPlayerByName(text2);
				if ((Object)(object)val6 != (Object)null && ulong.TryParse(val6._steamID, out var result3))
				{
					HideGlobalName(result3);
					Utils.NotifyCaller(c, "<color=cyan>[HideGlobal]</color> Hid @global name for " + val6._nickname + ".", Color.white);
				}
				else
				{
					Utils.NotifyCaller(c, "<color=yellow>[HideGlobal]</color> Player '" + text2 + "' not found.", Color.white);
				}
				return true;
			}, (CommandOptions?)value);
			Utils.RegisterCommand("unhideglobal", "Unhides a player's @global name.", (CommandCallback)delegate(Caller c, string[] a)
			{
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_004f: 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_00c0: Unknown result type (might be due to invalid IL or missing references)
				//IL_0095: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
				if (a.Length == 0)
				{
					return false;
				}
				string text = string.Join(" ", a);
				if (ulong.TryParse(text, out var result))
				{
					UnhideGlobalName(result);
					ForceRefreshAll();
					Utils.NotifyCaller(c, $"<color=green>[UnhideGlobal]</color> Unhid @global name for ID {result}.", Color.white);
					return true;
				}
				Player val5 = FindPlayerByName(text);
				if ((Object)(object)val5 != (Object)null && ulong.TryParse(val5._steamID, out var result2))
				{
					UnhideGlobalName(result2);
					ForceRefreshAll();
					Utils.NotifyCaller(c, "<color=green>[UnhideGlobal]</color> Unhid @global name for " + val5._nickname + ".", Color.white);
				}
				else
				{
					Utils.NotifyCaller(c, "<color=yellow>[UnhideGlobal]</color> Player not found. Use SteamID if hidden.", Color.white);
				}
				return true;
			}, (CommandOptions?)value);
			object obj3 = <>c.<>9__32_7;
			if (obj3 == null)
			{
				CommandCallback val4 = delegate(Caller c, string[] _)
				{
					//IL_0001: Unknown result type (might be due to invalid IL or missing references)
					//IL_0007: Unknown result type (might be due to invalid IL or missing references)
					//IL_0012: Unknown result type (might be due to invalid IL or missing references)
					//IL_0018: 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_0029: Unknown result type (might be due to invalid IL or missing references)
					//IL_0034: Unknown result type (might be due to invalid IL or missing references)
					//IL_003a: 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_004b: Unknown result type (might be due to invalid IL or missing references)
					//IL_0056: Unknown result type (might be due to invalid IL or missing references)
					//IL_005c: Unknown result type (might be due to invalid IL or missing references)
					//IL_0067: 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_0078: 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_0089: Unknown result type (might be due to invalid IL or missing references)
					//IL_008f: Unknown result type (might be due to invalid IL or missing references)
					//IL_009a: 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)
					Utils.NotifyCaller(c, "<color=#ff8800>=== PModeration Commands (all client-side) ===</color>", Color.white);
					Utils.NotifyCaller(c, "<color=white>/block <name></color> — Hide player (model, nameplate, audio)", Color.white);
					Utils.NotifyCaller(c, "<color=white>/unblock <name or SteamID></color> — Unhide player", Color.white);
					Utils.NotifyCaller(c, "<color=cyan>/hideglobal <name></color> — Hide only @global name (RP title stays)", Color.white);
					Utils.NotifyCaller(c, "<color=cyan>/unhideglobal <name or SteamID></color> — Unhide @global name", Color.white);
					Utils.NotifyCaller(c, "<color=white>/blocklist</color> — List all blocked SteamIDs", Color.white);
					Utils.NotifyCaller(c, "<color=white>/blockexport [optional path]</color> — Save blocklist to JSON", Color.white);
					Utils.NotifyCaller(c, "<color=white>/blockimport <path></color> — Load blocklist from JSON", Color.white);
					Utils.NotifyCaller(c, "<color=gray>Tip: Use SteamID with /unblock or /unhideglobal if the player is hidden and name not visible.</color>", Color.gray);
					Utils.NotifyCaller(c, "<color=gray>Config: Edit BepInEx/config/PModeration.cfg or use Mod Settings menu.</color>", Color.gray);
					return true;
				};
				<>c.<>9__32_7 = val4;
				obj3 = (object)val4;
			}
			Utils.RegisterCommand("blockhelp", "Shows all PModeration commands and tips.", (CommandCallback)obj3, (CommandOptions?)value);
		}

		private static Player FindPlayerByName(string name)
		{
			string name2 = name;
			return ((IEnumerable<Player>)Object.FindObjectsOfType<Player>()).FirstOrDefault((Func<Player, bool>)((Player p) => !((NetworkBehaviour)p).isLocalPlayer && p._nickname.IndexOf(name2, StringComparison.OrdinalIgnoreCase) >= 0));
		}
	}
	public static class PModerationAPI
	{
		public static event Action<ulong> OnPlayerBlocked;

		public static event Action<ulong> OnPlayerUnblocked;

		public static bool IsPlayerBlocked(ulong steamID)
		{
			return Plugin.Instance.IsBlocked(steamID);
		}

		public static void BlockPlayer(ulong steamID)
		{
			Plugin.Instance.AddBlock(steamID);
		}

		public static void UnblockPlayer(ulong steamID)
		{
			Plugin.Instance.RemoveBlock(steamID);
		}

		public static void HideGlobalName(ulong steamID)
		{
			Plugin.Instance.HideGlobalName(steamID);
		}

		public static void UnhideGlobalName(ulong steamID)
		{
			Plugin.Instance.UnhideGlobalName(steamID);
		}

		public static void IsGlobalNameHidden(ulong steamID)
		{
			Plugin.Instance.IsGlobalNameHidden(steamID);
		}

		internal static void NotifyBlocked(ulong id)
		{
			PModerationAPI.OnPlayerBlocked?.Invoke(id);
		}

		internal static void NotifyUnblocked(ulong id)
		{
			PModerationAPI.OnPlayerUnblocked?.Invoke(id);
		}
	}
	[HarmonyPatch(typeof(ChatBehaviour), "UserCode_Rpc_RecieveChatMessage__String__Boolean__ChatChannel")]
	[HarmonyPriority(0)]
	public static class ChatReceivePatch
	{
		private static bool Prefix(ChatBehaviour __instance, ref string message)
		{
			if (!Plugin.CfgEnabled.Value || !Plugin.CfgCensorChat.Value)
			{
				return true;
			}
			try
			{
				FieldInfo field = typeof(ChatBehaviour).GetField("_player", BindingFlags.Instance | BindingFlags.NonPublic);
				if (field != null)
				{
					object? value = field.GetValue(__instance);
					Player val = (Player)((value is Player) ? value : null);
					if ((Object)(object)val != (Object)null && ulong.TryParse(val._steamID, out var result) && Plugin.Instance.IsBlocked(result))
					{
						message = Plugin.CfgCensorReplacement.Value;
					}
				}
			}
			catch
			{
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(WhoMenuCell), "Process_FindEntries")]
	public static class WhoMenuCell_ProcessFindEntriesPatch
	{
		[HarmonyPostfix]
		public static void Postfix(WhoMenuCell __instance, ref IEnumerator __result)
		{
			__result = WrapCoroutine(__instance, __result);
		}

		private static IEnumerator WrapCoroutine(WhoMenuCell whoMenu, IEnumerator original)
		{
			while (original.MoveNext())
			{
				yield return original.Current;
			}
			yield return null;
			InjectButtons(whoMenu);
		}

		private static void InjectButtons(WhoMenuCell whoMenu)
		{
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Expected O, but got Unknown
			if ((Object)(object)whoMenu == (Object)null)
			{
				return;
			}
			FieldInfo field = typeof(WhoMenuCell).GetField("_scrollRectContent", BindingFlags.Instance | BindingFlags.NonPublic);
			if (field == null)
			{
				field = typeof(WhoMenuCell).GetField("_cell_ScrollViewContent", BindingFlags.Instance | BindingFlags.NonPublic);
			}
			if (field == null)
			{
				if (Plugin.CfgDebugMode.Value)
				{
					Plugin.Log.LogError((object)"PlayerListPatch: Could not find content field (_scrollRectContent).");
				}
				return;
			}
			object? value = field.GetValue(whoMenu);
			Transform val = (Transform)((value is Transform) ? value : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			foreach (Transform item in val)
			{
				Transform val2 = item;
				if (((Component)val2).gameObject.activeSelf)
				{
					WhoListDataEntry component = ((Component)val2).GetComponent<WhoListDataEntry>();
					if (!((Object)(object)component == (Object)null) && !((Object)(object)component._player == (Object)null) && !((NetworkBehaviour)component._player).isLocalPlayer)
					{
						UIBlockHelper.AddOrUpdateBlockButton(((Component)component).gameObject, component._player);
						UIBlockHelper.AddOrUpdateGlobalNameButton(((Component)component).gameObject, component._player);
					}
				}
			}
			LayoutRebuilder.ForceRebuildLayoutImmediate((RectTransform)(object)((val is RectTransform) ? val : null));
		}
	}
	public static class UIBlockHelper
	{
		private const string BLOCK_BUTTON_NAME = "BlockButton";

		private const string GLOBALNAME_BUTTON_NAME = "GlobalNameButton";

		private const string HEADER_NAME = "_dolly_whoInfo_header";

		private const string REF_BUTTON_NAME = "_button_steamProfile";

		private const string GLOBAL_TEXT_NAME = "_text_globalName";

		private const string CHAR_TEXT_NAME = "_text_characterName";

		private static Sprite _blockSprite;

		private static Sprite _unblockSprite;

		private static Sprite _globalShowSprite;

		private static Sprite _globalHideSprite;

		private static bool _spritesLoaded;

		private static void EnsureSpritesLoaded()
		{
			if (!_spritesLoaded)
			{
				_spritesLoaded = true;
				_blockSprite = LoadSpriteSmart("block.png");
				_unblockSprite = LoadSpriteSmart("unblock.png");
				_globalShowSprite = LoadSpriteSmart("globalshow.png");
				_globalHideSprite = LoadSpriteSmart("globalhide.png");
			}
		}

		private static Sprite LoadSpriteSmart(string fileNameEndsWith)
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Expected O, but got Unknown
			//IL_00c3: 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)
			string fileNameEndsWith2 = fileNameEndsWith;
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			string text = executingAssembly.GetManifestResourceNames().FirstOrDefault((string n) => n.EndsWith(fileNameEndsWith2, StringComparison.OrdinalIgnoreCase));
			if (string.IsNullOrEmpty(text))
			{
				Plugin.Log.LogError((object)("[UIBlockHelper] MISSING RESOURCE ending with: '" + fileNameEndsWith2 + "'"));
				return null;
			}
			using Stream stream = executingAssembly.GetManifestResourceStream(text);
			if (stream == null)
			{
				return null;
			}
			byte[] array = new byte[stream.Length];
			stream.Read(array, 0, array.Length);
			Texture2D val = new Texture2D(2, 2);
			ImageConversion.LoadImage(val, array);
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
		}

		public static void AddOrUpdateBlockButton(GameObject entryObj, Player player)
		{
			AddOrUpdateButton(entryObj, player, "BlockButton", isGlobalName: false);
		}

		public static void AddOrUpdateGlobalNameButton(GameObject entryObj, Player player)
		{
			AddOrUpdateButton(entryObj, player, "GlobalNameButton", isGlobalName: true);
		}

		private static void AddOrUpdateButton(GameObject entryObj, Player player, string buttonName, bool isGlobalName)
		{
			//IL_00a9: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Expected O, but got Unknown
			Player player2 = player;
			if ((Object)(object)entryObj == (Object)null || (Object)(object)player2 == (Object)null || !ulong.TryParse(player2._steamID, out var steamID))
			{
				return;
			}
			Transform val = FindChildRecursive(entryObj.transform, "_dolly_whoInfo_header");
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			ApplyLayoutConstraint(val, "_text_characterName", 65f);
			ApplyLayoutConstraint(val, "_text_globalName", 55f);
			RectTransform component = ((Component)val).GetComponent<RectTransform>();
			if ((Object)(object)component != (Object)null && component.sizeDelta.x < 400f)
			{
				component.sizeDelta = new Vector2(component.sizeDelta.x + 40f, component.sizeDelta.y);
				((Transform)component).localScale = new Vector3(0.9f, 1f, 1f);
			}
			Transform val2 = val.Find(buttonName);
			if ((Object)(object)val2 != (Object)null)
			{
				UpdateButtonState(((Component)val2).gameObject, steamID, isGlobalName);
				return;
			}
			Transform val3 = val.Find("_button_steamProfile");
			if ((Object)(object)val3 == (Object)null)
			{
				return;
			}
			GameObject btnObj = Object.Instantiate<GameObject>(((Component)val3).gameObject, val);
			((Object)btnObj).name = buttonName;
			btnObj.SetActive(true);
			btnObj.transform.SetSiblingIndex(val3.GetSiblingIndex() + 1);
			Button component2 = btnObj.GetComponent<Button>();
			((UnityEventBase)component2.onClick).RemoveAllListeners();
			((UnityEvent)component2.onClick).AddListener((UnityAction)delegate
			{
				if (isGlobalName ? Plugin.Instance.IsGlobalNameHidden(steamID) : Plugin.Instance.IsBlocked(steamID))
				{
					if (isGlobalName)
					{
						Plugin.Instance.UnhideGlobalName(steamID);
					}
					else
					{
						Plugin.Instance.RemoveBlock(steamID);
					}
				}
				else if (isGlobalName)
				{
					Plugin.Instance.HideGlobalName(steamID);
				}
				else
				{
					Plugin.Instance.AddBlock(steamID, player2._nickname);
				}
				UpdateButtonState(btnObj, steamID, isGlobalName);
			});
			UpdateButtonState(btnObj, steamID, isGlobalName);
		}

		private static void ApplyLayoutConstraint(Transform header, string childName, float width)
		{
			Transform val = header.Find(childName);
			if ((Object)(object)val != (Object)null)
			{
				LayoutElement val2 = ((Component)val).GetComponent<LayoutElement>();
				if ((Object)(object)val2 == (Object)null)
				{
					val2 = ((Component)val).gameObject.AddComponent<LayoutElement>();
				}
				val2.flexibleWidth = 0f;
				val2.preferredWidth = width;
			}
		}

		private static void UpdateButtonState(GameObject btnObj, ulong steamID, bool isGlobalName)
		{
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)btnObj == (Object)null)
			{
				return;
			}
			EnsureSpritesLoaded();
			bool flag = (isGlobalName ? Plugin.Instance.IsGlobalNameHidden(steamID) : Plugin.Instance.IsBlocked(steamID));
			Image val = null;
			Transform val2 = FindChildRecursive(btnObj.transform, "_icon_steamProfile") ?? FindChildRecursive(btnObj.transform, "Icon") ?? FindChildRecursive(btnObj.transform, "Image");
			val = ((!((Object)(object)val2 != (Object)null)) ? btnObj.GetComponent<Image>() : ((Component)val2).GetComponent<Image>());
			if ((Object)(object)val != (Object)null)
			{
				if (isGlobalName)
				{
					val.sprite = (flag ? _globalShowSprite : _globalHideSprite);
				}
				else
				{
					val.sprite = (flag ? _unblockSprite : _blockSprite);
				}
				((Graphic)val).color = Color.white;
			}
		}

		private static Transform FindChildRecursive(Transform parent, string name)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			foreach (Transform item in parent)
			{
				Transform val = item;
				if (((Object)val).name.Equals(name))
				{
					return val;
				}
				Transform val2 = FindChildRecursive(val, name);
				if ((Object)(object)val2 != (Object)null)
				{
					return val2;
				}
			}
			return null;
		}
	}
	internal static class ModInfo
	{
		public const string GUID = "com.PModeration.sftwre";

		public const string NAME = "PModeration";

		public const string VERSION = "1.1.4";
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}