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

FREE Skins : 2.0.0 2.0.0

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Libraries.Covalence;
using Oxide.Game.Rust.Cui;
using Object = UnityEngine.Object;

namespace Oxide.Plugins
{
    [Info("Skins", "Iv Misticos", "2.0.0")]
    [Description("Allow players to change items skin with the skin from steam workshop.")]
    class Skins : RustPlugin
    {
        #region Variables
        
        private static List<ContainerController> _controllers = new List<ContainerController>();

        private const string PermissionUse = "skins.use";
        private const string PermissionAdmin = "skins.admin";
        
        #endregion

        #region Configuration

        private static Configuration _config;

        private class Configuration
        {
            [JsonProperty(PropertyName = "Command")]
            public string Command = "skin";
            
            [JsonProperty(PropertyName = "Skins", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public Dictionary<string, List<ulong>> Skins = new Dictionary<string, List<ulong>>
            {
                { "shortname", new List<ulong>
                {
                    0
                } }
            };

            [JsonProperty(PropertyName = "Debug")]
            public bool Debug = false;
        }

        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                _config = Config.ReadObject<Configuration>();
                if (_config == null) throw new Exception();
            }
            catch
            {
                Config.WriteObject(_config, false, $"{Interface.GetMod().ConfigDirectory}/{Name}.jsonError");
                PrintError("The configuration file contains an error and has been replaced with a default config.\n" +
                           "The error configuration file was saved in the.jsonError extension");
                LoadDefaultConfig();
            }

            SaveConfig();
        }

        protected override void SaveConfig() => Config.WriteObject(_config);

        protected override void LoadDefaultConfig() => _config = new Configuration();
        
        #endregion

