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

FREE UnderwearSelection : 1.0.4 1.0.4

Нет прав для скачивания
C#:
using Oxide.Core;
using Oxide.Core.Libraries.Covalence;
using Oxide.Game.Rust.Cui;
using Oxide.Core.Plugins;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;

namespace Oxide.Plugins
{
    [Info("Underwear Selection", "Marat", "1.0.4")]
    [Description("Allows players to customize their underwear appearance")]
    class UnderwearSelection : RustPlugin
    {
        [PluginReference] private Plugin ImageLibrary;
        
        #region Field
        
        private const string InitialLayer = "UI_UnderwearLayer";
        private const string permissionUse = "underwearselection.use";
        
        #endregion
        
        #region Oxide Hooks
        
        private void OnServerInitialized()
        {
            if (ImageLibrary == null)
            {
                PrintError("[ImageLibrary] not found! Plugin is disabled!");
                Interface.Oxide.UnloadPlugin(Title);
                return;
            }
            
            foreach (var list in config.Underwear)
            {
                ImageLibrary.Call("AddImage", list.UrlMale, $"{list.Title}.Male");
                ImageLibrary.Call("AddImage", list.UrlFemale, $"{list.Title}.Female");
            }
            
            LoadData();
            AddCovalenceCommand(config.Commands, nameof(CmdChangeWear));
            permission.RegisterPermission(permissionUse, this);
            
            for (int i = 0; i < BasePlayer.activePlayerList.Count; i++)
            {
                OnPlayerConnected(BasePlayer.activePlayerList[i]);
            }
        }
        
        private void Unload()
        {
            for (int i = 0; i < BasePlayer.activePlayerList.Count; i++)
            {
                var player = BasePlayer.activePlayerList[i];
                CuiHelper.DestroyUi(player, InitialLayer);
                player.nextUnderwearValidationTime = Time.time + 0.2f;
                ServerMgr.Instance?.StopCoroutine(PreloadImages(player));
            }
            SaveData();
            config = null;
        }
        
        private void OnServerSave() => SaveData();
        
        private void OnPlayerConnected(BasePlayer player)
        {
            if (player == null || !player.IsConnected) return;
            if (player.IsReceivingSnapshot)
            {
                timer.Once(1f, () => OnPlayerConnected(player));
                return;
            }
            ServerMgr.Instance?.StartCoroutine(PreloadImages(player));
            
            if (!storedData.PlayerData.TryGetValue(player.userID, out var data))
            {
                data = new Data { id = player.lastValidUnderwearSkin, enable = false };
                storedData.PlayerData.Add(player.userID, data);
            }
            if (config.SkinConnection != 0)
            {
                data.enable = true;
                UnderwearChange(player, config.SkinConnection);
                return;
            }
            if (!permission.UserHasPermission(player.UserIDString, permissionUse)) return;
            UnderwearChange(player, data.id);
        }
        
        private void OnPlayerDisconnected(BasePlayer player)
        {
            player.nextUnderwearValidationTime = Time.time + 0.2f;
            ServerMgr.Instance?.StopCoroutine(PreloadImages(player));
        }
        
        private void OnPlayerRespawned(BasePlayer player)
        {
            if (player == null || !player.IsConnected) return;
            if (!storedData.PlayerData.TryGetValue(player.userID, out var data))
            {
                data = new Data { id = player.lastValidUnderwearSkin, enable = false };
                storedData.PlayerData.Add(player.userID, data);
            }
            if (config.UseRandomSkin)
            {
                var random = new System.Random();
                var randomUnderwear = config.Underwear[random.Next(config.Underwear.Count)];
                data.enable = true;
                UnderwearChange(player, randomUnderwear.Id);
                return;
            }
            if (!permission.UserHasPermission(player.UserIDString, permissionUse)) return;
            UnderwearChange(player, data.id);
        }
        
        #endregion
        
        #region Configuration
        
        private static PluginConfig config;
        
        private class PluginConfig
        {
            [JsonProperty("Commands")] public string[] Commands;
            [JsonProperty("Forced underwear skin when a player connects")] public uint SkinConnection;
            [JsonProperty("Random underwear skin upon respawn")] public bool UseRandomSkin;
            [JsonProperty("Image and description")] public List<ItemInfo> Underwear;
        }
        
