C#:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using UnityEngine;
namespace Oxide.Plugins {
[Info("Hud", "AhigaO#4485", "2.1.17")]
internal class Hud : RustPlugin {
#region Static
private const string Layer = "UI_Hud";
private const string PERM = "hud.use";
private Configuration _config;
private Data _data;
private List<string> CheckImages = new List<string>();
private List<string> OpenAditionalMenus = new List<string>();
private Dictionary<string, DisplayEvent> DisplayEvents = new Dictionary<string, DisplayEvent>();
private IEnumerator updateUICoroutine;
private TOD_Sky sky;
private bool isLeft;
private bool isTop;
private bool isBradley, isHelicopter, isCH47, isCargo, isAirDrop;
private int startPosX;
private bool grid;
private bool timeFormat;
private int active, sleeping, joining;
private float scale;
private float opacity;
private float Size;
private float Square;
[PluginReference]
private Plugin ImageLibrary, Economics, ServerRewards, Convoy, ArmoredTrain;
#region Classes
private class DisplayEvent {
public bool EntityDisplay;
public int PosX;
public DisplayEvent(bool entityDisplay, int posX) {
EntityDisplay = entityDisplay;
PosX = posX;
}
}
private class Configuration {
[JsonProperty(PropertyName = "Don't do Hud on top of everything")]
public bool Hide = true;
[JsonProperty(PropertyName = "Hud scale")]
public float ScaleC = 1;
[JsonProperty(PropertyName = "Hud transparency")]
public float OpacityC = 1;
[JsonProperty(PropertyName = "Name of your server")]
public string ServerName = "YOUR SERVER NAME";
[JsonProperty(PropertyName = "Server name color")]
public string ServerNameColor = "#B6FFFF";
[JsonProperty(PropertyName = "Hud position on the screen(Left or Right)")]
public string ScreenAngleX = "Left";
[JsonProperty(PropertyName = "Hud position on the screen(Top or Bottom)")]
public string ScreenAngleY = "Top";
[JsonProperty(PropertyName = "Offset from the top of the screen(in px)")]
public int MarginTop = 5;
[JsonProperty(PropertyName = "Offset from the right/left of the screen")]
public int MarginBorder = 10;
[JsonProperty(PropertyName = "Display active players when HUD is minimize")]
public bool DisplayActivePlayersMinimize = false;
[JsonProperty(PropertyName = "Display active players")]
public bool IsDisplayActivePlayers = true;
[JsonProperty(PropertyName = "Display offline players")]
public bool IsDisplayOfflinePlayers = true;
[JsonProperty(PropertyName = "Display players in queue")]
public bool IsDisplayQueuePLayers = true;
[JsonProperty(PropertyName = "Display Bradley")]
public bool IsDisplayBradley = true;
[JsonProperty(PropertyName = "Display Helicopter")]
public bool IsDisplayHelicopter = true;
[JsonProperty(PropertyName = "Display Big Helicopter (CH47)")]
public bool IsDisplayBigHelicopter = true;
[JsonProperty(PropertyName = "Display Cargo Ship")]
public bool IsDisplayCargo = true;
[JsonProperty(PropertyName = "Display AirDrop")]
public bool IsDisplayAirDrop = true;
[JsonProperty(PropertyName = "Use 12 hour format")]
public bool TimeFormat = false;
[JsonProperty(PropertyName = "Use the Economics plugin")]
public bool UseEconomics = false;
[JsonProperty(PropertyName = "User the Server Rewards plugin")]
public bool UseServerRewards = false;
[JsonProperty(PropertyName = "Use additional menu")]
public bool UseAdditionalMenu = true;
[JsonProperty(PropertyName = "Additional menu arrow color [HEX]")]
public string AdditionalMenuColor = "#ffff00";
[JsonProperty(PropertyName = "Auto minimize aditional menu timer (Set to 0 if you want to disable the function)")]
public int AditionalMenuMinimizeTimer = 10;
[JsonProperty(PropertyName = "Display player pos")]
public bool UsePlayerPos = false;
[JsonProperty(PropertyName = "If the figure in the player’s position is displayed not correctly change to True")]
public bool PlayerPosNum = false;
[JsonProperty(PropertyName = "Use grid pos system for player pos")]
public bool UseGrid = true;
[JsonProperty(PropertyName = "Offset from the left of the screen for text")]
public int MarginLeft = 0;
[JsonProperty(PropertyName = "Offset from the bottom of the screen for text")]
public int MarginBottom = 0;
[JsonProperty(PropertyName = "Interval between messages")]
public int Timer = 1800;
[JsonProperty(PropertyName = "Display info text")]
public bool UseInfoText = true;
[JsonProperty(PropertyName = "Disable aidrop after a cargo plane leaves")]
public bool AirdropRemove = false;
[JsonProperty(PropertyName = "Currency for the Economy plugin")]
public string Currency = "$";
}
private class Data {
public Dictionary<ulong, bool> Players = new Dictionary<ulong, bool>();
public List<Commands> CommandsList = new List<Commands>();
public List<InfoText> InfoList = new List<InfoText>();
public Dictionary<string, uint> Images = new Dictionary<string, uint>();
}
private class Commands {
public string Text;
public string Color;
public string Command;
public bool IsConsole;
}
private class InfoText {
public string Text = "Text";
public string Color = "#ffffff";
public int Size = 12;
}
#endregion
#region Image
private int ILCheck = 0;
private Dictionary<string, string> Images = new Dictionary<string, string>();
private void AddImage(string url) {
if (string.IsNullOrEmpty(url) || Images.ContainsKey(url)) return;
if (!ImageLibrary.Call<bool>("HasImage", url)) ImageLibrary.Call("AddImage", url, url);
timer.In(1f, () => Images.Add(url, ImageLibrary.Call<string>("GetImage", url)));
}
private string GetImage(string url) {
string image;
return Images.TryGetValue(url, out image) ? image : ImageLibrary.Call<string>("GetImage", url);
}
private void LoadImages() {
AddImage("https://i.imgur.com/uo5gMSz.png");
AddImage("https://i.imgur.com/Z0lMApg.png");
AddImage("https://i.imgur.com/IoVGwG7.png");
AddImage("https://i.imgur.com/qAiXjnk.png");
AddImage("https://i.imgur.com/u1ifv3O.png");
AddImage("https://i.imgur.com/wGOtMGr.png");
AddImage("https://i.imgur.com/dwF8AmR.png");
AddImage("https://i.imgur.com/6xbipyP.png");
AddImage("https://i.imgur.com/TfU4XTJ.png");
AddImage("https://i.imgur.com/FHoHYFx.png");
AddImage("https://i.imgur.com/FkOSMQB.png");
AddImage("https://i.imgur.com/DQinaJ9.png");
AddImage("https://i.imgur.com/7PamSLS.png");
AddImage("https://i.imgur.com/Gd83i83.png");
AddImage("https://i.imgur.com/zeNVJV3.png");
AddImage("https://i.imgur.com/DwjUUWt.png");
AddImage("https://i.imgur.com/93NwQiV.png");
AddImage("https://i.imgur.com/nPVBeaE.png");
}
#endregion
#region Config
protected override void LoadConfig() {
base.LoadConfig();
try {
_config = Config.ReadObject<Configuration>();
if (_config == null) throw new Exception();
SaveConfig();
}
catch {
PrintError("Your configuration file contains an error.Using default configuration values.");
LoadDefaultConfig();
}
}
protected override void SaveConfig() => Config.WriteObject(_config);
protected override void LoadDefaultConfig() => _config = new Configuration();
#endregion
#region Data
private void LoadData() => _data = Interface.Oxide.DataFileSystem.ExistsDatafile($"{Name}/data") ? Interface.Oxide.DataFileSystem.ReadObject<Data>($"{Name}/data") : new Data();
private void OnServerSave() => SaveData();
private void SaveData() {
if (_data != null) Interface.Oxide.DataFileSystem.WriteObject($"{Name}/data", _data);
}
#endregion
#endregion
#region OxideHooks
private void OnServerInitialized() {
if (!ImageLibrary) {
if (ILCheck == 3) {
PrintError("ImageLibrary not found!Unloading");
Interface.Oxide.UnloadPlugin(Name);
return;
}
timer.In(1, () => {
ILCheck++;
OnServerInitialized();
}
);
return;
}
LoadData();
LoadImages();
permission.RegisterPermission(PERM, this);
scale = _config.ScaleC;
grid = _config.UseGrid;
opacity = _config.OpacityC;
timeFormat = _config.TimeFormat;
isLeft = _config.ScreenAngleX == "Left";
isTop = _config.ScreenAngleY == "Top";
if (_config.UseEconomics && _config.UseServerRewards) {
_config.UseEconomics = false;
_config.UseServerRewards = false;
SaveConfig();
PrintError("You cannot use two balance plugins at the same time.Both options were disabled");
}
var size = ConVar.Server.worldsize;
Size = size / 2f;
Square = Mathf.Floor(size / 146.3f);
active = BasePlayer.activePlayerList.Count;
sleeping = BasePlayer.sleepingPlayerList.Count(x => x.userID.IsSteamId());
joining = ServerMgr.Instance.connectionQueue.Joining;
sky = TOD_Sky.Instance;
EventsInit();
timer.Once(2f, () => {
UpdateUIForAll();
updateUICoroutine = UpdateUI();
ServerMgr.Instance.StartCoroutine(updateUICoroutine);
timer.Every(_config.Timer, () => ShowUIInfoText());
}
);
}
private void Init() {
LoadData();
}
private void OnEntitySpawned(BradleyAPC entity) => timer.In(2f, () => {
if (entity == null || isBradley || updateUICoroutine == null || !IsVanilaBradley(entity)) return;
isBradley = true;
ShowUIBradleyState();
}
);
private void OnEntitySpawned(BaseHelicopter entity) => timer.In(2f, () => {
if (entity == null || isHelicopter || updateUICoroutine == null || (Convoy != null && HeliIsConvoy(entity))) return;
isHelicopter = true;
ShowUIHelicopterState();
}
);
private void OnEntitySpawned(CH47Helicopter entity) {
if (entity == null || isCH47 || updateUICoroutine == null) return;
isCH47 = true;
ShowUIBigHelicopterState();
}
private void OnEntitySpawned(CargoShip entity) {
if (entity == null || isCargo || updateUICoroutine == null) return;
isCargo = true;
ShowUICargoShipState();
}
private void OnEntitySpawned(SupplyDrop entity) {
if (entity == null || isAirDrop || updateUICoroutine == null) return;
isAirDrop = true;
ShowUIAirDropState();
}
private void OnEntityKill(BradleyAPC entity) {
if (entity == null || !isBradley || updateUICoroutine == null || !IsVanilaBradley(entity)) return;
isBradley = false;
ShowUIBradleyState();
}
private void OnEntityKill(BaseHelicopter entity) {
if (entity == null || !isHelicopter || updateUICoroutine == null || HeliIsConvoy(entity) || HeliIsArmoredTrain(entity)) return;
isHelicopter = false;
ShowUIHelicopterState();
}
private void OnEntityKill(CH47Helicopter entity) {
if (entity == null || !isCH47 || updateUICoroutine == null) return;
isCH47 = false;
ShowUIBigHelicopterState();
}
private void OnEntityKill(CargoShip entity) {
if (entity == null || !isCargo || updateUICoroutine == null) return;
isCargo = false;
ShowUICargoShipState();
}
private void OnEntityKill(CargoPlane entity) {
if (entity == null || !_config.AirdropRemove || updateUICoroutine == null) return;
NextTick(() => {
if (BaseNetworkable.serverEntities.OfType<CargoPlane>().Any()) return;
isAirDrop = false;
ShowUIAirDropState();
}
);
}
private void OnEntityKill(SupplyDrop entity) {
if (entity == null || _config.AirdropRemove || updateUICoroutine == null) return;
NextTick(() => {
if (!isAirDrop) return;
if (BaseNetworkable.serverEntities.OfType<SupplyDrop>().Any()) return;
isAirDrop = false;
ShowUIAirDropState();
}
);
}
private void OnPlayerConnected(BasePlayer player) {
if (player == null) return;
_data.Players.TryAdd(player.userID, true);
if (!_data.Players[player.userID]) {
ShowUIMiniPanelOpen(player);
return;
}
ShowUIMain(player);
NextTick(() => {
ShowUIPlayersActive();
ShowUIPlayersQueue();
if (_config.DisplayActivePlayersMinimize) ShowUIMiniPanelOpen();
}
);
}
private void OnPlayerSleep(BasePlayer player) => NextTick(() => ShowUIPlayersSleep());
private void OnPlayerSleepEnded(BasePlayer player) => NextTick(() => ShowUIPlayersSleep());
private void OnPlayerDisconnected(BasePlayer player) => NextTick(() => {
ShowUIPlayersActive();
if (_config.DisplayActivePlayersMinimize) ShowUIMiniPanelOpen();
}
);
private void OnUserApprove(Network.Connection connection) => NextTick(() => ShowUIPlayersQueue());
private void Unload() {
if (updateUICoroutine != null) {
ServerMgr.Instance.StopCoroutine(updateUICoroutine);
updateUICoroutine = null;
}
foreach (var check in BasePlayer.activePlayerList) CuiHelper.DestroyUi(check, Layer);
foreach (var check in BasePlayer.activePlayerList) CuiHelper.DestroyUi(check, Layer + ".bgS");
SaveData();
}
#endregion
#region Commands
[ConsoleCommand("UI_HD")]
private void cmdConsole(ConsoleSystem.Arg arg) {
if (!arg.HasArgs()) return;
var player = arg.Player();
switch (arg.GetString(0)) {
case "OPENADDITIONALMENU" : ShowUIAdditionalMenu(player);
CuiHelper.DestroyUi(player, Layer + ".btnOpen");
ShowUIAdditionalMenuClose(player);
OpenAditionalMenus.Add(player.UserIDString);
if (_config.AditionalMenuMinimizeTimer == 0) return;
timer.Once(_config.AditionalMenuMinimizeTimer, () => {
if (!OpenAditionalMenus.Contains(player.UserIDString)) return;
OpenAditionalMenus.Remove(player.UserIDString);
player.SendConsoleCommand("UI_HD CLOSEADDITIONALMENU");
}
);
break;
case "CLOSEADDITIONALMENU" : CuiHelper.DestroyUi(player, Layer + ".additionalMenu");
CuiHelper.DestroyUi(player, Layer + ".btnClose");
ShowUIAdditionalMenuOpen(player);
OpenAditionalMenus.Remove(player.UserIDString);
break;
case "CHTCOM" : player.SendConsoleCommand($"chat.say \"{string.Join(" ", arg.Args.Skip(1))}\"");
break;
case "SETSCALE" : if (arg.Args.Length < 2 || arg.GetFloat(1) < 0.1f || arg.GetFloat(1) > 2f) return;
_config.ScaleC = arg.GetFloat(1);
scale = _config.ScaleC;
SaveConfig();
UpdateUIForAll();
ShowUISetupPanel(player);
break;
case "SETOPACITY" : if (arg.Args.Length < 2 || arg.GetFloat(1) > 1) return;
_config.OpacityC = arg.GetFloat(1);
opacity = _config.OpacityC;
SaveConfig();
UpdateUIForAll();
ShowUISetupPanel(player);
break;
case "SETOFFSETTOP" : if (arg.Args.Length < 2) return;
_config.MarginTop = arg.GetInt(1);
SaveConfig();
UpdateUIForAll();
ShowUISetupPanel(player);
break;
case "SETOFFSETBORDER" : if (arg.Args.Length < 2) return;
_config.MarginBorder = arg.GetInt(1);
SaveConfig();
UpdateUIForAll();
ShowUISetupPanel(player);
break;
case "SETSERVERNAME" : if (arg.Args.Length < 2) return;
_config.ServerName = string.Join(" ", arg.Args.Skip(1));
SaveConfig();
UpdateUIForAll();
ShowUISetupPanel(player);
break;
case "SETOFFSETLEFT" : if (arg.Args.Length < 2) return;
_config.MarginLeft = arg.GetInt(1);
SaveConfig();
UpdateUIForAll();
ShowUISetupPanel(player);
break;
case "SETOFFSETBOTTOM" : if (arg.Args.Length < 2) return;
_config.MarginBottom = arg.GetInt(1);
SaveConfig();
UpdateUIForAll();
ShowUISetupPanel(player);
break;
case "SETTIMER" : if (arg.Args.Length < 2) return;
_config.Timer = arg.GetInt(1);
SaveConfig();
UpdateUIForAll();
ShowUISetupPanel(player);
break;
case "HUDPOSX" : if (_config.ScreenAngleX == "Left") {
_config.ScreenAngleX = "Right";
isLeft = false;
}
else {
_config.ScreenAngleX = "Left";
isLeft = true;
}
SaveConfig();
UpdateUIForAll();
ShowUISetupPanel(player);
break;
case "HUDPOSY" : if (_config.ScreenAngleY == "Top") {
_config.ScreenAngleY = "Bottom";
isTop = false;
}
else {
_config.ScreenAngleY = "Top";
isTop = true;
}
SaveConfig();
UpdateUIForAll();
ShowUISetupPanel(player);
break;
case "SETECONOMICS" : _config.UseEconomics = !_config.UseEconomics;
_config.UseServerRewards = false;
SaveConfig();
UpdateUIForAll();
ShowUISetupPanel(player);
break;
case "SETSERVERREWARDS" : _config.UseServerRewards = !_config.UseServerRewards;
_config.UseEconomics = false;
SaveConfig();
UpdateUIForAll();
ShowUISetupPanel(player);
break;
case "SETHIDE" : _config.Hide = !_config.Hide;
SaveConfig();
UpdateUIForAll();
ShowUISetupPanel(player);
break;
case "SETADDITIONALMENU" : _config.UseAdditionalMenu = !_config.UseAdditionalMenu;
SaveConfig();
UpdateUIForAll();
ShowUISetupPanel(player);
break;
case "SETUSEPLAYERPOS" : _config.UsePlayerPos = !_config.UsePlayerPos;
SaveConfig();
UpdateUIForAll();
ShowUISetupPanel(player);
break;
case "SETUSEGRID" : _config.UseGrid = !_config.UseGrid;
grid = _config.UseGrid;
SaveConfig();
UpdateUIForAll();
ShowUISetupPanel(player);
break;
case "SETUPAIRDROPREMOVE" : _config.AirdropRemove = !_config.AirdropRemove;
SaveConfig();
UpdateUIForAll();
ShowUISetupPanel(player);
break;
case "SETTIMEFORMAT" : _config.TimeFormat = !_config.TimeFormat;
timeFormat = _config.TimeFormat;
SaveConfig();
UpdateUIForAll();
ShowUISetupPanel(player);
break;
case "SETUSEINFOTEXT" : _config.UseInfoText = !_config.UseInfoText;
if (!_config.UseInfoText) foreach (var check in BasePlayer.activePlayerList) CuiHelper.DestroyUi(check, Layer + ".info");
SaveConfig();
UpdateUIForAll();
ShowUISetupPanel(player);
break;
case "ADDNEWCOMMAND" : ShowUIAddCommand(player, arg.GetInt(1));
break;
case "ADDNEWITEMINFOLIST" : _data.InfoList.Add(new InfoText());
ShowUIAddInfoList(player, arg.GetInt(1));
break;
case "CHANGEEXISTCOMMAND" : var chglist = arg.Args.ToList();
var chaColor = chglist.IndexOf("color");
var chaCommand = chglist.IndexOf("command");
var chaIsConsole = chglist.IndexOf("isConsole");
var chaName = chglist.IndexOf("name");
ShowUIAddCommand(player, arg.GetInt(1), true, HexToRustFormat(arg.GetString(chaColor + 1)) != "false" ? arg.GetString(chaColor + 1) : "#ffffff", string.Join(" ", chglist.Skip(chaCommand + 1).Take(chaIsConsole - (chaCommand + 1))), arg.GetBool(chaIsConsole + 1), string.Join(" ", chglist.Skip(chaName + 1)));
break;
case "CHANGEEXISTITEMTEXTINFO" : ShowUIAddInfoList(player, arg.GetInt(1), true);
break;
case "SETTEXTITEMINFO" : if (!arg.HasArgs(4)) return;
var indexText = arg.GetInt(1);
_data.InfoList[indexText].Text = string.Join(" ", arg.Args.Skip(3));
ShowUIAddInfoList(player, indexText);
break;
case "SETTEXTCOLORITEMINFO" : if (!arg.HasArgs(4)) return;
var indexColor = arg.GetInt(1);
_data.InfoList[indexColor].Color = HexToRustFormat(arg.GetString(3)) != "false" ? arg.GetString(3) : "#ffffff";
ShowUIAddInfoList(player, indexColor);
break;
case "SETFONTSIZEITEMINFO" : if (!arg.HasArgs(4)) return;
var indexSize = arg.GetInt(1);
_data.InfoList[indexSize].Size = arg.GetInt(3);
ShowUIAddInfoList(player, indexSize);
break;
case "SETBUTTONNAME" : var bnlist = arg.Args.ToList();
var bnaColor = bnlist.IndexOf("color");
var bnaCommand = bnlist.IndexOf("command");
var bnaIsConsole = bnlist.IndexOf("isConsole");
var bnaName = bnlist.IndexOf("name");
if (bnlist.Count > bnaName + 1) ShowUIAddCommand(player, arg.GetInt(1), arg.GetBool(2), HexToRustFormat(arg.GetString(bnaColor + 1)) != "false" ? arg.GetString(bnaColor + 1) : "#ffffff", string.Join(" ", bnlist.Skip(bnaCommand + 1).Take(bnaIsConsole - (bnaCommand + 1))), arg.GetBool(bnaIsConsole + 1), string.Join(" ", bnlist.Skip(bnaName + 1)));
break;
case "SETTEXTCOLOR" : var clist = arg.Args.ToList();
var caColor = clist.IndexOf("color");
var caCommand = clist.IndexOf("command");
var caIsConsole = clist.IndexOf("isConsole");
var caName = clist.IndexOf("name");
if (clist.Count > caColor + 1) ShowUIAddCommand(player, arg.GetInt(1), arg.GetBool(2), HexToRustFormat(arg.GetString(caColor + 1)) != "false" ? arg.GetString(caColor + 1) : "#ffffff", string.Join(" ", clist.Skip(caCommand + 1).Take(caIsConsole - (caCommand + 1))), arg.GetBool(caIsConsole + 1), string.Join(" ", clist.Skip(caName + 1).Take(caColor - (caName + 1))));
break;
case "SETCOMMAND" : var cmlist = arg.Args.ToList();
var cmaColor = cmlist.IndexOf("color");
var cmaCommand = cmlist.IndexOf("command");
var cmaIsConsole = cmlist.IndexOf("isConsole");
var cmaName = cmlist.IndexOf("name");
if (cmlist.Count > cmaCommand + 1) ShowUIAddCommand(player, arg.GetInt(1), arg.GetBool(2), HexToRustFormat(arg.GetString(cmaColor + 1)) != "false" ? arg.GetString(cmaColor + 1) : "#ffffff", string.Join(" ", cmlist.Skip(cmaCommand + 1)), arg.GetBool(cmaIsConsole + 1), string.Join(" ", cmlist.Skip(cmaName + 1).Take(cmaCommand - (cmaName + 1))));
break;
case "SETCONSOLE" : var cnlist = arg.Args.ToList();
var cnaColor = cnlist.IndexOf("color");
var cnaCommand = cnlist.IndexOf("command");
var cnaIsConsole = cnlist.IndexOf("isConsole");
var cnaName = cnlist.IndexOf("name");
if (cnlist.Count > cnaIsConsole + 1) ShowUIAddCommand(player, arg.GetInt(1), arg.GetBool(2), HexToRustFormat(arg.GetString(cnaColor + 1)) != "false" ? arg.GetString(cnaColor + 1) : "#ffffff", string.Join(" ", cnlist.Skip(cnaCommand + 1).Take(cnaIsConsole - (cnaCommand + 1))), !arg.GetBool(cnaIsConsole + 1), string.Join(" ", cnlist.Skip(cnaName + 1)));
break;
case "ADDTOCOMMANDSLIST" : var addlist = arg.Args.ToList();
var addaColor = addlist.IndexOf("color");
var addaCommand = addlist.IndexOf("command");
var addaIsConsole = addlist.IndexOf("isConsole");
var addaName = addlist.IndexOf("name");
if (arg.GetBool(2)) {
_data.CommandsList[arg.GetInt(1)] = new Commands() {
Text = string.Join(" ", addlist.Skip(addaName + 1)), Color = HexToRustFormat(arg.GetString(addaColor + 1)) != "false" ? arg.GetString(addaColor + 1) : "#ffffff", Command = string.Join(" ", addlist.Skip(addaCommand + 1).Take(addaIsConsole - (addaCommand + 1))), IsConsole = arg.GetBool(addaIsConsole + 1),
}
;
}
else {
_data.CommandsList.Add(new Commands() {
Text = string.Join(" ", addlist.Skip(addaName + 1)), Color = HexToRustFormat(arg.GetString(addaColor + 1)) != "false" ? arg.GetString(addaColor + 1) : "#ffffff", Command = string.Join(" ", addlist.Skip(addaCommand + 1).Take(addaIsConsole - (addaCommand + 1))), IsConsole = arg.GetBool(addaIsConsole + 1),
}
);
}
SaveData();
CuiHelper.DestroyUi(player, Layer + ".addcom");
ShowUISetup(player);
break;
case "ADDTOINFOLIST" : SaveData();
CuiHelper.DestroyUi(player, Layer + ".additeminfotext");
ShowUIInfoText(player);
ShowUISetup(player);
break;
case "CLOSEADDMENU" : if (arg.GetBool(2)) {
_data.CommandsList.Remove(_data.CommandsList[arg.GetInt(1)]);
ShowUIInfoText(player);
UpdateUIForAll();
}
CuiHelper.DestroyUi(player, Layer + ".addcom");
ShowUISetup(player);
break;
case "NEXTCOMMAND" : ShowUIAddAdditionalMenu(player, arg.GetInt(1));
break;
case "CLOSEINFOTEXTADDMENU" : if (arg.GetBool(2)) {
_data.InfoList.Remove(_data.InfoList[arg.GetInt(1)]);
ShowUISetupPanel(player);
UpdateUIForAll();
}
CuiHelper.DestroyUi(player, Layer + ".additeminfotext");
ShowUISetup(player);
break;
case "PAGES" : ShowUIAddItemInfoList(player, arg.GetInt(1));
break;
case "SETCOLOR" : _config.ServerNameColor = arg.GetString(1);
SaveConfig();
UpdateUIForAll();
ShowUISetupPanel(player);
break;
case "SETAUTOCLOSETIMER" : _config.AditionalMenuMinimizeTimer = arg.GetInt(1);
SaveConfig();
UpdateUIForAll();
ShowUISetupPanel(player);
break;
case "SETUPCURRENCY" : _config.Currency = arg.GetString(1);
SaveConfig();
UpdateUIForAll();
ShowUISetupPanel(player);
break;
case "SETBDISPLAYBRADLEY" : _config.IsDisplayBradley = !_config.IsDisplayBradley;
DisplayEvents["bradley"].EntityDisplay = _config.IsDisplayBradley;
SaveConfig();
EventsInit();
UpdateUIForAll();
ShowUISetupPanel(player);
break;
case "SETBDISPLAYHELICOPTER" : _config.IsDisplayHelicopter = !_config.IsDisplayHelicopter;
DisplayEvents["helicopter"].EntityDisplay = _config.IsDisplayHelicopter;
SaveConfig();
EventsInit();
UpdateUIForAll();
ShowUISetupPanel(player);
break;
case "SETBDISPLAYCH47" : _config.IsDisplayBigHelicopter = !_config.IsDisplayBigHelicopter;
DisplayEvents["ch47"].EntityDisplay = _config.IsDisplayBigHelicopter;
SaveConfig();
EventsInit();
UpdateUIForAll();
ShowUISetupPanel(player);
break;
case "SETBDISPLAYCARGO" : _config.IsDisplayCargo = !_config.IsDisplayCargo;
DisplayEvents["cargo"].EntityDisplay = _config.IsDisplayCargo;
SaveConfig();
EventsInit();
UpdateUIForAll();
ShowUISetupPanel(player);
break;
case "SETBDISPLAYAIRDROP" : _config.IsDisplayAirDrop = !_config.IsDisplayAirDrop;
DisplayEvents["airdrop"].EntityDisplay = _config.IsDisplayAirDrop;
SaveConfig();
EventsInit();
UpdateUIForAll();
ShowUISetupPanel(player);
break;
case "SETBDISPLAYACTIVEPLAYERS" : _config.IsDisplayActivePlayers = !_config.IsDisplayActivePlayers;
SaveConfig();
EventsInit();
UpdateUIForAll();
ShowUISetupPanel(player);
break;
case "SETACTIVEMINIMIZE" : _config.DisplayActivePlayersMinimize = !_config.DisplayActivePlayersMinimize;
SaveConfig();
EventsInit();
UpdateUIForAll();
ShowUISetupPanel(player);
break;
case "SETBDISPLAYOFFLINEPLAYERS" : _config.IsDisplayOfflinePlayers = !_config.IsDisplayOfflinePlayers;
SaveConfig();
EventsInit();
UpdateUIForAll();
ShowUISetupPanel(player);
break;
case "SETBDISPLAYQUEUEPLAYERS" : _config.IsDisplayQueuePLayers = !_config.IsDisplayQueuePLayers;
SaveConfig();
EventsInit();
UpdateUIForAll();
ShowUISetupPanel(player);
break;
}
}
[ConsoleCommand("UI_HUD")]
private void cmdConsoleUI_HUD(ConsoleSystem.Arg arg) {
var player = arg.Player();
if (player == null) return;
var userID = player.userID;
_data.Players.TryAdd(userID, false);
_data.Players[userID] = !_data.Players[userID];
if (_data.Players[userID]) {
ShowUIMain(player);
ShowUIInfoText(player);
}
else {
ShowUIMiniPanelOpen(player);
CuiHelper.DestroyUi(player, Layer + ".info");
}
}
[ChatCommand("h")]
private void cmdChat(BasePlayer player, string command, string[] args) {
if (player == null) return;
var isAdmin = player.IsAdmin || permission.UserHasPermission(player.UserIDString, PERM);
var text = "All commands:\n/h open th- open Server Hud UI\n/h close - close Server Hud UI\n/h hide - hide Server Hud UI" + (isAdmin ? "\n/h setup - Server Hud UI Settings" : "");
if (args.Length != 1) {
SendReply(player, text);
return;
}
switch (args[0]) {
case "open" : case "close" : player.SendConsoleCommand("UI_HUD");
break;
case "hide" : _data.Players[player.userID] = false;
CuiHelper.DestroyUi(player, Layer);
CuiHelper.DestroyUi(player, Layer + ".info");
break;
case "setup" : if (isAdmin) ShowUISetup(player);
else SendReply(player, text);
break;
default : SendReply(player, text);
break;
}
SaveData();
}
#endregion
#region Functions
private bool IsVanilaBradley(BaseNetworkable apc) {
var monumentInfo = TerrainMeta.Path.FindMonumentWithBoundsOverlap(apc.transform.position);
if (monumentInfo == null) return false;
if (!monumentInfo.displayPhrase.english.Contains("Launch Site")) return false;
var convoy = Convoy?.Call("IsConvoyVehicle", apc);
var armoredTrain = ArmoredTrain?.Call("IsTrainBradley", apc.net.ID);
if (convoy != null && (bool)convoy) return false;
if (armoredTrain != null && (bool)armoredTrain) return false;
return true;
}
private bool HeliIsArmoredTrain(BaseNetworkable entity) {
var armoredTrain = ArmoredTrain?.Call("IsTrainHeli", entity.net.ID);
if (armoredTrain != null) return (bool)armoredTrain;
return false;
}
private bool HeliIsConvoy(BaseNetworkable entity) {
var convoy = Convoy?.Call("IsConvoyHeli", entity);
if (convoy != null) return (bool)convoy;
return false;
}
private void EventsInit() {
foreach (var check in BaseNetworkable.serverEntities) {
if (check == null || check.IsDestroyed) continue;
if (_config.IsDisplayBradley && !isBradley && check is BradleyAPC) {
isBradley = IsVanilaBradley(check);
continue;
}
if (_config.IsDisplayHelicopter && !isHelicopter && check is BaseHelicopter) {
isHelicopter = true;
continue;
}
if (_config.IsDisplayBigHelicopter && !isCH47 && check is CH47Helicopter) {
if (Convoy == null) isCH47 = true;
else if (HeliIsConvoy(check)) isCH47 = true;
continue;
}
if (_config.IsDisplayCargo && !isCargo && check is CargoShip) {
isCargo = true;
continue;
}
if (!_config.IsDisplayAirDrop || (!_config.AirdropRemove || isAirDrop || !(check is CargoPlane)) && (_config.AirdropRemove || isAirDrop || !(check is SupplyDrop))) continue;
isAirDrop = true;
}
DisplayEvents.TryAdd("bradley", new DisplayEvent(_config.IsDisplayBradley, 0));
DisplayEvents.TryAdd("helicopter", new DisplayEvent(_config.IsDisplayBigHelicopter, (int) (46 * scale)));
DisplayEvents.TryAdd("ch47", new DisplayEvent(_config.IsDisplayBigHelicopter, (int) (92 * scale)));
DisplayEvents.TryAdd("cargo", new DisplayEvent(_config.IsDisplayCargo, (int) (138 * scale)));
DisplayEvents.TryAdd("airdrop", new DisplayEvent(_config.IsDisplayAirDrop, (int) (184 * scale)));
var posX = 0;
foreach (var check in DisplayEvents) {
if (!check.Value.EntityDisplay) continue;
check.Value.PosX = posX;
posX += 46;
}
startPosX = 19 * DisplayEvents.Count(x => x.Value.EntityDisplay == false);
}
private string GetGrid(Vector3 pos) {
var letter = 'A';
var xCoordinate = Mathf.Floor((pos.x + Size) / 146.3f);
var z = Square - Mathf.Floor((pos.z + Size) / 146.3f) - (_config.PlayerPosNum ? 0 : 1);
letter = (char) (letter + xCoordinate % 26);
return xCoordinate > 25 ? $"A{letter}{z}" : $"{letter}{z}";
}
private void UpdateUIForAll() {
foreach (var check in BasePlayer.activePlayerList) OnPlayerConnected(check);
}
private string HexToRustFormat(string hex) {
Color color;
return ColorUtility.TryParseHtmlString(hex, out color) ? $"{color.r:F2} {color.g:F2} {color.b:F2} {color.a:F2}" : "false";
}
private IEnumerator UpdateUI() {
while (updateUICoroutine != null) {
foreach (var check in BasePlayer.activePlayerList) {
if (!GetPlayerData(check.userID)) continue;
if (_config.UseEconomics || _config.UseServerRewards) ShowUIPanelMoney(check, GetBalance(check.userID));
if (_config.UsePlayerPos) ShowUIPlayerPos(check);
ShowUIServerTime(check);
}
yield return new WaitForSeconds(1f);
}
}
private bool GetPlayerData(ulong userID) {
bool isOpen;
if (_data.Players.TryGetValue(userID, out isOpen)) return isOpen;
_data.Players.TryAdd(userID, true);
return true;
}
private int GetBalance(ulong id) => !_config.UseEconomics ? !ServerRewards ? 0 : ServerRewards.Call<int>("CheckPoints", id) : !Economics ? 0 : (int) Economics.Call<double>("Balance", id);
#endregion
#region UI
#region Hud
private void ShowUIPlayerPos(BasePlayer player) {
var container = new CuiElementContainer();
var position = player.transform.position;
container.Add(new CuiElement {
Parent = Layer + ".pos", Name = Layer + ".possition", Components = {
new CuiTextComponent {
Text = isLeft ? grid ? GetGrid(player.transform.position) : $"X:{Math.Floor(position.x)}\nY:{Math.Floor(position.y)}\nZ:{Math.Floor(position.z)}" : grid ? GetGrid(player.transform.position) : $"{Math.Floor(position.x)}:X\n{Math.Floor(position.y)}:Y\n{Math.Floor(position.z)}:Z", Font = "robotocondensed-bold.ttf", FontSize = (int)(grid ? 20 * scale : 12 * scale), Align = isLeft ? grid ? TextAnchor.MiddleCenter : TextAnchor.MiddleLeft : grid ? TextAnchor.MiddleCenter : TextAnchor.MiddleRight, Color = "1 1 1 1"
}
, new CuiRectTransformComponent {
AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = isLeft ? grid ? "0 0" : $"{4 * scale} 0" : "0 0", OffsetMax = isLeft ? "0 0" : grid ? "0 0" : $"{-4 * scale} 0"
}
}
}
);
CuiHelper.DestroyUi(player, Layer + ".possition");
CuiHelper.AddUi(player, container);
}
private void ShowUIMiniPanelOpen(BasePlayer player = null) {
var container = new CuiElementContainer();
container.Add(new CuiElement {
Parent = _config.Hide ? "Hud" : "Overlay", Name = Layer, Components = {
new CuiRawImageComponent {
Png = GetImage("https://i.imgur.com/uo5gMSz.png"), Color = $"1 1 1 {opacity}"
}
, new CuiRectTransformComponent {
AnchorMin = $"{(isLeft ? 0 : 1)} {(isTop ? 1 : 0)}", AnchorMax = $"{(isLeft ? 0 : 1)} {(isTop ? 1 : 0)}", OffsetMin = $"{(isLeft ? -12 + _config.MarginBorder : -78 * scale - _config.MarginBorder)} {(isTop ? -78 * scale - _config.MarginTop : 54 * scale + _config.MarginTop)}", OffsetMax = $"{(isLeft ? 78 * scale + _config.MarginBorder : 10 - _config.MarginBorder)} {(isTop ? 10 * scale - _config.MarginTop : 142 * scale)}"
}
}
}
);
container.Add(new CuiButton {
RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 1"
}
, Button = {
Color = "0 0 0 0", Command = "UI_HUD"
}
, Text = {
Text = "", Font = "robotocondensed-bold.ttf", FontSize = (int) (15 * scale), Align = TextAnchor.MiddleCenter, Color = "1 1 1 1"
}
}
, Layer);
if (_config.DisplayActivePlayersMinimize) {
container.Add(new CuiElement {
Parent = Layer, Name = Layer + ".image", Components = {
new CuiRectTransformComponent {
AnchorMin = $"{(isLeft ? 1 : 0)} 1", AnchorMax = $"{(isLeft ? 1 : 0)} 1", OffsetMin = "-12 -55", OffsetMax = "8 -35"
}
, new CuiRawImageComponent {
Png = GetImage("https://i.imgur.com/DwjUUWt.png")
}
, new CuiOutlineComponent {
Color = "0 0 0 0.5", Distance = "1 -1"
}
,
}
,
}
);
active = BasePlayer.activePlayerList.Count;
container.Add(new CuiElement {
Parent = Layer, Name = Layer + ".label", Components = {
new CuiRectTransformComponent {
AnchorMin = $"{(isLeft ? 1 : 0)} 1", AnchorMax = $"{(isLeft ? 1 : 0)} 1", OffsetMin = $"{(isLeft ? 15 : -45)} -55", OffsetMax = $"{(isLeft ? 45 : -15)} -35"
}
, new CuiTextComponent {
Text = active.ToString(), FontSize = (int)(16 * scale), Color = "1 1 1 1", Align = isLeft ? TextAnchor.MiddleLeft : TextAnchor.MiddleRight, Font = "robotocondensed-regular.ttf",
}
, new CuiOutlineComponent {
Distance = "-0.5 -0.5", Color = "0 0 0 1"
}
,
}
,
}
);
}
if (player == null) {
foreach (var check in BasePlayer.activePlayerList) {
if (GetPlayerData(check.userID)) continue;
CuiHelper.DestroyUi(check, Layer);
CuiHelper.AddUi(check, container);
}
return;
}
CuiHelper.DestroyUi(player, Layer);
CuiHelper.AddUi(player, container);
}
private void ShowUIInfoText(BasePlayer player = null) {
if (_data.InfoList.Count == 0 || !_config.UseInfoText) return;
var container = new CuiElementContainer();
var item = _data.InfoList.GetRandom();
container.Add(new CuiElement {
Parent = "Hud", Name = Layer + ".info", Components = {
new CuiTextComponent {
Text = item.Text ?? "", FontSize = item.Size, Font = "robotocondensed-bold.ttf", Color = HexToRustFormat(item.Color), Align = TextAnchor.MiddleCenter
}
, new CuiRectTransformComponent {
AnchorMin = "0 0", AnchorMax = "0 0", OffsetMin = $"{_config.MarginLeft} {_config.MarginBottom}", OffsetMax = $"{_config.MarginLeft + 300} {_config.MarginBottom + 90}"
}
, new CuiOutlineComponent {
Color = "0 0 0 0.5", Distance = "1 -1"
}
,
}
}
);
if (player == null) {
foreach (var check in BasePlayer.activePlayerList) {
CuiHelper.DestroyUi(check, Layer + ".info");
CuiHelper.AddUi(check, container);
}
return;
}
CuiHelper.DestroyUi(player, Layer + ".info");
CuiHelper.AddUi(player, container);
}
private void ShowUIMain(BasePlayer player) {
var container = new CuiElementContainer();
container.Add(new CuiElement {
Parent = _config.Hide ? "Hud" : "Overlay", Name = Layer, Components = {
new CuiRawImageComponent {
Png = GetImage(isLeft ? _config.UseAdditionalMenu ? "https://i.imgur.com/FHoHYFx.png" : "https://i.imgur.com/DQinaJ9.png" : _config.UseAdditionalMenu ? "https://i.imgur.com/FkOSMQB.png" : "https://i.imgur.com/7PamSLS.png"), Color = $"1 1 1 {opacity}"
}
, new CuiRectTransformComponent {
AnchorMin = $"{(isLeft ? 0 : 1)} {(isTop ? 1 : 0)}", AnchorMax = $"{(isLeft ? 0 : 1)} {(isTop ? 1 : 0)}", OffsetMin = $"{(i
// ... [Code preview truncated due to length. Full source in attached file] ...