        #region Hooks

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                { "Not Allowed", "You don't have permission to use this command" },
                { "Cannot Use", "I'm sorry, you cannot use that right now" },
                { "Help", "Command usage:\n" +
                          "skin show - Show skins\n" +
                          "skin get - Get Skin ID of the item" },
                { "Admin Help", "Admin command usage:\n" +
                                "skin show - Show skins\n" +
                                "skin get - Get Skin ID of the item\n" +
                                "skin remove (Shortname) (Skin ID) - Remove a skin\n" +
                                "skin add (Shortname) (Skin ID) - Add a skin\n" +
                                "skin validate - Validate skins" },
                { "Skin Get Format", "{shortname}'s skin: {id}" },
                { "Skin Get No Item", "Please, hold the needed item" },
                { "Incorrect Skin", "You have entered an incorrect skin" },
                { "Skin Already Exists", "This skin already exists on this item" },
                { "Skin Does Not Exist", "This skin does not exist" },
                { "Skin Added", "Skin was successfully added" },
                { "Skin Removed", "Skin was removed" },
                { "Validation: Started", "Validating skins.." },
                { "Validation: Ended", "Invalid skins removed: {removed}" }
            }, this);
        }

        private void OnServerInitialized()
        {
            permission.RegisterPermission(PermissionUse, this);
            permission.RegisterPermission(PermissionAdmin, this);

            AddCovalenceCommand(_config.Command, nameof(CommandSkin));

            foreach (var player in BasePlayer.activePlayerList)
            {
                OnPlayerInit(player);
            }
        }

        private void Unload()
        {
            for (var i = _controllers.Count - 1; i >= 0; i--)
            {
                var container = _controllers[i];
                container.Destroy();
                
                _controllers.RemoveAt(i);
            }
        }

        private void OnPlayerInit(BasePlayer player)
        {
            _controllers.Add(new ContainerController(player)); // lol
        }

        private void OnPlayerDisconnected(BasePlayer player)
        {
            var index = ContainerController.FindIndex(player);
            var container = _controllers[index];
            container.Destroy();
            
            _controllers.RemoveAt(index);
        }

        #region Working With Containers

        private void OnItemAddedToContainer(ItemContainer itemContainer, Item item)
        {
            var player = itemContainer.GetOwnerPlayer();
            var container = ContainerController.Find(itemContainer);
            if (container == null || player != null)
                return;
            
            PrintDebug("OnItemAddedToContainer");
            item.position = 0;
            container.UpdateContent(0);
        }

        private void OnItemRemovedFromContainer(ItemContainer itemContainer, Item item)
        {
            var player = itemContainer.GetOwnerPlayer();
            var container = ContainerController.Find(itemContainer);
            if (container == null || player == null)
                return;
            
            PrintDebug("OnItemRemovedFromContainer");
            container.Clear();
        }

        private void OnPlayerLootEnd(PlayerLoot loot)
        {
            PrintDebug("OnLootEntityEnd");

            var player = loot.gameObject.GetComponent<BasePlayer>();
            if (player != loot.entitySource)
                return;
            
            var container = ContainerController.Find(player);
            if (container == null)
                return;
            
            PrintDebug("Ended looting container");
            container.Close();
        }

        private object CanLootPlayer(BasePlayer looter, Object target)
        {
            if (looter != target)
                return null;

            var container = ContainerController.Find(looter);
            if (container == null || !container.IsOpened)
                return null;

            PrintDebug("Allowing to loot player (skin container)");
            return true;
        }

        #endregion
        
        #endregion

        #region Commands

        private void CommandSkin(IPlayer player, string command, string[] args)
        {
            PrintDebug("Executed Skin command");
            
            if (!CanUse(player))
            {
                PrintDebug("Not allowed");
                player.Reply(GetMsg("Not Allowed", player.Id));
                return;
            }

            if (args.Length == 0)
                args = new[] {"show"}; // :P strange yeah

            var isAdmin = player.IsServer || CanUseAdmin(player);
            var basePlayer = player.Object as BasePlayer;
            var isPlayer = basePlayer != null;
            
            PrintDebug($"Arguments: {string.Join(" ", args)}");
            PrintDebug($"Is Admin: {isAdmin} : Is Player: {isPlayer}");
            
            switch (args[0].ToLower())
            {
                case "_tech-update":
                {
                    int page;
                    if (args.Length != 2 || !isPlayer || !int.TryParse(args[1], out page))
                        break;

                    var container = ContainerController.Find(basePlayer);

                    container?.UpdateContent(page);
                    container?.DestroyUI();
                    container?.DrawUI(page);
                    break;
                }
                    
                case "show":
                case "s":
                {
                    if (!isPlayer)
                    {
                        PrintDebug("Not a player");
                        player.Reply(GetMsg("Cannot Use", player.Id));
                        break;
                    }

                    var container = ContainerController.Find(basePlayer);
                    if (container == null || !container.CanShow())
                    {
                        PrintDebug("Cannot show container or container not found");
                        player.Reply(GetMsg("Cannot Use", player.Id));
                        break;
                    }

                    timer.Once(1f, () => container.Show());
                    break;
                }

                case "add":
                case "a":
                {
                    if (args.Length != 3)
                        goto default;

                    if (!isAdmin)
                    {
                        PrintDebug("Not an admin");
                        player.Reply(GetMsg("Not Allowed", player.Id));
                        break;
                    }

                    var shortname = args[1];
                    ulong skin;
                    if (!ulong.TryParse(args[2], out skin))
                    {
                        PrintDebug("Invalid skin");
                        player.Reply(GetMsg("Incorrect Skin", player.Id));
                        break;
                    }
                    
                    LoadConfig();

                    List<ulong> skins;
                    if (!_config.Skins.TryGetValue(shortname, out skins))
                        skins = new List<ulong>();

                    if (skins.Contains(skin))
                    {
                        PrintDebug("Skin already exists");
                        player.Reply(GetMsg("Skin Already Exists", player.Id));
                        break;
                    }
                    
                    skins.Add(skin);
                    _config.Skins[shortname] = skins;
                    player.Reply(GetMsg("Skin Added", player.Id));
                    
                    SaveConfig();
                    PrintDebug("Added skin");
                    break;
                }

                case "remove":
                case "delete":
                case "r":
                case "d":
                {
                    if (args.Length != 3)
                        goto default;

                    if (!isAdmin)
                    {
                        PrintDebug("Not an admin");
                        player.Reply(GetMsg("Not Allowed", player.Id));
                        break;
                    }

                    var shortname = args[1];
                    ulong skin;
                    if (!ulong.TryParse(args[2], out skin))
                    {
                        PrintDebug("Invalid skin");
                        player.Reply(GetMsg("Incorrect Skin", player.Id));
                        break;
                    }
                    
                    LoadConfig();

                    List<ulong> skins;
                    int index;
                    if (!_config.Skins.TryGetValue(shortname, out skins) || (index = skins.IndexOf(skin)) == -1)
                    {
                        PrintDebug("Skin doesnt exist");
                        player.Reply(GetMsg("Skin Does Not Exist", player.Id));
                        break;
                    }
                    
                    skins.RemoveAt(index);
                    _config.Skins[shortname] = skins;
                    player.Reply(GetMsg("Skin Removed", player.Id));
                    
                    SaveConfig();
                    PrintDebug("Removed skin");
                    break;
                }

                case "get":
                case "g":
                {
                    if (!isPlayer)
                    {
                        PrintDebug("Not a player");
                        player.Reply(GetMsg("Cannot Use", player.Id));
                        break;
                    }

                    var item = basePlayer.GetActiveItem();
                    if (item == null || !item.IsValid())
                    {
                        PrintDebug("Invalid item");
                        player.Reply(GetMsg("Skin Get No Item", player.Id));
                        break;
                    }

                    player.Reply(GetMsg("Skin Get Format", player.Id).Replace("{shortname}", item.info.shortname).Replace("{id}", item.skin.ToString()));
                    
                    break;
                }

                default: // and "help", and all other args
                {
                    PrintDebug("Unknown command");
                    player.Reply(GetMsg(isAdmin ? "Admin Help" : "Help", player.Id));
                    break;
                }
            }
        }

        #endregion
        
        #region Controller

        private class ContainerController
        {
            /*
             * Basic tips:
             * Item with slot 0: Player's skin item
             */

            private const int Capacity = 30;
            
            public BasePlayer Owner;
            public ItemContainer Container;
            public bool IsOpened = false;

            #region Search

            // ReSharper disable once SuggestBaseTypeForParameter
            public static int FindIndex(BasePlayer player)
            {
                if (!CanShow(player))
                    goto none;
                
                for (var i = 0; i < _controllers.Count; i++)
                {
                    if (_controllers[i].Owner == player)
                    {
                        return i;
                    }
                }

                none:
                return -1;
            }

            public static ContainerController Find(BasePlayer player)
            {
                var index = FindIndex(player);
                return index == -1 ? null : _controllers[index];
            }

            // ReSharper disable once SuggestBaseTypeForParameter
            public static int FindIndex(ItemContainer container)
            {
                if (container == null)
                    goto none;
                
                for (var i = 0; i < _controllers.Count; i++)
                {
                    if (_controllers[i].Container == container)
                    {
                        return i;
                    }
                }

                none:
                return -1;
            }

            public static ContainerController Find(ItemContainer container)
            {
                var index = FindIndex(container);
                return index == -1 ? null : _controllers[index];
            }
            
            #endregion

            public ContainerController(BasePlayer player)
            {
                Owner = player;
                
                Container = new ItemContainer
                {
                    entityOwner = Owner,
                    capacity = Capacity,
                    isServer = true,
                    allowedContents = ItemContainer.ContentsType.Generic
                };
                
                Container.GiveUID();
            }

            public void DestroyUI()
            {
                PrintDebug("Started UI destroy");
                CuiHelper.DestroyUi(Owner, "Skins.Background");
            }

            public void DrawUI(int page)
            {
                PrintDebug("Started UI draw");
                var elements = new CuiElementContainer();
                const string anchorCorner = "1.0 1.0";

                var background = new CuiElement
                {
                    Name = "Skins.Background",
                    Parent = "Overlay",
                    Components =
                    {
                        new CuiImageComponent
                        {
                            Color = "0.18 0.28 0.36"
                        },
                        new CuiRectTransformComponent
                        {
                            AnchorMin = anchorCorner,
                            AnchorMax = anchorCorner,
                            OffsetMin = "-300 -100",
                            OffsetMax = "0 0"
                        }
                    }
                };

                var left = new CuiElement
                {
                    Name = "Skins.Left",
                    Parent = background.Name,
                    Components =
                    {
                        new CuiButtonComponent
                        {
                            Close = background.Name,
                            Command = $"{_config.Command} _tech-update {page - 1}",
                            Color = "0.11 0.51 0.83"
                        },
                        new CuiRectTransformComponent
                        {
                            AnchorMin = "0.025 0.05",
                            AnchorMax = "0.325 0.95"
                        }
                    }
                };

                var leftText = new CuiElement
                {
                    Name = "Skins.Left.Text",
                    Parent = left.Name,
                    Components =
                    {
                        new CuiTextComponent
                        {
                            Text = "<"
                        },
                        new CuiRectTransformComponent
                        {
                            AnchorMin = "0 0",
                            AnchorMax = "1 1"
                        }
                    }
                };

                var center = new CuiElement
                {
                    Name = "Skins.Center",
                    Parent = background.Name,
                    Components =
                    {
                        new CuiImageComponent
                        {
                            Color = "0.11 0.51 0.83"
                        },
                        new CuiRectTransformComponent
                        {
                            AnchorMin = "0.350 0.05",
                            AnchorMax = "0.650 0.95"
                        }
                    }
                };

                var centerText = new CuiElement
                {
                    Name = "Skins.Center.Text",
                    Parent = center.Name,
                    Components =
                    {
                        new CuiTextComponent
                        {
                            Text = $"{page}"
                        },
                        new CuiRectTransformComponent
                        {
                            AnchorMin = "0 0",
                            AnchorMax = "1 1"
                        }
                    }
                };

                var right = new CuiElement
                {
                    Name = "Right.Left",
                    Parent = background.Name,
                    Components =
                    {
                        new CuiButtonComponent
                        {
                            Close = background.Name,
                            Command = $"{_config.Command} _tech-update {page - 1}",
                            Color = "0.11 0.51 0.83"
                        },
                        new CuiRectTransformComponent
                        {
                            AnchorMin = "0.675 0.05",
                            AnchorMax = "0.975 0.95"
                        }
                    }
                };

                var rightText = new CuiElement
                {
                    Name = "Skins.Right.Text",
                    Parent = right.Name,
                    Components =
                    {
                        new CuiTextComponent
                        {
                            Text = ">"
                        },
                        new CuiRectTransformComponent
                        {
                            AnchorMin = "0 0",
                            AnchorMax = "1 1"
                        }
                    }
                };
                
                elements.Add(background);
                elements.Add(left);
                elements.Add(leftText);
                elements.Add(center);
                elements.Add(centerText);
                elements.Add(right);
                elements.Add(rightText);

                PrintDebug("Started UI send");
                CuiHelper.AddUi(Owner, elements);
                PrintDebug("UI sent");
            }

            public void Close()
            {
                PrintDebug("Closing container");
                
                GiveItemBack();
                Clear();
                DestroyUI();
                
                IsOpened = false;
            }

            public void Show()
            {
                PrintDebug("Started container Show");
                
                IsOpened = true;
                UpdateContent(0);
                
                var loot = Owner.inventory.loot;
                
                loot.Clear();
                loot.PositionChecks = false;
                loot.entitySource = Owner;
                loot.itemSource = null;
                loot.AddContainer(Container);
                loot.SendImmediate();
                
                Owner.ClientRPCPlayer(null, Owner, "RPC_OpenLootPanel", "genericlarge");
            }
            
            #region Can Show

            public bool CanShow()
            {
                return CanShow(Owner);
            }

            private static bool CanShow(BaseCombatEntity player)
            {
                return player != null && !player.IsDead();
            }
            
            #endregion

            public void GiveItemBack()
            {
                if (!IsValid())
                    return;
                
                PrintDebug("Trying to give item back..");

                var item = Container.GetSlot(0);
                if (item == null)
                {
                    PrintDebug("Invalid item");
                    return;
                }

                Owner.GiveItem(item);
                PrintDebug("Gave item back");
            }

            public void Clear()
            {
                PrintDebug($"Clearing container");
                
                for (var i = 0; i < Container.itemList.Count; i++)
                {
                    var item = Container.itemList[i];
                    item.DoRemove();
                }
                
                Container.itemList.Clear();
                Container.MarkDirty();
            }

            public void Destroy()
            {
                Close();
                Container.Kill();
                
                PrintDebug("Destroyed container");
            }

            public void UpdateContent(int page)
            {
                var source = Container.GetSlot(0);
                source?.MarkDirty();

                /*
                PrintDebug($"Updating content ({page} page)");
                Clear(false);

                if (page < 0 || !IsValid() || container.itemList.Count <= 0)
                {
                    PrintDebug("Invalid page / items / etc");
                    return;
                }

                if (isOpened)
                {
                    PrintDebug("Opened.Drawing UI");
                    DrawUI(page);
                }

                var item = container.GetSlot(0);
                List<ulong> skins;
                if (!_config.Skins.TryGetValue(item.info.shortname, out skins))
                {
                    PrintDebug("Cannot find skins");
                    return;
                }

                var perPage = container.capacity - 1;
                var offset = perPage * page;
                if (offset >= skins.Count)
                    return;
                
                for (var i = 0; i < container.itemList.Count; i++)
                {
                    if (container.itemList[i].position == 0) // :(
                        continue;

                    container.itemList[i].DoRemove();
                    container.itemList.RemoveAt(i);
                }

                var slot = 1;
                for (var i = 0; i < skins.Count; i++)
                {
                    if (slot > container.capacity)
                        break;
                    
                    if (offset > i)
                        continue;
                    
                    var skin = skins[i];
                    var newItem = GetDuplicateItem(item, skin);
                    
                    newItem.RemoveFromContainer();
                    newItem.RemoveFromWorld();
                    
                    newItem.position = slot++;
                    newItem.parent = container;
                    
                    container.itemList.Add(newItem);
                    
                    foreach (var itemMod in newItem.info.itemMods)
                        itemMod.OnParentChanged(newItem);
                }
                */
            }

            public Item GetDuplicateItem(Item item, ulong skin)
            {
                PrintDebug($"Getting duplicate for {item.info.shortname}..");

                var newItem = ItemManager.Create(item.info, item.amount, skin);
                newItem._maxCondition = item._maxCondition;
                newItem._condition = item._condition;
                newItem.contents.capacity = item.contents.capacity;
                
                return newItem;
            }

            private bool IsValid() => Owner == null || Container?.itemList != null;
        }
        
        #endregion
        
        #region Helpers

        private bool CanUse(IPlayer player) => player.HasPermission(PermissionUse);

        private bool CanUseAdmin(IPlayer player) => player.HasPermission(PermissionAdmin);

        private string GetMsg(string key, string userId = null) => lang.GetMessage(key, this, userId);

        private static void PrintDebug(string message)
        {
            if (_config.Debug)
                Interface.Oxide.LogDebug(message);
        }

        #endregion
    }
}

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