        protected override void LoadDefaultConfig()
        {
            config = new PluginConfig
            {
                Commands = new string[] {"uw", "wear", "underwear"},
                SkinConnection = 0,
                UseRandomSkin = false,
                Underwear = new List<ItemInfo>()
                {
                    new("Scribble", 792014640, "https://i.ibb.co/cvFYv4B/scribble-male.png", "https://i.ibb.co/mHLj0FP/scribble-female.png"),
                    new("Gradient", 241501709, "https://i.ibb.co/MG5GMKh/gradient-male.png", "https://i.ibb.co/b70811b/gradient-female.png"),
                    new("PalmLeaves", 1756736103, "https://i.ibb.co/YQFnzZm/palmleaves-male.png", "https://i.ibb.co/z6dhs5R/palmleaves-female.png"),
                    new("Bikini/Rapido", 359039573, "https://i.ibb.co/42pYF1D/rapido-male.png", "https://i.ibb.co/j3wZXF4/pink-bikini.png"),
                    new("Coconut", 3797783720, "https://i.ibb.co/5RcSNsW/coconut-female-male.png", "https://i.ibb.co/5RcSNsW/coconut-female-male.png"),
                    new("MummyWraps", 1154108357, "https://i.ibb.co/3SWCyj2/mummywraps-male.png", "https://i.ibb.co/p15j3cD/mummywraps-female.png"),
                    new("Purple", 1967073602, "https://i.ibb.co/yVCBwSD/purple-male.png", "https://i.ibb.co/0QnjzKT/purple-female.png"),
                    new("GrassSkirt", 4122325535, "https://i.ibb.co/8XvwtzS/grassskirt-male.png", "https://i.ibb.co/T4Yg0Cm/grassskirt-top-female.png")
                }
            };
        }
        
        private class ItemInfo
        {
            public string Title;
            public uint Id;
            public string UrlMale;
            public string UrlFemale;
            
            public ItemInfo(string title, uint id, string urlMale, string urlFemale)
            {
                Title = title;
                Id = id;
                UrlMale = urlMale;
                UrlFemale = urlFemale;
            }
        }
        
