/* --- Contributor information --- * Please follow the following set of guidelines when working on this plugin, * this to help others understand this file more easily. * * -- Authors -- * Pho3niX90 2020-06 > current * Thimo (ThibmoRozier) 2020-04 * rfc1920 * Mheetu * * -- Naming -- * Avoid using non-alphabetic characters, eg: _ * Avoid using numbers in method and class names (Upgrade methods are allowed to have these, for readability) * Private constants -------------------- SHOULD start with a uppercase "C" (PascalCase) * Private readonly fields -------------- SHOULD start with a uppercase "C" (PascalCase) * Private fields ----------------------- SHOULD start with a uppercase "F" (PascalCase) * Arguments/Parameters ----------------- SHOULD start with a lowercase "a" (camelCase) * Classes ------------------------------ SHOULD start with a uppercase character (PascalCase) * Methods ------------------------------ SHOULD start with a uppercase character (PascalCase) * Public properties (constants/fields) - SHOULD start with a uppercase character (PascalCase) * Variables ---------------------------- SHOULD start with a lowercase character (camelCase) * * -- Style -- * Max-line-width ------- 160 * Single-line comments - // Single-line comment * Multi-line comments -- Just like this comment block! */ using Newtonsoft.Json; using Oxide.Core; using Oxide.Core.Libraries.Covalence; using Oxide.Core.Plugins; using Oxide.Game.Rust.Cui; using Oxide.Game.Rust.Libraries; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using UnityEngine; using RustLib = Oxide.Game.Rust.Libraries.Rust; namespace Oxide.Plugins { [Info("PlayerAdministration", "Pho3niX90", "1.6.02")] [Description("Allows server admins to moderate users using a GUI from within the game.")] public class PlayerAdministration : CovalencePlugin { #region Plugin References #pragma warning disable IDE0044, CS0649 [PluginReference] private Plugin Economics; [PluginReference] private Plugin ServerRewards; [PluginReference] private Plugin Freeze; [PluginReference] private Plugin PermissionsManager; [PluginReference] private Plugin DiscordMessages; [PluginReference] private Plugin BetterChatMute; [PluginReference] private Plugin Backpacks; [PluginReference] private Plugin InventoryViewer; [PluginReference] private Plugin ServerArmour; [PluginReference] private Plugin Clans; #pragma warning restore IDE0044, CS0649 #endregion Plugin References #region Library Imports private readonly RustLib rust = Interface.Oxide.GetLibrary(); private readonly Player Player = Interface.Oxide.GetLibrary(); #endregion Library Imports #region GUI #region Types /// /// UI Color object /// private class CuiColor { public byte R { get; set; } public byte G { get; set; } public byte B { get; set; } public float A { get; set; } public CuiColor(byte aRed = 255, byte aGreen = 255, byte aBlue = 255, float aAlpha = 1f) { R = aRed; G = aGreen; B = aBlue; A = aAlpha; } public override string ToString() => $"{(double)R / 255} {(double)G / 255} {(double)B / 255} {A}"; public static readonly CuiColor Background = new CuiColor(240, 240, 240, 0.3f); public static readonly CuiColor BackgroundMedium = new CuiColor(76, 74, 72, 0.83f); public static readonly CuiColor BackgroundDark = new CuiColor(42, 42, 42, 0.93f); public static readonly CuiColor Button = new CuiColor(42, 42, 42, 1f); public static readonly CuiColor ButtonInactive = new CuiColor(168, 168, 168, 1f); public static readonly CuiColor ButtonDecline = new CuiColor(192, 0, 0, 1f); public static readonly CuiColor ButtonDanger = new CuiColor(193, 46, 42, 1f); public static readonly CuiColor ButtonWarning = new CuiColor(213, 133, 18, 1f); public static readonly CuiColor ButtonSuccess = new CuiColor(57, 132, 57, 1f); public static readonly CuiColor Text = new CuiColor(0, 0, 0, 1f); public static readonly CuiColor TextAlt = new CuiColor(255, 255, 255, 1f); public static readonly CuiColor TextTitle = new CuiColor(206, 66, 43, 1f); public static readonly CuiColor None = new CuiColor(0, 0, 0, 0f); } /// /// Element position object /// private class CuiPoint { public float X { get; set; } public float Y { get; set; } public CuiPoint(float aX = 0f, float aY = 0f) { X = aX; Y = aY; } public override string ToString() => $"{X} {Y}"; public static readonly CuiPoint Zero = new CuiPoint(); } /// /// UI pages to make the switching more humanly readable /// private enum UiPage { Main = 0, PlayersOnline, PlayersOffline, PlayersBanned, PlayerPage, PlayerPageBanned } #endregion Types #region UI object definitions /// /// Input field object /// private class CuiInputField { public CuiInputFieldComponent InputField { get; } = new CuiInputFieldComponent(); public CuiRectTransformComponent RectTransform { get; } = new CuiRectTransformComponent(); public float FadeOut { get; set; } } #endregion UI object definitions #region Component container /// /// Custom version of the CuiElementContainer to add InputFields /// private class CustomCuiElementContainer : CuiElementContainer { public string Add(CuiInputField aInputField, string aParent = Cui.ParentHud, string aName = "") { if (string.IsNullOrEmpty(aName)) aName = CuiHelper.GetGuid(); if (aInputField == null) { FPluginInstance.LogError($"CustomCuiElementContainer::Add > Parameter 'aInputField' is null"); return string.Empty; } Add(new CuiElement { Name = aName, Parent = aParent, FadeOut = aInputField.FadeOut, Components = { aInputField.InputField, aInputField.RectTransform } }); return aName; } } #endregion Component container /// /// Rust UI object /// private class Cui { public const string ParentHud = "Hud"; public const string ParentOverlay = "Overlay"; private readonly CustomCuiElementContainer FContainer = new CustomCuiElementContainer(); private readonly BasePlayer FPlayer; public readonly ulong PlayerId; public readonly string PlayerIdString; public readonly float StartTime = Time.realtimeSinceStartup; /// /// Constructor /// /// The player this object is meant for public Cui(BasePlayer aPlayer) { if (aPlayer == null) { FPluginInstance.LogError("Cui::Cui > Parameter 'aPlayer' is null"); return; } FPlayer = aPlayer; PlayerId = aPlayer.userID; PlayerIdString = aPlayer.UserIDString; FPluginInstance.LogDebug("Cui instance created"); } /// /// Add a new panel /// /// The parent object name /// Left(x)-Bottom(y) relative position /// Right(x)-Top(y) relative position /// The panel requires the cursor /// Image color /// The object's name /// Image PNG file path /// New object name public string AddPanel( string aParent, CuiPoint aLeftBottomAnchor, CuiPoint aRightTopAnchor, bool aIndCursorEnabled, CuiColor aColor = null, string aName = "", string aPng = "" ) => AddPanel(aParent, aLeftBottomAnchor, aRightTopAnchor, CuiPoint.Zero, CuiPoint.Zero, aIndCursorEnabled, aColor, aName, aPng); /// /// Add a new panel /// /// The parent object name /// Left(x)-Bottom(y) relative position /// Right(x)-Top(y) relative position /// Left(x)-Bottom(y) relative offset /// Right(x)-Top(y) relative offset /// The panel requires the cursor /// Image color /// The object's name /// Image PNG file path /// New object name public string AddPanel( string aParent, CuiPoint aLeftBottomAnchor, CuiPoint aRightTopAnchor, CuiPoint aLeftBottomOffset, CuiPoint aRightTopOffset, bool aIndCursorEnabled, CuiColor aColor = null, string aName = "", string aPng = "" ) { if (aLeftBottomAnchor == null || aRightTopAnchor == null || aLeftBottomOffset == null || aRightTopOffset == null) { FPluginInstance.LogError($"Cui::AddPanel > One of the required parameters is null"); return string.Empty; } CuiPanel panel = new CuiPanel { RectTransform = { AnchorMin = aLeftBottomAnchor.ToString(), AnchorMax = aRightTopAnchor.ToString(), OffsetMin = aLeftBottomOffset.ToString(), OffsetMax = aRightTopOffset.ToString() }, CursorEnabled = aIndCursorEnabled }; if (!string.IsNullOrEmpty(aPng)) panel.Image = new CuiImageComponent { Png = aPng }; if (aColor != null) { if (panel.Image == null) { panel.Image = new CuiImageComponent { Color = aColor.ToString() }; } else { panel.Image.Color = aColor.ToString(); } } FPluginInstance.LogDebug("Added panel to container"); return FContainer.Add(panel, aParent, string.IsNullOrEmpty(aName) ? null : aName); } /// /// Add a new label /// /// The parent object name /// Left(x)-Bottom(y) relative position /// Right(x)-Top(y) relative position /// Text color /// Text to show /// The object's name /// Font size /// Text alignment /// New object name public string AddLabel( string aParent, CuiPoint aLeftBottomAnchor, CuiPoint aRightTopAnchor, CuiColor aColor, string aText, string aName = "", int aFontSize = 14, TextAnchor aAlign = TextAnchor.UpperLeft ) => AddLabel(aParent, aLeftBottomAnchor, aRightTopAnchor, CuiPoint.Zero, CuiPoint.Zero, aColor, aText, aName, aFontSize, aAlign); /// /// Add a new label /// /// The parent object name /// Left(x)-Bottom(y) relative position /// Right(x)-Top(y) relative position /// Left(x)-Bottom(y) relative offset /// Right(x)-Top(y) relative offset /// Text color /// Text to show /// The object's name /// Font size /// Text alignment /// New object name public string AddLabel( string aParent, CuiPoint aLeftBottomAnchor, CuiPoint aRightTopAnchor, CuiPoint aLeftBottomOffset, CuiPoint aRightTopOffset, CuiColor aColor, string aText, string aName = "", int aFontSize = 14, TextAnchor aAlign = TextAnchor.UpperLeft ) { if (aLeftBottomAnchor == null || aRightTopAnchor == null || aLeftBottomOffset == null || aRightTopOffset == null || aColor == null) { FPluginInstance.LogError($"Cui::AddLabel > One of the required parameters is null"); return string.Empty; } FPluginInstance.LogDebug("Added label to container"); return FContainer.Add( new CuiLabel { Text = { Text = aText ?? string.Empty, FontSize = aFontSize, Align = aAlign, Color = aColor.ToString() }, RectTransform = { AnchorMin = aLeftBottomAnchor.ToString(), AnchorMax = aRightTopAnchor.ToString(), OffsetMin = aLeftBottomOffset.ToString(), OffsetMax = aRightTopOffset.ToString() } }, aParent, string.IsNullOrEmpty(aName) ? null : aName ); } /// /// Add a new button /// /// The parent object name /// Left(x)-Bottom(y) relative position /// Right(x)-Top(y) relative position /// Button background color /// Text color /// Text to show /// OnClick event callback command /// Panel to close /// The object's name /// Font size /// Text alignment /// New object name public string AddButton( string aParent, CuiPoint aLeftBottomAnchor, CuiPoint aRightTopAnchor, CuiColor aButtonColor, CuiColor aTextColor, string aText, string aCommand = "", string aClose = "", string aName = "", int aFontSize = 14, TextAnchor aAlign = TextAnchor.MiddleCenter ) => AddButton( aParent, aLeftBottomAnchor, aRightTopAnchor, CuiPoint.Zero, CuiPoint.Zero, aButtonColor, aTextColor, aText, aCommand, aClose, aName, aFontSize, aAlign ); /// /// Add a new button /// /// The parent object name /// Left(x)-Bottom(y) relative position /// Right(x)-Top(y) relative position /// Left(x)-Bottom(y) relative offset /// Right(x)-Top(y) relative offset /// Button background color /// Text color /// Text to show /// OnClick event callback command /// Panel to close /// The object's name /// Font size /// Text alignment /// New object name public string AddButton( string aParent, CuiPoint aLeftBottomAnchor, CuiPoint aRightTopAnchor, CuiPoint aLeftBottomOffset, CuiPoint aRightTopOffset, CuiColor aButtonColor, CuiColor aTextColor, string aText, string aCommand = "", string aClose = "", string aName = "", int aFontSize = 14, TextAnchor aAlign = TextAnchor.MiddleCenter ) { if ( aLeftBottomAnchor == null || aRightTopAnchor == null || aLeftBottomOffset == null || aRightTopOffset == null || aButtonColor == null || aTextColor == null ) { FPluginInstance.LogError($"Cui::AddButton > One of the required parameters is null"); return string.Empty; } FPluginInstance.LogDebug("Added button to container"); return FContainer.Add( new CuiButton { Button = { Command = aCommand ?? string.Empty, Close = aClose ?? string.Empty, Color = aButtonColor.ToString() }, RectTransform = { AnchorMin = aLeftBottomAnchor.ToString(), AnchorMax = aRightTopAnchor.ToString(), OffsetMin = aLeftBottomOffset.ToString(), OffsetMax = aRightTopOffset.ToString() }, Text = { Text = aText ?? string.Empty, FontSize = aFontSize, Align = aAlign, Color = aTextColor.ToString() } }, aParent, string.IsNullOrEmpty(aName) ? null : aName ); } /// /// Add a new input field /// /// The parent object name /// Left(x)-Bottom(y) relative position /// Right(x)-Top(y) relative position /// Text color /// Text to show /// Max character count /// OnChanged event callback command /// Indicates that this input should show password chars /// The object's name /// Font size /// Text alignment /// New object name public string AddInputField( string aParent, CuiPoint aLeftBottomAnchor, CuiPoint aRightTopAnchor, CuiColor aColor, string aText = "", int aCharsLimit = 100, string aCommand = "", bool aIndPassword = false, string aName = "", int aFontSize = 14, TextAnchor aAlign = TextAnchor.MiddleLeft ) => AddInputField( aParent, aLeftBottomAnchor, aRightTopAnchor, CuiPoint.Zero, CuiPoint.Zero, aColor, aText, aCharsLimit, aCommand, aIndPassword, aName, aFontSize, aAlign ); /// /// Add a new input field /// /// The parent object name /// Left(x)-Bottom(y) relative position /// Right(x)-Top(y) relative position /// Left(x)-Bottom(y) relative offset /// Right(x)-Top(y) relative offset /// Fade-out time /// Text color /// Text to show /// Max character count /// OnChanged event callback command /// Indicates that this input should show password chars /// The object's name /// Font size /// New object name public string AddInputField( string aParent, CuiPoint aLeftBottomAnchor, CuiPoint aRightTopAnchor, CuiPoint aLeftBottomOffset, CuiPoint aRightTopOffset, CuiColor aColor, string aText = "", int aCharsLimit = 100, string aCommand = "", bool aIndPassword = false, string aName = "", int aFontSize = 14, TextAnchor aAlign = TextAnchor.MiddleLeft ) { if (aLeftBottomAnchor == null || aRightTopAnchor == null || aLeftBottomOffset == null || aRightTopOffset == null || aColor == null) { FPluginInstance.LogError($"Cui::AddInputField > One of the required parameters is null"); return string.Empty; } FPluginInstance.LogDebug("Added input field to container"); return FContainer.Add( new CuiInputField { InputField = { Text = aText ?? string.Empty, FontSize = aFontSize, Align = aAlign, Color = aColor.ToString(), CharsLimit = aCharsLimit, Command = aCommand ?? string.Empty, IsPassword = aIndPassword }, RectTransform = { AnchorMin = aLeftBottomAnchor.ToString(), AnchorMax = aRightTopAnchor.ToString(), OffsetMin = aLeftBottomOffset.ToString(), OffsetMax = aRightTopOffset.ToString() } }, aParent, string.IsNullOrEmpty(aName) ? null : aName ); } /// /// Add a new element /// /// The parent object name /// The object itself /// The object's name /// New object name public string AddElement(string aParent, CuiPanel aElement, string aName = "") => FContainer.Add(aElement, aParent, string.IsNullOrEmpty(aName) ? null : aName); /// /// Add a new element /// /// The parent object name /// The object itself /// The object's name /// New object name public string AddElement(string aParent, CuiLabel aElement, string aName = "") => FContainer.Add(aElement, aParent, string.IsNullOrEmpty(aName) ? null : aName); /// /// Add a new element /// /// The parent object name /// The object itself /// The object's name /// New object name public string AddElement(string aParent, CuiButton aElement, string aName = "") => FContainer.Add(aElement, aParent, string.IsNullOrEmpty(aName) ? null : aName); /// /// Add a new element /// /// The parent object name /// The object itself /// The object's name /// New object name public string AddElement(string aParent, CuiInputField aElement, string aName = "") => FContainer.Add(aElement, aParent, string.IsNullOrEmpty(aName) ? null : aName); /// /// Draw the UI to the player's client /// /// public bool Draw() => CuiHelper.AddUi(FPlayer, CuiHelper.ToJson(FContainer)); public string JSON { get { return CuiHelper.ToJson(FContainer, true); } } } #endregion GUI #region Utility methods /// /// Add a button to the tab menu /// /// Cui object /// Name of the parent object /// Text to show /// Button to execute /// Bounds of the button /// To indicate whether or not the button is active private void AddTabMenuBtn(ref Cui aUIObj, string aParent, string aCaption, string aCommand, int aPos, bool aIndActive) { Vector2 dimensions = new Vector2(0.096f, 0.75f); Vector2 offset = new Vector2(0.005f, 0.1f); CuiColor btnColor = (aIndActive ? CuiColor.ButtonInactive : CuiColor.Button); CuiPoint lbAnchor = new CuiPoint(((dimensions.x + offset.x) * aPos) + offset.x, offset.y); CuiPoint rtAnchor = new CuiPoint(lbAnchor.X + dimensions.x, offset.y + dimensions.y); aUIObj.AddButton(aParent, lbAnchor, rtAnchor, btnColor, CuiColor.TextAlt, aCaption, (aIndActive ? string.Empty : aCommand)); } /// /// Add a set of user buttons to the parent object /// /// Cui object /// Name of the parent object /// List of entities /// Base format of the command to execute (Will be completed with the user ID /// User list page private void AddPlayerButtons(ref Cui aUIObj, string aParent, ref List> aUserList, string aCommandFmt, int aPage) { List> userRange = aUserList.Skip(aPage * CMaxPlayerButtons).Take(CMaxPlayerButtons).ToList(); Vector2 dimensions = new Vector2(0.194f, 0.06f); Vector2 offset = new Vector2(0.005f, 0.01f); int col = -1; int row = 0; float margin = 0.09f; List addedNames = new List(); foreach (KeyValuePair user in userRange) { if (++col >= CMaxPlayerCols) { row++; col = 0; } float calcTop = (1f - margin) - (((dimensions.y + offset.y) * row) + offset.y); float calcLeft = ((dimensions.x + offset.x) * col) + offset.x; CuiPoint lbAnchor = new CuiPoint(calcLeft, calcTop - dimensions.y); CuiPoint rtAnchor = new CuiPoint(calcLeft + dimensions.x, calcTop); int suffix = 0; string btnTextTemp = EscapeString(user.Value ?? ""); string btnCommand = string.Format(aCommandFmt, user.Key); if (string.IsNullOrEmpty(btnTextTemp) || CUnknownNameList.Contains(btnTextTemp.ToLower())) btnTextTemp = user.Key; string btnText = btnTextTemp; while (addedNames.FindIndex(item => btnText.Equals(item, StringComparison.OrdinalIgnoreCase)) >= 0) { btnText = $"{btnTextTemp} {++suffix}"; } aUIObj.AddButton(aParent, lbAnchor, rtAnchor, CuiColor.Button, CuiColor.TextAlt, btnText, btnCommand, string.Empty, string.Empty, 16); addedNames.Add(btnText); } LogDebug("Added the player buttons to the container"); } /// /// Log an error message to the logfile /// /// private void LogError(string aMessage) => LogToFile(string.Empty, $"[{DateTime.Now.ToString("hh:mm:ss")}] ERROR > {aMessage}", this); /// /// Log an informational message to the logfile /// /// private void LogInfo(string aMessage) => LogToFile(string.Empty, $"[{DateTime.Now.ToString("hh:mm:ss")}] INFO > {aMessage}", this); /// /// Log a debugging message to the logfile /// /// private void LogDebug(string aMessage) { if (CDebugEnabled) LogToFile(string.Empty, $"[{DateTime.Now.ToString("hh:mm:ss")}] DEBUG > {aMessage}", this); } /// /// Verify if a user has the specified permission /// /// The player /// Pass to only verify /// Indicates that issues should be reported /// private bool VerifyPermission(ref BasePlayer aPlayer, string aPermission, bool aIndReport = false) { bool result = permission.UserHasPermission(aPlayer.UserIDString, CPermUiShow); aPermission = aPermission ?? string.Empty; // We need to get rid of possible null values if (FConfigData.UsePermSystem && result && aPermission.Length > 0) result = permission.UserHasPermission(aPlayer.UserIDString, aPermission); if (aIndReport && !result) { rust.SendChatMessage(aPlayer, string.Empty, lang.GetMessage("Permission Error Text", this, aPlayer.UserIDString)); LogError(string.Format(lang.GetMessage("Permission Error Log Text", this, aPlayer.UserIDString), aPlayer.displayName, aPermission)); } return result; } /// /// Verify if a user has the specified permission /// /// The player's ID /// Pass to only verify /// private bool VerifyPermission(string aPlayerId, string aPermission) { BasePlayer player = BasePlayer.Find(aPlayerId); return VerifyPermission(ref player, aPermission); } /// /// Retrieve server users /// /// Indicates if the output should be filtered /// User ID for retrieving filter text /// Retrieve the list of sleepers (offline players) /// private List> GetServerUserList(bool aIndFiltered, string aUserId, bool aIndOffline = false) { List> result; if (aIndOffline) { result = FOfflineUserList.ToList(); } else { result = FOnlineUserList.ToList(); } if (aIndFiltered && FUserBtnPageSearchInputText.ContainsKey(aUserId)) result = result.Where(x => x.Value.IndexOf(FUserBtnPageSearchInputText[aUserId], StringComparison.OrdinalIgnoreCase) >= 0 || x.Key.IndexOf(FUserBtnPageSearchInputText[aUserId], StringComparison.OrdinalIgnoreCase) >= 0 ).ToList(); LogDebug("Retrieved the server user list"); result.Sort((a, b) => { int diff = string.Compare(a.Value, b.Value); if (diff == 0) diff = a.Key.CompareTo(b.Key); return diff; }); return result; } /// /// Retrieve server users /// /// Indicates if the output should be filtered /// User ID for retrieving filter text /// private List> GetBannedUserList(bool aIndFiltered, string aUserId) { List> result = new List>(); foreach (ServerUsers.User user in ServerUsers.GetAll(ServerUsers.UserGroup.Banned)) { result.Add(new KeyValuePair(user.steamid.ToString(), user.username)); } if (aIndFiltered && FUserBtnPageSearchInputText.ContainsKey(aUserId)) result = result.Where(x => x.Value.IndexOf(FUserBtnPageSearchInputText[aUserId], StringComparison.OrdinalIgnoreCase) >= 0 || x.Key.ToString().IndexOf(FUserBtnPageSearchInputText[aUserId], StringComparison.OrdinalIgnoreCase) >= 0 ).ToList(); LogDebug("Retrieved the banned user list"); result.Sort((a, b) => { int diff = string.Compare(a.Value, b.Value); if (diff == 0) diff = a.Key.CompareTo(b.Key); return diff; }); return result; } /// /// Retrieve the target player ID from the arguments and report success /// /// Argument object /// Player ID /// private bool GetTargetFromArg(string[] aArgs, out ulong aTarget) { aTarget = 0; return aArgs.Count() > 0 && ulong.TryParse(aArgs[0], out aTarget); } /// /// Retrieve the target player ID and amount from the arguments and report success /// /// Argument object /// Player ID /// Amount /// private bool GetTargetAmountFromArg(string[] aArgs, out ulong aTarget, out float aAmount) { aTarget = 0; aAmount = 0; return aArgs.Count() >= 2 && ulong.TryParse(aArgs[0], out aTarget) && float.TryParse(aArgs[1], out aAmount); } /// /// Check if the player has the ChatMute flag set /// /// The player /// private bool GetIsMuted(ref BasePlayer aPlayer) { bool isServerMuted = aPlayer.HasPlayerFlag(BasePlayer.PlayerFlags.ChatMute); if (BetterChatMute != null) { return isServerMuted || (bool)BetterChatMute.Call("API_IsMuted", aPlayer.IPlayer); } else { return isServerMuted; } } /// /// Check if the player has the freeze.frozen permission /// /// The player's ID /// private bool GetIsFrozen(ulong aPlayerId) => permission.UserHasPermission(aPlayerId.ToString(), CPermFreezeFrozen); /// /// Send either a kick or a ban message to Discord via the DiscordMessages plugin /// /// The name of the admin /// The ID of the admin /// The name of the target player /// The ID of the target player /// The reason message /// If this is true a ban message is sent, else a kick message is sent private void SendDiscordKickBanMessage(string aAdminName, string aAdminId, string aTargetName, string aTargetId, string aReason, bool aIndIsBan) { if (DiscordMessages != null) { if (CUnknownNameList.Contains(aTargetName.ToLower())) aTargetName = aTargetId; object fields = new[] { new { name = "Player", value = $"[{aTargetName}](https://steamcommunity.com/profiles/{aTargetId})", inline = true }, new { name = aIndIsBan ? "Banned by" : "Kicked by", value = $"[{aAdminName}](https://steamcommunity.com/profiles/{aAdminId})", inline = true }, new { name = "Reason", value = aReason, inline = false } }; DiscordMessages.Call( "API_SendFancyMessage", aIndIsBan ? FConfigData.BanMsgWebhookUrl : FConfigData.KickMsgWebhookUrl, aIndIsBan ? "Player Ban" : "Player Kick", 3329330, JsonConvert.SerializeObject(fields) ); } } /// /// Custom internal version of Assert /// /// /// /// /// private string InternalAssert(bool aEval, string aTrueMsg = "True", string aFalseMsg = "False") => aEval ? aTrueMsg : aFalseMsg; /// /// Transform a string array into a printable string. /// /// /// private string StringArrToString(ref string[] aObj) => $"[ {string.Join(", ", aObj)} ]"; /// /// Transform a dictionary of strings into a printable string. /// /// /// private string StringDictToString(ref Dictionary aObj) { StringBuilder result = new StringBuilder("{\n"); foreach (KeyValuePair item in aObj) { result.Append($"'{item.Key}': '{item.Value}'\n"); } result.Append("}"); return result.ToString(); } /// /// Escape strings to make them usable in the UI. /// /// /// private string EscapeString(string aStr) => aStr.Replace("\0", "") .Replace("\a", "") .Replace("\b", "") .Replace("\f", "") .Replace("\r", "") .Replace("\n", " ") .Replace("\t", " ") .Replace("\v", "") .Replace("\"", "\u02EE") .Replace("/", "\u2215") .Replace("\\", "\u2216"); /// /// Gets the reason from the input box on the players screen. /// /// The player ID that entered the reason. /// The target ID the reason is for. /// string GetReason(string playerId, string targetId = "") { string reasonMsg; if (FUserPageReasonInputText.ContainsKey(playerId)) { reasonMsg = FUserPageReasonInputText[playerId].Trim(); if (string.IsNullOrEmpty(reasonMsg)) reasonMsg = lang.GetMessage("Ban Reason Message Text", this, targetId.ToString()); } else { reasonMsg = lang.GetMessage("Ban Reason Message Text", this, targetId.ToString()); } return reasonMsg; } #endregion Utility methods #region Upgrade methods /// /// Upgrade the config to 1.3.10 if needed /// /// private bool UpgradeTo1310() { bool result = false; Config.Load(); if (Config["Use Permission System"] == null) { FConfigData.UsePermSystem = true; result = true; } // Remove legacy config items if ( Config["Enable kick action"] != null || Config["Enable ban action"] != null || Config["Enable unban action"] != null || Config["Enable kill action"] != null || Config["Enable inventory clear action"] != null || Config["Enable blueprint reset action"] != null || Config["Enable metabolism reset action"] != null || Config["Enable hurt action"] != null || Config["Enable heal action"] != null || Config["Enable mute action"] != null || Config["Enable perms action"] != null || Config["Enable freeze action"] != null ) result = true; Config.Clear(); if (result) Config.WriteObject(FConfigData); return result; } /// /// Upgrade the config to 1.3.13 if needed /// /// private bool UpgradeTo1313() { bool result = false; Config.Load(); if (Config["Discord Webhook url for ban messages"] == null) { FConfigData.BanMsgWebhookUrl = string.Empty; result = true; } if (Config["Discord Webhook url for kick messages"] == null) { FConfigData.KickMsgWebhookUrl = string.Empty; result = true; } Config.Clear(); if (result) Config.WriteObject(FConfigData); return result; } /// /// Upgrade the config to 1.5.6 if needed /// /// private bool UpgradeTo156() { bool result = false; Dictionary oldPerms = new Dictionary() { { "playeradministration.show", CPermUiShow }, { "playeradministration.kick", CPermKick }, { "playeradministration.ban", CPermBan }, { "playeradministration.kill", CPermKill }, { "playeradministration.perms", CPermPerms }, { "playeradministration.voicemute", CPermMute }, { "playeradministration.chatmute", CPermMute }, { "playeradministration.freeze", CPermFreeze }, { "playeradministration.clearinventory", CPermClearInventory }, { "playeradministration.resetblueprint", CPermResetBP }, { "playeradministration.resetmetabolism", CPermResetMetabolism }, { "playeradministration.recovermetabolism", CPermRecoverMetabolism }, { "playeradministration.hurt", CPermHurt }, { "playeradministration.heal", CPermHeal }, { "playeradministration.teleport", CPermTeleport }, { "playeradministration.spectate", CPermSpectate } }; LogDebug($"Old Perms: {StringDictToString(ref oldPerms)}"); foreach (KeyValuePair item in oldPerms) { string[] groups = permission.GetPermissionGroups(item.Key); LogDebug($"Groups: {StringArrToString(ref groups)}"); string[] users = permission.GetPermissionUsers(item.Key); LogDebug($"Users: {StringArrToString(ref users)}"); if (groups.Count() <= 0 && users.Count() <= 0) { LogDebug("Counts are zero"); continue; } result = true; foreach (string group in groups) { permission.RevokeGroupPermission(group, item.Key); permission.GrantGroupPermission(group, item.Value, this); LogInfo($"Fixed group permission: {group} (OLD) {item.Key} -> (NEW) {item.Value}"); } foreach (string user in users) { string uid = user.Substring(0, user.IndexOf('(')); permission.RevokeUserPermission(uid, item.Key); permission.GrantUserPermission(uid, item.Value, this); LogInfo($"Fixed user permission: {user} (OLD) {item.Key} -> (NEW) {item.Value}"); } } permission.SaveData(); return result; } /// /// Upgrade the config to 1.5.19 if needed /// /// private bool UpgradeTo1519() { bool result = false; Dictionary oldPerms = new Dictionary() { { "playeradministration.access.voicemute", CPermMute }, { "playeradministration.access.chatmute", CPermMute } }; LogDebug($"Old Perms: {StringDictToString(ref oldPerms)}"); foreach (KeyValuePair item in oldPerms) { string[] groups = permission.GetPermissionGroups(item.Key); LogDebug($"Groups: {StringArrToString(ref groups)}"); string[] users = permission.GetPermissionUsers(item.Key); LogDebug($"Users: {StringArrToString(ref users)}"); if (groups.Count() <= 0 && users.Count() <= 0) { LogDebug("Counts are zero"); continue; } result = true; foreach (string group in groups) { permission.RevokeGroupPermission(group, item.Key); permission.GrantGroupPermission(group, item.Value, this); LogInfo($"Fixed group permission: {group} (OLD) {item.Key} -> (NEW) {item.Value}"); } foreach (string user in users) { string uid = user.Substring(0, user.IndexOf('(')); permission.RevokeUserPermission(uid, item.Key); permission.GrantUserPermission(uid, item.Value, this); LogInfo($"Fixed user permission: {user} (OLD) {item.Key} -> (NEW) {item.Value}"); } } permission.SaveData(); return result; } #endregion #region GUI build methods /// /// Build the tab nav-bar /// /// Cui object /// The active page type private void BuildTabMenu(ref Cui aUIObj, UiPage aPageType) { // Add the panels and title label string headerPanel = aUIObj.AddElement(CMainPanelName, CTabHeaderPanel); string tabBtnPanel = aUIObj.AddElement(CMainPanelName, CTabTabBtnPanel); aUIObj.AddElement(headerPanel, CTabMenuHeaderLbl); aUIObj.AddElement(headerPanel, CTabMenuCloseBtn); // Add the tab menu buttons AddTabMenuBtn( ref aUIObj, tabBtnPanel, lang.GetMessage("Main Tab Text", this, aUIObj.PlayerIdString), $"{CSwitchUiCmd} {CCmdArgMain}", 0, aPageType == UiPage.Main ? true : false ); AddTabMenuBtn( ref aUIObj, tabBtnPanel, lang.GetMessage("Online Player Tab Text", this, aUIObj.PlayerIdString), $"{CSwitchUiCmd} {CCmdArgPlayersOnline} 0", 1, aPageType == UiPage.PlayersOnline ? true : false ); AddTabMenuBtn( ref aUIObj, tabBtnPanel, lang.GetMessage("Offline Player Tab Text", this, aUIObj.PlayerIdString), $"{CSwitchUiCmd} {CCmdArgPlayersOffline} 0", 2, aPageType == UiPage.PlayersOffline ? true : false ); AddTabMenuBtn( ref aUIObj, tabBtnPanel, lang.GetMessage("Banned Player Tab Text", this, aUIObj.PlayerIdString), $"{CSwitchUiCmd} {CCmdArgPlayersBanned} 0", 3, aPageType == UiPage.PlayersBanned ? true : false ); LogDebug("Built the tab menu"); } /// /// Build the main-menu /// /// Cui object private void BuildMainPage(ref Cui aUIObj) { // Add the panels and title string panel = aUIObj.AddElement(CMainPanelName, CMainPagePanel); aUIObj.AddElement(panel, CMainPageTitleLbl); // Add the ban by ID group aUIObj.AddLabel( panel, CMainPageLblBanByIdTitleLbAnchor, CMainPageLblBanByIdTitleRtAnchor, CuiColor.TextTitle, lang.GetMessage("Ban By ID Title Text", this, aUIObj.PlayerIdString), string.Empty, 16, TextAnchor.MiddleLeft ); aUIObj.AddLabel( panel, CMainPageLblBanByIdLbAnchor, CMainPageLblBanByIdRtAnchor, CuiColor.TextAlt, lang.GetMessage("Ban By ID Label Text", this, aUIObj.PlayerIdString), string.Empty, 14, TextAnchor.MiddleLeft ); string panelBanByIdGroup = aUIObj.AddElement(panel, CBanByIdGroupPanel); if (VerifyPermission(aUIObj.PlayerIdString, CPermBan)) { aUIObj.AddElement(panelBanByIdGroup, CBanByIdEdt); aUIObj.AddElement(panel, CBanByIdActiveBtn); } else { aUIObj.AddElement(panel, CBanByIdInactiveBtn); } LogDebug("Built the main page"); LogDebug($"Elapsed time (BuildMainPage): {(Time.realtimeSinceStartup - aUIObj.StartTime).ToString("F8")}"); } /// /// Build the current user buttons /// /// Cui object /// The active page type /// The active page type /// User list page /// Command format for the buttons /// Total user count /// Indicates if the output should be filtered private void BuildUserButtons( ref Cui aUIObj, string aParent, UiPage aPageType, ref int aPage, out string aBtnCommandFmt, out int aUserCount, bool aIndFiltered ) { string commandFmt = $"{CSwitchUiCmd} {CCmdArgPlayerPage} {{0}}"; List> userList = GetServerUserList(aIndFiltered, aUIObj.PlayerIdString, aPageType == UiPage.PlayersOffline); if (aPageType == UiPage.PlayersOnline) { aBtnCommandFmt = $"{CSwitchUiCmd} {(aIndFiltered ? CCmdArgPlayersOnlineSearch : CCmdArgPlayersOnline)} {{0}}"; } else { aBtnCommandFmt = $"{CSwitchUiCmd} {(aIndFiltered ? CCmdArgPlayersOfflineSearch : CCmdArgPlayersOffline)} {{0}}"; } aUserCount = userList.Count; if ((aPage != 0) && (userList.Count <= CMaxPlayerButtons)) aPage = 0; // Reset page to 0 if user count is lower or equal to max button count AddPlayerButtons(ref aUIObj, aParent, ref userList, commandFmt, aPage); LogDebug("Built the current page of user buttons"); } /// /// Build a page of user buttons /// /// Cui object /// The active page type /// User list page /// Indicates if the output should be filtered private void BuildUserBtnPage(ref Cui aUIObj, UiPage aPageType, int aPage, bool aIndFiltered) { string npBtnCommandFmt; int userCount; string panel = aUIObj.AddElement(CMainPanelName, CMainPagePanel); aUIObj.AddLabel( panel, CUserBtnPageLblTitleLbAnchor, CUserBtnPageLblTitleRtAnchor, CuiColor.TextAlt, lang.GetMessage("User Button Page Title Text", this, aUIObj.PlayerIdString), string.Empty, 18, TextAnchor.MiddleLeft ); // Add search elements aUIObj.AddLabel( panel, CUserBtnPageLblSearchLbAnchor, CUserBtnPageLblSearchRtAnchor, CuiColor.TextAlt, lang.GetMessage("Search Label Text", this, aUIObj.PlayerIdString), string.Empty, 16, TextAnchor.MiddleLeft ); string panelSearchGroup = aUIObj.AddElement(panel, CUserBtnPageSearchInputPanel); aUIObj.AddInputField( panelSearchGroup, CUserBtnPageEdtSearchInputLbAnchor, CUserBtnPageEdtSearchInputRtAnchor, CuiColor.TextAlt, (FUserBtnPageSearchInputText.ContainsKey(aUIObj.PlayerIdString) ? FUserBtnPageSearchInputText[aUIObj.PlayerIdString] : string.Empty), 100, CUserBtnPageSearchInputTextCmd, false, string.Empty, 16 ); switch (aPageType) { case UiPage.PlayersOnline: { aUIObj.AddButton( panel, CUserBtnPageBtnSearchLbAnchor, CUserBtnPageBtnSearchRtAnchor, CuiColor.Button, CuiColor.TextAlt, lang.GetMessage("Go Button Text", this, aUIObj.PlayerIdString), $"{CSwitchUiCmd} {CCmdArgPlayersOnlineSearch} 0", string.Empty, string.Empty, 16 ); BuildUserButtons(ref aUIObj, panel, aPageType, ref aPage, out npBtnCommandFmt, out userCount, aIndFiltered); break; } case UiPage.PlayersOffline: { aUIObj.AddButton( panel, CUserBtnPageBtnSearchLbAnchor, CUserBtnPageBtnSearchRtAnchor, CuiColor.Button, CuiColor.TextAlt, lang.GetMessage("Go Button Text", this, aUIObj.PlayerIdString), $"{CSwitchUiCmd} {CCmdArgPlayersOfflineSearch} 0", string.Empty, string.Empty, 16 ); BuildUserButtons(ref aUIObj, panel, aPageType, ref aPage, out npBtnCommandFmt, out userCount, aIndFiltered); break; } default: { aUIObj.AddButton( panel, CUserBtnPageBtnSearchLbAnchor, CUserBtnPageBtnSearchRtAnchor, CuiColor.Button, CuiColor.TextAlt, lang.GetMessage("Go Button Text", this, aUIObj.PlayerIdString), $"{CSwitchUiCmd} {CCmdArgPlayersBannedSearch} 0", string.Empty, string.Empty, 16 ); string commandFmt = $"{CSwitchUiCmd} {CCmdArgPlayerPageBanned} {{0}}"; List> userList = GetBannedUserList(aIndFiltered, aUIObj.PlayerIdString); npBtnCommandFmt = $"{CSwitchUiCmd} {(aIndFiltered ? CCmdArgPlayersBannedSearch : CCmdArgPlayersBanned)} {{0}}"; userCount = userList.Count; if ((aPage != 0) && (userList.Count <= CMaxPlayerButtons)) aPage = 0; // Reset page to 0 if user count is lower or equal to max button count AddPlayerButtons(ref aUIObj, panel, ref userList, commandFmt, aPage); LogDebug("Built the current page of banned user buttons"); break; } } // Decide whether or not to activate the "previous" button if (aPage == 0) { aUIObj.AddElement(panel, CUserBtnPagePreviousInactiveBtn); } else { aUIObj.AddButton( panel, CUserBtnPageBtnPreviousLbAnchor, CUserBtnPageBtnPreviousRtAnchor, CuiColor.Button, CuiColor.TextAlt, "<<", string.Format(npBtnCommandFmt, aPage - 1), string.Empty, string.Empty, 18 ); } // Decide whether or not to activate the "next" button if (userCount > CMaxPlayerButtons * (aPage + 1)) { aUIObj.AddButton( panel, CUserBtnPageBtnNextLbAnchor, CUserBtnPageBtnNextRtAnchor, CuiColor.Button, CuiColor.TextAlt, ">>", string.Format(npBtnCommandFmt, aPage + 1), string.Empty, string.Empty, 18 ); } else { aUIObj.AddElement(panel, CUserBtnPageNextInactiveBtn); } LogDebug("Built the user button page"); LogDebug($"Elapsed time (BuildUserBtnPage): {(Time.realtimeSinceStartup - aUIObj.StartTime).ToString("F8")}"); } /// /// Add the user information labels to the parent element /// /// Cui object /// Parent panel name /// UI destination Player ID (SteamId64) /// Player ID (SteamId64) /// Player who's information we need to display private void AddUserPageInfoLabels(ref Cui aUIObj, string aParent, string aUiUserId, ulong aPlayerId, ref BasePlayer aPlayer) { string lastCheatStr = lang.GetMessage("Never Label Text", this, aUiUserId); string authLevel = ServerUsers.Get(aPlayerId)?.group.ToString() ?? "None"; // Pre-calc last admin cheat if (aPlayer.lastAdminCheatTime > 0f) { TimeSpan lastCheatSinceStart = new TimeSpan(0, 0, (int)(Time.realtimeSinceStartup - aPlayer.lastAdminCheatTime)); lastCheatStr = $"{DateTime.UtcNow.Subtract(lastCheatSinceStart).ToString(@"yyyy\/MM\/dd HH:mm:ss")} UTC"; } LogDebug("AddUserPageInfoLabels > Time since last admin cheat has been determined."); aUIObj.AddLabel( aParent, CUserPageLblIdLbAnchor, CUserPageLblIdRtAnchor, CuiColor.TextAlt, string.Format( lang.GetMessage("Id Label Format", this, aUiUserId), aPlayerId, (aPlayer.IsDeveloper ? lang.GetMessage("Dev Label Text", this, aUiUserId) : string.Empty) ), string.Empty, 14, TextAnchor.MiddleLeft ); aUIObj.AddLabel( aParent, CUserPageLblAuthLbAnchor, CUserPageLblAuthRtAnchor, CuiColor.TextAlt, string.Format(lang.GetMessage("Auth Level Label Format", this, aUiUserId), authLevel), string.Empty, 14, TextAnchor.MiddleLeft ); aUIObj.AddLabel( aParent, CUserPageLblConnectLbAnchor, CUserPageLblConnectRtAnchor, CuiColor.TextAlt, string.Format(lang.GetMessage( "Connection Label Format", this, aUiUserId), (aPlayer.IsConnected ? lang.GetMessage("Connected Label Text", this, aUiUserId) : lang.GetMessage("Disconnected Label Text", this, aUiUserId) ) ), string.Empty, 14, TextAnchor.MiddleLeft ); aUIObj.AddLabel( aParent, CUserPageLblSleepLbAnchor, CUserPageLblSleepRtAnchor, CuiColor.TextAlt, string.Format(lang.GetMessage( "Status Label Format", this, aUiUserId), (aPlayer.IsSleeping() ? lang.GetMessage("Sleeping Label Text", this, aUiUserId) : lang.GetMessage("Awake Label Text", this, aUiUserId)), (aPlayer.IsAlive() ? lang.GetMessage("Alive Label Text", this, aUiUserId) : lang.GetMessage("Dead Label Text", this, aUiUserId)) ), string.Empty, 14, TextAnchor.MiddleLeft ); LogDebug("AddUserPageInfoLabels > Generic info has been added."); if (VerifyPermission(aUiUserId, CPermDetailInfo)) { aUIObj.AddLabel( aParent, CUserPageLblFlagLbAnchor, CUserPageLblFlagRtAnchor, CuiColor.TextAlt, string.Format(lang.GetMessage( "Flags Label Format", this, aUiUserId), (aPlayer.IsFlying ? lang.GetMessage("Flying Label Text", this, aUiUserId) : string.Empty), (aPlayer.isMounted ? lang.GetMessage("Mounted Label Text", this, aUiUserId) : string.Empty) ), string.Empty, 14, TextAnchor.MiddleLeft ); aUIObj.AddLabel( aParent, CUserPageLblPosLbAnchor, CUserPageLblPosRtAnchor, CuiColor.TextAlt, string.Format(lang.GetMessage("Position Label Format", this, aUiUserId), aPlayer.ServerPosition), string.Empty, 14, TextAnchor.MiddleLeft ); aUIObj.AddLabel( aParent, CUserPageLblRotLbAnchor, CUserPageLblRotRtAnchor, CuiColor.TextAlt, string.Format(lang.GetMessage("Rotation Label Format", this, aUiUserId), aPlayer.GetNetworkRotation()), string.Empty, 14, TextAnchor.MiddleLeft ); aUIObj.AddLabel( aParent, CUserPageLblAdminCheatLbAnchor, CUserPageLblAdminCheatRtAnchor, CuiColor.TextAlt, string.Format(lang.GetMessage("Last Admin Cheat Label Format", this, aUiUserId), lastCheatStr), string.Empty, 14, TextAnchor.MiddleLeft ); aUIObj.AddLabel( aParent, CUserPageLblIdleLbAnchor, CUserPageLblIdleRtAnchor, CuiColor.TextAlt, string.Format(lang.GetMessage("Idle Time Label Format", this, aUiUserId), Math.Round(aPlayer.IdleTime, 2)), string.Empty, 14, TextAnchor.MiddleLeft ); if (Economics != null) { aUIObj.AddLabel( aParent, CUserPageLblBalanceLbAnchor, CUserPageLblBalanceRtAnchor, CuiColor.TextAlt, string.Format(lang.GetMessage("Economics Balance Label Format", this, aUiUserId), Math.Round((double)Economics.Call("Balance", aPlayerId), 2)), string.Empty, 14, TextAnchor.MiddleLeft ); LogDebug("AddUserPageInfoLabels > Economics info has been added."); } if (ServerRewards != null) { aUIObj.AddLabel( aParent, CUserPageLblRewardPointsLbAnchor, CUserPageLblRewardPointsRtAnchor, CuiColor.TextAlt, string.Format(lang.GetMessage("ServerRewards Points Label Format", this, aUiUserId), (int)(ServerRewards.Call("CheckPoints", aPlayerId) ?? 0)), string.Empty, 14, TextAnchor.MiddleLeft ); LogDebug("AddUserPageInfoLabels > ServerRewards info has been added."); } aUIObj.AddLabel( aParent, CUserPageLblHealthLbAnchor, CUserPageLblHealthRtAnchor, CuiColor.TextAlt, string.Format(lang.GetMessage("Health Label Format", this, aUiUserId), aPlayer.health), string.Empty, 14, TextAnchor.MiddleLeft ); aUIObj.AddLabel( aParent, CUserPageLblCalLbAnchor, CUserPageLblCalRtAnchor, CuiColor.TextAlt, string.Format(lang.GetMessage("Calories Label Format", this, aUiUserId), aPlayer.metabolism?.calories?.value), string.Empty, 14, TextAnchor.MiddleLeft ); aUIObj.AddLabel( aParent, CUserPageLblHydraLbAnchor, CUserPageLblHydraRtAnchor, CuiColor.TextAlt, string.Format(lang.GetMessage("Hydration Label Format", this, aUiUserId), aPlayer.metabolism?.hydration?.value), string.Empty, 14, TextAnchor.MiddleLeft ); aUIObj.AddLabel( aParent, CUserPageLblTempLbAnchor, CUserPageLblTempRtAnchor, CuiColor.TextAlt, string.Format(lang.GetMessage("Temp Label Format", this, aUiUserId), aPlayer.metabolism?.temperature?.value), string.Empty, 14, TextAnchor.MiddleLeft ); aUIObj.AddLabel( aParent, CUserPageLblWetLbAnchor, CUserPageLblWetRtAnchor, CuiColor.TextAlt, string.Format(lang.GetMessage("Wetness Label Format", this, aUiUserId), aPlayer.metabolism?.wetness?.value), string.Empty, 14, TextAnchor.MiddleLeft ); aUIObj.AddLabel( aParent, CUserPageLblComfortLbAnchor, CUserPageLblComfortRtAnchor, CuiColor.TextAlt, string.Format(lang.GetMessage("Comfort Label Format", this, aUiUserId), aPlayer.metabolism?.comfort?.value), string.Empty, 14, TextAnchor.MiddleLeft ); aUIObj.AddLabel( aParent, CUserPageLblBleedLbAnchor, CUserPageLblBleedRtAnchor, CuiColor.TextAlt, string.Format(lang.GetMessage("Bleeding Label Format", this, aUiUserId), aPlayer.metabolism?.bleeding?.value), string.Empty, 14, TextAnchor.MiddleLeft ); aUIObj.AddLabel( aParent, CUserPageLblRads1LbAnchor, CUserPageLblRads1RtAnchor, CuiColor.TextAlt, string.Format(lang.GetMessage("Radiation Label Format", this, aUiUserId), aPlayer.metabolism?.radiation_poison?.value), string.Empty, 14, TextAnchor.MiddleLeft ); aUIObj.AddLabel( aParent, CUserPageLblRads2LbAnchor, CUserPageLblRads2RtAnchor, CuiColor.TextAlt, string.Format(lang.GetMessage("Radiation Protection Label Format", this, aUiUserId), aPlayer.RadiationProtection()), string.Empty, 14, TextAnchor.MiddleLeft ); LogDebug("AddUserPageInfoLabels > Player statistics info has been added."); } } /// /// Build the user information and administration page /// This kind of method will always be complex, so ignore metrics about it, please. :) /// /// Cui object /// The active page type /// Player ID (SteamId64) private void BuildUserPage(ref Cui aUIObj, UiPage aPageType, ulong aPlayerId) { // Add panels string panel = aUIObj.AddPanel(CMainPanelName, CMainPanelLbAnchor, CMainPanelRtAnchor, false, CuiColor.Background); string infoPanel = aUIObj.AddPanel(panel, CUserPageInfoPanelLbAnchor, CUserPageInfoPanelRtAnchor, false, CuiColor.BackgroundMedium); string actionPanel = aUIObj.AddPanel(panel, CUserPageActionPanelLbAnchor, CUserPageActionPanelRtAnchor, false, CuiColor.BackgroundMedium); LogDebug("BuildUserPage > Panels have been added."); // Add title labels aUIObj.AddLabel( infoPanel, CUserPageLblinfoTitleLbAnchor, CUserPageLblinfoTitleRtAnchor, CuiColor.TextTitle, lang.GetMessage("Player Info Label Text", this, aUIObj.PlayerIdString), string.Empty, 14, TextAnchor.MiddleLeft ); aUIObj.AddLabel( actionPanel, CUserPageLblActionTitleLbAnchor, CUserPageLblActionTitleRtAnchor, CuiColor.TextTitle, lang.GetMessage("Player Actions Label Text", this, aUIObj.PlayerIdString), string.Empty, 14, TextAnchor.MiddleLeft ); LogDebug("BuildUserPage > Title lables have been added."); if (aPageType == UiPage.PlayerPage) { BasePlayer player = BasePlayer.FindByID(aPlayerId) ?? BasePlayer.FindSleeping(aPlayerId); LogDebug("BuildUserPage > player = null? " + InternalAssert(player == null)); aUIObj.AddLabel( panel, CMainLblTitleLbAnchor, CMainLblTitleRtAnchor, CuiColor.TextAlt, string.Format(lang.GetMessage("User Page Title Format", this, aUIObj.PlayerIdString), EscapeString(player.displayName), string.Empty), string.Empty, 18, TextAnchor.MiddleLeft ); // Add user info labels AddUserPageInfoLabels(ref aUIObj, infoPanel, aUIObj.PlayerIdString, aPlayerId, ref player); // --- Build player action panel // Ban, Kick if (VerifyPermission(aUIObj.PlayerIdString, CPermBan)) { aUIObj.AddButton( actionPanel, CUserPageBtnBanLbAnchor, CUserPageBtnBanRtAnchor, CuiColor.ButtonDanger, CuiColor.TextAlt, lang.GetMessage("Ban Button Text", this, aUIObj.PlayerIdString), $"{CBanUserCmd} {aPlayerId}" ); } else { aUIObj.AddButton( actionPanel, CUserPageBtnBanLbAnchor, CUserPageBtnBanRtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Ban Button Text", this, aUIObj.PlayerIdString) ); } if (VerifyPermission(aUIObj.PlayerIdString, CPermKick) && player.IsConnected) { aUIObj.AddButton( actionPanel, CUserPageBtnKickLbAnchor, CUserPageBtnKickRtAnchor, CuiColor.ButtonDanger, CuiColor.TextAlt, lang.GetMessage("Kick Button Text", this, aUIObj.PlayerIdString), $"{CKickUserCmd} {aPlayerId}" ); } else { aUIObj.AddButton( actionPanel, CUserPageBtnKickLbAnchor, CUserPageBtnKickRtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Kick Button Text", this, aUIObj.PlayerIdString) ); } aUIObj.AddLabel( actionPanel, CUserPageLblReasonLbAnchor, CUserPageLblReasonRtAnchor, CuiColor.TextAlt, lang.GetMessage("Reason Input Label Text", this, aUIObj.PlayerIdString), string.Empty, 14, TextAnchor.MiddleLeft ); string panelReasonGroup = aUIObj.AddPanel(actionPanel, CUserPagePanelReasonLbAnchor, CUserPagePanelReasonRtAnchor, false, CuiColor.BackgroundDark); aUIObj.AddInputField( panelReasonGroup, CUserPageEdtReasonLbAnchor, CUserPageEdtReasonRtAnchor, CuiColor.TextAlt, string.Empty, 24, CUserPageReasonInputTextCmd ); // Unmute, Mute (And timed ones if BetterChat is available) if (VerifyPermission(aUIObj.PlayerIdString, CPermMute) && player.IsConnected) { if (GetIsMuted(ref player)) { aUIObj.AddButton( actionPanel, CUserPageBtnUnmuteLbAnchor, CUserPageBtnUnmuteRtAnchor, CuiColor.ButtonSuccess, CuiColor.TextAlt, lang.GetMessage("Unmute Button Text", this, aUIObj.PlayerIdString), $"{CUnmuteUserCmd} {aPlayerId}" ); aUIObj.AddButton( actionPanel, CUserPageBtnMuteLbAnchor, CUserPageBtnMuteRtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Mute Button Text", this, aUIObj.PlayerIdString) ); if (BetterChatMute != null) { aUIObj.AddButton( actionPanel, CUserPageBtnMuteFifteenLbAnchor, CUserPageBtnMuteFifteenRtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Mute Button Text 15", this, aUIObj.PlayerIdString) ); aUIObj.AddButton( actionPanel, CUserPageBtnMuteThirtyLbAnchor, CUserPageBtnMuteThirtyRtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Mute Button Text 30", this, aUIObj.PlayerIdString) ); aUIObj.AddButton( actionPanel, CUserPageBtnMuteSixtyLbAnchor, CUserPageBtnMuteSixtyRtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Mute Button Text 60", this, aUIObj.PlayerIdString) ); } } else { aUIObj.AddButton( actionPanel, CUserPageBtnUnmuteLbAnchor, CUserPageBtnUnmuteRtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Unmute Button Text", this, aUIObj.PlayerIdString) ); aUIObj.AddButton( actionPanel, CUserPageBtnMuteLbAnchor, CUserPageBtnMuteRtAnchor, CuiColor.ButtonDanger, CuiColor.TextAlt, lang.GetMessage("Mute Button Text", this, aUIObj.PlayerIdString), $"{CMuteUserCmd} {aPlayerId} 0" ); if (BetterChatMute != null) { aUIObj.AddButton( actionPanel, CUserPageBtnMuteFifteenLbAnchor, CUserPageBtnMuteFifteenRtAnchor, CuiColor.ButtonDanger, CuiColor.TextAlt, lang.GetMessage("Mute Button Text 15", this, aUIObj.PlayerIdString), $"{CMuteUserCmd} {aPlayerId} 15" ); aUIObj.AddButton( actionPanel, CUserPageBtnMuteThirtyLbAnchor, CUserPageBtnMuteThirtyRtAnchor, CuiColor.ButtonDanger, CuiColor.TextAlt, lang.GetMessage("Mute Button Text 30", this, aUIObj.PlayerIdString), $"{CMuteUserCmd} {aPlayerId} 30" ); aUIObj.AddButton( actionPanel, CUserPageBtnMuteSixtyLbAnchor, CUserPageBtnMuteSixtyRtAnchor, CuiColor.ButtonDanger, CuiColor.TextAlt, lang.GetMessage("Mute Button Text 60", this, aUIObj.PlayerIdString), $"{CMuteUserCmd} {aPlayerId} 60" ); } } } else { aUIObj.AddButton( actionPanel, CUserPageBtnUnmuteLbAnchor, CUserPageBtnUnmuteRtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Unmute Button Text", this, aUIObj.PlayerIdString) ); aUIObj.AddButton( actionPanel, CUserPageBtnMuteLbAnchor, CUserPageBtnMuteRtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Mute Button Text", this, aUIObj.PlayerIdString) ); } // Unfreeze, Freeze if (Freeze == null) { aUIObj.AddButton( actionPanel, CUserPageBtnFreezeLbAnchor, CUserPageBtnFreezeRtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Freeze Not Installed Button Text", this, aUIObj.PlayerIdString) ); } else if (VerifyPermission(aUIObj.PlayerIdString, CPermFreeze) && player.IsConnected) { if (GetIsFrozen(aPlayerId)) { aUIObj.AddButton( actionPanel, CUserPageBtnUnFreezeLbAnchor, CUserPageBtnUnFreezeRtAnchor, CuiColor.ButtonSuccess, CuiColor.TextAlt, lang.GetMessage("UnFreeze Button Text", this, aUIObj.PlayerIdString), $"{CUnreezeCmd} {aPlayerId}" ); aUIObj.AddButton( actionPanel, CUserPageBtnFreezeLbAnchor, CUserPageBtnFreezeRtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Freeze Button Text", this, aUIObj.PlayerIdString) ); } else { aUIObj.AddButton( actionPanel, CUserPageBtnUnFreezeLbAnchor, CUserPageBtnUnFreezeRtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("UnFreeze Button Text", this, aUIObj.PlayerIdString) ); aUIObj.AddButton( actionPanel, CUserPageBtnFreezeLbAnchor, CUserPageBtnFreezeRtAnchor, CuiColor.ButtonDanger, CuiColor.TextAlt, lang.GetMessage("Freeze Button Text", this, aUIObj.PlayerIdString), $"{CFreezeCmd} {aPlayerId}" ); } } else { aUIObj.AddButton( actionPanel, CUserPageBtnUnFreezeLbAnchor, CUserPageBtnUnFreezeRtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("UnFreeze Button Text", this, aUIObj.PlayerIdString) ); aUIObj.AddButton( actionPanel, CUserPageBtnFreezeLbAnchor, CUserPageBtnFreezeRtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Freeze Button Text", this, aUIObj.PlayerIdString) ); } // Clear inventory, Reset BP, Reset metabolism if (VerifyPermission(aUIObj.PlayerIdString, CPermClearInventory)) { aUIObj.AddButton( actionPanel, CUserPageBtnClearInventoryLbAnchor, CUserPageBtnClearInventoryRtAnchor, CuiColor.ButtonWarning, CuiColor.TextAlt, lang.GetMessage("Clear Inventory Button Text", this, aUIObj.PlayerIdString), $"{CClearUserInventoryCmd} {aPlayerId}" ); } else { aUIObj.AddButton( actionPanel, CUserPageBtnClearInventoryLbAnchor, CUserPageBtnClearInventoryRtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Clear Inventory Button Text", this, aUIObj.PlayerIdString) ); } if (VerifyPermission(aUIObj.PlayerIdString, CPermResetBP)) { aUIObj.AddButton( actionPanel, CUserPageBtnResetBPLbAnchor, CUserPageBtnResetBPRtAnchor, CuiColor.ButtonWarning, CuiColor.TextAlt, lang.GetMessage("Reset Blueprints Button Text", this, aUIObj.PlayerIdString), $"{CResetUserBPCmd} {aPlayerId}" ); } else { aUIObj.AddButton( actionPanel, CUserPageBtnResetBPLbAnchor, CUserPageBtnResetBPRtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Reset Blueprints Button Text", this, aUIObj.PlayerIdString) ); } if (VerifyPermission(aUIObj.PlayerIdString, CPermResetMetabolism)) { aUIObj.AddButton( actionPanel, CUserPageBtnResetMetabolismLbAnchor, CUserPageBtnResetMetabolismRtAnchor, CuiColor.ButtonWarning, CuiColor.TextAlt, lang.GetMessage("Reset Metabolism Button Text", this, aUIObj.PlayerIdString), $"{CResetUserMetabolismCmd} {aPlayerId}" ); } else { aUIObj.AddButton( actionPanel, CUserPageBtnResetMetabolismLbAnchor, CUserPageBtnResetMetabolismRtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Reset Metabolism Button Text", this, aUIObj.PlayerIdString) ); } if (VerifyPermission(aUIObj.PlayerIdString, CPermRecoverMetabolism)) { aUIObj.AddButton( actionPanel, CUserPageBtnRecoverMetabolismLbAnchor, CUserPageBtnRecoverMetabolismRtAnchor, CuiColor.ButtonWarning, CuiColor.TextAlt, lang.GetMessage("Recover Metabolism Button Text", this, aUIObj.PlayerIdString), $"{CRecoverUserMetabolismCmd} {aPlayerId}" ); } else { aUIObj.AddButton( actionPanel, CUserPageBtnRecoverMetabolismLbAnchor, CUserPageBtnRecoverMetabolismRtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Recover Metabolism Button Text", this, aUIObj.PlayerIdString) ); } // Teleport to, Teleport, Spectate if (VerifyPermission(aUIObj.PlayerIdString, CPermTeleport)) { aUIObj.AddButton( actionPanel, CUserPageBtnTeleportToLbAnchor, CUserPageBtnTeleportToRtAnchor, CuiColor.ButtonSuccess, CuiColor.TextAlt, lang.GetMessage("Teleport To Player Button Text", this, aUIObj.PlayerIdString), $"{CTeleportToUserCmd} {aPlayerId}" ); aUIObj.AddButton( actionPanel, CUserPageBtnTeleportLbAnchor, CUserPageBtnTeleportRtAnchor, CuiColor.ButtonSuccess, CuiColor.TextAlt, lang.GetMessage("Teleport Player Button Text", this, aUIObj.PlayerIdString), $"{CTeleportUserCmd} {aPlayerId}" ); } else { aUIObj.AddButton( actionPanel, CUserPageBtnTeleportToLbAnchor, CUserPageBtnTeleportToRtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Teleport To Player Button Text", this, aUIObj.PlayerIdString) ); aUIObj.AddButton( actionPanel, CUserPageBtnTeleportLbAnchor, CUserPageBtnTeleportRtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Teleport Player Button Text", this, aUIObj.PlayerIdString) ); } if (VerifyPermission(aUIObj.PlayerIdString, CPermSpectate)) { aUIObj.AddButton( actionPanel, CUserPageBtnSpectateLbAnchor, CUserPageBtnSpectateRtAnchor, CuiColor.ButtonSuccess, CuiColor.TextAlt, lang.GetMessage("Spectate Player Button Text", this, aUIObj.PlayerIdString), $"{CSpectateUserCmd} {aPlayerId}" ); } else { aUIObj.AddButton( actionPanel, CUserPageBtnSpectateLbAnchor, CUserPageBtnSpectateRtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Spectate Player Button Text", this, aUIObj.PlayerIdString) ); } // Perms if (PermissionsManager == null) { aUIObj.AddButton( actionPanel, CUserPageBtnPermsLbAnchor, CUserPageBtnPermsRtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Perms Not Installed Button Text", this, aUIObj.PlayerIdString) ); } else if (VerifyPermission(aUIObj.PlayerIdString, CPermPerms)) { aUIObj.AddButton( actionPanel, CUserPageBtnPermsLbAnchor, CUserPageBtnPermsRtAnchor, CuiColor.ButtonSuccess, CuiColor.TextAlt, lang.GetMessage("Perms Button Text", this, aUIObj.PlayerIdString), $"{CPermsCmd} {aPlayerId}" ); } else { aUIObj.AddButton( actionPanel, CUserPageBtnPermsLbAnchor, CUserPageBtnPermsRtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Perms Button Text", this, aUIObj.PlayerIdString) ); } // Backpacks & Inventory if (Backpacks == null) { aUIObj.AddButton( actionPanel, CUserPageBtnBackpacksLbAnchor, CUserPageBtnBackpacksRtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Backpacks Not Installed Button Text", this, aUIObj.PlayerIdString)); } else if (VerifyPermission(aUIObj.PlayerIdString, CPermBackpacks)) { aUIObj.AddButton( actionPanel, CUserPageBtnBackpacksLbAnchor, CUserPageBtnBackpacksRtAnchor, CuiColor.ButtonSuccess, CuiColor.TextAlt, lang.GetMessage("Backpacks Button Text", this, aUIObj.PlayerIdString), $"{CBackpackViewCmd} {aPlayerId}"); } else { aUIObj.AddButton( actionPanel, CUserPageBtnBackpacksLbAnchor, CUserPageBtnBackpacksRtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Backpacks Button Text", this, aUIObj.PlayerIdString)); } if (InventoryViewer == null) { aUIObj.AddButton( actionPanel, CUserPageBtnInventoryLbAnchor, CUserPageBtnInventoryRtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Inventory Not Installed Button Text", this, aUIObj.PlayerIdString)); } else if (VerifyPermission(aUIObj.PlayerIdString, CPermInventory)) { aUIObj.AddButton( actionPanel, CUserPageBtnInventoryLbAnchor, CUserPageBtnInventoryRtAnchor, CuiColor.ButtonSuccess, CuiColor.TextAlt, lang.GetMessage("Inventory Button Text", this, aUIObj.PlayerIdString), $"{CInventoryViewCmd} {aPlayerId}"); } else { aUIObj.AddButton( actionPanel, CUserPageBtnInventoryLbAnchor, CUserPageBtnInventoryRtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Inventory Button Text", this, aUIObj.PlayerIdString)); } // Hurt 25, Hurt 50, Hurt 75, Hurt 100, Kill if (VerifyPermission(aUIObj.PlayerIdString, CPermHurt)) { aUIObj.AddButton( actionPanel, CUserPageBtnHurt25LbAnchor, CUserPageBtnHurt25RtAnchor, CuiColor.ButtonDanger, CuiColor.TextAlt, lang.GetMessage("Hurt 25 Button Text", this, aUIObj.PlayerIdString), $"{CHurtUserCmd} {aPlayerId} 25" ); aUIObj.AddButton( actionPanel, CUserPageBtnHurt50LbAnchor, CUserPageBtnHurt50RtAnchor, CuiColor.ButtonDanger, CuiColor.TextAlt, lang.GetMessage("Hurt 50 Button Text", this, aUIObj.PlayerIdString), $"{CHurtUserCmd} {aPlayerId} 50" ); aUIObj.AddButton( actionPanel, CUserPageBtnHurt75LbAnchor, CUserPageBtnHurt75RtAnchor, CuiColor.ButtonDanger, CuiColor.TextAlt, lang.GetMessage("Hurt 75 Button Text", this, aUIObj.PlayerIdString), $"{CHurtUserCmd} {aPlayerId} 75" ); aUIObj.AddButton( actionPanel, CUserPageBtnHurt100LbAnchor, CUserPageBtnHurt100RtAnchor, CuiColor.ButtonDanger, CuiColor.TextAlt, lang.GetMessage("Hurt 100 Button Text", this, aUIObj.PlayerIdString), $"{CHurtUserCmd} {aPlayerId} 100" ); } else { aUIObj.AddButton( actionPanel, CUserPageBtnHurt25LbAnchor, CUserPageBtnHurt25RtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Hurt 25 Button Text", this, aUIObj.PlayerIdString) ); aUIObj.AddButton( actionPanel, CUserPageBtnHurt50LbAnchor, CUserPageBtnHurt50RtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Hurt 50 Button Text", this, aUIObj.PlayerIdString) ); aUIObj.AddButton( actionPanel, CUserPageBtnHurt75LbAnchor, CUserPageBtnHurt75RtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Hurt 75 Button Text", this, aUIObj.PlayerIdString) ); aUIObj.AddButton( actionPanel, CUserPageBtnHurt100LbAnchor, CUserPageBtnHurt100RtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Hurt 100 Button Text", this, aUIObj.PlayerIdString) ); } if (VerifyPermission(aUIObj.PlayerIdString, CPermKill)) { aUIObj.AddButton( actionPanel, CUserPageBtnKillLbAnchor, CUserPageBtnKillRtAnchor, CuiColor.ButtonDanger, CuiColor.TextAlt, lang.GetMessage("Kill Button Text", this, aUIObj.PlayerIdString), $"{CKillUserCmd} {aPlayerId}" ); } else { aUIObj.AddButton( actionPanel, CUserPageBtnKillLbAnchor, CUserPageBtnKillRtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Kill Button Text", this, aUIObj.PlayerIdString) ); } // Heal 25, Heal 50, Heal 75, Heal 100, Heal wounds if (VerifyPermission(aUIObj.PlayerIdString, CPermHeal)) { aUIObj.AddButton( actionPanel, CUserPageBtnHeal25LbAnchor, CUserPageBtnHeal25RtAnchor, CuiColor.ButtonSuccess, CuiColor.TextAlt, lang.GetMessage("Heal 25 Button Text", this, aUIObj.PlayerIdString), $"{CHealUserCmd} {aPlayerId} 25" ); aUIObj.AddButton( actionPanel, CUserPageBtnHeal50LbAnchor, CUserPageBtnHeal50RtAnchor, CuiColor.ButtonSuccess, CuiColor.TextAlt, lang.GetMessage("Heal 50 Button Text", this, aUIObj.PlayerIdString), $"{CHealUserCmd} {aPlayerId} 50" ); aUIObj.AddButton( actionPanel, CUserPageBtnHeal75LbAnchor, CUserPageBtnHeal75RtAnchor, CuiColor.ButtonSuccess, CuiColor.TextAlt, lang.GetMessage("Heal 75 Button Text", this, aUIObj.PlayerIdString), $"{CHealUserCmd} {aPlayerId} 75" ); aUIObj.AddButton( actionPanel, CUserPageBtnHeal100LbAnchor, CUserPageBtnHeal100RtAnchor, CuiColor.ButtonSuccess, CuiColor.TextAlt, lang.GetMessage("Heal 100 Button Text", this, aUIObj.PlayerIdString), $"{CHealUserCmd} {aPlayerId} 100" ); aUIObj.AddButton( actionPanel, CUserPageBtnHealWoundsLbAnchor, CUserPageBtnHealWoundsRtAnchor, CuiColor.ButtonSuccess, CuiColor.TextAlt, lang.GetMessage("Heal Wounds Button Text", this, aUIObj.PlayerIdString), $"{CHealUserCmd} {aPlayerId} 0" ); } else { aUIObj.AddButton( actionPanel, CUserPageBtnHeal25LbAnchor, CUserPageBtnHeal25RtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Heal 25 Button Text", this, aUIObj.PlayerIdString) ); aUIObj.AddButton( actionPanel, CUserPageBtnHeal50LbAnchor, CUserPageBtnHeal50RtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Heal 50 Button Text", this, aUIObj.PlayerIdString) ); aUIObj.AddButton( actionPanel, CUserPageBtnHeal75LbAnchor, CUserPageBtnHeal75RtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Heal 75 Button Text", this, aUIObj.PlayerIdString) ); aUIObj.AddButton( actionPanel, CUserPageBtnHeal100LbAnchor, CUserPageBtnHeal100RtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Heal 100 Button Text", this, aUIObj.PlayerIdString) ); aUIObj.AddButton( actionPanel, CUserPageBtnHealWoundsLbAnchor, CUserPageBtnHealWoundsRtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Heal Wounds Button Text", this, aUIObj.PlayerIdString) ); } } else { ServerUsers.User serverUser = ServerUsers.Get(aPlayerId); aUIObj.AddLabel( panel, CMainLblTitleLbAnchor, CMainLblTitleRtAnchor, CuiColor.TextAlt, string.Format( lang.GetMessage("User Page Title Format", this, aUIObj.PlayerIdString), serverUser.username, lang.GetMessage("Banned Label Text", this, aUIObj.PlayerIdString) ), string.Empty, 18, TextAnchor.MiddleLeft ); // Add user info labels aUIObj.AddLabel( infoPanel, CUserPageLblIdLbAnchor, CUserPageLblIdRtAnchor, CuiColor.TextAlt, string.Format(lang.GetMessage("Id Label Format", this, aUIObj.PlayerIdString), aPlayerId, string.Empty), string.Empty, 14, TextAnchor.MiddleLeft ); // --- Build player action panel if (VerifyPermission(aUIObj.PlayerIdString, CPermBan)) { aUIObj.AddButton( actionPanel, CUserPageBtnBanLbAnchor, CUserPageBtnBanRtAnchor, CuiColor.Button, CuiColor.TextAlt, lang.GetMessage("Unban Button Text", this, aUIObj.PlayerIdString), $"{CUnbanUserCmd} {aPlayerId}" ); } else { aUIObj.AddButton( actionPanel, CUserPageBtnBanLbAnchor, CUserPageBtnBanRtAnchor, CuiColor.ButtonInactive, CuiColor.Text, lang.GetMessage("Unban Button Text", this, aUIObj.PlayerIdString) ); } } LogDebug("Built user information page"); LogDebug($"Elapsed time (BuildUserPage): {(Time.realtimeSinceStartup - aUIObj.StartTime).ToString("F8")}"); } /// /// Initiate the building of the UI page to show /// /// UI destination player /// Type of the page /// Argument /// Indicates if the output should be filtered private void BuildUI(BasePlayer aPlayer, UiPage aPageType, string aArg = "", bool aIndFiltered = false) { // Initiate the new UI and panel Cui newUiLib = new Cui(aPlayer); newUiLib.AddElement(CBasePanelName, CMainPanel, CMainPanelName); BuildTabMenu(ref newUiLib, aPageType); LogDebug($"Elapsed time (BuildTabMenu): {(Time.realtimeSinceStartup - newUiLib.StartTime).ToString("F8")}"); switch (aPageType) { case UiPage.Main: { BuildMainPage(ref newUiLib); break; } case UiPage.PlayersOnline: case UiPage.PlayersOffline: case UiPage.PlayersBanned: { int page = 0; if (!string.IsNullOrEmpty(aArg)) int.TryParse(aArg, out page); BuildUserBtnPage(ref newUiLib, aPageType, page, aIndFiltered); break; } case UiPage.PlayerPage: case UiPage.PlayerPageBanned: { ulong playerId = aPlayer.userID; if (!string.IsNullOrEmpty(aArg)) ulong.TryParse(aArg, out playerId); BuildUserPage(ref newUiLib, aPageType, playerId); break; } } LogDebug($"BuildUI JSON value: \n{newUiLib.JSON}"); // Cleanup any old/active UI and draw the new one CuiHelper.DestroyUi(aPlayer, CMainPanelName); LogDebug($"Elapsed time (CuiHelper.DestroyUi): {(Time.realtimeSinceStartup - newUiLib.StartTime).ToString("F8")}"); newUiLib.Draw(); LogDebug($"Elapsed time (newUiLib.Draw): {(Time.realtimeSinceStartup - newUiLib.StartTime).ToString("F8")}"); } #endregion GUI build methods #region Config /// /// The config type class /// private class ConfigData { [DefaultValue(true)] [JsonProperty("Use Permission System", DefaultValueHandling = DefaultValueHandling.Populate)] public bool UsePermSystem { get; set; } [DefaultValue("")] [JsonProperty("Discord Webhook url for ban messages", DefaultValueHandling = DefaultValueHandling.Populate)] public string BanMsgWebhookUrl { get; set; } [DefaultValue("")] [JsonProperty("Discord Webhook url for kick messages", DefaultValueHandling = DefaultValueHandling.Populate)] public string KickMsgWebhookUrl { get; set; } } #endregion #region Constants private static readonly bool CDebugEnabled = false; private const int CMaxPlayerCols = 5; private const int CMaxPlayerRows = 12; private const int CMaxPlayerButtons = CMaxPlayerCols * CMaxPlayerRows; private const string CBasePanelName = "PAdm_BasePanel"; private const string CMainPanelName = "PAdm_MainPanel"; private static readonly List CUnknownNameList = new List { "unnamed", "unknown" }; #region Local commands private const string CPadminCmd = "padmin"; private const string CCloseUiCmd = "playeradministration.closeui"; private const string CSwitchUiCmd = "playeradministration.switchui"; private const string CKickUserCmd = "playeradministration.kickuser"; private const string CBanUserCmd = "playeradministration.banuser"; private const string CMainPageBanByIdCmd = "playeradministration.mainpagebanbyid"; private const string CUnbanUserCmd = "playeradministration.unbanuser"; private const string CPermsCmd = "playeradministration.perms"; private const string CMuteUserCmd = "playeradministration.muteuser"; private const string CUnmuteUserCmd = "playeradministration.unmuteuser"; private const string CFreezeCmd = "playeradministration.freeze"; private const string CUnreezeCmd = "playeradministration.unfreeze"; private const string CClearUserInventoryCmd = "playeradministration.clearuserinventory"; private const string CResetUserBPCmd = "playeradministration.resetuserblueprints"; private const string CResetUserMetabolismCmd = "playeradministration.resetusermetabolism"; private const string CRecoverUserMetabolismCmd = "playeradministration.recoverusermetabolism"; private const string CHurtUserCmd = "playeradministration.hurtuser"; private const string CKillUserCmd = "playeradministration.killuser"; private const string CHealUserCmd = "playeradministration.healuser"; private const string CTeleportToUserCmd = "playeradministration.tptouser"; private const string CTeleportUserCmd = "playeradministration.tpuser"; private const string CSpectateUserCmd = "playeradministration.spectateuser"; private const string CMainPageBanIdInputTextCmd = "playeradministration.mainpagebanidinputtext"; private const string CUserBtnPageSearchInputTextCmd = "playeradministration.userbtnpagesearchinputtext"; private const string CUserPageReasonInputTextCmd = "playeradministration.userpagereasoninputtext"; private const string CBackpackViewCmd = "playeradministration.viewbackpack"; private const string CInventoryViewCmd = "playeradministration.viewinventory"; #endregion Local commands #region Foreign commands private const string CPermsPermsCmd = "perms player"; private const string CFreezeFreezeCmd = "freeze"; private const string CFreezeUnfreezeCmd = "unfreeze"; #endregion Foreign commands #region Local Command Static Arguments private const string CCmdArgMain = "main"; private const string CCmdArgPlayersOnline = "playersonline"; private const string CCmdArgPlayersOnlineSearch = "playersonlinesearch"; private const string CCmdArgPlayersOffline = "playersoffline"; private const string CCmdArgPlayersOfflineSearch = "playersofflinesearch"; private const string CCmdArgPlayersBanned = "playersbanned"; private const string CCmdArgPlayersBannedSearch = "playersbannedsearch"; private const string CCmdArgPlayerPage = "playerpage"; private const string CCmdArgPlayerPageBanned = "playerpagebanned"; #endregion Local Command Static Arguments #region Local permissions private const string CPermUiShow = "playeradministration.access.show"; private const string CPermKick = "playeradministration.access.kick"; private const string CPermBan = "playeradministration.access.ban"; private const string CPermKill = "playeradministration.access.kill"; private const string CPermPerms = "playeradministration.access.perms"; private const string CPermMute = "playeradministration.access.mute"; private const string CPermFreeze = "playeradministration.access.allowfreeze"; private const string CPermClearInventory = "playeradministration.access.clearinventory"; private const string CPermResetBP = "playeradministration.access.resetblueprint"; private const string CPermResetMetabolism = "playeradministration.access.resetmetabolism"; private const string CPermRecoverMetabolism = "playeradministration.access.recovermetabolism"; private const string CPermHurt = "playeradministration.access.hurt"; private const string CPermHeal = "playeradministration.access.heal"; private const string CPermTeleport = "playeradministration.access.teleport"; private const string CPermSpectate = "playeradministration.access.spectate"; private const string CPermDetailInfo = "playeradministration.access.detailedinfo"; private const string CPermProtectBan = "playeradministration.protect.ban"; private const string CPermProtectHurt = "playeradministration.protect.hurt"; private const string CPermProtectKick = "playeradministration.protect.kick"; private const string CPermProtectKill = "playeradministration.protect.kill"; private const string CPermProtectReset = "playeradministration.protect.reset"; #endregion Local permissions #region Foreign permissions private const string CPermFreezeFrozen = "freeze.frozen"; private const string CPermBackpacks = "backpacks.admin"; private const string CPermInventory = "inventoryviewer.allowed"; #endregion Foreign permissions /* Define layout */ #region Main bounds private static readonly CuiPoint CMainLbAnchor = new CuiPoint(0.03f, 0.15f); private static readonly CuiPoint CMainRtAnchor = new CuiPoint(0.97f, 0.97f); private static readonly CuiPoint CMainMenuHeaderContainerLbAnchor = new CuiPoint(0.005f, 0.937f); private static readonly CuiPoint CMainMenuHeaderContainerRtAnchor = new CuiPoint(0.995f, 0.99f); private static readonly CuiPoint CMainMenuTabBtnContainerLbAnchor = new CuiPoint(0.005f, 0.867f); private static readonly CuiPoint CMainMenuTabBtnContainerRtAnchor = new CuiPoint(0.995f, 0.927f); private static readonly CuiPoint CMainMenuHeaderLblLbAnchor = new CuiPoint(0f, 0f); private static readonly CuiPoint CMainMenuHeaderLblRtAnchor = new CuiPoint(1f, 1f); private static readonly CuiPoint CMainMenuCloseBtnLbAnchor = new CuiPoint(0.965f, 0f); private static readonly CuiPoint CMainMenuCloseBtnRtAnchor = new CuiPoint(1f, 1f); private static readonly CuiPoint CMainPanelLbAnchor = new CuiPoint(0.005f, 0.01f); private static readonly CuiPoint CMainPanelRtAnchor = new CuiPoint(0.995f, 0.857f); private static readonly CuiPoint CMainLblTitleLbAnchor = new CuiPoint(0.005f, 0.93f); private static readonly CuiPoint CMainLblTitleRtAnchor = new CuiPoint(0.995f, 0.99f); #endregion Main bounds #region Main page bounds private static readonly CuiPoint CMainPageLblBanByIdTitleLbAnchor = new CuiPoint(0.005f, 0.84f); private static readonly CuiPoint CMainPageLblBanByIdTitleRtAnchor = new CuiPoint(0.995f, 0.89f); private static readonly CuiPoint CMainPageLblBanByIdLbAnchor = new CuiPoint(0.005f, 0.76f); private static readonly CuiPoint CMainPageLblBanByIdRtAnchor = new CuiPoint(0.05f, 0.81f); private static readonly CuiPoint CMainPagePanelBanByIdLbAnchor = new CuiPoint(0.055f, 0.76f); private static readonly CuiPoint CMainPagePanelBanByIdRtAnchor = new CuiPoint(0.305f, 0.81f); private static readonly CuiPoint CMainPageEdtBanByIdLbAnchor = new CuiPoint(0.005f, 0f); private static readonly CuiPoint CMainPageEdtBanByIdRtAnchor = new CuiPoint(0.995f, 1f); private static readonly CuiPoint CMainPageBtnBanByIdLbAnchor = new CuiPoint(0.315f, 0.76f); private static readonly CuiPoint CMainPageBtnBanByIdRtAnchor = new CuiPoint(0.365f, 0.81f); #endregion Main page bounds #region User button page bounds private static readonly CuiPoint CUserBtnPageLblTitleLbAnchor = new CuiPoint(0.005f, 0.93f); private static readonly CuiPoint CUserBtnPageLblTitleRtAnchor = new CuiPoint(0.495f, 0.99f); private static readonly CuiPoint CUserBtnPageLblSearchLbAnchor = new CuiPoint(0.52f, 0.93f); private static readonly CuiPoint CUserBtnPageLblSearchRtAnchor = new CuiPoint(0.565f, 0.99f); private static readonly CuiPoint CUserBtnPagePanelSearchInputLbAnchor = new CuiPoint(0.57f, 0.94f); private static readonly CuiPoint CUserBtnPagePanelSearchInputRtAnchor = new CuiPoint(0.945f, 0.99f); private static readonly CuiPoint CUserBtnPageEdtSearchInputLbAnchor = new CuiPoint(0.005f, 0f); private static readonly CuiPoint CUserBtnPageEdtSearchInputRtAnchor = new CuiPoint(0.995f, 1f); private static readonly CuiPoint CUserBtnPageBtnSearchLbAnchor = new CuiPoint(0.95f, 0.94f); private static readonly CuiPoint CUserBtnPageBtnSearchRtAnchor = new CuiPoint(0.995f, 0.99f); private static readonly CuiPoint CUserBtnPageBtnPreviousLbAnchor = new CuiPoint(0.005f, 0.01f); private static readonly CuiPoint CUserBtnPageBtnPreviousRtAnchor = new CuiPoint(0.035f, 0.06f); private static readonly CuiPoint CUserBtnPageBtnNextLbAnchor = new CuiPoint(0.96f, 0.01f); private static readonly CuiPoint CUserBtnPageBtnNextRtAnchor = new CuiPoint(0.995f, 0.06f); #endregion User button page bounds #region User page panel bounds private static readonly CuiPoint CUserPageInfoPanelLbAnchor = new CuiPoint(0.005f, 0.01f); private static readonly CuiPoint CUserPageInfoPanelRtAnchor = new CuiPoint(0.28f, 0.92f); private static readonly CuiPoint CUserPageActionPanelLbAnchor = new CuiPoint(0.285f, 0.01f); private static readonly CuiPoint CUserPageActionPanelRtAnchor = new CuiPoint(0.995f, 0.92f); #region User page title label bounds private static readonly CuiPoint CUserPageLblinfoTitleLbAnchor = new CuiPoint(0.025f, 0.94f); private static readonly CuiPoint CUserPageLblinfoTitleRtAnchor = new CuiPoint(0.975f, 0.99f); private static readonly CuiPoint CUserPageLblActionTitleLbAnchor = new CuiPoint(0.01f, 0.94f); private static readonly CuiPoint CUserPageLblActionTitleRtAnchor = new CuiPoint(0.99f, 0.99f); #endregion User page title label bounds #region User page info label bounds // Top part private static readonly CuiPoint CUserPageLblIdLbAnchor = new CuiPoint(0.025f, 0.88f); private static readonly CuiPoint CUserPageLblIdRtAnchor = new CuiPoint(0.975f, 0.92f); private static readonly CuiPoint CUserPageLblAuthLbAnchor = new CuiPoint(0.025f, 0.835f); private static readonly CuiPoint CUserPageLblAuthRtAnchor = new CuiPoint(0.975f, 0.875f); private static readonly CuiPoint CUserPageLblConnectLbAnchor = new CuiPoint(0.025f, 0.79f); private static readonly CuiPoint CUserPageLblConnectRtAnchor = new CuiPoint(0.975f, 0.83f); private static readonly CuiPoint CUserPageLblSleepLbAnchor = new CuiPoint(0.025f, 0.745f); private static readonly CuiPoint CUserPageLblSleepRtAnchor = new CuiPoint(0.975f, 0.785f); private static readonly CuiPoint CUserPageLblFlagLbAnchor = new CuiPoint(0.025f, 0.70f); private static readonly CuiPoint CUserPageLblFlagRtAnchor = new CuiPoint(0.975f, 0.74f); private static readonly CuiPoint CUserPageLblPosLbAnchor = new CuiPoint(0.025f, 0.655f); private static readonly CuiPoint CUserPageLblPosRtAnchor = new CuiPoint(0.975f, 0.695f); private static readonly CuiPoint CUserPageLblRotLbAnchor = new CuiPoint(0.025f, 0.61f); private static readonly CuiPoint CUserPageLblRotRtAnchor = new CuiPoint(0.975f, 0.65f); private static readonly CuiPoint CUserPageLblAdminCheatLbAnchor = new CuiPoint(0.025f, 0.555f); private static readonly CuiPoint CUserPageLblAdminCheatRtAnchor = new CuiPoint(0.975f, 0.605f); private static readonly CuiPoint CUserPageLblIdleLbAnchor = new CuiPoint(0.025f, 0.51f); private static readonly CuiPoint CUserPageLblIdleRtAnchor = new CuiPoint(0.975f, 0.55f); private static readonly CuiPoint CUserPageLblBalanceLbAnchor = new CuiPoint(0.025f, 0.465f); private static readonly CuiPoint CUserPageLblBalanceRtAnchor = new CuiPoint(0.975f, 0.505f); private static readonly CuiPoint CUserPageLblRewardPointsLbAnchor = new CuiPoint(0.025f, 0.42f); private static readonly CuiPoint CUserPageLblRewardPointsRtAnchor = new CuiPoint(0.975f, 0.46f); // Bottom part private static readonly CuiPoint CUserPageLblHealthLbAnchor = new CuiPoint(0.025f, 0.195f); private static readonly CuiPoint CUserPageLblHealthRtAnchor = new CuiPoint(0.975f, 0.235f); private static readonly CuiPoint CUserPageLblCalLbAnchor = new CuiPoint(0.025f, 0.145f); private static readonly CuiPoint CUserPageLblCalRtAnchor = new CuiPoint(0.5f, 0.19f); private static readonly CuiPoint CUserPageLblHydraLbAnchor = new CuiPoint(0.5f, 0.145f); private static readonly CuiPoint CUserPageLblHydraRtAnchor = new CuiPoint(0.975f, 0.19f); private static readonly CuiPoint CUserPageLblTempLbAnchor = new CuiPoint(0.025f, 0.10f); private static readonly CuiPoint CUserPageLblTempRtAnchor = new CuiPoint(0.5f, 0.14f); private static readonly CuiPoint CUserPageLblWetLbAnchor = new CuiPoint(0.5f, 0.10f); private static readonly CuiPoint CUserPageLblWetRtAnchor = new CuiPoint(0.975f, 0.14f); private static readonly CuiPoint CUserPageLblComfortLbAnchor = new CuiPoint(0.025f, 0.055f); private static readonly CuiPoint CUserPageLblComfortRtAnchor = new CuiPoint(0.5f, 0.095f); private static readonly CuiPoint CUserPageLblBleedLbAnchor = new CuiPoint(0.5f, 0.055f); private static readonly CuiPoint CUserPageLblBleedRtAnchor = new CuiPoint(0.975f, 0.095f); private static readonly CuiPoint CUserPageLblRads1LbAnchor = new CuiPoint(0.025f, 0.01f); private static readonly CuiPoint CUserPageLblRads1RtAnchor = new CuiPoint(0.5f, 0.05f); private static readonly CuiPoint CUserPageLblRads2LbAnchor = new CuiPoint(0.5f, 0.01f); private static readonly CuiPoint CUserPageLblRads2RtAnchor = new CuiPoint(0.975f, 0.05f); #endregion User page info label bounds #region User page button bounds // Row 1 private static readonly CuiPoint CUserPageBtnBanLbAnchor = new CuiPoint(0.01f, 0.86f); private static readonly CuiPoint CUserPageBtnBanRtAnchor = new CuiPoint(0.16f, 0.92f); private static readonly CuiPoint CUserPageBtnKickLbAnchor = new CuiPoint(0.17f, 0.86f); private static readonly CuiPoint CUserPageBtnKickRtAnchor = new CuiPoint(0.32f, 0.92f); private static readonly CuiPoint CUserPageLblReasonLbAnchor = new CuiPoint(0.33f, 0.86f); private static readonly CuiPoint CUserPageLblReasonRtAnchor = new CuiPoint(0.48f, 0.92f); private static readonly CuiPoint CUserPagePanelReasonLbAnchor = new CuiPoint(0.49f, 0.86f); private static readonly CuiPoint CUserPagePanelReasonRtAnchor = new CuiPoint(0.99f, 0.92f); private static readonly CuiPoint CUserPageEdtReasonLbAnchor = new CuiPoint(0.005f, 0f); private static readonly CuiPoint CUserPageEdtReasonRtAnchor = new CuiPoint(0.995f, 1f); // Row 2 private static readonly CuiPoint CUserPageBtnUnmuteLbAnchor = new CuiPoint(0.01f, 0.78f); private static readonly CuiPoint CUserPageBtnUnmuteRtAnchor = new CuiPoint(0.16f, 0.84f); private static readonly CuiPoint CUserPageBtnMuteLbAnchor = new CuiPoint(0.17f, 0.78f); private static readonly CuiPoint CUserPageBtnMuteRtAnchor = new CuiPoint(0.32f, 0.84f); private static readonly CuiPoint CUserPageBtnMuteFifteenLbAnchor = new CuiPoint(0.33f, 0.78f); private static readonly CuiPoint CUserPageBtnMuteFifteenRtAnchor = new CuiPoint(0.48f, 0.84f); private static readonly CuiPoint CUserPageBtnMuteThirtyLbAnchor = new CuiPoint(0.49f, 0.78f); private static readonly CuiPoint CUserPageBtnMuteThirtyRtAnchor = new CuiPoint(0.64f, 0.84f); private static readonly CuiPoint CUserPageBtnMuteSixtyLbAnchor = new CuiPoint(0.65f, 0.78f); private static readonly CuiPoint CUserPageBtnMuteSixtyRtAnchor = new CuiPoint(0.80f, 0.84f); // Row 3 private static readonly CuiPoint CUserPageBtnUnFreezeLbAnchor = new CuiPoint(0.01f, 0.70f); private static readonly CuiPoint CUserPageBtnUnFreezeRtAnchor = new CuiPoint(0.16f, 0.76f); private static readonly CuiPoint CUserPageBtnFreezeLbAnchor = new CuiPoint(0.17f, 0.70f); private static readonly CuiPoint CUserPageBtnFreezeRtAnchor = new CuiPoint(0.32f, 0.76f); // Row 4 private static readonly CuiPoint CUserPageBtnClearInventoryLbAnchor = new CuiPoint(0.01f, 0.62f); private static readonly CuiPoint CUserPageBtnClearInventoryRtAnchor = new CuiPoint(0.16f, 0.68f); private static readonly CuiPoint CUserPageBtnResetBPLbAnchor = new CuiPoint(0.17f, 0.62f); private static readonly CuiPoint CUserPageBtnResetBPRtAnchor = new CuiPoint(0.32f, 0.68f); private static readonly CuiPoint CUserPageBtnResetMetabolismLbAnchor = new CuiPoint(0.33f, 0.62f); private static readonly CuiPoint CUserPageBtnResetMetabolismRtAnchor = new CuiPoint(0.48f, 0.68f); private static readonly CuiPoint CUserPageBtnRecoverMetabolismLbAnchor = new CuiPoint(0.49f, 0.62f); private static readonly CuiPoint CUserPageBtnRecoverMetabolismRtAnchor = new CuiPoint(0.64f, 0.68f); // Row 5 private static readonly CuiPoint CUserPageBtnTeleportToLbAnchor = new CuiPoint(0.01f, 0.54f); private static readonly CuiPoint CUserPageBtnTeleportToRtAnchor = new CuiPoint(0.16f, 0.60f); private static readonly CuiPoint CUserPageBtnTeleportLbAnchor = new CuiPoint(0.17f, 0.54f); private static readonly CuiPoint CUserPageBtnTeleportRtAnchor = new CuiPoint(0.32f, 0.60f); private static readonly CuiPoint CUserPageBtnSpectateLbAnchor = new CuiPoint(0.33f, 0.54f); private static readonly CuiPoint CUserPageBtnSpectateRtAnchor = new CuiPoint(0.48f, 0.60f); // Row 6 private static readonly CuiPoint CUserPageBtnPermsLbAnchor = new CuiPoint(0.01f, 0.46f); private static readonly CuiPoint CUserPageBtnPermsRtAnchor = new CuiPoint(0.16f, 0.52f); private static readonly CuiPoint CUserPageBtnBackpacksLbAnchor = new CuiPoint(0.17f, 0.46f); private static readonly CuiPoint CUserPageBtnBackpacksRtAnchor = new CuiPoint(0.32f, 0.52f); private static readonly CuiPoint CUserPageBtnInventoryLbAnchor = new CuiPoint(0.33f, 0.46f); private static readonly CuiPoint CUserPageBtnInventoryRtAnchor = new CuiPoint(0.48f, 0.52f); // Row 11 private static readonly CuiPoint CUserPageBtnHurt25LbAnchor = new CuiPoint(0.01f, 0.10f); private static readonly CuiPoint CUserPageBtnHurt25RtAnchor = new CuiPoint(0.16f, 0.16f); private static readonly CuiPoint CUserPageBtnHurt50LbAnchor = new CuiPoint(0.17f, 0.10f); private static readonly CuiPoint CUserPageBtnHurt50RtAnchor = new CuiPoint(0.32f, 0.16f); private static readonly CuiPoint CUserPageBtnHurt75LbAnchor = new CuiPoint(0.33f, 0.10f); private static readonly CuiPoint CUserPageBtnHurt75RtAnchor = new CuiPoint(0.48f, 0.16f); private static readonly CuiPoint CUserPageBtnHurt100LbAnchor = new CuiPoint(0.49f, 0.10f); private static readonly CuiPoint CUserPageBtnHurt100RtAnchor = new CuiPoint(0.64f, 0.16f); private static readonly CuiPoint CUserPageBtnKillLbAnchor = new CuiPoint(0.65f, 0.10f); private static readonly CuiPoint CUserPageBtnKillRtAnchor = new CuiPoint(0.80f, 0.16f); // Row 12 private static readonly CuiPoint CUserPageBtnHeal25LbAnchor = new CuiPoint(0.01f, 0.02f); private static readonly CuiPoint CUserPageBtnHeal25RtAnchor = new CuiPoint(0.16f, 0.08f); private static readonly CuiPoint CUserPageBtnHeal50LbAnchor = new CuiPoint(0.17f, 0.02f); private static readonly CuiPoint CUserPageBtnHeal50RtAnchor = new CuiPoint(0.32f, 0.08f); private static readonly CuiPoint CUserPageBtnHeal75LbAnchor = new CuiPoint(0.33f, 0.02f); private static readonly CuiPoint CUserPageBtnHeal75RtAnchor = new CuiPoint(0.48f, 0.08f); private static readonly CuiPoint CUserPageBtnHeal100LbAnchor = new CuiPoint(0.49f, 0.02f); private static readonly CuiPoint CUserPageBtnHeal100RtAnchor = new CuiPoint(0.64f, 0.08f); private static readonly CuiPoint CUserPageBtnHealWoundsLbAnchor = new CuiPoint(0.65f, 0.02f); private static readonly CuiPoint CUserPageBtnHealWoundsRtAnchor = new CuiPoint(0.80f, 0.08f); #endregion User page button bounds #endregion User page panel bounds #region Predefined UI elements private static readonly CuiPanel CBasePanel = new CuiPanel { RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "0 0", OffsetMax = "0 0" }, CursorEnabled = true, Image = new CuiImageComponent { Color = CuiColor.None.ToString() } }; private static readonly CuiPanel CMainPanel = new CuiPanel { RectTransform = { AnchorMin = CMainLbAnchor.ToString(), AnchorMax = CMainRtAnchor.ToString(), OffsetMin = "0 0", OffsetMax = "0 0" }, CursorEnabled = true, Image = new CuiImageComponent { Color = CuiColor.BackgroundDark.ToString() } }; private static readonly CuiPanel CTabHeaderPanel = new CuiPanel { RectTransform = { AnchorMin = CMainMenuHeaderContainerLbAnchor.ToString(), AnchorMax = CMainMenuHeaderContainerRtAnchor.ToString(), OffsetMin = "0 0", OffsetMax = "0 0" }, CursorEnabled = true, Image = new CuiImageComponent { Color = CuiColor.None.ToString() } }; private static readonly CuiPanel CTabTabBtnPanel = new CuiPanel { RectTransform = { AnchorMin = CMainMenuTabBtnContainerLbAnchor.ToString(), AnchorMax = CMainMenuTabBtnContainerRtAnchor.ToString(), OffsetMin = "0 0", OffsetMax = "0 0" }, CursorEnabled = true, Image = new CuiImageComponent { Color = CuiColor.Background.ToString() } }; private static readonly CuiPanel CMainPagePanel = new CuiPanel { RectTransform = { AnchorMin = CMainPanelLbAnchor.ToString(), AnchorMax = CMainPanelRtAnchor.ToString(), OffsetMin = "0 0", OffsetMax = "0 0" }, CursorEnabled = true, Image = new CuiImageComponent { Color = CuiColor.Background.ToString() } }; private static readonly CuiPanel CBanByIdGroupPanel = new CuiPanel { RectTransform = { AnchorMin = CMainPagePanelBanByIdLbAnchor.ToString(), AnchorMax = CMainPagePanelBanByIdRtAnchor.ToString(), OffsetMin = "0 0", OffsetMax = "0 0" }, CursorEnabled = true, Image = new CuiImageComponent { Color = CuiColor.BackgroundDark.ToString() } }; private static readonly CuiPanel CUserBtnPageSearchInputPanel = new CuiPanel { RectTransform = { AnchorMin = CUserBtnPagePanelSearchInputLbAnchor.ToString(), AnchorMax = CUserBtnPagePanelSearchInputRtAnchor.ToString(), OffsetMin = "0 0", OffsetMax = "0 0" }, CursorEnabled = true, Image = new CuiImageComponent { Color = CuiColor.BackgroundDark.ToString() } }; private static readonly CuiLabel CTabMenuHeaderLbl = new CuiLabel { Text = { Text = "Player Administration", FontSize = 22, Align = TextAnchor.MiddleCenter, Color = CuiColor.TextTitle.ToString() }, RectTransform = { AnchorMin = CMainMenuHeaderLblLbAnchor.ToString(), AnchorMax = CMainMenuHeaderLblRtAnchor.ToString(), OffsetMin = "0 0", OffsetMax = "0 0" } }; private static readonly CuiLabel CMainPageTitleLbl = new CuiLabel { Text = { Text = "Main", FontSize = 18, Align = TextAnchor.MiddleLeft, Color = CuiColor.TextAlt.ToString() }, RectTransform = { AnchorMin = CMainLblTitleLbAnchor.ToString(), AnchorMax = CMainLblTitleRtAnchor.ToString(), OffsetMin = "0 0", OffsetMax = "0 0" } }; private static readonly CuiButton CTabMenuCloseBtn = new CuiButton { Button = { Command = CCloseUiCmd, Close = string.Empty, Color = CuiColor.ButtonDecline.ToString() }, RectTransform = { AnchorMin = CMainMenuCloseBtnLbAnchor.ToString(), AnchorMax = CMainMenuCloseBtnRtAnchor.ToString(), OffsetMin = "0 0", OffsetMax = "0 0" }, Text = { Text = "X", FontSize = 22, Align = TextAnchor.MiddleCenter, Color = CuiColor.TextAlt.ToString() } }; private static readonly CuiButton CBanByIdActiveBtn = new CuiButton { Button = { Command = CMainPageBanByIdCmd, Close = string.Empty, Color = CuiColor.ButtonDanger.ToString() }, RectTransform = { AnchorMin = CMainPageBtnBanByIdLbAnchor.ToString(), AnchorMax = CMainPageBtnBanByIdRtAnchor.ToString(), OffsetMin = "0 0", OffsetMax = "0 0" }, Text = { Text = "Ban", FontSize = 14, Align = TextAnchor.MiddleCenter, Color = CuiColor.TextAlt.ToString() } }; private static readonly CuiButton CBanByIdInactiveBtn = new CuiButton { Button = { Command = string.Empty, Close = string.Empty, Color = CuiColor.ButtonInactive.ToString() }, RectTransform = { AnchorMin = CMainPageBtnBanByIdLbAnchor.ToString(), AnchorMax = CMainPageBtnBanByIdRtAnchor.ToString(), OffsetMin = "0 0", OffsetMax = "0 0" }, Text = { Text = "Ban", FontSize = 14, Align = TextAnchor.MiddleCenter, Color = CuiColor.TextAlt.ToString() } }; private static readonly CuiButton CUserBtnPagePreviousInactiveBtn = new CuiButton { Button = { Command = string.Empty, Close = string.Empty, Color = CuiColor.ButtonInactive.ToString() }, RectTransform = { AnchorMin = CUserBtnPageBtnPreviousLbAnchor.ToString(), AnchorMax = CUserBtnPageBtnPreviousRtAnchor.ToString(), OffsetMin = "0 0", OffsetMax = "0 0" }, Text = { Text = "<<", FontSize = 18, Align = TextAnchor.MiddleCenter, Color = CuiColor.TextAlt.ToString() } }; private static readonly CuiButton CUserBtnPageNextInactiveBtn = new CuiButton { Button = { Command = string.Empty, Close = string.Empty, Color = CuiColor.ButtonInactive.ToString() }, RectTransform = { AnchorMin = CUserBtnPageBtnNextLbAnchor.ToString(), AnchorMax = CUserBtnPageBtnNextRtAnchor.ToString(), OffsetMin = "0 0", OffsetMax = "0 0" }, Text = { Text = ">>", FontSize = 18, Align = TextAnchor.MiddleCenter, Color = CuiColor.TextAlt.ToString() } }; private static readonly CuiInputField CBanByIdEdt = new CuiInputField { InputField = { Text = string.Empty, FontSize = 14, Align = TextAnchor.MiddleLeft, Color = CuiColor.TextAlt.ToString(), CharsLimit = 24, Command = CMainPageBanIdInputTextCmd, IsPassword = false }, RectTransform = { AnchorMin = CMainPageEdtBanByIdLbAnchor.ToString(), AnchorMax = CMainPageEdtBanByIdRtAnchor.ToString(), OffsetMin = "0 0", OffsetMax = "0 0" } }; #endregion Predefined UI elements #endregion Constants #region Variables private static PlayerAdministration FPluginInstance; private ConfigData FConfigData; private Dictionary FMainPageBanIdInputText = new Dictionary(); // Format: private Dictionary FUserBtnPageSearchInputText = new Dictionary(); // Format: private Dictionary FUserPageReasonInputText = new Dictionary(); // Format: private Dictionary FOnlineUserList = new Dictionary(); // Format: private Dictionary FOfflineUserList = new Dictionary(); // Format: #endregion Variables #region Hooks void Loaded() { LoadConfig(); permission.RegisterPermission(CPermUiShow, this); permission.RegisterPermission(CPermKick, this); permission.RegisterPermission(CPermBan, this); permission.RegisterPermission(CPermKill, this); permission.RegisterPermission(CPermPerms, this); permission.RegisterPermission(CPermMute, this); permission.RegisterPermission(CPermFreeze, this); permission.RegisterPermission(CPermClearInventory, this); permission.RegisterPermission(CPermResetBP, this); permission.RegisterPermission(CPermResetMetabolism, this); permission.RegisterPermission(CPermRecoverMetabolism, this); permission.RegisterPermission(CPermHurt, this); permission.RegisterPermission(CPermHeal, this); permission.RegisterPermission(CPermTeleport, this); permission.RegisterPermission(CPermSpectate, this); permission.RegisterPermission(CPermDetailInfo, this); permission.RegisterPermission(CPermProtectBan, this); permission.RegisterPermission(CPermProtectHurt, this); permission.RegisterPermission(CPermProtectKick, this); permission.RegisterPermission(CPermProtectKill, this); permission.RegisterPermission(CPermProtectReset, this); FPluginInstance = this; if (UpgradeTo156()) LogDebug("Upgraded the config to version 1.5.6"); if (UpgradeTo1519()) LogDebug("Upgraded the config to version 1.5.19"); } void Unload() { foreach (BasePlayer player in Player.Players) { CuiHelper.DestroyUi(player, CBasePanelName); if (FMainPageBanIdInputText.ContainsKey(player.UserIDString)) FMainPageBanIdInputText.Remove(player.UserIDString); if (FUserBtnPageSearchInputText.ContainsKey(player.UserIDString)) FUserBtnPageSearchInputText.Remove(player.UserIDString); if (FUserPageReasonInputText.ContainsKey(player.UserIDString)) FUserPageReasonInputText.Remove(player.UserIDString); } FOnlineUserList.Clear(); FOfflineUserList.Clear(); FPluginInstance = null; } void OnServerInitialized() { foreach (BasePlayer user in Player.Players) { if (user.IsNpc) continue; ServerUsers.User servUser = ServerUsers.Get(user.userID); if (servUser == null || servUser?.group != ServerUsers.UserGroup.Banned) FOnlineUserList[user.UserIDString] = user.displayName; } foreach (BasePlayer user in Player.Sleepers) { if (user.IsNpc) continue; ServerUsers.User servUser = ServerUsers.Get(user.userID); if (servUser == null || servUser?.group != ServerUsers.UserGroup.Banned) FOfflineUserList[user.UserIDString] = user.displayName; } } void OnUserConnected(IPlayer aPlayer) { BasePlayer user = BasePlayer.Find(aPlayer.Id) ?? BasePlayer.FindSleeping(aPlayer.Id); if (user.IsNpc) return; if (FOfflineUserList.ContainsKey(user.UserIDString)) FOfflineUserList.Remove(user.displayName); FOnlineUserList[user.UserIDString] = user.displayName; } void OnUserDisconnected(IPlayer aPlayer) { if (FMainPageBanIdInputText.ContainsKey(aPlayer.Id)) FMainPageBanIdInputText.Remove(aPlayer.Id); if (FUserBtnPageSearchInputText.ContainsKey(aPlayer.Id)) FUserBtnPageSearchInputText.Remove(aPlayer.Id); if (FUserPageReasonInputText.ContainsKey(aPlayer.Id)) FUserPageReasonInputText.Remove(aPlayer.Id); BasePlayer user = BasePlayer.Find(aPlayer.Id) ?? BasePlayer.FindSleeping(aPlayer.Id); if (FOnlineUserList.ContainsKey(user.UserIDString)) FOnlineUserList.Remove(user.UserIDString); if (user.IsNpc) return; FOfflineUserList[user.UserIDString] = user.displayName; } void OnUserNameUpdated(string aId, string aOldName, string aNewName) { if (FOnlineUserList.ContainsKey(aId)) FOnlineUserList[aId] = aNewName; if (FOfflineUserList.ContainsKey(aId)) FOfflineUserList[aId] = aNewName; } protected override void LoadConfig() { base.LoadConfig(); try { FConfigData = Config.ReadObject(); if (FConfigData == null) LoadDefaultConfig(); if (UpgradeTo1310()) LogDebug("Upgraded the config to version 1.3.10"); if (UpgradeTo1313()) LogDebug("Upgraded the config to version 1.3.13"); } catch { LoadDefaultConfig(); } SaveConfig(); } protected override void LoadDefaultConfig() { FConfigData = new ConfigData { UsePermSystem = true, BanMsgWebhookUrl = string.Empty, KickMsgWebhookUrl = string.Empty }; LogDebug("Default config loaded"); } protected override void LoadDefaultMessages() { lang.RegisterMessages( new Dictionary { { "Permission Error Text", "You do not have the required permissions to use this command." }, { "Permission Error Log Text", "{0}: Tried to execute a command requiring the '{1}' permission" }, { "Kick Reason Message Text", "Administrative decision" }, { "Ban Reason Message Text", "Administrative decision" }, { "Protection Active Text", "Unable to perform this action, protection is enabled for this user" }, { "Dead Player Error Text", "Unable to perform this action, the target player is dead" }, { "Never Label Text", "Never" }, { "Banned Label Text", " (Banned)" }, { "Dev Label Text", " (Developer)" }, { "Connected Label Text", "Connected" }, { "Disconnected Label Text", "Disconnected" }, { "Sleeping Label Text", "Sleeping" }, { "Awake Label Text", "Awake" }, { "Alive Label Text", "Alive" }, { "Dead Label Text", "Dead" }, { "Flying Label Text", " Flying" }, { "Mounted Label Text", " Mounted" }, { "User Button Page Title Text", "Click a username to go to the player's control page" }, { "User Page Title Format", "Control page for player '{0}'{1}" }, { "Ban By ID Title Text", "Ban a user by ID" }, { "Ban By ID Label Text", "User ID:" }, { "Search Label Text", "Search:" }, { "Player Info Label Text", "Player information:" }, { "Player Actions Label Text", "Player actions:" }, { "Id Label Format", "ID: {0}{1}" }, { "Auth Level Label Format", "Auth level: {0}" }, { "Connection Label Format", "Connection: {0}" }, { "Status Label Format", "Status: {0} and {1}" }, { "Flags Label Format", "Flags:{0}{1}" }, { "Position Label Format", "Position: {0}" }, { "Rotation Label Format", "Rotation: {0}" }, { "Last Admin Cheat Label Format", "Last admin cheat: {0}" }, { "Idle Time Label Format", "Idle time: {0} seconds" }, { "Economics Balance Label Format", "Balance: {0} coins" }, { "ServerRewards Points Label Format", "Reward points: {0}" }, { "Health Label Format", "Health: {0}" }, { "Calories Label Format", "Calories: {0}" }, { "Hydration Label Format", "Hydration: {0}" }, { "Temp Label Format", "Temperature: {0}" }, { "Wetness Label Format", "Wetness: {0}" }, { "Comfort Label Format", "Comfort: {0}" }, { "Bleeding Label Format", "Bleeding: {0}" }, { "Radiation Label Format", "Radiation: {0}" }, { "Radiation Protection Label Format", "Protection: {0}" }, { "Main Tab Text", "Main" }, { "Online Player Tab Text", "Online Players" }, { "Offline Player Tab Text", "Offline Players" }, { "Banned Player Tab Text", "Banned Players" }, { "Go Button Text", "Go" }, { "Unban Button Text", "Unban" }, { "Ban Button Text", "Ban" }, { "Kick Button Text", "Kick" }, { "Reason Input Label Text", "Reason:" }, { "Unmute Button Text", "Unmute" }, { "Mute Button Text", "Mute" }, { "Mute Button Text 15", "Mute 15 Min" }, { "Mute Button Text 30", "Mute 30 Min" }, { "Mute Button Text 60", "Mute 60 Min" }, { "UnFreeze Button Text", "UnFreeze" }, { "Freeze Button Text", "Freeze" }, { "Freeze Not Installed Button Text", "Freeze Not Installed" }, { "Clear Inventory Button Text", "Clear Inventory" }, { "Reset Blueprints Button Text", "Reset Blueprints" }, { "Reset Metabolism Button Text", "Reset Metabolism" }, { "Recover Metabolism Button Text", "Recover Metabolism" }, { "Teleport To Player Button Text", "Teleport To Player" }, { "Teleport Player Button Text", "Teleport Player" }, { "Spectate Player Button Text", "Spectate Player" }, { "Perms Button Text", "Permissions" }, { "Perms Not Installed Button Text", "Perms Not Installed" }, { "Backpacks Button Text", "View Backpack" }, { "Backpacks Not Installed Button Text", "Backpacks Not Installed" }, { "Inventory Button Text", "View Inventory" }, { "Inventory Not Installed Button Text", "Inventory Viewer Not Installed" }, { "Hurt 25 Button Text", "Hurt 25" }, { "Hurt 50 Button Text", "Hurt 50" }, { "Hurt 75 Button Text", "Hurt 75" }, { "Hurt 100 Button Text", "Hurt 100" }, { "Kill Button Text", "Kill" }, { "Heal 25 Button Text", "Heal 25" }, { "Heal 50 Button Text", "Heal 50" }, { "Heal 75 Button Text", "Heal 75" }, { "Heal 100 Button Text", "Heal 100" }, { "Heal Wounds Button Text", "Heal Wounds" } }, this, "en" ); LogDebug("Default messages loaded"); } protected override void SaveConfig() => Config.WriteObject(FConfigData); #endregion Hooks #region Command Callbacks [Command(CPadminCmd)] private void PlayerAdministrationUICallback(IPlayer aPlayer, string aCommand, string[] aArgs) { BasePlayer player = BasePlayer.Find(aPlayer.Id); LogDebug("PlayerAdministrationUICallback was called"); CuiHelper.DestroyUi(player, CBasePanelName); if (aPlayer.IsServer || !VerifyPermission(ref player, string.Empty, true)) return; LogInfo($"{player.displayName}: Opened the menu"); CuiHelper.AddUi(player, CuiHelper.ToJson(new CuiElementContainer { { CBasePanel, Cui.ParentOverlay, CBasePanelName } }, false)); BuildUI(player, UiPage.Main); } [Command(CCloseUiCmd)] private void PlayerAdministrationCloseUICallback(IPlayer aPlayer, string aCommand, string[] aArgs) { LogDebug("PlayerAdministrationCloseUICallback was called"); if (aPlayer.IsServer) return; CuiHelper.DestroyUi(BasePlayer.Find(aPlayer.Id), CBasePanelName); if (FMainPageBanIdInputText.ContainsKey(aPlayer.Id)) FMainPageBanIdInputText.Remove(aPlayer.Id); if (FUserBtnPageSearchInputText.ContainsKey(aPlayer.Id)) FUserBtnPageSearchInputText.Remove(aPlayer.Id); } [Command(CSwitchUiCmd)] private void PlayerAdministrationSwitchUICallback(IPlayer aPlayer, string aCommand, string[] aArgs) { LogDebug("PlayerAdministrationSwitchUICallback was called"); BasePlayer player = BasePlayer.Find(aPlayer.Id); if (aPlayer.IsServer || !VerifyPermission(ref player, string.Empty, true) || aArgs.Count() <= 0) return; bool twoOrMore = aArgs.Count() >= 2; switch (aArgs[0].ToLower()) { case CCmdArgPlayersOnline: { BuildUI(player, UiPage.PlayersOnline, (twoOrMore ? aArgs[1] : string.Empty)); break; } case CCmdArgPlayersOnlineSearch: { BuildUI(player, UiPage.PlayersOnline, (twoOrMore ? aArgs[1] : string.Empty), true); break; } case CCmdArgPlayersOffline: { BuildUI(player, UiPage.PlayersOffline, (twoOrMore ? aArgs[1] : string.Empty)); break; } case CCmdArgPlayersOfflineSearch: { BuildUI(player, UiPage.PlayersOffline, (twoOrMore ? aArgs[1] : string.Empty), true); break; } case CCmdArgPlayersBanned: { BuildUI(player, UiPage.PlayersBanned, (twoOrMore ? aArgs[1] : string.Empty)); break; } case CCmdArgPlayersBannedSearch: { BuildUI(player, UiPage.PlayersBanned, (twoOrMore ? aArgs[1] : string.Empty), true); break; } case CCmdArgPlayerPage: { BuildUI(player, UiPage.PlayerPage, (twoOrMore ? aArgs[1] : string.Empty)); break; } case CCmdArgPlayerPageBanned: { BuildUI(player, UiPage.PlayerPageBanned, (twoOrMore ? aArgs[1] : string.Empty)); break; } default: { // Main is the default for everything BuildUI(player, UiPage.Main); break; } } } [Command(CUnbanUserCmd)] private void PlayerAdministrationUnbanUserCallback(IPlayer aPlayer, string aCommand, string[] aArgs) { LogDebug("PlayerAdministrationUnbanUserCallback was called"); ulong targetId; if (!GetTargetFromArg(aArgs, out targetId)) return; if (aPlayer.IsServer) { Player.Unban(targetId); LogInfo($"{aPlayer.Name}: Unbanned user ID {targetId}"); } else { BasePlayer player = BasePlayer.Find(aPlayer.Id); if (!VerifyPermission(ref player, CPermBan, true)) return; Player.Unban(targetId); LogInfo($"{player.displayName}: Unbanned user ID {targetId}"); timer.Once(0.01f, () => BuildUI(player, UiPage.Main)); } } [Command(CBanUserCmd)] private void PlayerAdministrationBanUserCallback(IPlayer aPlayer, string aCommand, string[] aArgs) { LogDebug("PlayerAdministrationBanUserCallback was called"); ulong targetId; if (!GetTargetFromArg(aArgs, out targetId)) return; if (aPlayer.IsServer) { if (permission.UserHasPermission(targetId.ToString(), CPermProtectBan)) { aPlayer.Reply(lang.GetMessage("Protection Active Text", this)); return; } string banReasonMsg = lang.GetMessage("Ban Reason Message Text", this, targetId.ToString()); Player.Ban(targetId, banReasonMsg); LogInfo($"{aPlayer.Name}: Banned user ID {targetId}"); SendDiscordKickBanMessage(aPlayer.Name, string.Empty, ServerUsers.Get(targetId).username, targetId.ToString(), banReasonMsg, true); } else { BasePlayer player = BasePlayer.Find(aPlayer.Id); if (!VerifyPermission(ref player, CPermBan, true)) return; if (permission.UserHasPermission(targetId.ToString(), CPermProtectBan)) { rust.SendChatMessage(player, string.Empty, lang.GetMessage("Protection Active Text", this, aPlayer.Id)); return; } string banReasonMsg = GetReason(aPlayer.Id, targetId.ToString()); if(ServerArmour != null) { ServerArmour.Call("API_BanPlayer", targetId, banReasonMsg, "30y"); } else { //API_BanPlayer(player, playerId, reason, length, ignoreSearch); Player.Ban(targetId, banReasonMsg); } LogInfo($"{player.displayName}: Banned user ID {targetId}"); SendDiscordKickBanMessage(player.displayName, aPlayer.Id, ServerUsers.Get(targetId).username, targetId.ToString(), banReasonMsg, true); timer.Once(0.01f, () => BuildUI(player, UiPage.PlayerPage, targetId.ToString())); } } [Command(CMainPageBanByIdCmd)] private void PlayerAdministrationMainPageBanByIdCallback(IPlayer aPlayer, string aCommand, string[] aArgs) { LogDebug("PlayerAdministrationMainPageBanByIdCallback was called"); BasePlayer player = BasePlayer.Find(aPlayer.Id); ulong targetId; if ( aPlayer.IsServer || !VerifyPermission(ref player, CPermBan, true) || !FMainPageBanIdInputText.ContainsKey(aPlayer.Id) || !ulong.TryParse(FMainPageBanIdInputText[aPlayer.Id], out targetId) ) return; if (permission.UserHasPermission(targetId.ToString(), CPermProtectBan)) { rust.SendChatMessage(player, string.Empty, lang.GetMessage("Protection Active Text", this, aPlayer.Id)); return; } string banReasonMsg = lang.GetMessage("Ban Reason Message Text", this, targetId.ToString()); Player.Ban(targetId, banReasonMsg); ServerUsers.User targetPlayer = ServerUsers.Get(targetId); LogInfo($"{player.displayName}: Banned user ID {targetId}"); SendDiscordKickBanMessage(player.displayName, aPlayer.Id, targetPlayer.username, targetId.ToString(), banReasonMsg, true); timer.Once(0.01f, () => BuildUI(player, UiPage.Main)); } [Command(CKickUserCmd)] private void PlayerAdministrationKickUserCallback(IPlayer aPlayer, string aCommand, string[] aArgs) { LogDebug("PlayerAdministrationKickUserCallback was called"); ulong targetId; if (!GetTargetFromArg(aArgs, out targetId)) return; BasePlayer targetPlayer = BasePlayer.FindByID(targetId); string inputReason = GetReason(aPlayer.Id, targetId.ToString()); string kickReasonMsg = inputReason.Equals(string.Empty) ? inputReason : lang.GetMessage("Kick Reason Message Text", this, targetId.ToString()); if (aPlayer.IsServer) { if (permission.UserHasPermission(targetId.ToString(), CPermProtectKick)) { aPlayer.Reply(lang.GetMessage("Protection Active Text", this)); return; } targetPlayer?.Kick(kickReasonMsg); LogInfo($"{aPlayer.Name}: Kicked user ID {targetId}"); SendDiscordKickBanMessage(aPlayer.Name, string.Empty, targetPlayer.displayName, targetPlayer.UserIDString, kickReasonMsg, false); } else { BasePlayer player = BasePlayer.Find(aPlayer.Id); if (!VerifyPermission(ref player, CPermKick, true)) return; if (permission.UserHasPermission(targetId.ToString(), CPermProtectKick)) { rust.SendChatMessage(player, string.Empty, lang.GetMessage("Protection Active Text", this, aPlayer.Id)); return; } targetPlayer?.Kick(kickReasonMsg); LogInfo($"{player.displayName}: Kicked user ID {targetId}"); SendDiscordKickBanMessage(player.displayName, aPlayer.Id, targetPlayer.displayName, targetPlayer.UserIDString, kickReasonMsg, false); timer.Once(0.01f, () => BuildUI(player, UiPage.PlayerPage, targetId.ToString())); } } [Command(CUnmuteUserCmd)] private void PlayerAdministrationUnmuteUserCallback(IPlayer aPlayer, string aCommand, string[] aArgs) { LogDebug("PlayerAdministrationUnmuteUserCallback was called"); ulong targetId; if (!GetTargetFromArg(aArgs, out targetId)) return; if (aPlayer.IsServer) { BasePlayer target = BasePlayer.FindByID(targetId) ?? BasePlayer.FindSleeping(targetId); if (BetterChatMute != null && target != null) { BetterChatMute.Call("API_Unmute", target.IPlayer, aPlayer); } else { target?.SetPlayerFlag(BasePlayer.PlayerFlags.ChatMute, false); } LogInfo($"{aPlayer.Name}: Unmuted user ID {targetId}"); } else { BasePlayer player = BasePlayer.Find(aPlayer.Id); if (!VerifyPermission(ref player, CPermMute, true)) return; BasePlayer target = BasePlayer.FindByID(targetId) ?? BasePlayer.FindSleeping(targetId); if (BetterChatMute != null && target != null) { BetterChatMute.Call("API_Unmute", target.IPlayer, aPlayer); } else { target?.SetPlayerFlag(BasePlayer.PlayerFlags.ChatMute, false); } LogInfo($"{player.displayName}: Unmuted user ID {targetId}"); timer.Once(0.01f, () => BuildUI(player, UiPage.PlayerPage, targetId.ToString())); } } [Command(CMuteUserCmd)] private void PlayerAdministrationMuteUserCallback(IPlayer aPlayer, string aCommand, string[] aArgs) { LogDebug("PlayerAdministrationMuteUserCallback was called"); ulong targetId; float time; if (!GetTargetAmountFromArg(aArgs, out targetId, out time)) return; string inputReason = GetReason(aPlayer.Id, targetId.ToString()); if (aPlayer.IsServer) { BasePlayer target = BasePlayer.FindByID(targetId) ?? BasePlayer.FindSleeping(targetId); if (BetterChatMute != null && target != null) { if (time == 0f) { BetterChatMute.Call("API_Mute", target.IPlayer, aPlayer, true, false); } else { BetterChatMute.Call("API_TimeMute", target.IPlayer, aPlayer, TimeSpan.FromMinutes(time), true, false); } } else { target?.SetPlayerFlag(BasePlayer.PlayerFlags.ChatMute, true); } LogInfo($"{aPlayer.Name}: Muted user ID {targetId}"); } else { BasePlayer player = BasePlayer.Find(aPlayer.Id); if (!VerifyPermission(ref player, CPermMute, true)) return; BasePlayer target = BasePlayer.FindByID(targetId) ?? BasePlayer.FindSleeping(targetId); if (BetterChatMute != null && target != null) { if (time == 0f) { BetterChatMute.Call("API_Mute", target.IPlayer, aPlayer, inputReason, true, false); } else { BetterChatMute.Call("API_TimeMute", target.IPlayer, aPlayer, TimeSpan.FromMinutes(time), inputReason, true, false); } } else { target?.SetPlayerFlag(BasePlayer.PlayerFlags.ChatMute, true); } LogInfo($"{player.displayName}: Muted user ID {targetId}"); timer.Once(0.01f, () => BuildUI(player, UiPage.PlayerPage, targetId.ToString())); } } [Command(CUnreezeCmd)] private void PlayerAdministrationUnfreezeCallback(IPlayer aPlayer, string aCommand, string[] aArgs) { LogDebug("PlayerAdministrationUnfreezeCallback was called"); BasePlayer player = BasePlayer.Find(aPlayer.Id); ulong targetId; if (aPlayer.IsServer || !VerifyPermission(ref player, CPermFreeze, true) || !GetTargetFromArg(aArgs, out targetId)) return; player.SendConsoleCommand($"{CFreezeUnfreezeCmd} {targetId}"); LogInfo($"{player.displayName}: Unfroze user ID {targetId}"); // Let code execute, then reload screen timer.Once(0.1f, () => BuildUI(player, UiPage.PlayerPage, targetId.ToString())); } [Command(CFreezeCmd)] private void PlayerAdministrationFreezeCallback(IPlayer aPlayer, string aCommand, string[] aArgs) { LogDebug("PlayerAdministrationFreezeCallback was called"); BasePlayer player = BasePlayer.Find(aPlayer.Id); ulong targetId; if (aPlayer.IsServer || !VerifyPermission(ref player, CPermFreeze, true) || !GetTargetFromArg(aArgs, out targetId)) return; player.SendConsoleCommand($"{CFreezeFreezeCmd} {targetId}"); LogInfo($"{player.displayName}: Froze user ID {targetId}"); // Let code execute, then reload screen timer.Once(0.1f, () => BuildUI(player, UiPage.PlayerPage, targetId.ToString())); } [Command(CBackpackViewCmd)] private void PlayerAdministrationViewBackpackCallback(IPlayer aPlayer, string aCommand, string[] aArgs) { LogDebug("PlayerAdministrationViewBackpackCallback was called"); BasePlayer player = BasePlayer.Find(aPlayer.Id); ulong targetId; if (aPlayer.IsServer || !VerifyPermission(ref player, CPermBackpacks, true) || !GetTargetFromArg(aArgs, out targetId)) return; Backpacks.Call("ViewBackpack", player, string.Empty, new[] { targetId.ToString() }); LogInfo($"{player.displayName}: Viewed backpack of {targetId}"); PlayerAdministrationCloseUICallback(player.IPlayer, string.Empty, new[] { string.Empty }); } [Command(CInventoryViewCmd)] private void PlayerAdministrationViewInventoryCallback(IPlayer aPlayer, string aCommand, string[] aArgs) { LogDebug("PlayerAdministrationViewInventoryCallback was called"); BasePlayer player = BasePlayer.Find(aPlayer.Id); ulong targetId; if (aPlayer.IsServer || !VerifyPermission(ref player, CPermInventory, true) || !GetTargetFromArg(aArgs, out targetId)) return; InventoryViewer.Call("ViewInventoryCommand", player, targetId.ToString(), new[] { targetId.ToString() }); LogInfo($"{player.displayName}: Viewed inventory of {targetId}"); PlayerAdministrationCloseUICallback(player.IPlayer, string.Empty, new[] { string.Empty }); } [Command(CClearUserInventoryCmd)] private void PlayerAdministrationClearUserInventoryCallback(IPlayer aPlayer, string aCommand, string[] aArgs) { LogDebug("PlayerAdministrationClearUserInventoryCallback was called"); ulong targetId; if (!GetTargetFromArg(aArgs, out targetId)) return; if (aPlayer.IsServer) { if (permission.UserHasPermission(targetId.ToString(), CPermProtectReset)) { aPlayer.Reply(lang.GetMessage("Protection Active Text", this)); return; } (BasePlayer.FindByID(targetId) ?? BasePlayer.FindSleeping(targetId))?.inventory.Strip(); LogInfo($"{aPlayer.Name}: Cleared the inventory of user ID {targetId}"); } else { BasePlayer player = BasePlayer.Find(aPlayer.Id); if (!VerifyPermission(ref player, CPermClearInventory, true)) return; if (permission.UserHasPermission(targetId.ToString(), CPermProtectReset)) { rust.SendChatMessage(player, string.Empty, lang.GetMessage("Protection Active Text", this, aPlayer.Id)); return; } (BasePlayer.FindByID(targetId) ?? BasePlayer.FindSleeping(targetId))?.inventory.Strip(); LogInfo($"{player.displayName}: Cleared the inventory of user ID {targetId}"); timer.Once(0.01f, () => BuildUI(player, UiPage.PlayerPage, targetId.ToString())); } } [Command(CResetUserBPCmd)] private void PlayerAdministrationResetUserBlueprintsCallback(IPlayer aPlayer, string aCommand, string[] aArgs) { LogDebug("PlayerAdministrationResetUserBlueprintsCallback was called"); ulong targetId; if (!GetTargetFromArg(aArgs, out targetId)) return; if (aPlayer.IsServer) { if (permission.UserHasPermission(targetId.ToString(), CPermProtectReset)) { aPlayer.Reply(lang.GetMessage("Protection Active Text", this)); return; } (BasePlayer.FindByID(targetId) ?? BasePlayer.FindSleeping(targetId))?.blueprints.Reset(); LogInfo($"{aPlayer.Name}: Reset the blueprints of user ID {targetId}"); } else { BasePlayer player = BasePlayer.Find(aPlayer.Id); if (!VerifyPermission(ref player, CPermResetBP, true)) return; if (permission.UserHasPermission(targetId.ToString(), CPermProtectReset)) { rust.SendChatMessage(player, string.Empty, lang.GetMessage("Protection Active Text", this, player.UserIDString)); return; } (BasePlayer.FindByID(targetId) ?? BasePlayer.FindSleeping(targetId))?.blueprints.Reset(); LogInfo($"{player.displayName}: Reset the blueprints of user ID {targetId}"); timer.Once(0.01f, () => BuildUI(player, UiPage.PlayerPage, targetId.ToString())); } } [Command(CResetUserMetabolismCmd)] private void PlayerAdministrationResetUserMetabolismCallback(IPlayer aPlayer, string aCommand, string[] aArgs) { LogDebug("PlayerAdministrationResetUserMetabolismCallback was called"); ulong targetId; if (!GetTargetFromArg(aArgs, out targetId)) return; if (aPlayer.IsServer) { if (permission.UserHasPermission(targetId.ToString(), CPermProtectReset)) { aPlayer.Reply(lang.GetMessage("Protection Active Text", this)); return; } (BasePlayer.FindByID(targetId) ?? BasePlayer.FindSleeping(targetId))?.metabolism.Reset(); LogInfo($"{aPlayer.Name}: Reset the metabolism of user ID {targetId}"); } else { BasePlayer player = BasePlayer.Find(aPlayer.Id); if (!VerifyPermission(ref player, CPermResetMetabolism, true)) return; if (permission.UserHasPermission(targetId.ToString(), CPermProtectReset)) { rust.SendChatMessage(player, string.Empty, lang.GetMessage("Protection Active Text", this, aPlayer.Id)); return; } (BasePlayer.FindByID(targetId) ?? BasePlayer.FindSleeping(targetId))?.metabolism.Reset(); LogInfo($"{player.displayName}: Reset the metabolism of user ID {targetId}"); timer.Once(0.01f, () => BuildUI(player, UiPage.PlayerPage, targetId.ToString())); } } [Command(CRecoverUserMetabolismCmd)] private void PlayerAdministrationRecoverUserMetabolismCallback(IPlayer aPlayer, string aCommand, string[] aArgs) { LogDebug("PlayerAdministrationRecoverUserMetabolismCallback was called"); ulong targetId; BasePlayer player = null; if (!GetTargetFromArg(aArgs, out targetId)) return; if (!aPlayer.IsServer) { player = BasePlayer.Find(aPlayer.Id); if (!VerifyPermission(ref player, CPermRecoverMetabolism, true)) return; } PlayerMetabolism playerState = (BasePlayer.FindByID(targetId) ?? BasePlayer.FindSleeping(targetId))?.metabolism; playerState.bleeding.value = playerState.bleeding.min; playerState.calories.value = playerState.calories.max; playerState.comfort.value = 0; playerState.hydration.value = playerState.hydration.max; playerState.oxygen.value = playerState.oxygen.max; playerState.poison.value = playerState.poison.min; playerState.radiation_level.value = playerState.radiation_level.min; playerState.radiation_poison.value = playerState.radiation_poison.min; playerState.temperature.value = (PlayerMetabolism.HotThreshold + PlayerMetabolism.ColdThreshold) / 2; playerState.wetness.value = playerState.wetness.min; if (aPlayer.IsServer) { LogInfo($"{aPlayer.Name}: Recovered the metabolism of user ID {targetId}"); } else { LogInfo($"{player.displayName}: Recovered the metabolism of user ID {targetId}"); timer.Once(0.01f, () => BuildUI(player, UiPage.PlayerPage, targetId.ToString())); } } [Command(CTeleportToUserCmd)] private void PlayerAdministrationTeleportToUserCallback(IPlayer aPlayer, string aCommand, string[] aArgs) { LogDebug("PlayerAdministrationTeleportToUserCallback was called"); BasePlayer player = BasePlayer.Find(aPlayer.Id); ulong targetId; if (aPlayer.IsServer || !VerifyPermission(ref player, CPermTeleport, true) || !GetTargetFromArg(aArgs, out targetId)) return; BasePlayer targetPlayer = BasePlayer.FindByID(targetId) ?? BasePlayer.FindSleeping(targetId); if (targetPlayer.IsAlive()) { player.Teleport(targetPlayer.transform.position); LogInfo($"{player.displayName}: Teleported to user ID {targetId}"); } else { aPlayer.Reply(lang.GetMessage("Dead Player Error Text", this, aPlayer.Id)); } timer.Once(0.01f, () => BuildUI(player, UiPage.PlayerPage, targetId.ToString())); } [Command(CTeleportUserCmd)] private void PlayerAdministrationTeleportUserCallback(IPlayer aPlayer, string aCommand, string[] aArgs) { LogDebug("PlayerAdministrationTeleportUserCallback was called"); BasePlayer player = BasePlayer.Find(aPlayer.Id); ulong targetId; if (aPlayer.IsServer || !VerifyPermission(ref player, CPermTeleport, true) || !GetTargetFromArg(aArgs, out targetId)) return; BasePlayer targetPlayer = BasePlayer.FindByID(targetId) ?? BasePlayer.FindSleeping(targetId); if (targetPlayer.IsAlive()) { targetPlayer.Teleport(player.transform.position); LogInfo($"{targetPlayer.displayName}: Teleported to admin {player.displayName}"); } else { aPlayer.Reply(lang.GetMessage("Dead Player Error Text", this, aPlayer.Id)); } timer.Once(0.01f, () => BuildUI(player, UiPage.PlayerPage, targetId.ToString())); } [Command(CSpectateUserCmd)] private void PlayerAdministrationSpectateUserCallback(IPlayer aPlayer, string aCommand, string[] aArgs) { LogDebug("PlayerAdministrationSpectateUserCallback was called"); BasePlayer player = BasePlayer.Find(aPlayer.Id); ulong targetId; if (aPlayer.IsServer || !VerifyPermission(ref player, CPermSpectate, true) || !GetTargetFromArg(aArgs, out targetId)) return; if (!player.IsDead()) player.DieInstantly(); player.StartSpectating(); player.UpdateSpectateTarget(targetId.ToString()); LogInfo($"{player.displayName}: Started spectating user ID {targetId}"); timer.Once(0.01f, () => BuildUI(player, UiPage.PlayerPage, targetId.ToString())); } [Command(CPermsCmd)] private void PlayerAdministrationRunPermsCallback(IPlayer aPlayer, string aCommand, string[] aArgs) { LogDebug("PlayerAdministrationRunPermsCallback was called"); BasePlayer player = BasePlayer.Find(aPlayer.Id); ulong targetId; if (aPlayer.IsServer || !VerifyPermission(ref player, CPermPerms, true) || !GetTargetFromArg(aArgs, out targetId)) return; if (PermissionsManager != null && PermissionsManager.IsLoaded) PermissionsManager.Call( (PermissionsManager.Version.Major > 0 ? "CmdPerms" : "cmdPerms"), player, string.Empty, new[] { "player", targetId.ToString() } ); LogInfo($"{player.displayName}: Opened the permissions manager for user ID {targetId}"); } [Command(CHurtUserCmd)] private void PlayerAdministrationHurtUserCallback(IPlayer aPlayer, string aCommand, string[] aArgs) { LogDebug("PlayerAdministrationHurtUserCallback was called"); ulong targetId; float amount; if (!GetTargetAmountFromArg(aArgs, out targetId, out amount)) return; if (aPlayer.IsServer) { if (permission.UserHasPermission(targetId.ToString(), CPermProtectHurt)) { aPlayer.Reply(lang.GetMessage("Protection Active Text", this)); return; } (BasePlayer.FindByID(targetId) ?? BasePlayer.FindSleeping(targetId))?.Hurt(amount); LogInfo($"{aPlayer.Name}: Hurt user ID {targetId} for {amount} points"); } else { BasePlayer player = BasePlayer.Find(aPlayer.Id); if (!VerifyPermission(ref player, CPermHurt, true)) return; if (permission.UserHasPermission(targetId.ToString(), CPermProtectHurt)) { rust.SendChatMessage(player, string.Empty, lang.GetMessage("Protection Active Text", this, aPlayer.Id)); return; } (BasePlayer.FindByID(targetId) ?? BasePlayer.FindSleeping(targetId))?.Hurt(amount); LogInfo($"{player.displayName}: Hurt user ID {targetId} for {amount} points"); timer.Once(0.01f, () => BuildUI(player, UiPage.PlayerPage, targetId.ToString())); } } [Command(CKillUserCmd)] private void PlayerAdministrationKillUserCallback(IPlayer aPlayer, string aCommand, string[] aArgs) { LogDebug("PlayerAdministrationKillUserCallback was called"); ulong targetId; if (!GetTargetFromArg(aArgs, out targetId)) return; if (aPlayer.IsServer) { if (permission.UserHasPermission(targetId.ToString(), CPermProtectKill)) { aPlayer.Reply(lang.GetMessage("Protection Active Text", this)); return; } (BasePlayer.FindByID(targetId) ?? BasePlayer.FindSleeping(targetId))?.Die(); LogInfo($"{aPlayer.Name}: Killed user ID {targetId}"); } else { BasePlayer player = BasePlayer.Find(aPlayer.Id); if (!VerifyPermission(ref player, CPermKill, true)) return; if (permission.UserHasPermission(targetId.ToString(), CPermProtectKill)) { rust.SendChatMessage(player, string.Empty, lang.GetMessage("Protection Active Text", this, player.UserIDString)); return; } (BasePlayer.FindByID(targetId) ?? BasePlayer.FindSleeping(targetId))?.Die(); LogInfo($"{player.displayName}: Killed user ID {targetId}"); timer.Once(0.01f, () => BuildUI(player, UiPage.PlayerPage, targetId.ToString())); } } [Command(CHealUserCmd)] private void PlayerAdministrationHealUserCallback(IPlayer aPlayer, string aCommand, string[] aArgs) { LogDebug("PlayerAdministrationHealUserCallback was called"); ulong targetId; float amount; if (!GetTargetAmountFromArg(aArgs, out targetId, out amount)) return; BasePlayer targetPlayer = BasePlayer.FindByID(targetId) ?? BasePlayer.FindSleeping(targetId); if (aPlayer.IsServer) { if (targetPlayer.IsWounded()) targetPlayer.StopWounded(); targetPlayer.Heal(amount); LogInfo($"{aPlayer.Name}: Healed user ID {targetId} for {amount} points"); } else { BasePlayer player = BasePlayer.Find(aPlayer.Id); if (!VerifyPermission(ref player, CPermHeal, true)) return; if (targetPlayer.IsWounded()) targetPlayer.StopWounded(); targetPlayer.Heal(amount); LogInfo($"{player.displayName}: Healed user ID {targetId} for {amount} points"); timer.Once(0.01f, () => BuildUI(player, UiPage.PlayerPage, targetId.ToString())); } } #endregion Command Callbacks #region Text Update Callbacks [Command(CMainPageBanIdInputTextCmd)] private void PlayerAdministrationMainPageBanIdInputTextCallback(IPlayer aPlayer, string aCommand, string[] aArgs) { BasePlayer player = BasePlayer.Find(aPlayer.Id); if (aPlayer.IsServer || !VerifyPermission(ref player, CPermUiShow) || aArgs.Count() <= 0) { if (FMainPageBanIdInputText.ContainsKey(aPlayer.Id)) FMainPageBanIdInputText.Remove(aPlayer.Id); return; } if (FMainPageBanIdInputText.ContainsKey(aPlayer.Id)) { FMainPageBanIdInputText[aPlayer.Id] = aArgs[0]; } else { FMainPageBanIdInputText.Add(aPlayer.Id, aArgs[0]); } } [Command(CUserBtnPageSearchInputTextCmd)] private void PlayerAdministrationUserBtnPageSearchInputTextCallback(IPlayer aPlayer, string aCommand, string[] aArgs) { BasePlayer player = BasePlayer.Find(aPlayer.Id); if (aPlayer.IsServer || !VerifyPermission(ref player, CPermUiShow) || aArgs.Count() <= 0) { if (FUserBtnPageSearchInputText.ContainsKey(aPlayer.Id)) FUserBtnPageSearchInputText.Remove(aPlayer.Id); return; } if (FUserBtnPageSearchInputText.ContainsKey(aPlayer.Id)) { FUserBtnPageSearchInputText[aPlayer.Id] = aArgs[0]; } else { FUserBtnPageSearchInputText.Add(aPlayer.Id, aArgs[0]); } } [Command(CUserPageReasonInputTextCmd)] private void PlayerAdministrationUserPageReasonInputTextCallback(IPlayer aPlayer, string aCommand, string[] aArgs) { BasePlayer player = BasePlayer.Find(aPlayer.Id); if (aPlayer.IsServer || !VerifyPermission(ref player, CPermUiShow) || aArgs.Count() <= 0) { if (FUserPageReasonInputText.ContainsKey(aPlayer.Id)) FUserPageReasonInputText.Remove(aPlayer.Id); return; } if (FUserPageReasonInputText.ContainsKey(aPlayer.Id)) { FUserPageReasonInputText[aPlayer.Id] = aArgs[0]; } else { FUserPageReasonInputText.Add(aPlayer.Id, aArgs[0]); } } #endregion Text Update Callbacks } }