Иконка ресурса

FREE AdminMap : 2.0.4 2.0.4

Нет прав для скачивания
C#:
using CompanionServer.Handlers;
using Facepunch;
using HarmonyLib;
using Network;
using Newtonsoft.Json;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using ProtoBuf;
using Rust;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using Time = UnityEngine.Time;
namespace Oxide.Plugins {
    [Info("AdminMap", "0xF // dsc.gg/0xf-plugins", "2.0.4")]
    partial class AdminMap : RustPlugin {
#region References
        [PluginReference]
        private Plugin AdminMenu;
#endregion
#region Consts
        private const string PERMISSION_ALLOW = "adminmap.allow";
        private const string PERMISSION_TPMARKER = "adminmap.teleport2marker";
        private const string PERMISSION_INVIS = "adminmap.invis";
        private const string PERMISSION_RUSTPLUS = "adminmap.rust+";
        private const string PERMISSION_RUSTPLUSINVIS = "adminmap.rust+.invis";
#endregion
#region Vars
        private static AdminMap Instance;
        private static string CapsuleBackgroundVerticalCRC, LetterTCRC;
        private List<string> permissions = new() {
            PERMISSION_ALLOW, PERMISSION_TPMARKER, PERMISSION_INVIS, PERMISSION_RUSTPLUS, PERMISSION_RUSTPLUSINVIS
        }
        ;
        private Dictionary<(ulong userID, string permissionName), bool> permissionCache = new();
#endregion
#region Enums
        public enum MapLayer {
            None, Player = 1 << 0, Sleeper = 1 << 2, TC = 1 << 3, Stash = 1 << 4, SleepingBag = 1 << 5, Text = 1 << 6,
        }
        public enum MapLayerModification {
            None, NoLabels = 1 << 0
        }
#endregion
#region Hooks
        void Init() {
            Instance = this;
            foreach (var button in config.Buttons) if (!string.IsNullOrEmpty(button.Permission)) permissions.Add($"adminmap.{button.Permission}");
            foreach (var perm in permissions) permission.RegisterPermission(perm, this);
        }
        void Unload() {
            permissions.Clear();
            permissionCache.Clear();
            foreach (ConnectionData connectionData in ConnectionData.all.Values.ToArray()) connectionData.Dispose();
        }
        void OnServerInitialized(bool initial) {
            CapsuleBackgroundVerticalCRC = FileStorage.server.Store(Convert.FromBase64String("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TYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoUQZMiaFIETYqgSRE0KYImRdCkCJoU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"), FileStorage.Type.png, CommunityEntity.ServerInstance.net.ID).ToString();
            LetterTCRC = FileStorage.server.Store(Convert.FromBase64String("iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAThSURBVHgB7d3Pi1V1GMDh96RoZYmWRUW1KggtComgH1ZYFC2kIFq0bdH/IEEUtHIV7aJli0CCFtG+RbSoFi0kLRgRSSSFMCkxU0/v4U4YUTD3Xhq/57zPAy9nFjMgOO9nzjl37pkIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAZfR9f3fOIzldANOWi35bzqs5H+Ss9Fe8H0yOqheXi709D0/l7F2dXf/xqRdztnRddyGYjI1BKbnwW/KwJ64s/EM5G9bwpcP3yh05x4LJEICJy4Uf/o8fzHl2dYbl3xyLWUsoGBEBmJhc+GFJh5/qw7I/kfNkztaAfyEAE5BLP1y3PxezU3oLz5oJwIjl4t+Shw9zng9YwDXBmB0Iy88SBGDcdgcsQQDGzV15liIAUJgAQGECAIUJABQmAFCYAEBhAgCFCQAUJgBQmABAYQIAhQkAFCYAUJgAQGECAIV5JFhD+r7flofXY/Zs/uvW8CV3xfp6J/+NZ2M+fc7JnM+6rvsmaIo/DNKQXK4v8vB4TNPlnD0ZgS+DZrgEaEQu/00x3eUfDN9r+4KmCEA7bozp87jyxggAFCYAUJgAQGECAIUJABQmAFCYAEBhAgCFCQAUJgBQmABAYQIAhQkAFCYAUJgAtONcTN/5oCkC0Iiu607n4WhM21dBUzwTsC0v5ryZszPW9kzAO3M2xfr5JWaP9prH8EzAEzkf5xwMmuKZgCPW9/2hmD1AdL3ck2cqK8FkuASAwgQAChMAKEwAoDABgMIEAAoTAChMAKAwAYDCBAAKEwAoTACgMAGAwgQAChMAKEwAoDABgMIEAAoTAChMAKAwAYDCBAAKEwAoTACgMAGAwgQAChMAKEwAoDABgMIEAAoTAChMAKAwAYDCBAAKEwAoTACgMAGAwgSAeWwIJkUAmMeWYFIEgHlsDyZFAJjHA8GkCADzeDqYFAFgHvv6vr83mAwBYB7DqwCfZARuDSZBAJjXrpwjGYE3cu4LRq0LRisX8FDMFvJq+jXnWM5POX3OmdXjP13KOZzzXtd1Z4ImbAxYzg0596/OWuzOeSlogkuAcetjfPYGzRCAcfs9xsdvEzZEAMbtfMASBGDcBIClCMC4/RywBAEYtx8DliAA43YiYAkCMG5HA5YgAOP2dcASBGDEuq4b7gGcDFiQAIzf5wELEoDxOxiwIO8GHLm+76+N2WXAthiHy3np4unCjXAGMHK5TMNvA74bsABnABOQZwFb87CSsyPa5wygIc4AJiAX6mweXotxvj2Yq0gAJiIj8GkeDgTMQQCmZX/OW9H2mcCFoBkCMCF5FtDnvJ0fvpxzPNr0XQD/r7wxeH3O/pzjfTvO5TwTNMOrABOXCzfccX8h55WcfbG+f9/vYszesPR9zrc5H+UZyuGgGQJQSMZguOTbmfNozmM5D+fcnnNzLG6433AqZi9DHsn5IWYLP3y8kgv/R9AsAeCvs4QhAjtWj5tj9vDOTX/7tOF7ZVj232J2I+90zBb/VC75pQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKbpT6jRW4l52+/oAAAAAElFTkSuQmCC"), FileStorage.Type.png, CommunityEntity.ServerInstance.net.ID).ToString();
            foreach (BasePlayer player in BasePlayer.allPlayerList) UpdatePermissionCache(player);
            foreach (BasePlayer player in BasePlayer.activePlayerList) OnPlayerConnected(player);
        }
        void Loaded() {
            foreach (Type type in this.GetType().GetNestedTypes(BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)) {
                object[] attribute = type.GetCustomAttributes(typeof(HarmonyPatch), false);
                if (attribute.Length >= 1) {
                    PatchClassProcessor patchClassProcessor = this.HarmonyInstance.CreateClassProcessor(type);
                    patchClassProcessor.Patch();
                }
            }
        }
        void OnPlayerConnected(BasePlayer player) {
            UpdatePermissionCache(player);
            CheckConnectionDataConditions(player);
            if (config.AutoShowPanel) ConnectionData.Get(player.Connection)?.UI.RenderSidebar();
        }
        void OnPlayerDisconnected(BasePlayer player) {
            ConnectionData connectionData = ConnectionData.Get(player.Connection);
            if (connectionData != null) connectionData.Dispose();
        }
        void OnUserPermissionGranted(string userID, string permName) {
            if (!permissions.Contains(permName)) return;
            BasePlayer player = BasePlayer.FindAwakeOrSleepingByID(ulong.Parse(userID));
            if (player == null) return;
            UpdatePermissionCache(player);
            CheckConnectionDataConditions(player);
        }
        void OnUserPermissionRevoked(string userID, string permName) {
            if (!permissions.Contains(permName)) return;
            BasePlayer player = BasePlayer.FindAwakeOrSleepingByID(ulong.Parse(userID));
            if (player == null) return;
            UpdatePermissionCache(player);
            CheckConnectionDataConditions(player);
        }
        void OnUserGroupAdded(string userID, string groupName) {
            BasePlayer player = BasePlayer.FindAwakeOrSleepingByID(ulong.Parse(userID));
            if (player == null) return;
            UpdatePermissionCache(player);
            CheckConnectionDataConditions(player);
        }
        void OnUserGroupRemoved(string userID, string groupName) {
            BasePlayer player = BasePlayer.FindAwakeOrSleepingByID(ulong.Parse(userID));
            if (player == null) return;
            UpdatePermissionCache(player);
            CheckConnectionDataConditions(player);
        }
        object OnMapMarkerAdd(BasePlayer player, ProtoBuf.MapNote note) {
            if (HasPermission(player.userID, PERMISSION_TPMARKER)) {
                if (player.serverInput.WasDown(BUTTON.DUCK)) {
                    float y = TerrainMeta.HeightMap.GetHeight(note.worldPosition) + 2.5f;
                    float highestPoint = TerrainMeta.HighestPoint.y + 250f;
                    RaycastHit[] hits = Physics.RaycastAll(note.worldPosition.WithY(highestPoint), Vector3.down, ++highestPoint, Layers.Mask.World | Layers.Mask.Terrain | Layers.Mask.Default, QueryTriggerInteraction.Ignore);
                    if (hits.Length > 0) {
                        GamePhysics.Sort(hits);
                        y = hits.Max(hit => hit.point.y);
                    }
                    if (player.IsFlying) y = Mathf.Max(y, player.transform.position.y);
                    player.Teleport(note.worldPosition.WithY(y));
                    return false;
                }
            }
            if (HasPermission(player.userID, PERMISSION_ALLOW)) {
                ConnectionData connectionData = ConnectionData.Get(player.Connection);
                if (connectionData == null) return null;
                if (connectionData.IsLayerActive(MapLayer.Text)) {
                    (BasePlayer player, float distance) minDistancePlayer = (null, float.MaxValue);
                    foreach (BasePlayer basePlayer in connectionData.textPlayers) {
                        float distance = Vector2.Distance(basePlayer.transform.position.XZ2D(), note.worldPosition.XZ2D());
                        if (distance < minDistancePlayer.distance) minDistancePlayer = (basePlayer, distance);
                    }
                    if (minDistancePlayer.distance < 75) {
                        Instance.InvokeActionMenu(connectionData, player, minDistancePlayer.player);
                        return false;
                    }
                }
            }
            return null;
        }
        void OnPlayerPingsSend(BasePlayer player, MapNoteList mapNoteList) {
            ConnectionData connectionData = ConnectionData.Get(player.Connection);
            if (connectionData == null) return;
            mapNoteList.notes.AddRange(connectionData.notes);
        }
        object OnTeamLeave(RelationshipManager.PlayerTeam team, BasePlayer player) {
            return BasePlayer_TeamUpdate_Patch.Prefix(player) ? null : false;
        }
#endregion
#region Methods
        private void UpdatePermissionCache(BasePlayer player) {
            foreach (string permissionName in permissions) permissionCache[(player.userID, permissionName)] = permission.UserHasPermission(player.UserIDString, permissionName);
        }
        private bool HasPermission(ulong userID, string permission) {
            if (!Instance.permissionCache.TryGetValue((userID, permission), out bool result)) return false;
            return result;
        }
        public void SendPingsToClient(BasePlayer player, List<MapNote> notes) {
            using (MapNoteList mapNoteList = Facepunch.Pool.Get<MapNoteList>()) {
                mapNoteList.notes = Facepunch.Pool.Get<List<MapNote>>();
                mapNoteList.notes.AddRange(notes);
                player.ClientRPC<MapNoteList>(global : : RpcTarget.Player("Client_ReceivePings", player), mapNoteList);
                Facepunch.Pool.FreeUnmanaged(ref mapNoteList.notes);
            }
        }
        private void CheckConnectionDataConditions(BasePlayer player) {
            if (!player.IsConnected) return;
            Connection connection = player.Connection;
            ConnectionData connectionData = ConnectionData.Get(connection);
            bool hasPermission = HasPermission(player.userID, PERMISSION_ALLOW);
            if (hasPermission && connectionData == null) ConnectionData.GetOrCreate(connection);
            else if (!hasPermission && connectionData != null) connectionData.Dispose();
        }
        private void InvokeActionMenu(ConnectionData connectionData, BasePlayer from, BasePlayer to) {
            if (config.AdminMenuInsteadOfActionMenu && Instance.AdminMenu != null && Instance.AdminMenu.IsLoaded) {
                from.SendConsoleCommand($"adminmenu userinfo.open {to.UserIDString}");
                return;
            }
            connectionData.selectedPlayer = to;
            connectionData.UI.RenderPlayerActionUI(to);
        }
        private static string GetHexColorForTeam(ulong teamID) {
            return Convert.ToString((int)Math.Floor((Math.Abs(Math.Sin(teamID) * 16777215))), 16);
        }
        private void ExceptPlayers(List<BasePlayer> list, BasePlayer @for = null, bool rustPlus = false) {
            if (@for != null) list.Remove(@for);
            for (int i = 0; i < list.Count; i++) {
                BasePlayer player = list[i];
                if (HasPermission(player.userID, PERMISSION_INVIS) || rustPlus && HasPermission(player.userID, PERMISSION_RUSTPLUSINVIS)) if (list.Remove(player)) i--;
            }
        }
        private static AppMarker GetPlayerMarker(global : : BasePlayer player) {
            AppMarker appMarker = Facepunch.Pool.Get<AppMarker>();
            Vector2 vector = CompanionServer.Util.WorldToMap(player.transform.position);
            appMarker.id = player.net.ID;
            appMarker.type = AppMarkerType.Player;
            appMarker.x = vector.x;
            appMarker.y = vector.y;
            appMarker.steamId = player.userID;
            return appMarker;
        }
        private static bool TryAddAppMarkers(ulong userId, List<AppMarker> markers) {
            if (!Instance.HasPermission(userId, PERMISSION_RUSTPLUS)) return false;
            List<BasePlayer> list = Facepunch.Pool.Get<List<BasePlayer>>();
            list.AddRange(BasePlayer.activePlayerList);
            Instance.ExceptPlayers(list, null, true);
            foreach (BasePlayer player in list) markers.Add(GetPlayerMarker(player));
            Facepunch.Pool.FreeUnmanaged(ref list);
            return true;
        }
        private static AppTeamInfo GetAppTeamInfo(ulong userId) {
            if (!Instance.HasPermission(userId, PERMISSION_RUSTPLUS)) return null;
            AppTeamInfo appTeamInfo = Pool.Get<AppTeamInfo>();
            appTeamInfo.members = Pool.Get<List<AppTeamInfo.Member>>();
            List<BasePlayer> list = Facepunch.Pool.Get<List<BasePlayer>>();
            list.AddRange(BasePlayer.activePlayerList);
            Instance.ExceptPlayers(list, null, true);
            foreach (BasePlayer player in list) {
                AppTeamInfo.Member member = Pool.Get<AppTeamInfo.Member>();
                Vector2 vector = CompanionServer.Util.WorldToMap(player.transform.position);
                member.steamId = player.userID;
                member.name = (player.displayName ?? "");
                member.x = vector.x;
                member.y = vector.y;
                member.isOnline = player.IsConnected;
                AppTeamInfo.Member member2 = member;
                PlayerLifeStory lifeStory = player.lifeStory;
                member2.spawnTime = ((lifeStory != null) ? lifeStory.timeBorn : 0U);
                member.isAlive = player.IsAlive();
                AppTeamInfo.Member member3 = member;
                PlayerLifeStory previousLifeStory = player.previousLifeStory;
                member3.deathTime = ((previousLifeStory != null) ? previousLifeStory.timeDied : 0U);
                appTeamInfo.members.Add(member);
            }
            Facepunch.Pool.FreeUnmanaged(ref list);
            appTeamInfo.leaderSteamId = 0UL;
            appTeamInfo.mapNotes = Pool.Get<List<AppTeamInfo.Note>>();
            appTeamInfo.leaderMapNotes = Pool.Get<List<AppTeamInfo.Note>>();
            return appTeamInfo;
        }
#region Notes
        private void AddTempNote(BasePlayer player, ulong noteId, MapNote note, float time) {
            if (!player.IsConnected) return;
            ConnectionData connectionData = ConnectionData.Get(player.Connection);
            if (connectionData == null) return;
            AddTempNote(connectionData, noteId, note, time);
        }
        private void AddTempNote(ConnectionData data, ulong noteId, MapNote note, float time) {
            note.totalDuration = Time.realtimeSinceStartup + time;
            if (data.tempNotes.TryGetValue(noteId, out MapNote note2)) note2.Dispose();
            data.tempNotes[noteId] = note;
        }
        private MapNote GetNote(int icon, int color, Vector3 worldPosition, NetworkableId associatedId = default(NetworkableId)) {
            return new MapNote {
                noteType = 1, isPing = true, icon = icon, colourIndex = color, worldPosition = worldPosition, associatedId = associatedId
            }
            ;
        }
        private void GetPlayerNotes(IEnumerable<BasePlayer> players, List<MapNote> list, bool withoutLabels = false) {
            const int icon = 6;
            foreach (BasePlayer player in players) {
                int color = player.IsSleeping() ? 3 : 2;
                MapNote note = GetNote(icon, color, player.transform.position, player.net.ID);
                if (!withoutLabels) note.label = player.displayName;
                list.Add(note);
            }
        }
        private void GetTCNotes(IEnumerable<BuildingPrivlidge> privlidges, List<MapNote> list) {
            const int icon = 2;
            foreach (BuildingPrivlidge privlidge in privlidges) {
                int color = Mathf.Clamp(privlidge.authorizedPlayers.Count - 1, 0, 5);
                MapNote note = GetNote(icon, color, privlidge.transform.position, privlidge.net.ID);
                list.Add(note);
            }
        }
        private void GetTCNotes(IEnumerable<SimplePrivilege> privlidges, List<MapNote> list) {
            const int icon = 5;
            foreach (SimplePrivilege privlidge in privlidges) {
                int color = Mathf.Clamp(privlidge.authorizedPlayers.Count - 1, 0, 5);
                MapNote note = GetNote(icon, color, privlidge.transform.position, privlidge.net.ID);
                list.Add(note);
            }
        }
        private void GetTCNotes(List<MapNote> list) {
            GetTCNotes(BaseNetworkable.serverEntities.OfType<BuildingPrivlidge>(), list);
            GetTCNotes(BaseNetworkable.serverEntities.OfType<SimplePrivilege>(), list);
        }
        private void GetStashNotes(IEnumerable<StashContainer> stashes, List<MapNote> list) {
            const int icon = 11;
            foreach (StashContainer stash in stashes) {
                if (stash.inventory.itemList.Count == 0) continue;
                int color = Mathf.Clamp(stash.inventory.itemList.Count - 1, 0, 5);
                MapNote note = GetNote(icon, color, stash.transform.position, stash.net.ID);
                list.Add(note);
            }
        }
        private void GetStashNotes(List<MapNote> list) {
            GetStashNotes(BaseNetworkable.serverEntities.OfType<StashContainer>(), list);
        }
        private void GetSleepingBagNotes(IEnumerable<SleepingBag> sleepingBags, List<MapNote> list) {
            foreach (SleepingBag sleepingBag in sleepingBags) list.Add(GetSleepingBagNote(sleepingBag));
        }
        private MapNote GetSleepingBagNote(SleepingBag sleepingBag) {
            const int icon = 7;
            const int color = 3;
            return GetNote(icon, color, sleepingBag.transform.position, sleepingBag.net.ID);
        }
        private void GetSleepingBagNotes(List<MapNote> list) {
            GetSleepingBagNotes(BaseNetworkable.serverEntities.OfType<SleepingBag>(), list);
        }
#endregion
#endregion
#region Commands
        [ChatCommand("amap")]
        private void amap(BasePlayer player, string command, string[] args) {
            ConnectionData connectionData = ConnectionData.Get(player.Connection);
            if (connectionData != null) {
                if (args.Length > 0 && args[0] == "off") connectionData.Reset();
                else connectionData.UI.RenderSidebar();
            }
        }
        [ConsoleCommand("adminmap.cmd")]
        private void cmd(ConsoleSystem.Arg arg) {
            if (arg.Args.Length < 1) return;
            BasePlayer player = arg.Player();
            if (player == null) return;
            if (!HasPermission(player.userID, PERMISSION_ALLOW)) return;
            ConnectionData connectionData = ConnectionData.Get(player.Connection);
            if (connectionData == null) return;
            switch (arg.GetString(0)) {
                case "player_action" : {
                    Configuration.Button button = config.Buttons.ElementAtOrDefault(arg.GetInt(1, -1));
                    if (!string.IsNullOrEmpty(button.Permission) && !HasPermission(player.userID, $"adminmap.{button.Permission}")) break;
                    string[] commands = button.Command.Split(';');
                    for (int i = 0; i < commands.Length; i++) {
                        string command = commands[i];
                        if (command.First() == '/') command = command.Replace(command, $"chat.say \"{command}\"");
                        command = command.Replace("{steamid}", connectionData.selectedPlayer.UserIDString).Replace("{username}", connectionData.selectedPlayer.displayName).Replace("{admin.steamid}", player.UserIDString).Replace("{admin.username}", player.displayName);
                        player.SendConsoleCommand(command);
                    }
                    break;
                }
                case "teleport" : {
                    NetworkableId networkableId = arg.GetEntityID(1);
                    if (!networkableId.IsValid) break;
                    BaseEntity entity = BaseNetworkable.serverEntities.Find(networkableId) as BaseEntity;
                    if (entity) player.Teleport(entity.transform.position);
                    break;
                }
                case "toggle_layer" : {
                    MapLayer mapLayer = (MapLayer)arg.GetInt(1);
                    if (mapLayer == MapLayer.None) break;
                    if (connectionData.IsLayerActive(mapLayer)) {
                        connectionData.Layers &= ~mapLayer;
                        if (mapLayer == MapLayer.Text) connectionData.RestoreTeam();
                    }
                    else {
                        connectionData.Layers |= mapLayer;
                    }
                    connectionData.UI.RenderSidebar();
                    break;
                }
                case "toggle_mod" : {
                    MapLayerModification layerModification = (MapLayerModification)arg.GetInt(1);
                    if (layerModification == MapLayerModification.None) break;
                    if (connectionData.HasModification(layerModification)) connectionData.Modifications &= ~layerModification;
                    else connectionData.Modifications |= layerModification;
                    connectionData.UI.RenderSidebar();
                    break;
                }
                case "show_player_teammates" : {
                    BasePlayer argPlayer = arg.GetPlayerOrSleeper(1);
                    if (argPlayer == null) break;
                    if (argPlayer.currentTeam == 0) {
                        player.ShowToast(GameTip.Styles.Red_Normal, $"The player is not a member of the team");
                        break;
                    }
                    RelationshipManager.PlayerTeam team = RelationshipManager.ServerInstance.FindTeam(argPlayer.currentTeam);
                    if (team == null) {
                        player.ShowToast(GameTip.Styles.Red_Normal, $"The team #{argPlayer.currentTeam} not found");
                        break;
                    }
                    List<MapNote> notes = Facepunch.Pool.Get<List<MapNote>>();
                    GetPlayerNotes(team.members.Select(userId => BasePlayer.FindAwakeOrSleepingByID(userId)), notes);
                    foreach (MapNote note in notes) {
                        if (note.colourIndex != 3) note.colourIndex = 5;
                        AddTempNote(connectionData, note.associatedId.Value, note, 15);
                    }
                    Facepunch.Pool.FreeUnmanaged(ref notes);
                    connectionData.updater.SendUpdate();
                    player.ShowToast(GameTip.Styles.Blue_Normal, $"Showing {team.members.Count} teammates for 15 sec.");
                    break;
                }
                case "show_player_privlidges" : {
                    BasePlayer argPlayer = arg.GetPlayerOrSleeper(1);
                    if (argPlayer == null) break;
                    var privlidges = BaseNetworkable.serverEntities.OfType<BuildingPrivlidge>().Where(p => p.IsAuthed(argPlayer));
                    var privlidges2 = BaseNetworkable.serverEntities.OfType<SimplePrivilege>().Where(p => p.IsAuthed(argPlayer));
                    int privlidgesCount = privlidges.Count() + privlidges2.Count();
                    if (privlidgesCount > 0) {
                        List<MapNote> notes = Facepunch.Pool.Get<List<MapNote>>();
                        GetTCNotes(privlidges, notes);
                        GetTCNotes(privlidges2, notes);
                        foreach (MapNote note in notes) AddTempNote(connectionData, note.associatedId.Value, note, 10);
                        Facepunch.Pool.FreeUnmanaged(ref notes);
                        connectionData.updater.SendUpdate();
                        player.ShowToast(GameTip.Styles.Blue_Normal, $"Showing {privlidgesCount} privlidges for 10 sec.");
                    }
                    else {
                        player.ShowToast(GameTip.Styles.Red_Normal, $"No privlidges of player {argPlayer.displayName} found");
                    }
                    break;
                }
                case "show_player_sleepingbags" : {
                    BasePlayer argPlayer = arg.GetPlayerOrSleeper(1);
                    if (argPlayer == null) break;
                    var sleepingBags = BaseNetworkable.serverEntities.OfType<SleepingBag>().Where(p => p.deployerUserID == argPlayer.userID);
                    int sleepingBagsCount = sleepingBags.Count();
                    if (sleepingBagsCount > 0) {
                        List<MapNote> notes = Facepunch.Pool.Get<List<MapNote>>();
                        GetSleepingBagNotes(sleepingBags, notes);
                        foreach (MapNote note in notes) AddTempNote(connectionData, note.associatedId.Value, note, 10);
                        Facepunch.Pool.FreeUnmanaged(ref notes);
                        connectionData.updater.SendUpdate();
                        player.ShowToast(GameTip.Styles.Blue_Normal, $"Showing {sleepingBagsCount} sleeping bags for 10 sec.");
                    }
                    else {
                        player.ShowToast(GameTip.Styles.Red_Normal, $"No sleeping bags of player {argPlayer.displayName} found");
                    }
                    break;
                }
                case "show_player_stashes" : {
                    BasePlayer argPlayer = arg.GetPlayerOrSleeper(1);
                    if (argPlayer == null) break;
                    var stashes = BaseNetworkable.serverEntities.OfType<StashContainer>().Where(p => p.OwnerID == argPlayer.userID);
                    int stashesCount = stashes.Count();
                    if (stashesCount > 0) {
                        List<MapNote> notes = Facepunch.Pool.Get<List<MapNote>>();
                        GetStashNotes(stashes, notes);
                        foreach (MapNote note in notes) AddTempNote(connectionData, note.associatedId.Value, note, 10);
                        Facepunch.Pool.FreeUnmanaged(ref notes);
                        connectionData.updater.SendUpdate();
                        player.ShowToast(GameTip.Styles.Blue_Normal, $"Showing {stashesCount} stashes for 10 sec.");
                    }
                    else {
                        player.ShowToast(GameTip.Styles.Red_Normal, $"No stashes of player {argPlayer.displayName} found");
                    }
                    break;
                }
                case "show_owned_item" : {
                    int icon = arg.GetInt(3, 10);
                    int color = arg.GetInt(4, 4);
                    BasePlayer argPlayer = arg.GetPlayerOrSleeper(1);
                    if (argPlayer == null) break;
                    string filter = arg.GetString(2, "");
                    var entities = BaseEntity.Util.FindTargetsOwnedBy(argPlayer.userID, filter);
                    int entitiesCount = entities.Count();
                    if (entitiesCount > 0) {
                        foreach (BaseEntity entity in entities) {
                            MapNote note = GetNote(icon, color, entity.transform.position, entity.net.ID);
                            AddTempNote(connectionData, note.associatedId.Value, note, 15);
                        }
                        connectionData.updater.SendUpdate();
                        player.ShowToast(GameTip.Styles.Blue_Normal, $"Showing {entitiesCount} entities for 15 sec.");
                    }
                    else {
                        player.ShowToast(GameTip.Styles.Red_Normal, $"No entities of player {argPlayer.displayName} found");
                    }
                    break;
                }
            }
        }
#endregion
#region Classes
        public class AdminMapper : FacepunchBehaviour {
            private BasePlayer player;
            void Awake() {
                player = GetComponent<BasePlayer>();
                InvokeRepeating(SendUpdateInternal, 2f, 2f);
            }
            private bool HasPermission() {
                return Instance.HasPermission(player.userID, PERMISSION_ALLOW);
            }
            public void SendUpdate() {
                CancelInvoke(SendUpdateInternal);
                InvokeRepeating(SendUpdateInternal, 0, 2f);
            }
            private List<BasePlayer> GetPooledPlayerList() {
                List<BasePlayer> list = Facepunch.Pool.Get<List<BasePlayer>>();
                list.AddRange(BasePlayer.activePlayerList);
                Instance.ExceptPlayers(list, player);
                return list;
            }
            private void SendUpdateInternal() {
                if (player == null || !player.IsConnected) {
                    Destroy(this);
                    return;
                }
                ConnectionData connectionData = ConnectionData.Get(player.Connection);
                if (!HasPermission()) {
                    Destroy(this);
                    connectionData.Reset();
                    return;
                }
                connectionData.notes.Clear();
                if (connectionData.Layers == MapLayer.None && connectionData.tempNotes.Count == 0) return;
                for (int i = 0; i < connectionData.tempNotes.Count; i++) {
                    var pair = connectionData.tempNotes.ElementAt(i);
                    MapNote note = pair.Value;
                    if (note.totalDuration < Time.realtimeSinceStartup) {
                        connectionData.tempNotes.Remove(pair.Key);
                        i--;
                        continue;
                    }
                }
                List<BasePlayer> players = null;
                bool withoutLabels = connectionData.HasModification(MapLayerModification.NoLabels);
                if (connectionData.IsLayerActive(MapLayer.Player)) Instance.GetPlayerNotes(players ??= GetPooledPlayerList(), connectionData.notes, withoutLabels);
                if (connectionData.IsLayerActive(MapLayer.Sleeper)) Instance.GetPlayerNotes(BasePlayer.sleepingPlayerList, connectionData.notes, withoutLabels);
                if (connectionData.IsLayerActive(MapLayer.TC)) Instance.GetTCNotes(connectionData.notes);
                if (connectionData.IsLayerActive(MapLayer.Stash)) Instance.GetStashNotes(connectionData.notes);
                if (connectionData.IsLayerActive(MapLayer.SleepingBag)) Instance.GetSleepingBagNotes(connectionData.notes);
                connectionData.notes.AddRange(connectionData.tempNotes.Values);
                if (connectionData.IsLayerActive(MapLayer.Text)) {
                    connectionData.textPlayers.Clear();
                    players ??= GetPooledPlayerList();
                    using (PlayerTeam playerTeam = Facepunch.Pool.Get<PlayerTeam>()) {
                        playerTeam.members = Facepunch.Pool.Get<List<PlayerTeam.TeamMember>>();
                        for (int i = 0; i < players.Count; i++) {
                            BasePlayer player = players[i];
                            PlayerTeam.TeamMember teamMember = Facepunch.Pool.Get<PlayerTeam.TeamMember>();
                            string color = config.TextMap.SoloColor;
                            if (player.IsSleeping()) color = config.TextMap.SleeperColor;
                            else if (player.currentTeam > 0) color = (config.TextMap.UseGeneratedTeamsColors ? GetHexColorForTeam(player.currentTeam) : config.TextMap.TeamColor);
                            teamMember.displayName = $"\t\t\t<size={config.TextMap.FontSize * 10}><color=#{color}>{player.displayName}</color></size>\t\t\t";
                            teamMember.healthFraction = 1;
                            teamMember.online = true;
                            teamMember.wounded = true;
                            teamMember.position = player.transform.position;
                            teamMember.userID = (ulong)i;
                            playerTeam.members.Add(teamMember);
                            connectionData.textPlayers.Add(player);
                        }
                        player.ClientRPC<PlayerTeam>(global : : RpcTarget.PlayerAndSpectators("CLIENT_ReceiveTeamInfo", player), playerTeam);
                    }
                }
                player.SendPingsToClient();
                if (players != null) Facepunch.Pool.FreeUnmanaged(ref players);
            }
        }
        public class ConnectionData : IDisposable {
            public Connection connection;
            public List<MapNote> notes = new List<MapNote>();
            public Dictionary<ulong, MapNote> tempNotes = new Dictionary<ulong, MapNote>();
            public List<BasePlayer> textPlayers = new List<BasePlayer>();
            public BasePlayer selectedPlayer;
            public AdminMapper updater;
            private MapLayer layers = MapLayer.None;
            private MapLayerModification modifications = MapLayerModification.None;
            public ConnectionUI UI {
                get;
            }
            public ConnectionData(Connection connection) {
                this.connection = connection;
                this.UI = new ConnectionUI(this);
                BasePlayer player = this.Player;
                if (player == null || !player.IsConnected) return;
                updater = player.gameObject.AddComponent<AdminMapper>();
            }
            public BasePlayer Player {
                get {
                    return connection.player as BasePlayer;
                }
            }
            public MapLayer Layers {
                get {
                    return layers;
                }
                set {
                    layers = value;
                    if (layers == MapLayer.None) Reset();
                    updater.SendUpdate();
                }
            }
            public MapLayerModification Modifications {
                get {
                    return modifications;
                }
                set {
                    modifications = value;
                    updater?.SendUpdate();
                }
            }
            public void Reset() {
                notes.Clear();
                textPlayers.Clear();
                layers = MapLayer.None;
                modifications = MapLayerModification.None;
                selectedPlayer = null;
                RestoreTeam();
                Player.SendPingsToClient();
                UI.Dispose();
            }
            public void RestoreTeam() {
                BasePlayer player = this.Player;
                if (player.currentTeam != 0UL) player.TeamUpdate();
                else player.ClientRPC(RpcTarget.PlayerAndSpectators("CLIENT_ClearTeam", player));
            }
            public bool IsLayerActive(MapLayer mapType) {
                return (this.layers & mapType) == mapType;
            }
            public bool HasModification(MapLayerModification modification) {
                return (this.modifications & modification) == modification;
            }
            public void Dispose() {
                UnityEngine.Object.Destroy(updater);
                Reset();
                all.Remove(connection);
            }
            public static Dictionary<Connection, ConnectionData> all = new Dictionary<Connection, ConnectionData>();
            public static ConnectionData Get(Connection connection) {
                if (connection == null) return null;
                ConnectionData data;
                if (all.TryGetValue(connection, out data)) return data;
                return null;
            }
            public static ConnectionData GetOrCreate(Connection connection) {
                if (connection == null) return null;
                ConnectionData data = Get(connection);
                if (data == null) data = all[connection] = new ConnectionData(connection);
                return data;
            }
        }
        public class ConnectionUI : IDisposable {
            private Connection connection;
            private ConnectionData connectionData;
            private static (Func<ConnectionData, bool> condition, string command, string icon, (string min, string max) offset)[] sidebarButtonsProperties = new (Func<ConnectionData, bool>, string, string, (string, string))[7] {
                ((ConnectionData cd) => cd.IsLayerActive(MapLayer.Player), $"adminmap.cmd toggle_layer {(int)MapLayer.Player}", "assets/content/ui/map/icon-map_pin.png", ("0 1", "0 1")), ((ConnectionData cd) => cd.IsLayerActive(MapLayer.Text), $"adminmap.cmd toggle_layer {(int)MapLayer.Text}", LetterTCRC, ("-0.5 0", "-0.5 0")), ((ConnectionData cd) => cd.IsLayerActive(MapLayer.Sleeper), $"adminmap.cmd toggle_layer {(int)MapLayer.Sleeper}", "assets/content/ui/map/icon-map_sleep.png", ("0 0", "0 0")), ((ConnectionData cd) => cd.IsLayerActive(MapLayer.TC), $"adminmap.cmd toggle_layer {(int)MapLayer.TC}", "assets/content/ui/map/icon-map_home.png", ("-4 -5", "4 3")), ((ConnectionData cd) => cd.IsLayerActive(MapLayer.Stash), $"adminmap.cmd toggle_layer {(int)MapLayer.Stash}", "assets/prefabs/deployable/small stash/small_stash.png", ("6 6", "-6 -6")), ((ConnectionData cd) => cd.IsLayerActive(MapLayer.SleepingBag), $"adminmap.cmd toggle_layer {(int)MapLayer.SleepingBag}", "assets/prefabs/deployable/sleeping bag/sleepingbag.png", ("6 6", "-6 -6")), ((ConnectionData cd) => cd.HasModification(MapLayerModification.NoLabels), $"adminmap.cmd toggle_mod {(int)MapLayerModification.NoLabels}", "assets/content/ui/hypnotized.png", ("4 4", "-4 -4")),
            }
            ;
            public ConnectionUI(ConnectionData connectionData) {
                this.connectionData = connectionData;
                this.connection = connectionData.connection;
            }
            public void RenderSidebar() {
                const string lockedButtonBackground = "0.723 0.035 0 1";
                const string lockedButtonIcon = "0.902 0.282 0.2 1";
                const string disabledButtonBackground = "0.31 0.302 0.294 1";
                const string disabledButtonIcon = "0.565 0.545 0.529 1";
                const string enabledButtonBackground = "0.3568628 0.4431373 0.2235294 1";
                const string enabledButtonIcon = "0.5490196 0.7764707 0.1921569 1";
                CUI.Root root = new CUI.Root("OverlayNonScaled");
                float height = 7 * 32.8f;
                float halfHeight = height * 0.5f;
                var container = root.AddContainer(anchorMin : "0 0.5", anchorMax : "0 0.5", offsetMin : $"3 -{halfHeight}", offsetMax : $"39 {halfHeight}", name : "ADMINMAP_SIDEBAR").AddDestroySelfAttribute();
                container.AddHImage(CapsuleBackgroundVerticalCRC, color : "0 0 0 1");
                for (int i = 0; i < sidebarButtonsProperties.Length; i++) {
                    var prop = sidebarButtonsProperties[i];
                    string command = prop.command;
                    string icon
// ... [Code preview truncated due to length. Full source in attached file] ...

Автор
15FPS
Скачиваний
0
Просмотры
1
Первый выпуск
Обновление
Оценка
0.00 звёзд 0 оценок
Сверху