        protected override void SaveConfig() => Config.WriteObject(config);
        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                config = Config.ReadObject<PluginConfig>();
                if (config == null) LoadDefaultConfig();
            }
            catch
            {
                PrintWarning("The config file contains an error and has been replaced with the default config.");
                LoadDefaultConfig();
            }
            SaveConfig();
        }
        
        #endregion
        
        #region Commands
        
        private void CmdChangeWear(IPlayer ipPlayer, string command, string[] arg)
        {
            var player = ipPlayer?.Object as BasePlayer;
            if (player == null) return;
            if (!permission.UserHasPermission(player.UserIDString, permissionUse))
            {
                PrintToChat(player, GetMessage("Lang_NoPermissions", player));
                return;
            }
            InitializeLayers(player, true);
        }
        
        [ConsoleCommand("setwear")]
        private void CmdConsoleExpPlus(ConsoleSystem.Arg arg)
        {
            if (!arg.IsAdmin) return;
            if (arg.Args == null || arg.Args.Length <= 0 || arg.Args.Length < 2)
            {
                SendReply(arg, "Invalid syntax. Use setwear {name/steamId} {skinId}");
                return;
            }
            var player = BasePlayer.Find(arg.Args[0]);
            if (player == null)
            {
                SendReply(arg, "Player not found. Check the correct spelling of the player name or steamId.");
                return;
            }
            if (!uint.TryParse(arg.Args[1], out uint index) || config.Underwear.Find(x => x.Id == index) == null)
            {
                SendReply(arg, $"SkinId [{index}] not found. Check the correct spelling of the skin ID.");
                return;
            }
            if (!storedData.PlayerData.ContainsKey(player.userID))
            {
                SendReply(arg, $"Player not found. {player} is missing from the plugin database.");
                return;
            }
            var data = storedData.PlayerData[player.userID];
            data.id = index;
            data.enable = true;
            UnderwearChange(player, index);
            SendReply(arg, $"SkinId [{index}] was successfully set to player {player}.");
        }
        
        [ConsoleCommand("UI_WearController")]
        private void CmdConsoleHandler(ConsoleSystem.Arg arg)
        {
            var player = arg.Player();
            if (player == null || !arg.HasArgs(1)) return;
            var data = storedData.PlayerData[player.userID];
            switch (arg.Args[0].ToLower())
            {
                case "choose":
                {
                    if (!uint.TryParse(arg.Args[1], out uint index)) return;
                    data.id = index;
                    data.enable = true;
                    UnderwearChange(player, index);
                    InitializeLayers(player, false);
                    EffectNetwork.Send(new Effect("assets/prefabs/npc/autoturret/effects/targetlost.prefab", player, 0, new Vector3(), new Vector3()), player.Connection);
                    break;
                }
                case "enabled":
                {
                    var enable = !data.enable;
                    data.enable = enable;
                    if (!data.enable) player.nextUnderwearValidationTime = Time.time + 0.2f;
                    InitializeLayers(player, false);
                    break;
                }
            }
        }
        
        #endregion
        
        #region Methods
        
        private void UnderwearChange(BasePlayer player, uint id)
        {
            if (!storedData.PlayerData[player.userID].enable) return;
            player.nextUnderwearValidationTime = float.PositiveInfinity;
            player.lastValidUnderwearSkin = id;
            player.SendNetworkUpdateImmediate();
        }
        
        private string GetMessage(string key, BasePlayer player)
        {
            return lang.GetMessage(key, this, player.UserIDString);
        }
        
        #endregion
        
        #region Interfaces
        
        private void InitializeLayers(BasePlayer player, bool update)
        {
            float fade = !update ? 0f : 0.25f;
            var data = storedData.PlayerData[player.userID];
            
            CuiElementContainer container = new CuiElementContainer();
            
            container.Add(new CuiElement()
            {
                Parent = "Overlay",
                Name = InitialLayer,
                DestroyUi = InitialLayer,
                Components =
                {
                    new CuiRectTransformComponent { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "0 0", OffsetMax = "0 0" },
                    new CuiImageComponent { Color = "0.235 0.227 0.2 0.9" },
                    new CuiNeedsCursorComponent()
                }
            });
            
            container.Add(new CuiButton()
            {
                RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "0 0", OffsetMax = "0 0" },
                Button = { Close = InitialLayer, Color = "0.141 0.137 0.096 0.98", Sprite = "assets/content/ui/ui.background.transparent.radial.psd" }
            }, InitialLayer);
            
            container.Add(new CuiPanel()
            {
                RectTransform = { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = $"-440 -300", OffsetMax = $"440 300" },
                Image = { Color = "0.11 0.12 0.10 0.8", Material = "assets/content/ui/uibackgroundblur.mat", FadeIn = fade }
            }, InitialLayer, InitialLayer + ".Main");
            
            container.Add(new CuiPanel()
            {
                RectTransform = { AnchorMin = "0 1", AnchorMax = "1 1", OffsetMin = $"0 -50", OffsetMax = $"0 0" },
                Image = { Color = "0.08 0.08 0.08 0.8", Material = "assets/content/ui/uibackgroundblur.mat", FadeIn = fade }
            }, InitialLayer + ".Main", InitialLayer + ".Title");
            
            container.Add(new CuiLabel()
            {
                RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "0 0", OffsetMax = "0 0" },
                Text = { Text = GetMessage("Lang_Title", player).ToUpper(), Color = "0.78 0.74 0.70 1.0", FontSize = 20, Font = "robotocondensed-bold.ttf", Align = TextAnchor.MiddleCenter, FadeIn = fade }
            }, InitialLayer + ".Title");
            
            container.Add(new CuiPanel()
            {
                RectTransform = { AnchorMin = "0 0.5", AnchorMax = "0 0.5", OffsetMin = $"20 -13", OffsetMax = $"120 13" },
                Image = { Color = "0.11 0.12 0.10 0.8", Material = "assets/content/ui/uibackgroundblur.mat", FadeIn = fade }
            }, InitialLayer + ".Title", InitialLayer + ".Toggle");
            
            var text = GetMessage(data.enable ? "Lang_Enable" : "Lang_Disable", player);
            var offsetMin = data.enable ? "1 1" : "50 1";
            var offsetMax = data.enable ? "-50 -1" : "-1 -1";
            
            container.Add(new CuiButton()
            {
                RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = offsetMin, OffsetMax = offsetMax },
                Button = { Command = $"UI_WearController enabled", Color = data.enable ? "0.36 0.44 0.22 1.0" : "0.71 0.22 0.15 1.0", Material = "assets/content/ui/uibackgroundblur.mat" },
                Text = { Text = text.ToUpper(), Color = data.enable ? "0.78 0.74 0.70 1.0" : "0.78 0.74 0.70 0.6", FontSize = 12, Font = "robotocondensed-bold.ttf", Align = TextAnchor.MiddleCenter }
            }, InitialLayer + ".Toggle");
            
            container.Add(new CuiButton()
            {
                RectTransform = { AnchorMin = "1 1", AnchorMax = "1 1", OffsetMin = "-25 -25", OffsetMax = "-5 -5" },
                Button = { Close = InitialLayer, Color = "0.71 0.22 0.15 1.0", Sprite = "assets/icons/close.png" }
            }, InitialLayer + ".Main");
            
            const int marginTop = 18, margin = 15, width = 200, height = 250;
            
            for (var i = 0; i < config.Underwear.Count; i++)
            {
                var offsetX = i % 4 * (width + margin) - (2 * width + 1.5 * margin);
                var offsetY = -i / 4 * (height + margin) - marginTop;
                
                container.Add(new CuiPanel()
                {
                    RectTransform = { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = $"{offsetX} {offsetY}", OffsetMax = $"{offsetX + width} {offsetY + height}" },
                    Image = { Color = "0.19 0.23 0.14 1.0", Material = "assets/content/ui/uibackgroundblur.mat", FadeIn = fade }
                }, InitialLayer + ".Main", InitialLayer + $".Button.{i}");
                
                var isSelected = player.lastValidUnderwearSkin == config.Underwear[i].Id;
                var image = Underwear.IsFemale(player) ? $"{config.Underwear[i].Title}.Female" : $"{config.Underwear[i].Title}.Male";
                
                container.Add(new CuiElement()
                {
                    Parent = InitialLayer + $".Button.{i}",
                    Name = InitialLayer + $".Image.{i}",
                    DestroyUi = InitialLayer + $".Image.{i}",
                    Components =
                    {
                        new CuiRectTransformComponent { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-85 -72", OffsetMax = "85 98" },
                        new CuiRawImageComponent { Png = (string) ImageLibrary.Call("GetImage", image), Color = "1 1 1 1" }
                    }
                });
                
                if (isSelected)
                {
                    container.Add(new CuiPanel()
                    {
                        RectTransform = { AnchorMin = "1 1", AnchorMax = "1 1", OffsetMin = "-30 -28", OffsetMax = "-10 -10" },
                        Image = { Color = "0.81 0.77 0.74 0.8", Sprite = "assets/icons/clothing.png" }
                    }, InitialLayer + $".Button.{i}");
                }
                
                container.Add(new CuiPanel()
                {
                    RectTransform = { AnchorMin = "0 0", AnchorMax = "1 0", OffsetMin = "0 0", OffsetMax = "0 26" },
                    Image = { Color = "0 0 0 0.6" }
                }, InitialLayer + $".Button.{i}", InitialLayer + $".Title.{i}");
                
                string[] parts = config.Underwear[i].Title.Split('/');
                string genderTitle = Underwear.IsFemale(player) ? parts[0] : (parts.Length > 1 ? parts[1] : parts[0]);
                
                container.Add(new CuiLabel()
                {
                    RectTransform = { AnchorMin = "0 0", AnchorMax = "0 0", OffsetMin = "10 0", OffsetMax = "125 26" },
                    Text = { Text = GetMessage($"{genderTitle}", player).ToUpper(), Color = "0.81 0.77 0.74 1.0", FontSize = 11, Font = "robotocondensed-bold.ttf", Align = TextAnchor.MiddleLeft }
                }, InitialLayer + $".Title.{i}");
                
                var textTitle = GetMessage(isSelected ? "Lang_Installed" : "Lang_Apply", player);
                var colorTitle = !isSelected ? "0.59 0.84 0.18 1.0" : "0.30 0.65 0.90 1.0";
                var colorButton = !isSelected ? "0.30 0.36 0.16 1.0" : "0.20 0.30 0.40 1.0";
                var command = !isSelected ? $"UI_WearController choose {config.Underwear[i].Id}" : "";
                
                container.Add(new CuiButton()
                {
                    RectTransform = { AnchorMin = "1 0", AnchorMax = "1 0", OffsetMin = "-75 0", OffsetMax = "0 26" },
                    Button = { Command = command, Color = colorButton, Material = "assets/content/ui/uibackgroundblur.mat" },
                    Text = { Text = textTitle.ToUpper(), Color = colorTitle, FontSize = 11, Font = "robotocondensed-bold.ttf", Align = TextAnchor.MiddleCenter }
                }, InitialLayer + $".Title.{i}");
            }
            
            CuiHelper.AddUi(player, container);
        }
        
        private IEnumerator PreloadImages(BasePlayer player)
        {
            if (player == null || !player.IsConnected) yield break;
            for (var i = 0; i < config.Underwear.Count; i++)
            {
                var image = $"{config.Underwear[i].Title}.{(Underwear.IsFemale(player) ? "Female" : "Male")}";
                CuiElementContainer temp = new CuiElementContainer();
                
                temp.Add(new CuiElement()
                {
                    Parent = "Hud",
                    Name = $".{i}",
                    Components =
                    {
                        new CuiRectTransformComponent { AnchorMin = "0 0", AnchorMax = "0 0" },
                        new CuiRawImageComponent { Png = (string) ImageLibrary?.Call("GetImage", image) }
                    }
                });
                
                CuiHelper.AddUi(player, temp);
                yield return new WaitForSeconds(1.0f);
                CuiHelper.DestroyUi(player, $".{i}");
            }
        }
        
        #endregion
        
        #region Language
        
        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["Lang_NoPermissions"] = "You don't have permission to use this command.",
                ["Lang_Title"] = "Underwear Selection",
                ["Lang_Apply"] = "Apply",
                ["Lang_Installed"] = "Installed",
                ["Lang_Enable"] = "On",
                ["Lang_Disable"] = "Off",
                ["Scribble"] = "Scribble",
                ["Gradient"] = "Gradient",
                ["PalmLeaves"] = "Palm Leaves",
                ["Bikini"] = "Pink Bikini",
                ["Rapido"] = "Rapido",
                ["Coconut"] = "Coconut",
                ["MummyWraps"] = "Mummy Wraps",
                ["Purple"] = "Purple",
                ["GrassSkirt"] = "Grass Skirt"
            }, this);
            
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["Lang_NoPermissions"] = "У вас нет разрешения на использование этой команды.",
                ["Lang_Title"] = "Выбор нижнего белья",
                ["Lang_Apply"] = "Применить",
                ["Lang_Installed"] = "Установлен",
                ["Lang_Enable"] = "Вкл",
                ["Lang_Disable"] = "Выкл",
                ["Scribble"] = "Каракули",
                ["Gradient"] = "Градиент",
                ["PalmLeaves"] = "Пальмовые листья",
                ["Bikini"] = "Розовое бикини",
                ["Rapido"] = "Rapido",
                ["Coconut"] = "Кокос",
                ["MummyWraps"] = "Mummy Wraps",
                ["Purple"] = "Фиолетовое белье",
                ["GrassSkirt"] = "Травяная юбка"
            }, this, "ru");
        }
        
        #endregion
        
        #region Data
        
        private StoredData storedData;
        
        private class StoredData
        {
            public Dictionary<ulong, Data> PlayerData = new Dictionary<ulong, Data>();
        }
        
        private class Data
        {
            public uint id;
            public bool enable;
        }
        
        private void SaveData()
        {
            if (storedData != null)
            {
                Interface.Oxide.DataFileSystem.WriteObject($"{Name}_Data", storedData, true);
            }
        }
        
        private void LoadData()
        {
            storedData = Interface.Oxide.DataFileSystem.ReadObject<StoredData>($"{Name}_Data");
            if (storedData == null)
            {
                storedData = new StoredData();
                SaveData();
            }
        }
        
        #endregion
    }
}

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