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

FREE AdvancedStatus : 0.1.21 0.1.21

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6

/*
*  < ----- End-User License Agreement ----->
*  
*  You may not copy, modify, merge, publish, distribute, sublicense, or sell copies of this software without the developer’s consent.*
*  THIS SOFTWARE IS PROVIDED BY IIIaKa AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
*  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
*  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
*  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
*  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*
*  Developer: IIIaKa
*      https://t.me/iiiaka
*      Discord: @iiiaka
*      https://github.com/IIIaKa
*      https://umod.org/user/IIIaKa
*      https://codefling.com/iiiaka
*      https://lone.design/vendor/iiiaka/
*      https://www.patreon.com/iiiaka
*      https://boosty.to/iiiaka
*  Codefling plugin page: https://codefling.com/plugins/advanced-status
*  Codefling license: https://codefling.com/plugins/advanced-status?tab=downloads_field_4
*  
*  Lone.Design plugin page: https://lone.design/product/advanced-status/
*
*  Copyright © 2023-2025 IIIaKa
*/
using HarmonyLib;
using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using Network;
using Facepunch;
using Facepunch.CardGames;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.Networking;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using Oxide.Core.Libraries.Covalence;
namespace Oxide.Plugins {
    [Info("Advanced Status", "IIIaKa", "0.1.21")]
    [Description("A useful API plugin that mimics in-game status bars and allows the addition of custom ones.")]
    class AdvancedStatus : RustPlugin {
        [PluginReference]
        private Plugin ImageLibrary;
#region ~Variables~
        private static AdvancedStatus Instance {
            get;
            set;
        }
        private Harmony _harmony;
        private const string IdForHarmony = "iiiaka.advancedstatus";
        private bool _isReady = false;
        private const string PERMISSION_ADMIN = "advancedstatus.admin", AdvancedStatusName = "AdvancedStatus", DefaultImage = $"{AdvancedStatusName}_Default", GetImage = "GetImage", NoteInv = "note.inv", Hooks_OnLoaded = $"On{AdvancedStatusName}Loaded", Hooks_OnBarDeleted = "OnAdvancedBarDeleted", Hooks_GainedBuilding = "OnPlayerGainedBuildingPrivilege", Hooks_LostBuilding = "OnPlayerLostBuildingPrivilege", Placeholders_UserId = "*userId*", Placeholders_UserName = "*userName*";
        private readonly string[] HttpScheme = new string[] {
            "http://", "https://"
        }
        ;
        private string ImagePath = string.Empty;
        public static Hash<ulong, PlayerWatcher> _playersList;
        public Dictionary<string, string> _imagesList = new Dictionary<string, string>();
        public string[] _cachedBarsContainer = new string[25];
        private readonly HashSet<ItemCategory> _buildingItemsExceptedCategories = new HashSet<ItemCategory> {
            ItemCategory.Attire, ItemCategory.Medical, ItemCategory.Component
        }
        ;
        private readonly Dictionary<ItemCategory, HashSet<int>> _buildingItems = new Dictionary<ItemCategory, HashSet<int>>() {
            {
                ItemCategory.Weapon, new HashSet<int>() {
                    1714509152, -187304968, 1145722690, -759279626, -1290278434
                }
            }
            , {
                ItemCategory.Resources, new HashSet<int>() {
                    634478325
                }
            }
            , {
                ItemCategory.Tool, new HashSet<int>() {
                    1803831286, 200773292
                }
            }
            , {
                ItemCategory.Food, new HashSet<int>() {
                    122783240, 1911552868, 838831151, 803954639, -778875547, 998894949, 1512054436, -2084071424, -1305326964, -1776128552, -886280491, -237809779, 1898094925, -1511285251, 2133269020, 830839496, 390728933, -520133715, 1533551194, -992286106, -798662404, 1004843240, -19360132, -1037472336, 912235912, 1412103380, 924598634, -1790885730
                }
            }
            , {
                ItemCategory.Ammunition, new HashSet<int>() {
                    -484006286, -1827561369
                }
            }
            , {
                ItemCategory.Misc, new HashSet<int>() {
                    573676040, 1242522330, -1973785141, -695124222, 282103175, 809199956, -1679267738, -489848205, -2058362263, 1358643074, -173268125, -173268126, -173268128, -173268129, -173268131, -173268132, 882559853, 1885488976, 2104517339, 699075597, -173268127
                }
            }
        }
        ;
        private readonly Dictionary<ItemCategory, HashSet<int>> _buildingItems2 = new Dictionary<ItemCategory, HashSet<int>>() {
            {
                ItemCategory.Items, new HashSet<int>() {
                    613961768, 696029452, -1501434104, -593892112, 1099611828, 2047789913, -903796529, 1629564540
                }
            }
            , {
                ItemCategory.Electrical, new HashSet<int>() {
                    363163265, -144513264, -566907190, -144417939
                }
            }
            , {
                ItemCategory.Fun, new HashSet<int>() {
                    -2124352573, -1379036069, -1530414568, -1049881973, -1961560162, -979951147, 476066818, -912398867, 1523403414, -583379016, -20045316, -2040817543, 273172220, 576509618, -2107018088, 1784406797, 204970153, 1094293920
                }
            }
        }
        ;
        private readonly HashSet<int> _stackableItems = new HashSet<int>() {
            1055319033, 349762871, 915408809, -1023065463, -1234735557, 215754713, 14241751, 588596902, -2097376851, 785728077, 51984655, -1691396643, -1211166256, -1321651331, 605467368, 1712070256, -1685290200, -1036635990, -727717969, -1800345240, -1671551935, -1199897169, -1199897172, -1023374709, 1553078977, 1401987718, -89874794, -493159321, 1072924620, 1330084809, 926800282, -1802083073, 479143914, 1882709339, 95950017, 1199391518, 1414245522, 1234880403, -1994909036, -1021495308, 642482233, 2019042823, 73681876, 1744298439, 1324203999, -656349006, -7270019, -379734527, -1553999294, -280223496, -515830359, -1306288356, -1486461488, -99886070, 261913429, -454370658, -1538109120, -586342290, -568419968, 1770475779, 1668129151, 989925924, 1973684065, -1848736516, -1440987069, -751151717, -78533081, -1509851560, 1422530437, 1917703890, -1162759543, -1130350864, -682687162, 1536610005, -1709878924, 1272768630, -989755543, 1873897110, -1520560807, 1827479659, 813023040, -395377963, -1167031859, 1391703481, -242084766, 621915341, -996920608, 1819863051, -1770889433, -1824770114, 831955134, -1433390281, 1036321299, 1223900335, -602717596, -126305173, -888153050, 1364514421, -455286320, 1762167092, 1223729384, 1572152877, -282193997, 180752235, -1386082991, 70102328, 22947882, 81423963, 1058261682, -151387974, 550753330, -384243979, 1771755747, 122783240, 1911552868, 1112162468, 838831151, 803954639, 858486327, -1305326964, -1776128552, 1272194103, 2133269020, 830839496, 854447607, 1533551194, -992286106, 1660145984, 390728933, -520133715, 1367190888, -778875547, 998894949, -886280491, -237809779, -2086926071, 1512054436, -2084071424, -567909622, 1898094925, -1511285251, -1018587433, 1776460938, 1719978075, 634478325, -1938052175, -858312878, -321733511, 1568388703, -592016202, -930193596, -265876753, -1579932985, -1982036270, 317398316, 1381010055, -946369541, 69511070, -4031221, -1779183908, -804769727, -544317637, -277057363, -932201673, -2099697608, -1157596551, -1581843485, 1523195708, -1779180711, -151838493, -1366326648, 1735402444, -1673693549, -1513203236, 1858828593, 1601800933, 1348294923, -2035449523, 1130729138, -724146494, 1925646349, 734320711, -798662404, 1004843240, 1414245519, -19360132, -1037472336, -611118083, 912235912, 1412103380, 1178325727, 924598634, -1790885730, -170436364, -1318837358, 392828520, -2100458529, -2095813057, -1081599445, -1616704051, -1796837031, 248643189, -963819285, -594596146, 2036395619, -274709858
        }
        ;
        private static readonly HashSet<string> _doubleMountsList = new HashSet<string>(StringComparer.OrdinalIgnoreCase) {
            "horsesaddle", "horsesaddlerear", "bikedriverseat", "bikepassengerseat"
        }
        ;
        private static readonly HashSet<string> _mountsList = new HashSet<string>(StringComparer.OrdinalIgnoreCase) {
            "motorbikedriverseat", "motorbikepassengerseat", "modularcardriverseat", "modularcarpassengerseatleft", "modularcarpassengerseatright", "modularcarpassengerseatlesslegroomleft", "modularcarpassengerseatlesslegroomright", "modularcarpassengerseatsidewayleft", "miniheliseat", "minihelipassenger", "transporthelipilot", "transporthelicopilot", "attackhelidriver", "attackheligunner", "submarinesolodriverstanding", "submarineduodriverseat", "submarineduopassengerseat", "snowmobiledriverseat", "snowmobilepassengerseat", "snowmobilepassengerseat tomaha", "workcartdriver", "locomotivedriver", "craneoperator", "batteringramseat", "ballistagun.entity"
        }
        ;
        private static readonly string[] _layersList = new string[] {
            "Under", "Overall", "Overlay", "Hud", "Hud.Menu"
        }
        , _fontsList = new string[] {
            "RobotoCondensed-Bold.ttf", "RobotoCondensed-Regular.ttf", "PermanentMarker.ttf", "DroidSansMono.ttf"
        }
        ;
#endregion
#region ~Configuration~
        private static Configuration _config;
        private class Configuration {
            [JsonProperty(PropertyName = "Chat command")]
            public string Command = string.Empty;
            [JsonProperty(PropertyName = "Is it worth enabling console notifications for the successful loading of local images?")]
            public bool Notify_Images = false;
            [JsonProperty(PropertyName = "Interval(in seconds) for counting in-game status bars")]
            public float Count_Interval = 0.5f;
            [JsonProperty(PropertyName = "Interval(in seconds) for counting Building Privilege status bars.Note: Calculating Building Privilege is significantly more resource-intensive than other counts")]
            public float Count_Interval_Privilege = 1f;
            [JsonProperty(PropertyName = "Bar - Display Layer.If you have button bars, it's advisable to use Hud(https://umod.org/guides/rust/basic-concepts-of-gui#layers)")]
            public string Bar_Layer = string.Empty;
            [JsonProperty(PropertyName = "Bar - Left to Right")]
            public bool Bar_LeftToRight = true;
            [JsonProperty(PropertyName = "Bar - Offset between status bars")]
            public int Bar_Offset_Between = 2;
            [JsonProperty(PropertyName = "Bar - Default Height")]
            public int Bar_Height = 26;
            [JsonProperty(PropertyName = "Main - Default Color")]
            public string Bar_Main_Color = string.Empty;
            [JsonProperty(PropertyName = "Main - Default Transparency")]
            public float Bar_Main_Transparency = 0.7f;
            [JsonProperty(PropertyName = "Main - Default Material(empty to disable)")]
            public string Bar_Main_Material = string.Empty;
            [JsonProperty(PropertyName = "Image - Default Image")]
            public string Bar_Image = string.Empty;
            [JsonProperty(PropertyName = "Image - Default Color")]
            public string Bar_Image_Color = string.Empty;
            [JsonProperty(PropertyName = "Image - Default Transparency")]
            public float Bar_Image_Transparency = 1.0f;
            [JsonProperty(PropertyName = "Image - Outline Default Color")]
            public string Bar_Image_Outline_Color = string.Empty;
            [JsonProperty(PropertyName = "Image - Outline Default Transparency")]
            public float Bar_Image_Outline_Transparency = 1.0f;
            [JsonProperty(PropertyName = "Image - Outline Default Distance")]
            public string Bar_Image_Outline_Distance = "0.75 0.75";
            [JsonProperty(PropertyName = "Text - Default Size")]
            public int Bar_Text_Size = 12;
            [JsonProperty(PropertyName = "Text - Default Color")]
            public string Bar_Text_Color = string.Empty;
            [JsonProperty(PropertyName = "Text - Default Transparency")]
            public float Bar_Text_Transparency = 1f;
            [JsonProperty(PropertyName = "Text - Default Font(https://umod.org/guides/rust/basic-concepts-of-gui#fonts)")]
            public string Bar_Text_Font = string.Empty;
            [JsonProperty(PropertyName = "Text - Default Offset Horizontal")]
            public int Bar_Text_Offset_Horizontal = 0;
            [JsonProperty(PropertyName = "Text - Outline Default Color")]
            public string Bar_Text_Outline_Color = string.Empty;
            [JsonProperty(PropertyName = "Text - Outline Default Transparency")]
            public float Bar_Text_Outline_Transparency = 1.0f;
            [JsonProperty(PropertyName = "Text - Outline Default Distance")]
            public string Bar_Text_Outline_Distance = string.Empty;
            [JsonProperty(PropertyName = "SubText - Default Size")]
            public int Bar_SubText_Size = 12;
            [JsonProperty(PropertyName = "SubText - Default Color")]
            public string Bar_SubText_Color = string.Empty;
            [JsonProperty(PropertyName = "SubText - Default Transparency")]
            public float Bar_SubText_Transparency = 1f;
            [JsonProperty(PropertyName = "SubText - Default Font")]
            public string Bar_SubText_Font = string.Empty;
            [JsonProperty(PropertyName = "SubText - Outline Default Color")]
            public string Bar_SubText_Outline_Color = string.Empty;
            [JsonProperty(PropertyName = "SubText - Outline Default Transparency")]
            public float Bar_SubText_Outline_Transparency = 1.0f;
            [JsonProperty(PropertyName = "SubText - Outline Default Distance")]
            public string Bar_SubText_Outline_Distance = string.Empty;
            [JsonProperty(PropertyName = "Progress - Default Color")]
            public string Bar_Progress_Color = string.Empty;
            [JsonProperty(PropertyName = "Progress - Default Transparency")]
            public float Bar_Progress_Transparency = 0.7f;
            [JsonProperty(PropertyName = "Progress - Default OffsetMin")]
            public string Bar_Progress_OffsetMin = string.Empty;
            [JsonProperty(PropertyName = "Progress - Default OffsetMax")]
            public string Bar_Progress_OffsetMax = string.Empty;
            public Oxide.Core.VersionNumber Version;
        }
        protected override void LoadConfig() {
            base.LoadConfig();
            try {
                _config = Config.ReadObject<Configuration>();
            }
            catch (Exception ex) {
                PrintError($"{ex.Message}\n\n[{Title}] Your configuration file contains an error.");
            }
            if (_config == null || _config.Version == new VersionNumber()) {
                PrintWarning("The configuration file is not found or contains errors.Creating a new one...");
                LoadDefaultConfig();
            }
            else if (_config.Version < Version) {
                PrintWarning($"Your configuration file version({_config.Version}) is outdated.Updating it to {Version}.");
                _config.Version = Version;
                PrintWarning($"The configuration file has been successfully updated to version {_config.Version}!");
            }
            if (string.IsNullOrWhiteSpace(_config.Command)) _config.Command = "bar";
            _config.Count_Interval = Mathf.Clamp(_config.Count_Interval, float.Epsilon, 10f);
            _config.Count_Interval_Privilege = Mathf.Clamp(_config.Count_Interval_Privilege, float.Epsilon, 10f);
            if (!_layersList.Contains(_config.Bar_Layer)) _config.Bar_Layer = _layersList[0];
            if (!IsStringHexColor(_config.Bar_Main_Color)) _config.Bar_Main_Color = "#505F75";
            _config.Bar_Main_Transparency = Mathf.Clamp01(_config.Bar_Main_Transparency);
            if (string.IsNullOrWhiteSpace(_config.Bar_Image)) _config.Bar_Image = DefaultImage;
            if (!IsStringHexColor(_config.Bar_Image_Color)) _config.Bar_Image_Color = "#6B7E95";
            _config.Bar_Image_Transparency = Mathf.Clamp01(_config.Bar_Image_Transparency);
            if (!IsStringHexColor(_config.Bar_Image_Outline_Color)) _config.Bar_Image_Outline_Color = "#000000";
            _config.Bar_Image_Outline_Transparency = Mathf.Clamp01(_config.Bar_Image_Outline_Transparency);
            _config.Bar_Text_Size = Math.Clamp(_config.Bar_Text_Size, 1, 25);
            if (!IsStringHexColor(_config.Bar_Text_Color)) _config.Bar_Text_Color = "#FFFFFF";
            _config.Bar_Text_Transparency = Mathf.Clamp01(_config.Bar_Text_Transparency);
            _config.Bar_Text_Font = GetValidFont(_config.Bar_Text_Font);
            if (!IsStringHexColor(_config.Bar_Text_Outline_Color)) _config.Bar_Text_Outline_Color = "#000000";
            _config.Bar_Text_Outline_Transparency = Mathf.Clamp01(_config.Bar_Text_Outline_Transparency);
            if (string.IsNullOrWhiteSpace(_config.Bar_Text_Outline_Distance)) _config.Bar_Text_Outline_Distance = "0.75 0.75";
            _config.Bar_SubText_Size = Math.Clamp(_config.Bar_SubText_Size, 1, 25);
            if (!IsStringHexColor(_config.Bar_SubText_Color)) _config.Bar_SubText_Color = "#FFFFFF";
            _config.Bar_SubText_Transparency = Mathf.Clamp01(_config.Bar_SubText_Transparency);
            _config.Bar_SubText_Font = GetValidFont(_config.Bar_SubText_Font);
            if (!IsStringHexColor(_config.Bar_SubText_Outline_Color)) _config.Bar_SubText_Outline_Color = "#000000";
            _config.Bar_SubText_Outline_Transparency = Mathf.Clamp01(_config.Bar_SubText_Outline_Transparency);
            if (string.IsNullOrWhiteSpace(_config.Bar_SubText_Outline_Distance)) _config.Bar_SubText_Outline_Distance = "0.75 0.75";
            if (!IsStringHexColor(_config.Bar_Progress_Color)) _config.Bar_Progress_Color = "#89B840";
            _config.Bar_Progress_Transparency = Mathf.Clamp01(_config.Bar_Progress_Transparency);
            if (string.IsNullOrWhiteSpace(_config.Bar_Progress_OffsetMin)) _config.Bar_Progress_OffsetMin = "25 2.5";
            if (string.IsNullOrWhiteSpace(_config.Bar_Progress_OffsetMax)) _config.Bar_Progress_OffsetMax = "-3.5 -3.5";
            SaveConfig();
        }
        protected override void SaveConfig() => Config.WriteObject(_config);
        protected override void LoadDefaultConfig() => _config = new Configuration() {
            Version = Version
        }
        ;
#endregion
#region ~Language~
        protected override void LoadDefaultMessages() {
            lang.RegisterMessages(new Dictionary<string, string> {
                ["MsgDays"]
                = "d", ["MsgHours"] = "h", ["MsgMinutes"] = "m", ["MsgSeconds"] = "s"
            }
            , this);
            lang.RegisterMessages(new Dictionary<string, string> {
                ["MsgDays"]
                = "д", ["MsgHours"] = "ч", ["MsgMinutes"] = "м", ["MsgSeconds"] = "с"
            }
            , this, "ru");
        }
#endregion
#region ~Methods~
        private System.Collections.IEnumerator InitPlugin() {
            yield return ServerMgr.Instance.StartCoroutine(InitImages());
            yield return new WaitForSeconds(1);
            foreach (var player in BasePlayer.activePlayerList) {
                if (player.userID.IsSteamId()) InitPlayer(player);
            }
            Subscribe(nameof(OnPluginUnloaded));
            Subscribe(nameof(OnPlayerConnected));
            Subscribe(nameof(OnPlayerDisconnected));
            Subscribe(nameof(OnPlayerSleep));
            Subscribe(nameof(OnPlayerSleepEnded));
            Subscribe(nameof(OnEntityDeath));
            Subscribe(nameof(OnSendCommand));
            Subscribe(nameof(OnEntityMounted));
            Subscribe(nameof(OnEntityDismounted));
            Subscribe(nameof(OnNpcConversationStart));
            Subscribe(nameof(OnNpcConversationEnded));
            Subscribe(nameof(OnActiveTelephoneUpdated));
            _isReady = true;
            yield return new WaitForSeconds(1);
            Interface.CallHook(Hooks_OnLoaded, Version);
        }
        private System.Collections.IEnumerator InitImages() {
            string[] images = Interface.Oxide.DataFileSystem.GetFiles($"{AdvancedStatusName}{Path.DirectorySeparatorChar}Images", "*.png");
            if (images.Any()) {
                int lastSeparator;
                string name, path;
                for (int i = 0; i < images.Length; i++) {
                    path = images[i];
                    if (string.IsNullOrWhiteSpace(path)) continue;
                    lastSeparator = path.LastIndexOf(Path.DirectorySeparatorChar);
                    name = path.Substring(lastSeparator + 1, path.LastIndexOf('.') - lastSeparator - 1);
                    yield return ServerMgr.Instance.StartCoroutine(StoreImage(name, path));
                }
            }
            if (!_imagesList.ContainsKey(DefaultImage)) {
                _imagesList[DefaultImage] = string.Empty;
                PrintError($"The image folder is empty, or the default image is missing!\nFor proper functionality, the file {string.Format(ImagePath, DefaultImage)} must be present! Please reload the plugin after adding it.");
            }
        }
        private System.Collections.IEnumerator StoreImages(Dictionary<string, string> images) {
            foreach (var kvp in images) yield return ServerMgr.Instance.StartCoroutine(StoreImage(kvp.Key, kvp.Value));
        }
        private System.Collections.IEnumerator StoreImage(string name, string path) {
            using (UnityWebRequest request = UnityWebRequestTexture.GetTexture($"file://{path}")) {
                yield return request.SendWebRequest();
                if (request.result != UnityWebRequest.Result.Success) {
                    PrintError($"Failed to load the image '{name}' from '{path}'");
                    yield break;
                }
                Texture2D tex = DownloadHandlerTexture.GetContent(request);
                if (_imagesList.ContainsKey(name)) FileStorage.server.Remove(uint.Parse(_imagesList[name]), FileStorage.Type.png, CommunityEntity.ServerInstance.net.ID);
                _imagesList[name] = FileStorage.server.Store(tex.EncodeToPNG(), FileStorage.Type.png, CommunityEntity.ServerInstance.net.ID).ToString();
                if (_config.Notify_Images) Puts($"The image '{name}' was stored successfully!");
                UnityEngine.Object.DestroyImmediate(tex);
            }
        }
        private void InitPlayer(BasePlayer player) {
            RemovePlayer(player);
            player.gameObject.AddComponent<PlayerWatcher>();
        }
        private void RemovePlayer(BasePlayer player) {
            var playerWatcher = player.gameObject.GetComponent<PlayerWatcher>();
            if (playerWatcher != null) UnityEngine.Object.DestroyImmediate(playerWatcher);
            _playersList.Remove(player.userID);
        }
        private static bool TryGetWatcher(ulong userID, out PlayerWatcher result) => _playersList.TryGetValue(userID, out result);
        public static void AdvancedStatus_JoinTable(CardGameController __instance, ulong userID) {
            if (__instance != null && __instance.IsAtTable(userID) && TryGetWatcher(userID, out var watcher)) watcher.OnVanillaUi(true);
        }
        public static void AdvancedStatus_LeaveTable(ulong userID) {
            if (TryGetWatcher(userID, out var watcher)) watcher.OnVanillaUi(false);
        }
        private bool IsBuildingBlockItem(ItemDefinition itemDef) {
            if (itemDef != null && !_buildingItemsExceptedCategories.Contains(itemDef.category)) {
                if (_buildingItems.TryGetValue(itemDef.category, out var list)) return list.Contains(itemDef.itemid);
                else if (_buildingItems2.TryGetValue(itemDef.category, out var list2)) return !list2.Contains(itemDef.itemid);
                return true;
            }
            return false;
        }
        public static BuildingPrivlidge GetBuildingPrivilege(BasePlayer player) {
            var obb = new OBB(player.transform.position, player.transform.lossyScale, player.transform.rotation, player.bounds);
            BuildingBlock other = null;
            BuildingPrivlidge result = null;
            var obj2 = Pool.Get<List<BuildingBlock>>();
            Vis.Entities(obb.position, 16f + obb.extents.magnitude, obj2, 2097152);
            for (int i = 0; i < obj2.Count; i++) {
                var buildingBlock = obj2[i];
                if (buildingBlock.isServer != player.isServer || !buildingBlock.IsOlderThan(other) || obb.Distance(buildingBlock.WorldSpaceBounds()) > 16f) continue;
                var building = buildingBlock.GetBuilding();
                if (building != null) {
                    var dominatingBuildingPrivilege = building.GetDominatingBuildingPrivilege();
                    if (!(dominatingBuildingPrivilege == null)) {
                        other = buildingBlock;
                        result = dominatingBuildingPrivilege;
                    }
                }
            }
            Pool.FreeUnmanaged(ref obj2);
            return result;
        }
        public static bool TryGetEntityPrivilege(BasePlayer player, out EntityPrivilege result) {
            var obb = new OBB(player.transform.position, player.transform.lossyScale, player.transform.rotation, player.bounds);
            LegacyShelter other = null;
            var shelterList = Pool.Get<List<LegacyShelter>>();
            Vis.Entities(obb.position, 10f, shelterList, 2097152);
            for (int i = 0; i < shelterList.Count; i++) {
                var shelter = shelterList[i];
                if (shelter.isServer != player.isServer || !shelter.IsOlderThan(other) || obb.Distance(shelter.WorldSpaceBounds()) > 3f) continue;
                other = shelter;
            }
            Pool.FreeUnmanaged(ref shelterList);
            result = other?.GetEntityBuildingPrivilege();
            return result != null;
        }
        public static HashSet<VehiclePrivilege> GetVehiclePrivileges(BasePlayer player) {
            var obb = new OBB(player.transform.position, player.transform.lossyScale, player.transform.rotation, player.bounds);
            var result = new HashSet<VehiclePrivilege>();
            var tugList = Pool.Get<List<Tugboat>>();
            Vis.Entities(obb.position, 1f, tugList);
            Tugboat tug;
            VehiclePrivilege privilege;
            for (int i = 0; i < tugList.Count; i++) {
                tug = tugList[i];
                if (tug.isServer != player.isServer || tug.children == null || obb.Distance(tug.WorldSpaceBounds()) > 3f) continue;
                for (int j = 0; j < tug.children.Count; j++) {
                    privilege = tug.children[j] as VehiclePrivilege;
                    if (privilege != null) {
                        result.Add(privilege);
                        break;
                    }
                }
            }
            Pool.FreeUnmanaged(ref tugList);
            return result;
        }
        public static void SortAdvancedBars(List<AdvancedBar> bars) {
            bars.Sort((b1, b2) => {
                int orderComparison = b1.Order.CompareTo(b2.Order);
                return (orderComparison != 0) ? orderComparison : b1.Id.CompareTo(b2.Id);
            }
            );
        }
        public static bool IsStringHexColor(string hexColor) => !string.IsNullOrWhiteSpace(hexColor) && hexColor[0] == '#' && hexColor.Length == 7;
        public static string StringColorFromHex(string hexColor, float transparent) {
            if (string.IsNullOrWhiteSpace(hexColor)) return $"1 1 1 {transparent:F2}";
            if (hexColor[0] != '#' || hexColor.Length < 7) return hexColor;
            int red = Convert.ToInt32(hexColor.Substring(1, 2), 16);
            int green = Convert.ToInt32(hexColor.Substring(3, 2), 16);
            int blue = Convert.ToInt32(hexColor.Substring(5, 2), 16);
            double redPercentage = (double)red / 255;
            double greenPercentage = (double)green / 255;
            double bluePercentage = (double)blue / 255;
            return $"{redPercentage:F2} {greenPercentage:F2} {bluePercentage:F2} {transparent:F2}";
        }
        public static string GetValidFont(string font) {
            if (!string.IsNullOrWhiteSpace(font)) {
                for (int i = 0; i < _fontsList.Length; i++) {
                    if (font.Equals(_fontsList[i], StringComparison.OrdinalIgnoreCase)) return _fontsList[i];
                }
            }
            return _fontsList[0];
        }
#endregion
#region ~API~
        private object IsReady() => _isReady ? true : null;
        private void CreateBar(object obj, Dictionary<string, object> parameters) => CreateBar($"{obj}", parameters);
        private void CreateBar(string userIDStr, Dictionary<string, object> parameters) {
            if (ulong.TryParse(userIDStr, out var userID)) CreateBar(userID, parameters);
        }
        private void CreateBar(BasePlayer player, Dictionary<string, object> parameters) => CreateBar(player.userID.Get(), parameters);
        private void CreateBar(ulong userID, Dictionary<string, object> parameters) {
            /*if (parameters == null || !parameters.TryGetValue("Plugin", out var pNameObj) || pNameObj is not string pluginName ||
                !parameters.TryGetValue("Id", out var bIdObj) || bIdObj is not string barId || !TryGetWatcher(userID, out var watcher)) return;*/
            if (parameters == null || !userID.IsSteamId() || !parameters.TryGetValue("Plugin", out var pNameObj) || pNameObj is not string pluginName || !parameters.TryGetValue("Id", out var bIdObj) || bIdObj is not string barId) return;
            //TODO
            //delete after adding the subscription order to hooks
            //https://github.com/OxideMod/Oxide.Core/pull/103
            if (!TryGetWatcher(userID, out var watcher)) {
                if (BasePlayer.TryFindByID(userID, out var player)) InitPlayer(player);
                if (!TryGetWatcher(userID, out watcher)) {
                    PrintWarning($"Plugin '{pluginName}' is trying to create a status bar for player '{userID}', but its watcher was not found or hasn't been created yet.");
                    return;
                }
            }
            AdvancedBar bar = null;
            for (int i = 0; i < watcher.Bars.Count; i++) {
                var tBar = watcher.Bars[i];
                if (tBar.Plugin.Equals(pluginName, StringComparison.OrdinalIgnoreCase) && tBar.Id.Equals(barId, StringComparison.OrdinalIgnoreCase)) {
                    bar = tBar;
                    break;
                }
            }
            bool isOrder = true;
            if (bar != null) bar.Update(parameters, out var _, out var _, out isOrder);
            else {
                bar = new AdvancedBar(pluginName, barId, parameters);
                watcher.Bars.Add(bar);
            }
            if (isOrder) SortAdvancedBars(watcher.Bars);
            bar.ShouldRemove = false;
            if (watcher.CanShowBars) DrawBars(watcher, !watcher.IsUiActive ? 0 : watcher.Bars.IndexOf(bar));
        }
        private void UpdateContent(object obj, Dictionary<string, object> parameters) => UpdateContent($"{obj}", parameters);
        private void UpdateContent(string userIDStr, Dictionary<string, object> parameters) {
            if (ulong.TryParse(userIDStr, out var userID)) UpdateContent(userID, parameters);
        }
        private void UpdateContent(BasePlayer player, Dictionary<string, object> parameters) => UpdateContent(player.userID.Get(), parameters);
        private void UpdateContent(ulong userID, Dictionary<string, object> parameters) {
            if (parameters == null || !parameters.TryGetValue("Plugin", out var pNameObj) || pNameObj is not string pluginName || !parameters.TryGetValue("Id", out var bIdObj) || bIdObj is not string barId || !TryGetWatcher(userID, out var watcher)) return;
            AdvancedBar bar;
            bool isOrder = false;
            for (int i = 0; i < watcher.Bars.Count; i++) {
                bar = watcher.Bars[i];
                if (bar.Plugin.Equals(pluginName, StringComparison.OrdinalIgnoreCase) && bar.Id.Equals(barId, StringComparison.OrdinalIgnoreCase)) {
                    bar.Update(parameters, out var isProgress, out var isText, out isOrder);
                    if (watcher.IsUiActive) {
                        if (isProgress) DrawProgress(watcher.Player, bar);
                        if (isText) DrawText(watcher.Player, bar);
                    }
                    break;
                }
            }
            if (isOrder) SortAdvancedBars(watcher.Bars);
        }
        private void CreateBar(object obj, Dictionary<int, object> parameters) => CreateBar($"{obj}", parameters);
        private void CreateBar(string userIDStr, Dictionary<int, object> parameters) {
            if (ulong.TryParse(userIDStr, out var userID)) CreateBar(userID, parameters);
        }
        private void CreateBar(BasePlayer player, Dictionary<int, object> parameters) => CreateBar(player.userID.Get(), parameters);
        private void CreateBar(ulong userID, Dictionary<int, object> parameters) {
            /*if (parameters == null || !parameters.TryGetValue(1, out var pNameObj) || pNameObj is not string pluginName ||
                !parameters.TryGetValue(0, out var bIdObj) || bIdObj is not string barId || !TryGetWatcher(userID, out var watcher)) return;*/
            if (parameters == null || !userID.IsSteamId() || !parameters.TryGetValue(1, out var pNameObj) || pNameObj is not string pluginName || !parameters.TryGetValue(0, out var bIdObj) || bIdObj is not string barId) return;
            //TODO
            //delete after adding the subscription order to hooks
            //https://github.com/OxideMod/Oxide.Core/pull/103
            if (!TryGetWatcher(userID, out var watcher)) {
                if (BasePlayer.TryFindByID(userID, out var player)) InitPlayer(player);
                if (!TryGetWatcher(userID, out watcher)) {
                    PrintWarning($"Plugin '{pluginName}' is trying to create a status bar for player '{userID}', but its watcher was not found or hasn't been created yet.");
                    return;
                }
            }
            AdvancedBar bar = null;
            for (int i = 0; i < watcher.Bars.Count; i++) {
                var tBar = watcher.Bars[i];
                if (tBar.Plugin.Equals(pluginName, StringComparison.OrdinalIgnoreCase) && tBar.Id.Equals(barId, StringComparison.OrdinalIgnoreCase)) {
                    bar = tBar;
                    break;
                }
            }
            bool isOrder = true;
            if (bar != null) bar.Update(parameters, out var _, out var _, out isOrder);
            else {
                bar = new AdvancedBar(pluginName, barId, parameters);
                watcher.Bars.Add(bar);
            }
            if (isOrder) SortAdvancedBars(watcher.Bars);
            bar.ShouldRemove = false;
            if (watcher.CanShowBars) DrawBars(watcher, !watcher.IsUiActive ? 0 : watcher.Bars.IndexOf(bar));
        }
        private void UpdateContent(object obj, Dictionary<int, object> parameters) => UpdateContent($"{obj}", parameters);
        private void UpdateContent(string userIDStr, Dictionary<int, object> parameters) {
            if (ulong.TryParse(userIDStr, out var userID)) UpdateContent(userID, parameters);
        }
        private void UpdateContent(BasePlayer player, Dictionary<int, object> parameters) => UpdateContent(player.userID.Get(), parameters);
        private void UpdateContent(ulong userID, Dictionary<int, object> parameters) {
            if (parameters == null || !parameters.TryGetValue(1, out var pNameObj) || pNameObj is not string pluginName || !parameters.TryGetValue(0, out var bIdObj) || bIdObj is not string barId || !TryGetWatcher(userID, out var watcher)) return;
            AdvancedBar bar;
            bool isOrder = false;
            for (int i = 0; i < watcher.Bars.Count; i++) {
                bar = watcher.Bars[i];
                if (bar.Plugin.Equals(pluginName, StringComparison.OrdinalIgnoreCase) && bar.Id.Equals(barId, StringComparison.OrdinalIgnoreCase)) {
                    bar.Update(parameters, out var isProgress, out var isText, out isOrder);
                    if (watcher.IsUiActive) {
                        if (isProgress) DrawProgress(watcher.Player, bar);
                        if (isText) DrawText(watcher.Player, bar);
                    }
                    break;
                }
            }
            if (isOrder) SortAdvancedBars(watcher.Bars);
        }
        private void DeleteBar(object obj, string barId, string pluginName) => DeleteBar($"{obj}", barId, pluginName);
        private void DeleteBar(string userIDStr, string barId, string pluginName) {
            if (ulong.TryParse(userIDStr, out var userID)) DeleteBar(userID, barId, pluginName);
        }
        private void DeleteBar(BasePlayer player, string barId, string pluginName) => DeleteBar(player.userID.Get(), barId, pluginName);
        private void DeleteBar(ulong userID, string barId, string pluginName) {
            if (!TryGetWatcher(userID, out var watcher)) return;
            AdvancedBar bar;
            for (int i = 0; i < watcher.Bars.Count; i++) {
                bar = watcher.Bars[i];
                if (bar.Plugin.Equals(pluginName, StringComparison.OrdinalIgnoreCase) && bar.Id.Equals(barId, StringComparison.OrdinalIgnoreCase)) {
                    bar.ShouldRemove = true;
                    break;
                }
            }
        }
        private void DeleteBarForAll(string barId, string pluginName) {
            AdvancedBar bar;
            foreach (var watcher in _playersList.Values) {
                for (int i = 0; i < watcher.Bars.Count; i++) {
                    bar = watcher.Bars[i];
                    if (bar.Plugin.Equals(pluginName, StringComparison.OrdinalIgnoreCase) && bar.Id.Equals(barId, StringComparison.OrdinalIgnoreCase)) {
                        bar.ShouldRemove = true;
                        break;
                    }
                }
            }
        }
        private void DeleteCategory(object obj, string category, string pluginName) => DeleteCategory($"{obj}", category, pluginName);
        private void DeleteCategory(string userIDStr, string category, string pluginName) {
            if (ulong.TryParse(userIDStr, out var userID)) DeleteCategory(userID, category, pluginName);
        }
        private void DeleteCategory(BasePlayer player, string category, string pluginName) => DeleteCategory(player.userID.Get(), category, pluginName);
        private void DeleteCategory(ulong userID, string category, string pluginName) {
            if (!TryGetWatcher(userID, out var watcher)) return;
            AdvancedBar bar;
            for (int i = 0; i < watcher.Bars.Count; i++) {
                bar = watcher.Bars[i];
                if (bar.Plugin.Equals(pluginName, StringComparison.OrdinalIgnoreCase) && bar.Category.Equals(category, StringComparison.OrdinalIgnoreCase)) bar.ShouldRemove = true;
            }
        }
        private void DeleteCategoryForAll(string category, string pluginName) {
            AdvancedBar bar;
            foreach (var watcher in _playersList.Values) {
                for (int i = 0; i < watcher.Bars.Count; i++) {
                    bar = watcher.Bars[i];
                    if (bar.Plugin.Equals(pluginName, StringComparison.OrdinalIgnoreCase) && bar.Category.Equals(category, StringComparison.OrdinalIgnoreCase)) bar.ShouldRemove = true;
                }
            }
        }
        private void DeleteAllBars(object obj, string pluginName) => DeleteAllBars($"{obj}", pluginName);
        private void DeleteAllBars(string userIDStr, string pluginName) {
            if (ulong.TryParse(userIDStr, out var userID)) DeleteAllBars(userID, pluginName);
        }
        private void DeleteAllBars(BasePlayer player, string pluginName) => DeleteAllBars(player.userID.Get(), pluginName);
        private void DeleteAllBars(ulong userID, string pluginName) {
            if (!TryGetWatcher(userID, out var watcher)) return;
            AdvancedBar bar;
            for (int i = 0; i < watcher.Bars.Count; i++) {
                bar = watcher.Bars[i];
                if (bar.Plugin.Equals(pluginName, StringComparison.OrdinalIgnoreCase)) bar.ShouldRemove = true;
            }
        }
        private void DeleteAllPluginBars(string pluginName) {
            AdvancedBar bar;
            foreach (var watcher in _playersList.Values) {
                for (int i = 0; i < watcher.Bars.Count; i++) {
                    bar = watcher.Bars[i];
                    if (bar.Plugin.Equals(pluginName, StringComparison.OrdinalIgnoreCase)) bar.ShouldRemove = true;
                }
            }
        }
        private int GetTotalClientBars(object obj) => GetTotalClientBars($"{obj}");
        private int GetTotalClientBars(string userIDStr) => ulong.TryParse(userIDStr, out var userID) ? GetTotalClientBars(userID) : 0;
        private int GetTotalClientBars(BasePlayer player) => GetTotalClientBars(player.userID.Get());
        private int GetTotalClientBars(ulong userID) => TryGetWatcher(userID, out var watcher) ? Math.Max(watcher.ClientBars, 0) : 0;
        private int GetTotalPlayerBars(object obj) => GetTotalPlayerBars($"{obj}");
        private int GetTotalPlayerBars(string userIDStr) => ulong.TryParse(userIDStr, out var userID) ? GetTotalPlayerBars(userID) : 0;
        private int GetTotalPlayerBars(BasePlayer player) => GetTotalPlayerBars(player.userID.Get());
        private int GetTotalPlayerBars(ulong userID) {
            int result = 0;
            if (TryGetWatcher(userID, out var watcher)) {
                for (int i = 0; i < watcher.Bars.Count; i++) {
                    if (!watcher.Bars[i].ShouldRemove) result++;
                }
            }
            return result;
        }
        private void LoadImages(List<string> list, bool force = false) {
            Dictionary<string, string> images;
            if (force) images = list.Where(i => !string.IsNullOrWhiteSpace(i)).ToDictionary(i => i, i => string.Format(ImagePath, i));
            else {
                string path;
                images = new Dictionary<string, string>();
                for (int i = 0; i < list.Count; i++) {
                    var name = list[i];
                    if (!string.IsNullOrWhiteSpace(name) && !_imagesList.ContainsKey(name)) {
                        path = string.Format(ImagePath, name);
                        if (!_imagesList.ContainsKey(name) && File.Exists(path)) images[name] = string.Format(ImagePath, name);
                    }
                }
            }
            ServerMgr.Instance.StartCoroutine(StoreImages(images));
        }
        private void LoadImage(string name, bool force = false) {
            if (string.IsNullOrWhiteSpace(name) || (!force && _imagesList.ContainsKey(name))) return;
            string path = string.Format(ImagePath, name);
            if (File.Exists(path)) ServerMgr.Instance.StartCoroutine(StoreImage(name, path));
        }
        private void CopyImage(string source, string newImage, bool force = false) {
            if (string.IsNullOrWhiteSpace(source) || string.IsNullOrWhiteSpace(newImage)) return;
            string sourcePath = string.Format(ImagePath, source), newPath = string.Format(ImagePath, newImage);
            if (File.Exists(sourcePath) && (force || !File.Exists(newPath))) {
                try {
                    File.Copy(sourcePath, newPath, overwrite : true);
                    ServerMgr.Instance.StartCoroutine(StoreImage(newImage, newPath));
                }
                catch {
                }
            }
        }
        private void DeleteImages(List<string> list, bool deleteFile = true) {
            for (int i = 0; i < list.Count; i++) DeleteImage(list[i], deleteFile);
        }
        private void DeleteImage(string name, bool deleteFile = true) {
            if (string.IsNullOrWhiteSpace(name)) return;
            if (_imagesList.TryGetValue(name, out var crcStr)) {
                uint crc = uint.Parse(crcStr);
                FileStorage.server.Remove(crc, FileStorage.Type.png, CommunityEntity.ServerInstance.net.ID);
                _imagesList.Remove(name);
            }
            if (deleteFile) {
                try {
                    File.Delete(string.Format(ImagePath, name));
                }
                catch {
                }
            }
        }
        private bool BarExists(object obj, string barId, string pluginName) => BarExists($"{obj}", barId, pluginName);
        private bool BarExists(string userIDStr, string barId, string pluginName) => ulong.TryParse(userIDStr, out var userID) ? BarExists(userID, barId, pluginName) : false;
        private bool BarExists(BasePlayer player, string barId, string pluginName) => BarExists(player.userID.Get(), barId, pluginName);
        private bool BarExists(ulong userID, string barId, string pluginName) {
            if (TryGetWatcher(userID, out var watcher)) {
                AdvancedBar bar;
                for (int i = 0; i < watcher.Bars.Count; i++) {
                    bar = watcher.Bars[i];
                    if (bar.Plugin.Equals(pluginName, StringComparison.OrdinalIgnoreCase) && bar.Id.Equals(barId, StringComparison.OrdinalIgnoreCase)) return true;
                }
            }
            return false;
        }
        private bool InBuildingPrivilege(object obj) => InBuildingPrivilege($"{obj}");
        private bool InBuildingPrivilege(string userIDStr) => ulong.TryParse(userIDStr, out var userID) ? InBuildingPrivilege(userID) : false;
        private bool InBuildingPrivilege(BasePlayer player) => InBuildingPrivilege(player.userID.Get());
        private bool InBuildingPrivilege(ulong userID) => TryGetWatcher(userID, out var watcher) ? watcher.InOwnBuilding : false;
#endregion
#region ~Oxide Hooks~
        //void OnPlayerConnected(BasePlayer player) => InitPlayer(player);
        void OnPlayerConnected(BasePlayer player) {
            //TODO del
            //https://github.com/OxideMod/Oxide.Core/pull/103
            if (!_playersList.ContainsKey(player.userID)) InitPlayer(player);
        }
   
// ... [Code preview truncated due to length. Full source in attached file] ...

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