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

FREE FloatingText : 1.0.1 1.0.1

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using Newtonsoft.Json;
using UnityEngine;
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using Oxide.Core.Libraries.Covalence;
namespace Oxide.Plugins {
    [Info("Floating Text", "IO Rust Group", "1.0.1")]
    [Description("Create in-world floating text for admins.")]
    class FloatingText : CovalencePlugin {
#region Initialization
        public static FloatingText ft;
        PluginConfig config;
        private GameObject textChecker;
        private List<DDrawData> floatingTextObjects = new List<DDrawData>();
        private void OnServerInitialized() {
            AddCovalenceCommand("addfloatingtext", "AddFloatingText");
            AddCovalenceCommand("findfloatingtext", "FindFloatingText");
            AddCovalenceCommand("removefloatingtext", "RemoveFloatingText");
            AddCovalenceCommand("refreshfloatingtext", "RefreshFloatingText");
            CreateTextHost();
            ft = this;
        }
#endregion
#region Commands
        private void AddFloatingText(IPlayer player, string command, string[] args) {
            if (!player.IsAdmin) {
                PrivateMessage(player, GetLang("notAdmin"));
                return;
            }
            var bPlayer = player.Object as BasePlayer;
            DateTime datetimeends = DateTime.Now;
            var text = "Default Floating Text";
            var size = 25f;
            int minutes = 0;
            var hexColor = "#FFFFFF";
            var drawDistance = 10;
            string message = "addTextSuccess";
            bool isTimed = false;
            Vector3 pos = new Vector3(bPlayer.ServerPosition.x, bPlayer.ServerPosition.y, bPlayer.ServerPosition.z ) + config.generalSettings.PositionOffset;
            try {
                int argCount = 0;
                float argSize = 0;
                if (!args[1].Contains("#") && int.TryParse(args[0], out minutes)) argCount++;
                size = float.Parse(args[argCount]);
                argCount++;
                hexColor = args[argCount];
                argCount++;
                drawDistance = Int32.Parse(args[argCount]);
                argCount++;
                text = string.Join(" ", args.Skip(argCount).ToArray());
            }
            catch {
                PrivateMessage(player, GetLang("addTextBadFormatting"));
                return;
            }
            if (minutes > 0) {
                datetimeends = datetimeends.AddMinutes(minutes);
                isTimed = true;
                message = "addTimedTextSuccess";
            }
            CreateFloatingTextObject(text, size, hexColor, drawDistance, pos, datetimeends, isTimed);
            PrivateMessage(player, GetLang(message));
        }
        private void RemoveFloatingText(IPlayer player, string command, string[] args) {
            if (!player.IsAdmin) {
                PrivateMessage(player, GetLang("notAdmin"));
                return;
            }
            if (args.Length != 1) {
                PrivateMessage(player, GetLang("removeTextBadID"));
                return;
            }
            int textIndex;
            try {
                textIndex = Int32.Parse(args[0]);
            }
            catch {
                PrivateMessage(player, GetLang("removeTextBadID"));
                return;
            }
            if (textIndex > floatingTextObjects.Count - 1 || textIndex < 0) {
                PrivateMessage(player, GetLang("removeTextBadID"));
                return;
            }
            if (DestroyFloatingTextObject(textIndex)) {
                PrivateMessage(player, GetLang("removeTextSuccess"));
                return;
            }
            else {
                PrivateMessage(player, GetLang("removeTextBadID"));
                return;
            }
        }
        private void FindFloatingText(IPlayer player, string command, string[] args) {
            if (!player.IsAdmin) {
                PrivateMessage(player, GetLang("notAdmin"));
                return;
            }
            var bPlayer = player.Object as BasePlayer;
            if (bPlayer.GetComponent<FloatingTextFinder>() == null) {
                bPlayer.gameObject.AddComponent<FloatingTextFinder>().floatingTextObjects = this.floatingTextObjects;
                PrivateMessage(player, GetLang("findTextToggleOn"));
            }
            else if (bPlayer.GetComponent<FloatingTextFinder>() != null) {
                UnityEngine.Object.Destroy(bPlayer.GetComponent<FloatingTextFinder>());
                PrivateMessage(player, GetLang("findTextToggleOff"));
            }
        }
        private void RefreshFloatingText(IPlayer player, string command, string[] args) {
            if (!player.IsAdmin) {
                PrivateMessage(player, GetLang("notAdmin"));
                return;
            }
            LoadConfig();
            LoadData();
            UpdateComponentLists();
            PrivateMessage(player, GetLang("confirmRefresh"));
        }
        private void UpdateComponentLists() {
            foreach (var basePlayer in BasePlayer.activePlayerList) {
                if (basePlayer.GetComponent<FloatingTextFinder>() != null) {
                    basePlayer.GetComponent<FloatingTextFinder>().floatingTextObjects = this.floatingTextObjects;
                }
            }
            if (textChecker != null && textChecker.GetComponent<FloatingTextVisualizer>()) {
                textChecker.GetComponent<FloatingTextVisualizer>().floatingTextObjects = this.floatingTextObjects;
            }
        }
#endregion
#region Create/Destroy Text
        /// <summary>
        /// Create a floating text object for players.Text ID's are automatically assigned./// </summary>
        /// <param name="text">The displayed text string.</param>
        /// <param name="size">How big the text appears.~10 is small, ~25 medium, 50+ is large.</param>
        /// <param name="hexColor">Web hexidecimal color.Parsed by ColorUtility.TryParseHtmlString() to match those requirements.Alpha channel does not work correctly.</param>
        /// <param name="drawDistance">How close a player needs to be to see the text.Players may run past values smaller than 5 before they load in.10-20 is a good starting point.</param>
        /// <param name="position">World position text is drawn.</param>
        public void CreateFloatingTextObject(string text, float size, string hexColor, float drawDistance, Vector3 position, DateTime dateTime, bool IsTextTimed = false) {
            floatingTextObjects.Add(new DDrawData() {
                Text = text, Size = size, HexColor = hexColor, DrawDistance = drawDistance, Position = position, TimeEnds = dateTime, IsTimed = IsTextTimed,
            }
            );
            UpdateComponentLists();
            SaveData();
        }
        /// <summary>
        /// Destroys a floating text object given its index in the floatingTextObject list./// </summary>
        /// <param name="textId">Index in floatingTextObject list.</param>
        /// <returns>Index exists, floating text object deleted.</returns>
        public bool DestroyFloatingTextObject(int textId) {
            if (floatingTextObjects.Count < textId) return false;
            floatingTextObjects.RemoveAt(textId);
            UpdateComponentLists();
            SaveData();
            return true;
        }
#endregion
#region Configuration
        protected override void LoadDefaultConfig() => config = LoadBaseConfig();
        protected override void SaveConfig() => Config.WriteObject(config, true);
        protected override void LoadConfig() {
            base.LoadConfig();
            try {
                config = Config.ReadObject<PluginConfig>();
                if (config == null) throw new JsonException();
                if (config.Version < Version || config.Version > Version) {
                    LogWarning(GetLang("configUpdated"));
                    LoadDefaultConfig();
                }
                SaveConfig();
            }
            catch {
                LoadDefaultConfig();
                LogWarning(GetLang("confCorrupt"));
                SaveConfig();
            }
        }
        private PluginConfig LoadBaseConfig() {
            return new PluginConfig {
                generalSettings = new PluginConfig.GeneralSettings {
                    PositionOffset = new Vector3(0.0f, 1.0f, 0.0f)
                }
                , chatSettings = new PluginConfig.ChatSettings {
                    Announce = true, EnableChatTag = true, ChatTagColor = "4A95CC", ChatMessageColor = "C57039",
                }
                , Version = Version
            }
            ;
        }
        class PluginConfig {
            [JsonProperty(PropertyName = "General Settings")]
            public GeneralSettings generalSettings {
                get;
                set;
            }
            [JsonProperty(PropertyName = "Chat Settings")]
            public ChatSettings chatSettings {
                get;
                set;
            }
            public class GeneralSettings {
                [JsonProperty("Default AddFloatingText position (offset from floor, [X,Y,Z])")]
                public Vector3 PositionOffset {
                    get;
                    set;
                }
                [JsonProperty("Refresh Duration")]
                public float RefreshDuration {
                    get;
                    set;
                }
                = 1f;
                [JsonProperty("Anti Flicker Duration")]
                public float AntiFlickerDuration {
                    get;
                    set;
                }
                = 1f;
            }
            public class ChatSettings {
                [JsonProperty("Announces Plugin Load/Unload")]
                public bool Announce {
                    get;
                    set;
                }
                [JsonProperty("Chat Tag Enabled")]
                public bool EnableChatTag {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Chat Tag Color")]
                public string ChatTagColor {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Chat Message Color")]
                public string ChatMessageColor {
                    get;
                    set;
                }
            }
            [JsonProperty(PropertyName = "Version: ")]
            public Oxide.Core.VersionNumber Version {
                get;
                set;
            }
        }
#endregion
#region Data Files
        private void LoadData() {
            if (Interface.Oxide.DataFileSystem.ExistsDatafile($"{Name}/FloatingTextObjects")) {
                floatingTextObjects = Interface.Oxide.DataFileSystem.ReadObject<List<DDrawData>>($"{Name}/FloatingTextObjects");
            }
            else {
                LogWarning(GetLang("creatingNewData"));
                floatingTextObjects = new List<DDrawData>();
                SaveData();
            }
        }
        private void SaveData() {
            if (floatingTextObjects != null) {
                Interface.Oxide.DataFileSystem.WriteObject($"{Name}/FloatingTextObjects", floatingTextObjects);
            }
            else {
                // Note to developers (or cheeky admins): This should literally never occur
                // because floatingTextObjects is declared as an empty Dictionary (~ln.20)
                // If this happens then who knows what is going wrong :) Maybe check if the
                // plugin has been modified and accidentally sets FloatingTectObjects to null?
                LogWarning(GetLang("calledWhileObjNull"));
            }
        }
        private void OnServerSave() => SaveData();
#endregion
#region Lang
        private string GetLang(string message) => lang.GetMessage(message, this);
        protected override void LoadDefaultMessages() {
            lang.RegisterMessages(new Dictionary<string, string> {
                ["notAdmin"]
                = "You must be admin to use this command.", ["confCorrupt"] = "Config is corrupt.", ["configUpdated"] = "Different version detected, updating config.", ["creatingNewData"] = "Datafile not found! Creating new one.", ["nullAnnounce"] = "Announcement message null.", ["pmNull"] = "Private message null.", ["pluginLoaded"] = "Floating Text By <I/O> Rust Group Loaded.", ["pluginUnloaded"] = "Floating Text By <I/O> Rust Group Unloaded.", ["confirmRefresh"] = "Floating Text datafile has been reloaded.", ["calledWhileObjNull"] = "SaveData was called while FloatingTestObjects is null.This shouldn't happen! " + "Try a restart, then a fresh install.If problems persist, contact a developer.", ["addTextBadFormatting"] = "Formatting incorrect./addfloatingtext [size] [#RRGGBB] [draw distance] [text] or /addfloatingtext [duration (minutes)] [size] [#RRGGBB] [draw distance] [text].Note a draw distance smaller than 10 is not reccomended (players may run past it before it loads!).", ["addTextSuccess"] = "Text created!", ["addTimedTextSuccess"] = "Timed Text created!", ["findTextToggleOn"] = "All floating text has been highlighted./findfloatingtext to toggle it off.", ["findTextToggleOff"] = "No longer highlighting floating text./findfloatingtext to toggle it on.", ["removeTextBadID"] = "Formatting incorrect or invalid ID./removefloatingtext [textid].You can find the text ID using /findfloatingtext, or simply remove the text from the datafile.", ["removeTextSuccess"] = "Floating text object has been removed.Text objects may now have a new ID."
            }
            , this);
        }
#endregion
#region Oxide/Umod
        void Loaded() {
            LoadConfig();
            LoadData();
            if (config.chatSettings.Announce) SendAnnouncement(GetLang("pluginLoaded"));
            ft = this;
        }
        void Unload() {
            foreach (var player in BasePlayer.activePlayerList) {
                if (player.GetComponent<FloatingTextFinder>() != null) {
                    UnityEngine.Object.Destroy(player.GetComponent<FloatingTextFinder>());
                }
            }
            if (textChecker != null) if (textChecker.GetComponent<FloatingTextVisualizer>()) textChecker.GetComponent<FloatingTextVisualizer>().Deactivate();
            if (config.chatSettings.Announce) SendAnnouncement(GetLang("pluginUnloaded"));
        }
        void OnPlayerDisconnected(BasePlayer player, string reason) {
            if (player.GetComponent<FloatingTextFinder>() != null) {
                UnityEngine.Object.Destroy(player.GetComponent<FloatingTextFinder>());
            }
        }
#endregion
#region Helpers
        private void SendAnnouncement(string message) {
            if (message == null) {
                LogWarning(GetLang("nullAnnounce"));
                return;
            }
            foreach (IPlayer player in players.Connected) {
                PrivateMessage(player, message);
            }
        }
        private void PrivateMessage(IPlayer player, string message) {
            if (message == null) {
                LogWarning(GetLang("pmNull"));
                return;
            }
            string tagColor = config.chatSettings.ChatTagColor;
            string msgColor = config.chatSettings.ChatMessageColor;
            string finalMessage = $"<color=#{msgColor}>{message}</color>";
            if (config.chatSettings.EnableChatTag) {
                finalMessage = $"<color=#{tagColor}>[Floating Text]</color> <color=#{msgColor}>{message}</color>";
            }
            player.Reply(finalMessage);
            return;
        }
#endregion
#region Behaviour
        public class FloatingTextVisualizer : MonoBehaviour {
            public List<DDrawData> floatingTextObjects;
            float refreshDuration = ft.config.generalSettings.RefreshDuration;
            float antiFlickerDuration = ft.config.generalSettings.AntiFlickerDuration;
            void Start() {
                if (floatingTextObjects == null) throw new ArgumentNullException("Start()", "FloatingTextObjects is null.The developer has not assigned it when the component was added or the server has not started.");
                Activate();
            }
            void CheckVisibility() {
                foreach (var textObject in floatingTextObjects) {
                    if (textObject.IsTimed) {
                        if (DateTime.Compare(DateTime.Now, textObject.TimeEnds) >= 1) {
                            continue;
                        }
                    }
                    //("{0} {1} {2}", earlier, sameas, layerthan);
                    List<BasePlayer> players = new List<BasePlayer>();
                    Vis.Entities<BasePlayer>(textObject.Position, textObject.DrawDistance, players);
                    foreach (BasePlayer player in players) {
                        if (player != null && player.IsConnected && !player.IsSleeping()) {
                            CreateFloatingText(player, textObject);
                        }
                    }
                }
            }
            private void CreateFloatingText(BasePlayer player, DDrawData textData) {
                if (player == null) return;
                var textColor = Color.white;
                ColorUtility.TryParseHtmlString(textData.HexColor, out textColor);
                if (player.IsAdmin) {
                    player.SendConsoleCommand ("ddraw.text", refreshDuration + antiFlickerDuration, textColor, textData.Position, $"<size={textData.Size}>{textData.Text}</size>" );
                }
                else {
                    player.SetPlayerFlag(BasePlayer.PlayerFlags.IsAdmin, true);
                    player.SendNetworkUpdateImmediate();
                    player.SendConsoleCommand ("ddraw.text", refreshDuration + antiFlickerDuration, textColor, textData.Position, $"<size={textData.Size}>{textData.Text}</size>" );
                    player.SetPlayerFlag(BasePlayer.PlayerFlags.IsAdmin, false);
                    player.SendNetworkUpdateImmediate();
                }
            }
            public void Activate() {
                InvokeRepeating("CheckVisibility", 0, refreshDuration);
            }
            public void Deactivate() {
                UnityEngine.Object.Destroy(gameObject);
                Destroy(this);
            }
        }
        public class FloatingTextFinder : MonoBehaviour {
            private BasePlayer player;
            public List<DDrawData> floatingTextObjects;
            float refreshDuration = 2;
            void Start() {
                if (floatingTextObjects == null) throw new ArgumentNullException("Start()", "FloatingTextObjects is null.The developer has not assigned it when the component was added.");
                player = gameObject.GetComponent<BasePlayer>();
                Activate();
            }
            void CreateFloatingText() {
                for (int i = 0; i < floatingTextObjects.Count; i++) {
                    DrawTextTracker(refreshDuration, floatingTextObjects[i].Position, i);
                }
            }
            private void DrawTextTracker(float duration, Vector3 textPosition, int textIndex) {
                if (player.IsAdmin) {
                    player.SendConsoleCommand ("ddraw.text", duration, Color.yellow, textPosition += new Vector3(0f, 0.5f, 0f), "<size=40>×</size>" );
                    player.SendConsoleCommand ("ddraw.text", duration, Color.yellow, textPosition += new Vector3(0f, 0.6f, 0f), $"<size=20>{textIndex}</size>" );
                }
                else {
                    player.SetPlayerFlag(BasePlayer.PlayerFlags.IsAdmin, true);
                    player.SendNetworkUpdateImmediate();
                    player.SendConsoleCommand ("ddraw.text", duration, Color.yellow, textPosition += new Vector3(0f, 0.5f, 0f), "<size=40>×</size>" );
                    player.SendConsoleCommand ("ddraw.text", duration, Color.yellow, textPosition += new Vector3(0f, 0.75f, 0f), $"<size=20>{textIndex}</size>" );
                    player.SetPlayerFlag(BasePlayer.PlayerFlags.IsAdmin, false);
                    player.SendNetworkUpdateImmediate();
                }
            }
            public void Activate() {
                if (player != null) {
                    InvokeRepeating("CreateFloatingText", 0, refreshDuration);
                }
            }
        }
        public class DDrawData {
            [JsonProperty(PropertyName = "Text")]
            public string Text {
                get;
                set;
            }
            [JsonProperty(PropertyName = "Size")]
            public float Size {
                get;
                set;
            }
            [JsonProperty(PropertyName = "Color (#RRGGBB)")]
            public string HexColor {
                get;
                set;
            }
            [JsonProperty(PropertyName = "Position (X,Y,Z)")]
            public Vector3 Position {
                get;
                set;
            }
            [JsonProperty("Draw Distance")]
            public float DrawDistance {
                get;
                set;
            }
            [JsonProperty("Time Ends")]
            public DateTime TimeEnds {
                get;
                set;
            }
            [JsonProperty("Is Timed")]
            public bool IsTimed {
                get;
                set;
            }
        }
#endregion
#region Other
        private void CreateTextHost() {
            var entity = GameManager.server.CreateEntity("assets/prefabs/visualization/sphere.prefab", new Vector3(0, TerrainMeta.HeightMap.GetHeight(new Vector3(0, 0, 0)) - 10, 0)).GetComponent<SphereEntity>();
            entity.currentRadius = 1;
            entity.lerpSpeed = 0f;
            textChecker = entity.gameObject;
            textChecker.AddComponent<FloatingTextVisualizer>().floatingTextObjects = this.floatingTextObjects;
            entity.Spawn();
        }
#endregion
    }
}

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