C#:
// Reference: 0Harmony
using Harmony;
using Network;
using Newtonsoft.Json;
using Oxide.Game.Rust.Cui;
using ProtoBuf;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using UnityEngine;
namespace Oxide.Plugins {
[Info("AdminMap", "0xF", "1.2")]
partial class AdminMap : RustPlugin {
#region Consts
const string PERMISSION_TO_USE = "adminmap.allow";
const BasePlayer.PlayerFlags MarkerAdminMap = (BasePlayer.PlayerFlags)536870912;
const BasePlayer.PlayerFlags TextAdminMap = unchecked((BasePlayer.PlayerFlags)(536870912 * 2));
const BasePlayer.PlayerFlags SleepersAdminMap = unchecked((BasePlayer.PlayerFlags)(536870912 / 2));
const BasePlayer.PlayerFlags CupboardsAdminMap = unchecked((BasePlayer.PlayerFlags)(536870912 / 4));
const BasePlayer.PlayerFlags MarkersWL = unchecked((BasePlayer.PlayerFlags)(536870912 * 4));
#endregion
#region Vars
private static HarmonyInstance harmonyInstance;
private static AdminMap Instance;
static MapMarkerGenericRadius scanarea;
#endregion
#region Hooks
void Init() {
Instance = this;
permission.RegisterPermission(PERMISSION_TO_USE, this);
foreach (var button in config.Buttons) if (button.Permission != string.Empty) permission.RegisterPermission($"adminmap.{button.Permission}", this);
}
void OnServerInitialized(bool initial) {
ServerMgr.Instance.StartCoroutine(this.Loop());
scanarea = GameManager.server.CreateEntity("assets/prefabs/tools/map/genericradiusmarker.prefab", Vector3.zero) as MapMarkerGenericRadius;
scanarea.enableSaving = false;
scanarea.radius = 0f;
scanarea.alpha = 0f;
scanarea.color1 = config.ScanArea.Color;
scanarea.Spawn();
}
void Loaded() {
harmonyInstance = HarmonyInstance.Create(this.Name);
harmonyInstance.Patch(AccessTools.Method(typeof(BasePlayer), "Server_RemovePointOfInterest"), new HarmonyMethod(GetType(), "Server_RemovePointOfInterest"));
harmonyInstance.Patch(AccessTools.Method(typeof(BasePlayer), "TeamUpdate"), new HarmonyMethod(GetType(), "TeamsBypass"));
harmonyInstance.Patch(AccessTools.Method(typeof(BasePlayer), "ClearTeam"), new HarmonyMethod(GetType(), "TeamsBypass"));
}
void Unload() {
harmonyInstance.UnpatchAll(this.Name);
foreach (var admin in BasePlayer.activePlayerList.Select(AdminsDatabase.Get).OfType<AdminsDatabase.AdminData>()) {
admin.SelectedPlayer = null;
admin.SelectedCupboard = null;
RestoreState(admin.currentPlayer);
}
scanarea.Kill();
}
object OnMapMarkerAdd(BasePlayer player, MapNote note) {
AdminsDatabase.AdminData adminData = AdminsDatabase.Get(player);
if (adminData != null && adminData.UsesAnyMap) {
if (player.serverInput.IsDown(BUTTON.DUCK)) {
player.Teleport(GetGroundPosition(note.worldPosition));
}
else {
adminData.SelectedPlayer = null;
adminData.SelectedCupboard = null;
if (!adminData.currentPlayer.HasPlayerFlag(CupboardsAdminMap)) {
adminData.scannerMarker = note;
SendMapData();
SendLocalMarkerUpdate(player, scanarea, note.worldPosition, 20.25f * config.ScanArea.Radius);
}
}
return false;
}
return null;
}
public static bool Server_RemovePointOfInterest(BaseEntity.RPCMessage msg) {
BasePlayer sender = msg.player;
int index = msg.read.Int32();
AdminsDatabase.AdminData adminData = AdminsDatabase.Get(sender);
if (adminData != null && adminData.UsesAnyMap) {
if (adminData.currentPlayer.HasPlayerFlag(CupboardsAdminMap)) {
var cupboards = GetAllBuildingPrivlidges();
if (index >= cupboards.Count()) return false;
adminData.SelectedCupboard = cupboards.ElementAt(index);
}
else {
MapNote scannerMarker = adminData?.scannerMarker;
if (scannerMarker != null) {
if (index >= adminData.RenderedPlayers.Count) return false;
adminData.SelectedPlayer = adminData.RenderedPlayers.ElementAt(index);
return false;
}
}
}
return true;
}
public static bool TeamsBypass(BasePlayer __instance) {
if (__instance.HasPlayerFlag(TextAdminMap)) return false;
return true;
}
object OnMapMarkersClear(BasePlayer player, List<MapNote> notes) {
if (AdminsDatabase.Get(player)?.UsesAnyMap == true) return false;
return null;
}
void OnPlayerTick(BasePlayer player, PlayerTick msg, bool wasPlayerStalled) {
AdminsDatabase.AdminData adminData = AdminsDatabase.Get(player);
if (adminData == null || !adminData.UsesAnyMap) return;
if (player.serverInput.current.aimAngles == player.serverInput.previous.aimAngles) return;
if (adminData.SelectedPlayer != null) adminData.SelectedPlayer = null;
if (adminData.SelectedCupboard != null) adminData.SelectedCupboard = null;
}
#endregion
#region Commands
[ChatCommand("amap")]
private void MainCMD(BasePlayer player, string command, string[] args) {
AdminsDatabase.AdminData adminData = AdminsDatabase.Get(player);
if (adminData == null) {
player.ChatMessage(GetMessage(LangKeys.NO_PERMS, player.UserIDString));
return;
}
if (args.Length == 0) {
if (adminData.UsesAnyMap) {
player.SetPlayerFlag(MarkerAdminMap, false);
player.SetPlayerFlag(TextAdminMap, false);
player.SetPlayerFlag(SleepersAdminMap, false);
player.SetPlayerFlag(CupboardsAdminMap, false);
goto disable;
}
else {
player.SetPlayerFlag(CupboardsAdminMap, false);
player.SetPlayerFlag(SleepersAdminMap, false);
player.SetPlayerFlag(TextAdminMap, false);
player.SetPlayerFlag(MarkerAdminMap, true);
goto enable;
}
disable : player.ShowToast(global : : GameTip.Styles.Blue_Long, GetMessage(LangKeys.DISABLE, player.UserIDString), Array.Empty<string>());
RestoreState(player);
return;
enable : player.ShowToast(global : : GameTip.Styles.Blue_Long, GetMessage(LangKeys.ENABLE, player.UserIDString), Array.Empty<string>());
return;
}
else if (args.Length > 0) {
switch (args[0]) {
case "d" : player.SetPlayerFlag(SleepersAdminMap, false);
player.SetPlayerFlag(TextAdminMap, false);
player.SetPlayerFlag(CupboardsAdminMap, false);
RestoreState(player);
player.SetPlayerFlag(MarkerAdminMap, true);
player.ShowToast(global : : GameTip.Styles.Blue_Long, GetMessage(LangKeys.ENABLE, player.UserIDString), Array.Empty<string>());
break;
case "t" : player.SetPlayerFlag(SleepersAdminMap, false);
player.SetPlayerFlag(MarkerAdminMap, false);
player.SetPlayerFlag(CupboardsAdminMap, false);
RestoreState(player);
player.SetPlayerFlag(TextAdminMap, true);
player.ShowToast(global : : GameTip.Styles.Blue_Long, GetMessage(LangKeys.TEXT_MAP_ENABLED, player.UserIDString), Array.Empty<string>());
break;
case "c" : player.SetPlayerFlag(SleepersAdminMap, false);
player.SetPlayerFlag(MarkerAdminMap, false);
player.SetPlayerFlag(TextAdminMap, false);
RestoreState(player);
player.SetPlayerFlag(CupboardsAdminMap, true);
player.ShowToast(global : : GameTip.Styles.Blue_Long, GetMessage(LangKeys.CUPBOARDS_MAP_ENABLED, player.UserIDString), Array.Empty<string>());
break;
case "s" : player.SetPlayerFlag(MarkerAdminMap, false);
player.SetPlayerFlag(TextAdminMap, false);
player.SetPlayerFlag(CupboardsAdminMap, false);
RestoreState(player);
player.SetPlayerFlag(SleepersAdminMap, true);
player.ShowToast(global : : GameTip.Styles.Blue_Long, GetMessage(LangKeys.SLEEPERS_MAP_ENABLED, player.UserIDString), Array.Empty<string>());
break;
case "ss" : adminData.searchQuery = (args.Length > 1 ? string.Concat(args.Skip(1)) : string.Empty);
if (adminData.searchQuery != string.Empty) {
Func<BasePlayer, bool> func = (p => p.displayName.ToLower().Contains(adminData.searchQuery));
Func<BuildingPrivlidge, bool> func2 = (priv => priv.authorizedPlayers.Exists(p => p.username.ToLower().Contains(adminData.searchQuery)));
IEnumerable<BasePlayer> online = BasePlayer.activePlayerList.Where(func);
IEnumerable<BasePlayer> offline = BasePlayer.sleepingPlayerList.Where(func);
IEnumerable<BuildingPrivlidge> cupboards = GetAllBuildingPrivlidges().Where(func2);
player.ChatMessage(string.Format(GetMessage(LangKeys.SEARCH_QUERY_RESULT, player.UserIDString) + $"\nActive (<color=yellow>{online.Count()}</color>): {string.Join(", ", online.Select(p => p.displayName))}" + $"\nSleeping (<color=yellow>{offline.Count()}</color>): {string.Join(", ", offline.Select(p => p.displayName))}" + $"\nCupboards - <color=yellow>{cupboards.Count()}</color>", $"<color=yellow>{adminData.searchQuery}</color>"));
}
else player.ChatMessage(GetMessage(LangKeys.SEARCH_QUERY_CLEAR, player.UserIDString));
break;
case "wl" : bool mwlNewState = !player.HasPlayerFlag(MarkersWL);
player.SetPlayerFlag(MarkersWL, mwlNewState);
player.ShowToast(global : : GameTip.Styles.Blue_Long, (mwlNewState ? GetMessage(LangKeys.WL_ENABLED, player.UserIDString) : GetMessage(LangKeys.WL_DISABLED, player.UserIDString)), Array.Empty<string>());
break;
}
return;
}
}
[ConsoleCommand("adminmap.gui.cmd")]
private void guicmd(ConsoleSystem.Arg arg) {
BasePlayer player = arg.Player();
if (!player.IsAdmin && !permission.UserHasPermission(player.UserIDString, PERMISSION_TO_USE)) return;
AdminsDatabase.AdminData adminData = AdminsDatabase.Get(player);
if (adminData == null || !adminData.UsesAnyMap) return;
adminData.SelectedPlayer = null;
adminData.SelectedCupboard = null;
string commands = arg.FullString.Replace("\\\"", "\"");
foreach (var command in commands.Split(';')) player.SendConsoleCommand(command);
}
#endregion
#region Methods
void RestoreState(BasePlayer player) {
if (player.currentTeam != 0UL) player.TeamUpdate();
else player.ClearTeam();
player.SendPingsToClient();
player.SendMarkersToClient();
SendLocalMarkerUpdate(player, scanarea, Vector3.zero, 0);
}
Vector3 GetGroundPosition(Vector3 sourcePos) {
RaycastHit hitInfo;
if (UnityEngine.Physics.Raycast(sourcePos, Vector3.down, out hitInfo)) sourcePos.y = hitInfo.point.y;
sourcePos.y = Mathf.Max(sourcePos.y, TerrainMeta.HeightMap.GetHeight(sourcePos)) + 2.5f;
return sourcePos;
}
string GetHexColorForTeam(ulong teamID) {
return Convert.ToString((int)Math.Floor((Math.Abs(Math.Sin(teamID) * 16777215))), 16);
}
static IEnumerable<BuildingPrivlidge> GetAllBuildingPrivlidges() {
return ServerBuildingManager.server.buildingDictionary.SelectMany(b => b.Value.buildingPrivileges);
}
MapNote GetTCNote(BuildingPrivlidge privlidge, string label = null) => new MapNote {
label = label, noteType = 1, isPing = true, icon = 2, colourIndex = Mathf.Clamp(privlidge.authorizedPlayers.Count - 1, 0, 5), worldPosition = privlidge.transform.position
}
;
MapNote GetPlayerNote(BasePlayer player, int forceColor = -1, bool withLabel = true) => new MapNote {
label = withLabel ? player.displayName : null, noteType = 1, isPing = true, icon = 6, colourIndex = forceColor > -1 ? forceColor : (player.IsSleeping() ? 3 : 2), worldPosition = player.transform.position
}
;
MapNote GetVirtualMarker(BasePlayer player, int forceColor = -1) => new MapNote {
label = player.displayName, noteType = 1, isPing = true, icon = 6, colourIndex = forceColor > -1 ? forceColor : (player.IsSleeping() ? 3 : 2), worldPosition = Vector3.negativeInfinity
}
;
void SendLocalMarkerUpdate(BasePlayer player, MapMarkerGenericRadius marker, Vector3 position, float radius) {
SendInfo playerSendInfo = new SendInfo(player.Connection);
NetWrite netWrite = Network.Net.sv.StartWrite();
Network.Connection connection = player.net.connection;
connection.validate.entityUpdates = connection.validate.entityUpdates + 1U;
netWrite.PacketID(Message.Type.Entities);
netWrite.UInt32(player.net.connection.validate.entityUpdates);
BaseNetworkable.SaveInfo saveInfo = new BaseNetworkable.SaveInfo {
forConnection = player.net.connection, forDisk = false
}
;
using (saveInfo.msg = Facepunch.Pool.Get<ProtoBuf.Entity>()) {
marker.Save(saveInfo);
saveInfo.msg.baseEntity.pos = position;
saveInfo.msg.ToProto(netWrite);
}
netWrite.Send(playerSendInfo);
marker.ClientRPCEx<Vector3, float, Vector3, float, float>(playerSendInfo, null, "MarkerUpdate", new Vector3(marker.color1.r, marker.color1.g, marker.color1.b), 1, -Vector3.one, marker.color1.a, (1024f / TerrainMeta.Size.x * 0.2f) * radius);
}
void SendMapData() {
IEnumerable<AdminsDatabase.AdminData> admins = BasePlayer.activePlayerList .Select(AdminsDatabase.Get) .OfType<AdminsDatabase.AdminData>();
if (admins.Count() == 0) return;
// Text Player Map
IEnumerable<AdminsDatabase.AdminData> textAdmins = admins.Where(a => a.currentPlayer.HasPlayerFlag(TextAdminMap));
if (textAdmins.Count() > 0) {
var tmsettings = config.TextMapSettings;
using (PlayerTeam playerTeam = Facepunch.Pool.Get<PlayerTeam>()) {
playerTeam.teamLeader = 0;
playerTeam.teamID = 0;
playerTeam.teamName = string.Empty;
playerTeam.teamLifetime = 0;
playerTeam.teamPings = Facepunch.Pool.GetList<MapNote>();
foreach (var admin in textAdmins) {
playerTeam.members = Facepunch.Pool.GetList<PlayerTeam.TeamMember>();
foreach (var player in BasePlayer.activePlayerList) {
if (player == admin.currentPlayer) continue;
PlayerTeam.TeamMember teamMember = Facepunch.Pool.Get<PlayerTeam.TeamMember>();
string color = tmsettings.SoloColor;
if (admin.searchQuery != string.Empty && player.displayName.ToLower().Contains(admin.searchQuery.ToLower())) color = tmsettings.SearchColor;
else if (player.IsSleeping()) color = tmsettings.SleepersColor;
else if (player.currentTeam > 0) {
if (tmsettings.UseGeneratedTeamsColors) color = GetHexColorForTeam(player.currentTeam);
else color = tmsettings.TeamsColor;
}
teamMember.displayName = $"\t\t\t<size={tmsettings.FontSize * 10}><color=#{color}>{player.displayName}</color></size>\t\t\t";
teamMember.healthFraction = 100;
teamMember.position = player.transform.position;
teamMember.online = true;
teamMember.wounded = false;
teamMember.userID = 0;
playerTeam.members.Add(teamMember);
}
admin.currentPlayer.ClientRPCEx<PlayerTeam>(new SendInfo(admin.currentPlayer.Connection), null, "CLIENT_ReceiveTeamInfo", playerTeam);
var scannerMarker = admin.scannerMarker;
if (scannerMarker != null) {
using (MapNoteList markers = Facepunch.Pool.Get<MapNoteList>()) {
markers.notes = Facepunch.Pool.GetList<MapNote>();
admin.RenderedPlayers.Clear();
foreach (var player in BasePlayer.activePlayerList) {
if (player == admin.currentPlayer) continue;
if (Vector3.Distance(player.transform.position, scannerMarker.worldPosition) < 150 * config.ScanArea.Radius) {
if (markers.notes.Count < 12) {
var colorIndex = -1;
if (admin.searchQuery != string.Empty && player.displayName.ToLower().Contains(admin.searchQuery.ToLower())) colorIndex = 5;
markers.notes.Add(GetVirtualMarker(player, colorIndex));
admin.RenderedPlayers.Add(player);
}
}
}
admin.currentPlayer.ClientRPCPlayer<MapNoteList>(null, admin.currentPlayer, "Client_ReceiveMarkers", markers);
}
}
}
}
}
// Marker Player Map
IEnumerable<AdminsDatabase.AdminData> markerAdmins = admins.Where(a => a.currentPlayer.HasPlayerFlag(MarkerAdminMap) || a.currentPlayer.HasPlayerFlag(SleepersAdminMap));
if (markerAdmins.Count() > 0) {
foreach (var admin in markerAdmins) {
var withSearch = admin.searchQuery != string.Empty;
bool usingSleeperMap = admin.currentPlayer.HasPlayerFlag(SleepersAdminMap);
bool renderWithoutLabels = admin.currentPlayer.HasPlayerFlag(MarkersWL);
MapNoteList pings = Facepunch.Pool.Get<MapNoteList>();
pings.notes = Facepunch.Pool.GetList<MapNote>();
MapNoteList markers = Facepunch.Pool.Get<MapNoteList>();
markers.notes = Facepunch.Pool.GetList<MapNote>();
IEnumerable<BasePlayer> playersToRender = (usingSleeperMap ? BasePlayer.sleepingPlayerList : BasePlayer.activePlayerList);
IEnumerable<BasePlayer> searchResult = null;
if (withSearch) searchResult = playersToRender.Where(player => player.displayName.ToLower().Contains(admin.searchQuery.ToLower()));
var scannerMarker = admin.scannerMarker;
admin.RenderedPlayers.Clear();
foreach (var player in playersToRender) {
if (player == admin.currentPlayer) continue;
bool? existInSeachQuery = searchResult?.Contains(player);
var colorIndex = -1;
if (existInSeachQuery.HasValue && existInSeachQuery.Value) colorIndex = 5;
if (scannerMarker != null && Vector3.Distance(player.transform.position, scannerMarker.worldPosition) < 150 * config.ScanArea.Radius) {
if (markers.notes.Count < 12) {
if (renderWithoutLabels || usingSleeperMap) {
if (!(usingSleeperMap && existInSeachQuery.HasValue && !existInSeachQuery.Value)) markers.notes.Add(GetVirtualMarker(player, colorIndex));
pings.notes.Add(GetPlayerNote(player, colorIndex, existInSeachQuery.HasValue && existInSeachQuery.Value));
}
else markers.notes.Add(GetPlayerNote(player, colorIndex, true));
admin.RenderedPlayers.Add(player);
}
}
else {
bool withLabels = true;
if (renderWithoutLabels || usingSleeperMap) withLabels = false;
if (existInSeachQuery.HasValue && existInSeachQuery.Value) withLabels = true;
pings.notes.Add(GetPlayerNote(player, colorIndex, withLabels));
}
}
admin.currentPlayer.ClientRPCPlayer<MapNoteList>(null, admin.currentPlayer, "Client_ReceivePings", pings);
admin.currentPlayer.ClientRPCPlayer<MapNoteList>(null, admin.currentPlayer, "Client_ReceiveMarkers", markers);
markers.Dispose();
pings.Dispose();
}
}
// Marker Cupboards Map
IEnumerable<AdminsDatabase.AdminData> cupboardAdmins = admins.Where(a => a.currentPlayer.HasPlayerFlag(CupboardsAdminMap));
if (cupboardAdmins.Count() > 0) {
foreach (var admin in cupboardAdmins) {
using (MapNoteList markers = Facepunch.Pool.Get<MapNoteList>()) {
IEnumerable<BuildingPrivlidge> privlidges = GetAllBuildingPrivlidges();
IEnumerable<BuildingPrivlidge> searchResult = null;
if (admin.searchQuery != string.Empty) searchResult = privlidges.Where(priv => priv.authorizedPlayers.Exists(p => p.username.ToLower().Contains(admin.searchQuery.ToLower())));
markers.notes = Facepunch.Pool.GetList<MapNote>();
foreach (var priv in privlidges) {
string label = null;
if (searchResult != null && searchResult.Contains(priv)) {
var __1 = priv.authorizedPlayers.Where(authPlayer => authPlayer.username.ToLower().Contains(admin.searchQuery.ToLower()));
var __2 = priv.authorizedPlayers.Where(authPlayer => !__1.Contains(authPlayer));
label = $"{string.Join(", ", __1.Select(p => p.username))}\n{string.Join(", ", __2.Select(p => p.username))}";
}
markers.notes.Add(GetTCNote(priv, label));
}
admin.currentPlayer.ClientRPCPlayer<MapNoteList>(null, admin.currentPlayer, "Client_ReceiveMarkers", markers);
}
}
}
}
IEnumerator Loop() {
while (this.IsLoaded) {
SendMapData();
yield return UnityEngine.CoroutineEx.waitForSeconds(1f);
}
yield break;
}
#endregion
#region Classes
public static class AdminsDatabase {
public class AdminData {
public BasePlayer currentPlayer;
public AdminData(BasePlayer player) {
currentPlayer = player;
}
public bool UsesAnyMap => currentPlayer.HasPlayerFlag(MarkerAdminMap) || currentPlayer.HasPlayerFlag(SleepersAdminMap) || currentPlayer.HasPlayerFlag(TextAdminMap) || currentPlayer.HasPlayerFlag(CupboardsAdminMap);
public string searchQuery = string.Empty;
public MapNote scannerMarker;
private BasePlayer _selectedPlayer;
private BuildingPrivlidge _selectedCupboard;
public BasePlayer SelectedPlayer {
get {
return _selectedPlayer;
}
set {
_selectedPlayer = value;
if (_selectedPlayer != null) RenderGuiForPlayers();
else CuiHelper.DestroyUi(currentPlayer, "AdminMap / Buttons");
}
}
public BuildingPrivlidge SelectedCupboard {
get {
return _selectedCupboard;
}
set {
_selectedCupboard = value;
if (_selectedCupboard != null) RenderCupboardInfoGui(_selectedCupboard);
else CuiHelper.DestroyUi(currentPlayer, "AdminMap / CupboardInfoGui");
}
}
public List<BasePlayer> RenderedPlayers {
get;
set;
}
= new List<BasePlayer>();
public void RenderGuiForPlayers() {
CUI cui = new CUI();
var container = cui.AddContainer(anchorMin : "0.12 0.96", anchorMax : "0.12 0.96", offsetMin : $"0 -70", offsetMax : $"{5 * 70} -0", parent : "Hud.Menu", name : "AdminMap / Buttons");
cui.AddText(text : SelectedPlayer.ToString(), font : CUI.Font.DroidSansMono, fontSize : 14, align : TextAnchor.MiddleLeft, color : "1 1 1 1", anchorMin : "0 1", anchorMax : "0 1", offsetMin : "30 0", offsetMax : "450 40", parent : container);
int buttonCounter = 0;
foreach (var button in config.Buttons) {
if (button.Permission != string.Empty && !Instance.permission.UserHasPermission(currentPlayer.UserIDString, $"adminmap.{button.Permission}")) continue;
string[] commands = button.Command.Split(';');
for (int i = 0; i < commands.Length; i++) {
string command = commands[i];
if (command.First() == '/') commands[i] = command.Replace(command, $"chat.say \"{command}\"");
}
button.Command = string.Join(";", commands);
var circleContaner = cui.AddContainer(anchorMin : "0 0", anchorMax : "0 1", offsetMin : $"{buttonCounter * 70} 0", offsetMax : $"{(buttonCounter + 1) * 70} 0", parent : container);
cui.AddText(text : button.Label, font : CUI.Font.RobotoCondensedBold, fontSize : 10, align : TextAnchor.MiddleCenter, color : "1 1 1 1", anchorMin : "0 0", anchorMax : "1 1", parent : circleContaner);
cui.AddButton(color : button.ColorString, sprite : "assets/icons/circle_open.png", imageType : UnityEngine.UI.Image.Type.Tiled, command : $"adminmap.gui.cmd {button.Command.Replace(" {
steamid
}
", SelectedPlayer.UserIDString).Replace(" {
username
}
", SelectedPlayer.displayName)}", parent : circleContaner);
buttonCounter++;
}
cui.RenderWithDestroy(currentPlayer);
}
private void RenderCupboardInfoGui(BuildingPrivlidge cupboard) {
var cui = new CUI();
var __1 = cui.AddColorPanel(color : "0.05 0.05 0.05 0.85", sprite : "assets/content/ui/ui.background.rounded.png", imageType : UnityEngine.UI.Image.Type.Tiled, anchorMin : "0 0", anchorMax : "0 0", offsetMin : "200 10", offsetMax : "400 360", parent : "Hud.Menu", name : "AdminMap / CupboardInfoGui");
List<global : : ItemAmount> list = Facepunch.Pool.GetList<global : : ItemAmount>();
cupboard.CalculateUpkeepCostAmounts(list);
cui.AddText(text : $"<b>Authorized players:</b>\n" + string.Concat(cupboard.authorizedPlayers.Select(player => (searchQuery != string.Empty && player.username.ToLower().Contains(searchQuery.ToLower())? $"<color=yellow>{player.username}</color>\n" : $"{player.username}\n"))) + "<b>Upkeep Cost:</b>\n" + string.Concat(list.Select(itemAmount => $"{(int)itemAmount.amount} {itemAmount.itemDef.displayName.translated}\n")), font : CUI.Font.RobotoCondensedRegular, fontSize : 16, align : TextAnchor.MiddleCenter, color : "1 1 1 1", anchorMin : "0 0", anchorMax : "1 1", offsetMin : "10 30", offsetMax : "-10 -10", parent : __1);
Facepunch.Pool.FreeList<global : : ItemAmount>(ref list);
var buttonContaner = cui.AddColorPanel(color : "0.7 0 0 0.5", anchorMin : "0 0", anchorMax : "1 0", offsetMin : $"0 0", offsetMax : $"0 20", parent : __1);
cui.AddText(text : "Teleport", font : CUI.Font.RobotoCondensedBold, fontSize : 10, align : TextAnchor.MiddleCenter, color : "1 1 1 1", anchorMin : "0 0", anchorMax : "1 1", parent : buttonContaner);
cui.AddButton(command : $"teleportpos ({cupboard.transform.position.x},{cupboard.transform.position.y},{cupboard.transform.position.z})", parent : buttonContaner);
cui.RenderWithDestroy(currentPlayer);
}
}
static Dictionary<ulong, AdminData> Database = new Dictionary<ulong, AdminData>();
public static AdminData Get(BasePlayer player) {
AdminData data = null;
if (player.IsAdmin || Instance.permission.UserHasPermission(player.UserIDString, PERMISSION_TO_USE)) {
if (!Database.TryGetValue(player.userID, out data)) Database.Add(player.userID, data = new AdminData(player));
}
else if (Database.ContainsKey(player.userID)) Database.Remove(player.userID);
return data;
}
}
#endregion
#region Config
static Configuration config;
public class Configuration {
public class ScanAreaSettings {
[JsonProperty(PropertyName = "Radius")]
public float Radius {
get;
set;
}
= 2f;
[JsonProperty(PropertyName = "Color")]
public string ColorString {
get;
set;
}
= "0 0.7 0 0.6";
[JsonIgnore]
public Color Color {
get {
string[] colorSplit = ColorString.Split(' ');
return new Color(float.Parse(colorSplit[0]), float.Parse(colorSplit[1]), float.Parse(colorSplit[2]), float.Parse(colorSplit[3]));
}
}
}
[JsonProperty(PropertyName = "Scan Area Settings")]
public ScanAreaSettings ScanArea {
get;
set;
}
= new ScanAreaSettings();
public class Button {
public Button() {
}
public Button(string permission, string label, string command) {
this.Permission = permission;
this.Label = label;
this.Command = command;
}
public Button(string permission, string label, string command, string color) : this(permission, label, command) {
this.ColorString = color;
}
[JsonProperty(PropertyName = "Permission (adminmap.<perm>)")]
public string Permission {
get;
set;
}
= string.Empty;
[JsonProperty(PropertyName = "Label")]
public string Label {
get;
set;
}
= string.Empty;
[JsonProperty(PropertyName = "Command")]
public string Command {
get;
set;
}
= string.Empty;
[JsonProperty(PropertyName = "Color")]
public string ColorString {
get;
set;
}
= "1 1 1 1";
}
public class TMSettings {
[JsonProperty(PropertyName = "Font size")]
public int FontSize {
get;
set;
}
= 16;
[JsonProperty(PropertyName = "Use color generation for teams?")]
public bool UseGeneratedTeamsColors {
get;
set;
}
= true;
[JsonProperty(PropertyName = "Color for searches")]
public string SearchColor {
get;
set;
}
= "00ffff";
[JsonProperty(PropertyName = "Color for teams")]
public string TeamsColor {
get;
set;
}
= "ffaf4d";
[JsonProperty(PropertyName = "Color for solo players")]
public string SoloColor {
get;
set;
}
= "9bd92f";
[JsonProperty(PropertyName = "Color for sleepers")]
public string SleepersColor {
get;
set;
}
= "404040";
}
[JsonProperty(PropertyName = "Text Map Settings")]
public TMSettings TextMapSettings {
get;
set;
}
= new TMSettings();
[JsonProperty(PropertyName = "Command Buttons")]
public IList<Button> Buttons {
get;
set;
}
= new ReadOnlyCollection<Button>(new List<Button> {
new Button(string.Empty, "TP", "teleport {steamid}"), new Button(string.Empty, "TP2ME", "teleport2me {steamid}"), new Button(string.Empty, "INV", "/viewinv {username}"), new Button(string.Empty, "SPECTATE", "spectate {steamid}"), new Button(string.Empty, "KILL", "kill {steamid}", "1 0 0 1"), new Button(string.Empty, "KICK", "kick {steamid}", "1 0 0 1"),
}
);
public static Configuration DefaultConfig() => new Configuration();
}
protected override void LoadConfig() {
base.LoadConfig();
try {
config = Config.ReadObject<Configuration>();
if (config == null) LoadDefaultConfig();
SaveConfig();
}
catch (Exception e) {
Debug.LogException(e);
PrintWarning("Creating new config file.");
LoadDefaultConfig();
}
}
protected override void LoadDefaultConfig() => config = Configuration.DefaultConfig();
protected override void SaveConfig() => Config.WriteObject(config);
#endregion
#region Language
public static class LangKeys {
public const string NO_PERMS = nameof(NO_PERMS);
public const string ENABLE = nameof(ENABLE);
public const string DISABLE = nameof(DISABLE);
public const string TEXT_MAP_ENABLED = nameof(TEXT_MAP_ENABLED);
public const string SLEEPERS_MAP_ENABLED = nameof(SLEEPERS_MAP_ENABLED);
public const string CUPBOARDS_MAP_ENABLED = nameof(CUPBOARDS_MAP_ENABLED);
public const string SEARCH_QUERY_RESULT = nameof(SEARCH_QUERY_RESULT);
public const string SEARCH_QUERY_CLEAR = nameof(SEARCH_QUERY_CLEAR);
public const string WL_ENABLED = nameof(WL_ENABLED);
public const string WL_DISABLED = nameof(WL_DISABLED);
}
protected override void LoadDefaultMessages() {
lang.RegisterMessages(new Dictionary<string, string> {
[LangKeys.NO_PERMS]
= "You dont have permission to use this command.", [LangKeys.ENABLE] = "Admin map enabled", [LangKeys.DISABLE] = "Admin map disabled", [LangKeys.TEXT_MAP_ENABLED] = "Text ADMIN MAP ENABLED", [LangKeys.SLEEPERS_MAP_ENABLED] = "SLEEPERS ADMIN MAP ENABLED", [LangKeys.CUPBOARDS_MAP_ENABLED] = "CUPBOARDS ADMIN MAP ENABLED", [LangKeys.WL_ENABLED] = "MARKERS WITHOUT LABLES ENABLED", [LangKeys.WL_DISABLED] = "MARKERS WITHOUT LABLES DISABLED", [LangKeys.SEARCH_QUERY_RESULT] = "The query \"{0}\" found:", [LangKeys.SEARCH_QUERY_CLEAR] = "The search query has been cleared."
}
, this);
}
private string GetMessage(string langKey, string userID) => lang.GetMessage(langKey, this, userID);
private string GetMessage(string langKey, string userID, params object[] args) => (args.Length == 0) ? GetMessage(langKey, userID) : string.Format(GetMessage(langKey, userID), args);
#endregion
}
#region 0xF UI Library
partial class AdminMap {
public class CUI {
public CuiElementContainer ElementContainer {
get;
set;
}
= new CuiElementContainer();
readonly string[] FontNames = new string[] {
"RobotoCondensed-Bold.ttf", "RobotoCondensed-Regular.ttf", "DroidSansMono.ttf", "PermanentMarker.ttf"
}
;
public enum Font {
RobotoCondensedBold, RobotoCondensedRegular, DroidSansMono, PermanentMarker
}
public string AddText(string text = "Text", string color = "1 1 1 1", Font font = Font.RobotoCondensedRegular, int fontSize = 14, TextAnchor align = TextAnchor.UpperLeft, VerticalWrapMode overflow = VerticalWrapMode.Overflow, string anchorMin = "0 0", string anchorMax = "1 1", string offsetMin = "0 0", string offsetMax = "0 0", float fadeIn = 0f, float fadeOut = 0f, string parent = "Hud", string name = null) {
if (name == null) name = CuiHelper.GetGuid();
CuiElement element = new CuiElement {
Components = {
new CuiTextComponent {
Text = text, Color = color, Font = FontNames[(int)font], VerticalOverflow = overflow, FontSize = fontSize, Align = align, FadeIn = fadeIn
}
, new CuiRectTransformComponent() {
AnchorMin = anchorMin, AnchorMax = anchorMax, OffsetMin = offsetMin, OffsetMax = offsetMax
}
,
}
, FadeOut = fadeOut, Parent = parent, Name = name,
}
;
Add(element);
return name;
}
public string AddOutlinedText(string text = "Text", string color = "1 1 1 1", Font font = Font.RobotoCondensedRegular, int fontSize = 14, TextAnchor align = TextAnchor.UpperLeft, VerticalWrapMode overflow = VerticalWrapMode.Overflow, string outlineColor = "0 0 0 1", float outlineWidth = 1, string anchorMin = "0 0", string anchorMax = "1 1", string offsetMin = "0 0", string offsetMax = "0 0", float fadeIn = 0f, float fadeOut = 0f, string parent = "Hud", string name = null) {
if (name == null) name = CuiHelper.GetGuid();
CuiElement element = new CuiElement {
Components = {
new CuiTextComponent {
Text = text, Color = color, Font = FontNames[(int)font], VerticalOverflow = overflow, FontSize = fontSize, Align = align, FadeIn = fadeIn
}
, new CuiOutlineComponent {
Color = outlineColor, Distance = $"{outlineWidth} {-outlineWidth}"
}
, new CuiRectTransformComponent() {
AnchorMin = anchorMin, AnchorMax = anchorMax, OffsetMin = offsetMin, OffsetMax = offsetMax
}
,
}
, FadeOut = fadeOut, Parent = parent, Name = name
}
;
Add(element);
return name;
}
public string AddInputfield(string command, string text = "Enter text here...", string color = "1 1 1 1", Font font = Font.RobotoCondensedRegular, int fontSize = 14, TextAnchor align = TextAnchor.UpperLeft, string anchorMin = "0 0", string anchorMax = "1 1", string offsetMin = "0 0", string offsetMax = "0 0", bool needsKeyboard = true, bool autoFocus = false, bool isPassword = false, int charsLimit = 0, string parent = "Hud", string name = null) {
if (name == null) name = CuiHelper.GetGuid();
CuiElement element = new CuiElement {
Components = {
new CuiInputFieldComponent {
Text = text, Color = color, Font = FontNames[(int)font], FontSize = fontSize, Align = align, Autofocus = autoFocus, Command = command, IsPassword = isPassword, CharsLimit = charsLimit, NeedsKeyboard = needsKeyboard,
}
, new CuiRectTransformComponent() {
AnchorMin = anchorMin, AnchorMax = anchorMax, OffsetMin = offsetMin, OffsetMax = offsetMax
}
,
}
, Parent = parent, Name = name
}
;
Add(element);
return name;
}
public string AddPanel(string color = "0 0 0 0", string sprite = "assets/content/ui/ui.background.tile.psd", string material = "assets/icons/iconmaterial.mat", UnityEngine.UI.Image.Type imageType = UnityEngine.UI.Image.Type.Simple, string anchorMin = "0 0", string anchorMax = "1 1", string offsetMin = "0 0", string offsetMax = "0 0", float fadeIn = 0f, float fadeOut = 0f, bool cursorEnabled = false, bool keyboardEnabled = false, string parent = "Hud", string name = null) {
if (name == null) name = CuiHelper.GetGuid();
CuiPanel panel = new CuiPanel {
Image = {
Color = color, Sprite = sprite, Material = material, ImageType = imageType, FadeIn = fadeIn,
}
, RectTransform = {
AnchorMin = anchorMin, AnchorMax = anchorMax, OffsetMin = offsetMin, OffsetMax = offsetMax,
}
, CursorEnabled = cursorEnabled, KeyboardEnabled = keyboardEnabled, FadeOut = fadeOut
}
;
ElementContainer.Add(panel, parent, name);
return name;
}
public string AddButton(string command, string color = "0 0 0 0", string sprite = "assets/content/ui/ui.background.tile.psd", string material = "assets/icons/iconmaterial.mat", UnityEngine.UI.Image.Type imageType = UnityEngine.UI.Image.Type.Simple, string anchorMin = "0 0", string anchorMax = "1 1", string offsetMin = "0 0", string offsetMax = "0 0", float fadeIn = 0f, float fadeOut = 0f, string parent = "Hud", string name = null) {
if (name == null) name = CuiHelper.GetGuid();
CuiButton button = new CuiButton {
Button = {
Close = "", Command = command, Color = color, Sprite = sprite, Material = material, ImageType = imageType, FadeIn = fadeIn,
}
, RectTransform = {
AnchorMin = anchorMin, AnchorMax = anchorMax, OffsetMin = offsetMin, OffsetMax = offsetMax,
}
, FadeOut = fadeOut,
}
;
ElementContainer.Add(button, parent, name);
return name;
}
public string AddImage(string content, string color = "1 1 1 1", string anchorMin = "0 0", string anchorMax = "1 1", string offsetMin = "0 0", string offsetMax = "0 0", float fadeIn = 0f, float fadeOut = 0f, string parent = "Hud", string name = null) {
if (name == null) name = CuiHelper.GetGuid();
CuiElement element = new CuiElement {
Components = {
new CuiRawImageComponent() {
Color = color, Png = content, Sprite = "assets/content/textures/generic/fulltransparent.tga", FadeIn = fadeIn
}
, new CuiRectTransformComponent() {
AnchorMin = anchorMin, AnchorMax = anchorMax, OffsetMin = offsetMin, OffsetMax = offsetMax
}
,
}
, Parent = parent, Name = name, FadeOut = fadeOut
}
;
Add(element);
return name;
}
public string AddHImage(string content, string color = "1 1 1 1", string anchorMin = "0 0", string anchorMax = "1 1", string offsetMin = "0 0", string offsetMax = "0 0", string parent = "Hud", string name = null) {
if (name == null) name = CuiHelper.GetGuid();
CuiElement element = new CuiElement {
Components = {
new CuiRawImageComponent() {
Color = color, Png = content, Sprite = "assets/content/textures/generic/fulltransparent.tga", Material = "assets/icons/iconmaterial.mat"
}
, new CuiRectTransformComponent() {
AnchorMin = anchorMin, AnchorMax = anchorMax, OffsetMin = offsetMin, OffsetMax = offsetMax
}
,
}
, Pare
// ... [Code preview truncated due to length. Full source in attached file] ...