C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using UnityEngine;
using Oxide.Game.Rust.Cui;
using Newtonsoft.Json;
namespace Oxide.Plugins
{
[Info("PlayerAdministration", "ThibmoRozier", "1.2.0", ResourceId = 0)]
[Description("Allows server admins to moderate users using a GUI from within the game.")]
public class PlayerAdministration : RustPlugin
{
#region GUI
#region Types
/// <summary>
/// UI Color object
/// </summary>
public class CuiColor
{
public byte R { get; set; } = 255;
public byte G { get; set; } = 255;
public byte B { get; set; } = 255;
public float A { get; set; } = 1f;
public CuiColor() { }
public CuiColor(byte red, byte green, byte blue, float alpha = 1f)
{
R = red;
G = green;
B = blue;
A = alpha;
}
public override string ToString() => $"{(double)R / 255} {(double)G / 255} {(double)B / 255} {A}";
}
/// <summary>
/// Element position object
/// </summary>
public class CuiPoint
{
public float X { get; set; } = 0f;
public float Y { get; set; } = 0f;
public CuiPoint() { }
public CuiPoint(float x, float y)
{
X = x;
Y = y;
}
public override string ToString() => $"{X} {Y}";
}
/// <summary>
/// UI pages to make the switching more humanly readable
/// </summary>
private enum UiPage
{
Main = 0,
PlayersOnline,
PlayersOffline,
PlayersBanned,
PlayerPage,
PlayerPageBanned
}
#endregion Types
#region Defaults
/// <summary>
/// Predefined default color set
/// </summary>
public class CuiDefaultColors
{
public static CuiColor Background { get; } = new CuiColor(240, 240, 240, 0.3f);
public static CuiColor BackgroundMedium { get; } = new CuiColor(76, 74, 72, 0.83f);
public static CuiColor BackgroundDark { get; } = new CuiColor(42, 42, 42, 0.93f);
public static CuiColor Button { get; } = new CuiColor(42, 42, 42, 0.9f);
public static CuiColor ButtonInactive { get; } = new CuiColor(168, 168, 168, 0.9f);
public static CuiColor ButtonDecline { get; } = new CuiColor(192, 0, 0, 0.9f);
public static CuiColor Text { get; } = new CuiColor(0, 0, 0, 1f);
public static CuiColor TextAlt { get; } = new CuiColor(255, 255, 255, 1f);
public static CuiColor TextTitle { get; } = new CuiColor(206, 66, 43, 1f);
public static CuiColor None { get; } = new CuiColor(0, 0, 0, 0f);
}
#endregion Defaults
#region UI object definitions
/// <summary>
/// Input field object
/// </summary>
public 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
/// <summary>
/// Custom version of the CuiElementContainer to add InputFields
/// </summary>
public class CustomCuiElementContainer : CuiElementContainer
{
public string Add(CuiInputField inputField, string parent = "Hud", string name = null)
{
if (string.IsNullOrEmpty(name))
name = CuiHelper.GetGuid();
Add(new CuiElement {
Name = name,
Parent = parent,
FadeOut = inputField.FadeOut,
Components = {
inputField.InputField,
inputField.RectTransform
}
});
return name;
}
}
#endregion Component container
/// <summary>
/// Rust UI object
/// </summary>
public class Cui
{
public const string PARENT_HUD = "Hud";
public const string PARENT_OVERLAY = "Overlay";
public string MainPanelName { get; set; }
private BasePlayer player;
private CustomCuiElementContainer container = new CustomCuiElementContainer();
/// <summary>
/// Constructor
/// </summary>
/// <param name="player">The player this object is meant for</param>
public Cui(BasePlayer player)
{
this.player = player;
}
/// <summary>
/// Add a new panel
/// </summary>
/// <param name="parent">The parent object name</param>
/// <param name="leftBottomAnchor">Left(x)-Bottom(y) relative position</param>
/// <param name="rightTopAnchor">Right(x)-Top(y) relative position</param>
/// <param name="cursorEnabled">The panel requires the cursor</param>
/// <param name="color">Image color</param>
/// <param name="name">The object's name</param>
/// <param name="png">Image PNG file path</param>
/// <returns>New object name</returns>
public string AddPanel(string parent, CuiPoint leftBottomAnchor, CuiPoint rightTopAnchor, bool cursorEnabled, CuiColor color = null,
string name = null, string png = null) =>
AddPanel(parent, leftBottomAnchor, rightTopAnchor, new CuiPoint(), new CuiPoint(), cursorEnabled, color, name, png);
/// <summary>
/// Add a new panel
/// </summary>
/// <param name="parent">The parent object name</param>
/// <param name="leftBottomAnchor">Left(x)-Bottom(y) relative position</param>
/// <param name="rightTopAnchor">Right(x)-Top(y) relative position</param>
/// <param name="leftBottomOffset">Left(x)-Bottom(y) relative offset</param>
/// <param name="rightTopOffset">Right(x)-Top(y) relative offset</param>
/// <param name="cursorEnabled">The panel requires the cursor</param>
/// <param name="color">Image color</param>
/// <param name="name">The object's name</param>
/// <param name="png">Image PNG file path</param>
/// <returns>New object name</returns>
public string AddPanel(string parent, CuiPoint leftBottomAnchor, CuiPoint rightTopAnchor, CuiPoint leftBottomOffset, CuiPoint rightTopOffset,
bool cursorEnabled, CuiColor color = null, string name = null, string png = null)
{
CuiPanel panel = new CuiPanel() {
RectTransform = {
AnchorMin = leftBottomAnchor.ToString(),
AnchorMax = rightTopAnchor.ToString(),
OffsetMin = leftBottomOffset.ToString(),
OffsetMax = rightTopOffset.ToString()
},
CursorEnabled = cursorEnabled
};
if (!string.IsNullOrEmpty(png) || (color != null)) {
panel.Image = new CuiImageComponent() {
Color = color.ToString(),
Png = png
};
}
return container.Add(panel, parent, name);
}
/// <summary>
/// Add a new label
/// </summary>
/// <param name="parent">The parent object name</param>
/// <param name="leftBottomAnchor">Left(x)-Bottom(y) relative position</param>
/// <param name="rightTopAnchor">Right(x)-Top(y) relative position</param>
/// <param name="color">Text color</param>
/// <param name="text">Text to show</param>
/// <param name="name">The object's name</param>
/// <param name="fontSize">Font size</param>
/// <param name="align">Text alignment</param>
/// <returns>New object name</returns>
public string AddLabel(string parent, CuiPoint leftBottomAnchor, CuiPoint rightTopAnchor, CuiColor color, string text, string name = null,
int fontSize = 14, TextAnchor align = TextAnchor.UpperLeft) =>
AddLabel(parent, leftBottomAnchor, rightTopAnchor, new CuiPoint(), new CuiPoint(), color, text, name, fontSize, align);
/// <summary>
/// Add a new label
/// </summary>
/// <param name="parent">The parent object name</param>
/// <param name="leftBottomAnchor">Left(x)-Bottom(y) relative position</param>
/// <param name="rightTopAnchor">Right(x)-Top(y) relative position</param>
/// <param name="leftBottomOffset">Left(x)-Bottom(y) relative offset</param>
/// <param name="rightTopOffset">Right(x)-Top(y) relative offset</param>
/// <param name="color">Text color</param>
/// <param name="text">Text to show</param>
/// <param name="name">The object's name</param>
/// <param name="fontSize">Font size</param>
/// <param name="align">Text alignment</param>
/// <returns>New object name</returns>
public string AddLabel(string parent, CuiPoint leftBottomAnchor, CuiPoint rightTopAnchor, CuiPoint leftBottomOffset, CuiPoint rightTopOffset,
CuiColor color, string text, string name = null, int fontSize = 14, TextAnchor align = TextAnchor.UpperLeft)
{
return container.Add(new CuiLabel() {
Text = {
Text = text ?? "",
FontSize = fontSize,
Align = align,
Color = color.ToString()
},
RectTransform = {
AnchorMin = leftBottomAnchor.ToString(),
AnchorMax = rightTopAnchor.ToString(),
OffsetMin = leftBottomOffset.ToString(),
OffsetMax = rightTopOffset.ToString()
}
}, parent, name);
}
/// <summary>
/// Add a new button
/// </summary>
/// <param name="parent">The parent object name</param>
/// <param name="leftBottomAnchor">Left(x)-Bottom(y) relative position</param>
/// <param name="rightTopAnchor">Right(x)-Top(y) relative position</param>
/// <param name="buttonColor">Button background color</param>
/// <param name="textColor">Text color</param>
/// <param name="text">Text to show</param>
/// <param name="command">OnClick event callback command</param>
/// <param name="close">Panel to close</param>
/// <param name="name">The object's name</param>
/// <param name="fontSize">Font size</param>
/// <param name="align">Text alignment</param>
/// <returns>New object name</returns>
public string AddButton(string parent, CuiPoint leftBottomAnchor, CuiPoint rightTopAnchor, CuiColor buttonColor, CuiColor textColor, string text,
string command = "", string close = "", string name = null, int fontSize = 14, TextAnchor align = TextAnchor.MiddleCenter) =>
AddButton(parent, leftBottomAnchor, rightTopAnchor, new CuiPoint(), new CuiPoint(), buttonColor, textColor, text, command, close, name,
fontSize, align);
/// <summary>
/// Add a new button
/// </summary>
/// <param name="parent">The parent object name</param>
/// <param name="leftBottomAnchor">Left(x)-Bottom(y) relative position</param>
/// <param name="rightTopAnchor">Right(x)-Top(y) relative position</param>
/// <param name="leftBottomOffset">Left(x)-Bottom(y) relative offset</param>
/// <param name="rightTopOffset">Right(x)-Top(y) relative offset</param>
/// <param name="buttonColor">Button background color</param>
/// <param name="textColor">Text color</param>
/// <param name="text">Text to show</param>
/// <param name="command">OnClick event callback command</param>
/// <param name="close">Panel to close</param>
/// <param name="name">The object's name</param>
/// <param name="fontSize">Font size</param>
/// <param name="align">Text alignment</param>
/// <returns>New object name</returns>
public string AddButton(string parent, CuiPoint leftBottomAnchor, CuiPoint rightTopAnchor, CuiPoint leftBottomOffset, CuiPoint rightTopOffset,
CuiColor buttonColor, CuiColor textColor, string text, string command = "", string close = "", string name = null,
int fontSize = 14, TextAnchor align = TextAnchor.MiddleCenter)
{
return container.Add(new CuiButton() {
Button = {
Command = command ?? "",
Close = close ?? "",
Color = buttonColor.ToString()
},
RectTransform = {
AnchorMin = leftBottomAnchor.ToString(),
AnchorMax = rightTopAnchor.ToString(),
OffsetMin = leftBottomOffset.ToString(),
OffsetMax = rightTopOffset.ToString()
},
Text = {
Text = text ?? "",
FontSize = fontSize,
Align = align,
Color = textColor.ToString()
}
}, parent, name);
}
/// <summary>
/// Add a new input field
/// </summary>
/// <param name="parent">The parent object name</param>
/// <param name="leftBottomAnchor">Left(x)-Bottom(y) relative position</param>
/// <param name="rightTopAnchor">Right(x)-Top(y) relative position</param>
/// <param name="color">Text color</param>
/// <param name="text">Text to show</param>
/// <param name="charsLimit">Max character count</param>
/// <param name="command">OnChanged event callback command</param>
/// <param name="isPassword">Indicates that this input should show password chars</param>
/// <param name="name">The object's name</param>
/// <param name="fontSize">Font size</param>
/// <param name="align">Text alignment</param>
/// <returns>New object name</returns>
public string AddInputField(string parent, CuiPoint leftBottomAnchor, CuiPoint rightTopAnchor, CuiColor color, string text = "",
int charsLimit = 100, string command = "", bool isPassword = false, string name = null, int fontSize = 14,
TextAnchor align = TextAnchor.MiddleLeft) =>
AddInputField(parent, leftBottomAnchor, rightTopAnchor, new CuiPoint(), new CuiPoint(), color, text, charsLimit, command, isPassword, name,
fontSize, align);
/// <summary>
/// Add a new input field
/// </summary>
/// <param name="parent">The parent object name</param>
/// <param name="leftBottomAnchor">Left(x)-Bottom(y) relative position</param>
/// <param name="rightTopAnchor">Right(x)-Top(y) relative position</param>
/// <param name="leftBottomOffset">Left(x)-Bottom(y) relative offset</param>
/// <param name="rightTopOffset">Right(x)-Top(y) relative offset</param>
/// <param name="fadeOut">Fade-out time</param>
/// <param name="color">Text color</param>
/// <param name="text">Text to show</param>
/// <param name="charsLimit">Max character count</param>
/// <param name="command">OnChanged event callback command</param>
/// <param name="isPassword">Indicates that this input should show password chars</param>
/// <param name="name">The object's name</param>
/// <param name="fontSize">Font size</param>
/// <returns>New object name</returns>
public string AddInputField(string parent, CuiPoint leftBottomAnchor, CuiPoint rightTopAnchor, CuiPoint leftBottomOffset, CuiPoint rightTopOffset,
CuiColor color, string text = "", int charsLimit = 100, string command = "", bool isPassword = false,
string name = null, int fontSize = 14, TextAnchor align = TextAnchor.MiddleLeft)
{
return container.Add(new CuiInputField() {
InputField = {
Text = text ?? "",
FontSize = fontSize,
Align = align,
Color = color.ToString(),
CharsLimit = charsLimit,
Command = command ?? "",
IsPassword = isPassword
},
RectTransform = {
AnchorMin = leftBottomAnchor.ToString(),
AnchorMax = rightTopAnchor.ToString(),
OffsetMin = leftBottomOffset.ToString(),
OffsetMax = rightTopOffset.ToString()
}
}, parent, name);
}
/// <summary>
/// Draw the UI to the player's client
/// </summary>
/// <returns></returns>
public bool Draw()
{
if (!string.IsNullOrEmpty(MainPanelName))
return CuiHelper.AddUi(player, container);
return false;
}
/// <summary>
/// Retrieve the userId of the player this GUI is intended for
/// </summary>
/// <returns>Player ID</returns>
public string GetPlayerId() => player.UserIDString;
}
#endregion GUI
#region Utility methods
/// <summary>
/// Get a "page" of entities from a specified list
/// </summary>
/// <param name="aList">List of entities</param>
/// <param name="aPage">Page number (Starting from 0)</param>
/// <param name="aPageSize">Page size</param>
/// <returns>List of entities</returns>
List<T> GetPage<T>(IList<T> aList, int aPage, int aPageSize) => aList.Skip(aPage * aPageSize).Take(aPageSize).ToList();
/// <summary>
/// Add a button to the tab menu
/// </summary>
/// <param name="aUIObj">Cui object</param>
/// <param name="aParent">Name of the parent object</param>
/// <param name="aCaption">Text to show</param>
/// <param name="aCommand">Button to execute</param>
/// <param name="aPos">Bounds of the button</param>
/// <param name="aIndActive">To indicate whether or not the button is active</param>
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 ? CuiDefaultColors.ButtonInactive : CuiDefaultColors.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, CuiDefaultColors.TextAlt, aCaption, (aIndActive ? "" : aCommand));
}
/// <summary>
/// Add a set of user buttons to the parent object
/// </summary>
/// <param name="aUIObj">Cui object</param>
/// <param name="aParent">Name of the parent object</param>
/// <param name="aUserList">List of entities</param>
/// <param name="aCommandFmt">Base format of the command to execute (Will be completed with the user ID</param>
/// <param name="aPage">User list page</param>
private void AddPlayerButtons<T>(ref Cui aUIObj, string aParent, ref List<T> aUserList, string aCommandFmt, int aPage)
{
List<T> userRange = GetPage(aUserList, aPage, MAX_PLAYER_BUTTONS);
Vector2 dimensions = new Vector2(0.194f, 0.09f);
Vector2 offset = new Vector2(0.005f, 0.01f);
int col = -1;
int row = 0;
float margin = 0.12f;
foreach (T user in userRange) {
if (++col >= MAX_PLAYER_COLS) {
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);
if (typeof(T) == typeof(BasePlayer)) {
string btnText = (user as BasePlayer).displayName;
string btnCommand = string.Format(aCommandFmt, (user as BasePlayer).UserIDString);
aUIObj.AddButton(aParent, LBAnchor, RTAnchor, CuiDefaultColors.Button, CuiDefaultColors.TextAlt, btnText, btnCommand, "", "", 16);
} else {
string btnText = (user as ServerUsers.User).username;
string btnCommand = string.Format(aCommandFmt, (user as ServerUsers.User).steamid);
if (string.IsNullOrEmpty(btnText) || UNKNOWN_NAME_LIST.Contains(btnText.ToLower()))
btnText = (user as ServerUsers.User).steamid.ToString();
aUIObj.AddButton(aParent, LBAnchor, RTAnchor, CuiDefaultColors.Button, CuiDefaultColors.TextAlt, btnText, btnCommand, "", "", 16);
}
};
}
/// <summary>
/// Get translated message for the specified key
/// </summary>
/// <param name="aKey">Message key</param>
/// <param name="aPlayerId">Player ID</param>
/// <param name="args">Optional args</param>
/// <returns></returns>
private string _(string aKey, string aPlayerId, params object[] args) => string.Format(lang.GetMessage(aKey, this, aPlayerId), args);
/// <summary>
/// Log an error message to the logfile
/// </summary>
/// <param name="aMessage"></param>
private void LogError(string aMessage) => LogToFile("", $"[{DateTime.Now.ToString("hh:mm:ss")}] ERROR > {aMessage}", this);
/// <summary>
/// Log an informational message to the logfile
/// </summary>
/// <param name="aMessage"></param>
private void LogInfo(string aMessage) => LogToFile("", $"[{DateTime.Now.ToString("hh:mm:ss")}] INFO > {aMessage}", this);
/// <summary>
/// Send a message to a specific player
/// </summary>
/// <param name="aPlayer">The player to send the message to</param>
/// <param name="aMessage">The message to send</param>
private void SendMessage(ref BasePlayer aPlayer, string aMessage) => rust.SendChatMessage(aPlayer, "", aMessage);
/// <summary>
/// Verify if a user has the specified permission
/// </summary>
/// <param name="aPlayer">The player</param>
/// <param name="aPermission"></param>
/// <returns></returns>
private bool VerifyPermission(ref BasePlayer aPlayer, string aPermission)
{
if (permission.UserHasPermission(aPlayer.UserIDString, aPermission)) // User MUST have the required permission
return true;
SendMessage(ref aPlayer, _("Permission Error Text", aPlayer.UserIDString));
LogError(_("Permission Error Log Text", aPlayer.UserIDString, aPlayer.displayName, aPermission));
return false;
}
/// <summary>
/// Retrieve server users
/// </summary>
/// <param name="aIndOffline">Retrieve the list of sleepers (offline players)</param>
/// <returns></returns>
private List<BasePlayer> GetServerUserList(bool aIndOffline = false)
{
List<BasePlayer> result = new List<BasePlayer>();
if (!aIndOffline) {
Player.Players.ForEach(user => {
ServerUsers.User servUser = ServerUsers.Get(user.userID);
if (servUser == null || servUser?.group != ServerUsers.UserGroup.Banned)
result.Add(user);
});
} else {
Player.Sleepers.ForEach(user => {
ServerUsers.User servUser = ServerUsers.Get(user.userID);
if (servUser == null || servUser?.group != ServerUsers.UserGroup.Banned)
result.Add(user);
});
}
return result;
}
/// <summary>
/// Retrieve server users
/// </summary>
/// <returns></returns>
private List<ServerUsers.User> GetBannedUserList() => ServerUsers.GetAll(ServerUsers.UserGroup.Banned).ToList();
/// <summary>
/// Retrieve the target player ID from the arguments and report success
/// </summary>
/// <param name="aArg">Argument object</param>
/// <param name="aTarget">Player ID</param>
/// <returns></returns>
private bool GetTargetFromArg(ref ConsoleSystem.Arg aArg, out ulong aTarget)
{
aTarget = 0;
if (!aArg.HasArgs() || !ulong.TryParse(aArg.Args[0], out aTarget))
return false;
return true;
}
/// <summary>
/// Retrieve the target player ID and amount from the arguments and report success
/// </summary>
/// <param name="aArg">Argument object</param>
/// <param name="aTarget">Player ID</param>
/// <param name="aAmount">Amount</param>
/// <returns></returns>
private bool GetTargetAmountFromArg(ref ConsoleSystem.Arg aArg, out ulong aTarget, out float aAmount)
{
aTarget = 0;
aAmount = 0;
if (!aArg.HasArgs(2) || !ulong.TryParse(aArg.Args[0], out aTarget) || !float.TryParse(aArg.Args[1], out aAmount))
return false;
return true;
}
#endregion Utility methods
#region GUI build methods
/// <summary>
/// Build the tab nav-bar
/// </summary>
/// <param name="aUIObj">Cui object</param>
/// <param name="aPageType">The active page type</param>
private void BuildTabMenu(ref Cui aUIObj, UiPage aPageType)
{
string uiUserId = aUIObj.GetPlayerId();
// Add the panels and title label
string headerPanel = aUIObj.AddPanel(aUIObj.MainPanelName, TabMenuHeaderContainerLBAnchor, TabMenuHeaderContainerRTAnchor, false,
CuiDefaultColors.None);
string tabBtnPanel = aUIObj.AddPanel(aUIObj.MainPanelName, TabMenuTabBtnContainerLBAnchor, TabMenuTabBtnContainerRTAnchor, false,
CuiDefaultColors.Background);
aUIObj.AddLabel(headerPanel, TabMenuHeaderLblLBAnchor, TabMenuHeaderLblRTAnchor, CuiDefaultColors.TextTitle,
"Player Administration by ThibmoRozier", "", 22, TextAnchor.MiddleCenter);
aUIObj.AddButton(headerPanel, TabMenuCloseBtnLBAnchor, TabMenuCloseBtnRTAnchor, CuiDefaultColors.ButtonDecline, CuiDefaultColors.TextAlt, "X",
"padm_closeui", "", null, 22);
// Add the tab menu buttons
AddTabMenuBtn(ref aUIObj, tabBtnPanel, _("Main Tab Text", uiUserId), "padm_switchui Main", 0, (aPageType == UiPage.Main ? true : false));
AddTabMenuBtn(ref aUIObj, tabBtnPanel, _("Online Player Tab Text", uiUserId), "padm_switchui PlayersOnline 0", 1,
(aPageType == UiPage.PlayersOnline ? true : false));
AddTabMenuBtn(ref aUIObj, tabBtnPanel, _("Offline Player Tab Text", uiUserId), "padm_switchui PlayersOffline 0", 2,
(aPageType == UiPage.PlayersOffline ? true : false));
AddTabMenuBtn(ref aUIObj, tabBtnPanel, _("Banned Player Tab Text", uiUserId), "padm_switchui PlayersBanned 0", 3,
(aPageType == UiPage.PlayersBanned ? true : false));
}
/// <summary>
/// Build the main-menu
/// </summary>
/// <param name="aUIObj">Cui object</param>
private void BuildMainPage(ref Cui aUIObj)
{
string uiUserId = aUIObj.GetPlayerId();
// Add the panels and title
string panel = aUIObj.AddPanel(aUIObj.MainPanelName, MainPagePanelLBAnchor, MainPagePanelRTAnchor, false, CuiDefaultColors.Background);
aUIObj.AddLabel(panel, MainPageLblTitleLBAnchor, MainPageLblTitleRTAnchor, CuiDefaultColors.TextAlt, "Main", "", 18, TextAnchor.MiddleLeft);
// Add the ban by ID group
aUIObj.AddLabel(panel, MainPageLblBanByIdTitleLBAnchor, MainPageLblBanByIdTitleRTAnchor, CuiDefaultColors.TextTitle,
_("Ban By ID Title Text", uiUserId), null, 16, TextAnchor.MiddleLeft);
aUIObj.AddLabel(panel, MainPageLblBanByIdLBAnchor, MainPageLblBanByIdRTAnchor, CuiDefaultColors.TextAlt, _("Ban By ID Label Text", uiUserId), null,
14, TextAnchor.MiddleLeft);
string panelBanByIdGroup = aUIObj.AddPanel(panel, MainPagePanelBanByIdLBAnchor, MainPagePanelBanByIdRTAnchor, false, CuiDefaultColors.BackgroundDark);
aUIObj.AddInputField(panelBanByIdGroup, MainPageEdtBanByIdLBAnchor, MainPageEdtBanByIdRTAnchor, CuiDefaultColors.TextAlt, null, 24,
"padm_mainpagebanidinputtext");
if (configData.EnableBan) {
aUIObj.AddButton(panel, MainPageBtnBanByIdLBAnchor, MainPageBtnBanByIdRTAnchor, CuiDefaultColors.Button, CuiDefaultColors.TextAlt, "Ban",
"padm_mainpagebanbyid");
} else {
aUIObj.AddButton(panel, MainPageBtnBanByIdLBAnchor, MainPageBtnBanByIdRTAnchor, CuiDefaultColors.ButtonInactive, CuiDefaultColors.TextAlt, "Ban");
}
}
/// <summary>
/// Build a page of user buttons
/// </summary>
/// <param name="aUIObj">Cui object</param>
/// <param name="aPageType">The active page type</param>
/// <param name="aPage">User list page</param>
private void BuildUserBtnPage(ref Cui aUIObj, UiPage aPageType, int aPage)
{
string pageLabel = _("User Button Page Title Text", aUIObj.GetPlayerId());
string npBtnCommandFmt;
int userCount;
string panel = aUIObj.AddPanel(aUIObj.MainPanelName, UserBtnPanelLBAnchor, UserBtnPanelRTAnchor, false, CuiDefaultColors.Background);
aUIObj.AddLabel(panel, UserBtnLblLBAnchor, UserBtnLblRTAnchor, CuiDefaultColors.TextAlt, pageLabel, "", 18, TextAnchor.MiddleLeft);
if (aPageType == UiPage.PlayersOnline || aPageType == UiPage.PlayersOffline) {
BuildUserButtons(ref aUIObj, panel, aPageType, ref aPage, out npBtnCommandFmt, out userCount);
} else {
BuildBannedUserButtons(ref aUIObj, panel, ref aPage, out npBtnCommandFmt, out userCount);
}
// Decide whether or not to activate the "previous" button
if (aPage == 0) {
aUIObj.AddButton(panel, UserBtnPreviousBtnLBAnchor, UserBtnPreviousBtnRTAnchor, CuiDefaultColors.ButtonInactive, CuiDefaultColors.TextAlt, "<<",
"", "", "", 18);
} else {
aUIObj.AddButton(panel, UserBtnPreviousBtnLBAnchor, UserBtnPreviousBtnRTAnchor, CuiDefaultColors.Button, CuiDefaultColors.TextAlt, "<<",
string.Format(npBtnCommandFmt, aPage - 1), "", "", 18);
};
// Decide whether or not to activate the "next" button
if (userCount > MAX_PLAYER_BUTTONS * (aPage + 1)) {
aUIObj.AddButton(panel, UserBtnNextBtnLBAnchor, UserBtnNextBtnRTAnchor, CuiDefaultColors.Button, CuiDefaultColors.TextAlt, ">>",
string.Format(npBtnCommandFmt, aPage + 1), "", "", 18);
} else {
aUIObj.AddButton(panel, UserBtnNextBtnLBAnchor, UserBtnNextBtnRTAnchor, CuiDefaultColors.ButtonInactive, CuiDefaultColors.TextAlt, ">>", "", "",
"", 18);
};
}
/// <summary>
/// Build the current user buttons
/// </summary>
/// <param name="aUIObj">Cui object</param>
/// <param name="aParent">The active page type</param>
/// <param name="aPageType">The active page type</param>
/// <param name="aPage">User list page</param>
/// <param name="aBtnCommandFmt">Command format for the buttons</param>
/// <param name="aUserCount">Total user count</param>
private void BuildUserButtons(ref Cui aUIObj, string aParent, UiPage aPageType, ref int aPage, out string aBtnCommandFmt, out int aUserCount)
{
string commandFmt = "padm_switchui PlayerPage {0}";
List<BasePlayer> userList;
if (aPageType == UiPage.PlayersOnline) {
userList = GetServerUserList();
aBtnCommandFmt = "padm_switchui PlayersOnline {0}";
} else {
userList = GetServerUserList(true);
aBtnCommandFmt = "padm_switchui PlayersOffline {0}";
}
aUserCount = userList.Count;
if ((aPage != 0) && (userList.Count <= MAX_PLAYER_BUTTONS))
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);
}
/// <summary>
/// Build the banned user buttons
/// </summary>
/// <param name="aUIObj">Cui object</param>
/// <param name="aParent">The active page type</param>
/// <param name="aPage">User list page</param>
/// <param name="aBtnCommandFmt">Command format for the buttons</param>
/// <param name="aUserCount">Total user count</param>
private void BuildBannedUserButtons(ref Cui aUIObj, string aParent, ref int aPage, out string aBtnCommandFmt, out int aUserCount)
{
string commandFmt = "padm_switchui PlayerPageBanned {0}";
List<ServerUsers.User> userList = GetBannedUserList();
aBtnCommandFmt = "padm_switchui PlayersBanned {0}";
aUserCount = userList.Count;
if ((aPage != 0) && (userList.Count <= MAX_PLAYER_BUTTONS))
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);
}
/// <summary>
/// Build the user information and administration page
/// </summary>
/// <param name="aUIObj">Cui object</param>
/// <param name="aPageType">The active page type</param>
/// <param name="aPlayerId">Player ID (SteamId64)</param>
private void BuildUserPage(ref Cui aUIObj, UiPage aPageType, ulong aPlayerId)
{
string uiUserId = aUIObj.GetPlayerId();
// Add panels
string panel = aUIObj.AddPanel(aUIObj.MainPanelName, UserPagePanelLBAnchor, UserPagePanelRTAnchor, false, CuiDefaultColors.Background);
string infoPanel = aUIObj.AddPanel(panel, UserPageInfoPanelLBAnchor, UserPageInfoPanelRTAnchor, false, CuiDefaultColors.BackgroundMedium);
string actionPanel = aUIObj.AddPanel(panel, UserPageActionPanelLBAnchor, UserPageActionPanelRTAnchor, false, CuiDefaultColors.BackgroundMedium);
// Add title labels
aUIObj.AddLabel(infoPanel, UserPageLblinfoTitleLBAnchor, UserPageLblinfoTitleRTAnchor, CuiDefaultColors.TextTitle,
_("Player Info Label Text", uiUserId), "", 14, TextAnchor.MiddleLeft);
aUIObj.AddLabel(actionPanel, UserPageLblActionTitleLBAnchor, UserPageLblActionTitleRTAnchor, CuiDefaultColors.TextTitle,
_("Player Actions Label Text", uiUserId), "", 14, TextAnchor.MiddleLeft);
if (aPageType == UiPage.PlayerPage) {
BasePlayer player = BasePlayer.FindByID(aPlayerId) ?? BasePlayer.FindSleeping(aPlayerId);
bool playerConnected = player.IsConnected;
string lastCheatStr = _("Never Label Text", uiUserId);
string authLevel = ServerUsers.Get(aPlayerId)?.group.ToString() ?? "None";
// Pre-calc last admin cheat
if (player.lastAdminCheatTime != 0f) {
TimeSpan lastCheatSinceStart = new TimeSpan(0, 0, (int)(Time.realtimeSinceStartup - player.lastAdminCheatTime));
DateTime lastCheat = DateTime.UtcNow.Subtract(lastCheatSinceStart);
lastCheatStr = $"{lastCheat.ToString(@"yyyy\/MM\/dd HH:mm:ss")} UTC";
};
aUIObj.AddLabel(panel, UserPageLblLBAnchor, UserPageLblRTAnchor, CuiDefaultColors.TextAlt,
_("User Page Title Format", uiUserId, player.displayName, ""), "", 18, TextAnchor.MiddleLeft);
// Add user info labels
aUIObj.AddLabel(infoPanel, UserPageLblIdLBAnchor, UserPageLblIdRTAnchor, CuiDefaultColors.TextAlt, _("Id Label Format", uiUserId, aPlayerId,
(player.IsDeveloper ? _("Dev Label Text", uiUserId) : "")), "", 14, TextAnchor.MiddleLeft);
aUIObj.AddLabel(infoPanel, UserPageLblAuthLBAnchor, UserPageLblAuthRTAnchor, CuiDefaultColors.TextAlt,
_("Auth Level Label Format", uiUserId, authLevel), "", 14, TextAnchor.MiddleLeft);
aUIObj.AddLabel(infoPanel, UserPageLblConnectLBAnchor, UserPageLblConnectRTAnchor, CuiDefaultColors.TextAlt,
_("Connection Label Format", uiUserId, (
playerConnected ? _("Connected Label Text", uiUserId)
: _("Disconnected Label Text", uiUserId))
), "", 14, TextAnchor.MiddleLeft);
aUIObj.AddLabel(infoPanel, UserPageLblSleepLBAnchor, UserPageLblSleepRTAnchor, CuiDefaultColors.TextAlt, _("Status Label Format", uiUserId, (
player.IsSleeping() ? _("Sleeping Label Text", uiUserId)
: _("Awake Label Text", uiUserId)
), (
player.IsAlive() ? _("Alive Label Text", uiUserId)
: _("Dead Label Text", uiUserId))
), "", 14, TextAnchor.MiddleLeft);
aUIObj.AddLabel(infoPanel, UserPageLblFlagLBAnchor, UserPageLblFlagRTAnchor, CuiDefaultColors.TextAlt, _("Flags Label Format", uiUserId,
(player.IsFlying ? _("Flying Label Text", uiUserId) : ""),
(player.isMounted ? _("Mounted Label Text", uiUserId) : "")
), "", 14, TextAnchor.MiddleLeft);
aUIObj.AddLabel(infoPanel, UserPageLblPosLBAnchor, UserPageLblPosRTAnchor, CuiDefaultColors.TextAlt,
_("Position Label Format", uiUserId, player.ServerPosition), "", 14, TextAnchor.MiddleLeft);
aUIObj.AddLabel(infoPanel, UserPageLblRotLBAnchor, UserPageLblRotRTAnchor, CuiDefaultColors.TextAlt,
_("Rotation Label Format", uiUserId, player.GetNetworkRotation()), "", 14, TextAnchor.MiddleLeft);
aUIObj.AddLabel(infoPanel, UserPageLblAdminCheatLBAnchor, UserPageLblAdminCheatRTAnchor, CuiDefaultColors.TextAlt,
_("Last Admin Cheat Label Format", uiUserId, lastCheatStr), "", 14, TextAnchor.MiddleLeft);
aUIObj.AddLabel(infoPanel, UserPageLblIdleLBAnchor, UserPageLblIdleRTAnchor, CuiDefaultColors.TextAlt,
_("Idle Time Label Format", uiUserId, Convert.ToInt32(player.IdleTime)), "", 14, TextAnchor.MiddleLeft);
aUIObj.AddLabel(infoPanel, UserPageLblHealthLBAnchor, UserPageLblHealthRTAnchor, CuiDefaultColors.TextAlt,
_("Health Label Format", uiUserId, player.health), "", 14, TextAnchor.MiddleLeft);
aUIObj.AddLabel(infoPanel, UserPageLblCalLBAnchor, UserPageLblCalRTAnchor, CuiDefaultColors.TextAlt,
_("Calories Label Format", uiUserId, player.metabolism?.calories?.value), "", 14, TextAnchor.MiddleLeft);
aUIObj.AddLabel(infoPanel, UserPageLblHydraLBAnchor, UserPageLblHydraRTAnchor, CuiDefaultColors.TextAlt,
_("Hydration Label Format", uiUserId, player.metabolism?.hydration?.value), "", 14, TextAnchor.MiddleLeft);
aUIObj.AddLabel(infoPanel, UserPageLblTempLBAnchor, UserPageLblTempRTAnchor, CuiDefaultColors.TextAlt,
_("Temp Label Format", uiUserId, player.metabolism?.temperature?.value), "", 14, TextAnchor.MiddleLeft);
aUIObj.AddLabel(infoPanel, UserPageLblWetLBAnchor, UserPageLblWetRTAnchor, CuiDefaultColors.TextAlt,
_("Wetness Label Format", uiUserId, player.metabolism?.wetness?.value), "", 14, TextAnchor.MiddleLeft);
aUIObj.AddLabel(infoPanel, UserPageLblComfortLBAnchor, UserPageLblComfortRTAnchor, CuiDefaultColors.TextAlt,
_("Comfort Label Format", uiUserId, player.metabolism?.comfort?.value), "", 14, TextAnchor.MiddleLeft);
aUIObj.AddLabel(infoPanel, UserPageLblBleedLBAnchor, UserPageLblBleedRTAnchor, CuiDefaultColors.TextAlt,
_("Bleeding Label Format", uiUserId, player.metabolism?.bleeding?.value), "", 14, TextAnchor.MiddleLeft);
aUIObj.AddLabel(infoPanel, UserPageLblRads1LBAnchor, UserPageLblRads1RTAnchor, CuiDefaultColors.TextAlt,
_("Radiation Label Format", uiUserId, player.metabolism?.radiation_poison?.value), "", 14, TextAnchor.MiddleLeft);
aUIObj.AddLabel(infoPanel, UserPageLblRads2LBAnchor, UserPageLblRads2RTAnchor, CuiDefaultColors.TextAlt,
_("Radiation Protection Label Format", uiUserId, player.RadiationProtection()), "", 14, TextAnchor.MiddleLeft);
/* Build player action panel */
if (configData.EnableBan) {
aUIObj.AddButton(actionPanel, UserPageBtnBanLBAnchor, UserPageBtnBanRTAnchor, CuiDefaultColors.Button, CuiDefaultColors.TextAlt,
_("Ban Button Text", uiUserId), $"padm_banuser {aPlayerId}");
} else {
aUIObj.AddButton(actionPanel, UserPageBtnBanLBAnchor, UserPageBtnBanRTAnchor, CuiDefaultColors.ButtonInactive, CuiDefaultColors.Text,
_("Ban Button Text", uiUserId));
}
if (configData.EnableKill) {
aUIObj.AddButton(actionPanel, UserPageBtnKillLBAnchor, UserPageBtnKillRTAnchor, CuiDefaultColors.Button, CuiDefaultColors.TextAlt,
_("Kill Button Text", uiUserId), $"padm_killuser {aPlayerId}");
} else {
aUIObj.AddButton(actionPanel, UserPageBtnKillLBAnchor, UserPageBtnKillRTAnchor, CuiDefaultColors.ButtonInactive, CuiDefaultColors.Text,
_("Kill Button Text", uiUserId));
}
if (configData.EnableKick && playerConnected) {
aUIObj.AddButton(actionPanel, UserPageBtnKickLBAnchor, UserPageBtnKickRTAnchor, CuiDefaultColors.Button, CuiDefaultColors.TextAlt,
_("Kick Button Text", uiUserId), $"padm_kickuser {aPlayerId}");
} else {
aUIObj.AddButton(actionPanel, UserPageBtnKickLBAnchor, UserPageBtnKickRTAnchor, CuiDefaultColors.ButtonInactive, CuiDefaultColors.Text,
_("Kick Button Text", uiUserId));
};
// Add reset buttons
if (configData.EnableClearInv) {
aUIObj.AddButton(actionPanel, UserPageBtnClearInventoryLBAnchor, UserPageBtnClearInventoryRTAnchor, CuiDefaultColors.Button,
CuiDefaultColors.TextAlt, _("Clear Inventory Button Text", uiUserId), $"padm_clearuserinventory {aPlayerId}");
} else {
aUIObj.AddButton(actionPanel, UserPageBtnClearInventoryLBAnchor, UserPageBtnClearInventoryRTAnchor, CuiDefaultColors.ButtonInactive,
CuiDefaultColors.Text, _("Clear Inventory Button Text", uiUserId));
}
if (configData.EnableResetBP) {
aUIObj.AddButton(actionPanel, UserPageBtnResetBPLBAnchor, UserPageBtnResetBPRTAnchor, CuiDefaultColors.Button, CuiDefaultColors.TextAlt,
_("Reset Blueprints Button Text", uiUserId), $"padm_resetuserblueprints {aPlayerId}");
} else {
aUIObj.AddButton(actionPanel, UserPageBtnResetBPLBAnchor, UserPageBtnResetBPRTAnchor, CuiDefaultColors.ButtonInactive,
CuiDefaultColors.Text, _("Reset Blueprints Button Text", uiUserId));
}
if (configData.EnableResetMetabolism) {
aUIObj.AddButton(actionPanel, UserPageBtnResetMetabolismLBAnchor, UserPageBtnResetMetabolismRTAnchor, CuiDefaultColors.Button,
CuiDefaultColors.TextAlt, _("Reset Metabolism Button Text", uiUserId), $"padm_resetusermetabolism {aPlayerId}");
} else {
aUIObj.AddButton(actionPanel, UserPageBtnResetMetabolismLBAnchor, UserPageBtnResetMetabolismRTAnchor, CuiDefaultColors.ButtonInactive,
CuiDefaultColors.Text, _("Reset Metabolism Button Text", uiUserId));
}
// Add hurt buttons
if (configData.EnableHurt) {
aUIObj.
// ... [Code preview truncated due to length. Full source in attached file] ...