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

FREE SkinBox : 1.0.2 1.0.2

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

///Скачано с дискорд сервера Rust Edit [PRO+]
///discord.gg/9vyTXsJyKR

namespace Oxide.Plugins 
{
    [Info("SkinBox", "discord.gg/9vyTXsJyKR", "1.0.2")]
    class SkinBox : RustPlugin 
    {
		private static SkinBox instance;
		
        private bool skinsLoaded;        
        private static SkinBox skinBox = null;
        private bool isValidated = false;        
		
        private static Dictionary<string, LinkedList<ulong>> skinsCache = new Dictionary<string, LinkedList<ulong>>();        
        private static Dictionary<string, int> approvedSkinsCount = new Dictionary<string, int>();        
        private static Dictionary<string, DateTime> cooldownTimes = new Dictionary<string, DateTime>();
        private static Dictionary<string, string> NameToItemName = new Dictionary<string, string>();
        private static Dictionary<string, string> ItemNameToName = new Dictionary<string, string>();        
        private static List<ulong> excludedSkins = new List<ulong>();
		private static Dictionary <string, List<ulong>> manualAddedSkins = new Dictionary <string, List<ulong>>();
        private static List<object> excludedSkinsPre = new List<object>();
        private static Dictionary <ulong, Vector3> activeBoxUsers = new Dictionary <ulong, Vector3>();		
        		
        Coroutine _validateManualSkins;
        Coroutine _validateExcludedSkins;        
		
        private static Dictionary<string, object> missingWorkshopNames() 
        {
            var dp = new Dictionary<string, object>();
            dp.Add("rug", "Rug");
            dp.Add("chair", "Chair");
            dp.Add("rug.bear", "Bearskin Rug");
            dp.Add("mask.bandana", "Bandana");
            dp.Add("table", "Table");
            dp.Add("fridge", "Fridge");
            return dp;
        }        		      		                                     
        
        protected override void LoadDefaultMessages() 
        {
            lang.RegisterMessages(new Dictionary<string, string> 
            {                
                {"NoPermission", "Недостаточно прав!"},                 
                {"CooldownTime", "Что бы повторно поменять скины, вам нужно подождать {0} секунд."}                
            },this);
        }
        
        private void Init()
        {
            LoadVariables();
            LoadDefaultMessages();
			
            cmd.AddChatCommand("skin", this, "cmdSkinBox");
			cmd.AddChatCommand("skins", this, "cmdSkinBox");
			cmd.AddChatCommand("skinbox", this, "cmdSkinBox");
			
			foreach(var permissionUse in configData.permissionsUse)
				if (!permission.PermissionExists(permissionUse)) 
					permission.RegisterPermission(permissionUse, this);                                               
				
            skinsCache = new Dictionary<string, LinkedList<ulong>>();            
            approvedSkinsCount = new Dictionary<string, int>();
            NameToItemName = new Dictionary<string, string>();
            ItemNameToName = new Dictionary<string, string>();            
            activeBoxUsers = new Dictionary <ulong, Vector3>();
            skinsLoaded = false;
            skinBox = this;
        }
        
        private void OnServerInitialized() 
        {
			instance = this;
            UnsubscribeAll();
            timer.Once(65f, ()=> OnServerInit());			
        }
        
        private void Unload() 
        {
            var objs = UnityEngine.Object.FindObjectsOfType<SkinBoxHandler>().ToList();
            if (objs.Count > 0) 
				foreach (var obj in objs) 
				{
					if (obj.looter == null) continue;
					obj.looter.EndLooting();
					obj.PlayerStoppedLooting(obj.looter);
					GameObject.Destroy(obj);
				}
				
			foreach (BasePlayer player in BasePlayer.activePlayerList)				
				CuiHelper.DestroyUi(player, "Buttons");			
            
            if (Interface.Oxide.IsShuttingDown) return;
			
            if (_validateManualSkins != null) ServerMgr.Instance.StopCoroutine(_validateManualSkins);
            if (_validateExcludedSkins != null) ServerMgr.Instance.StopCoroutine(_validateExcludedSkins);            
        }
        
        private void OnServerInit() 
        {
            foreach (var itemtype in Rust.Workshop.Approved.All.Values.ToList()) 
            {
                if (itemtype.Skinnable.Name == null || itemtype.Skinnable.Name == string.Empty) continue;
                if (itemtype.Skinnable.ItemName == null || itemtype.Skinnable.ItemName == string.Empty) continue;
                if (!NameToItemName.ContainsKey(itemtype.Skinnable.Name.ToLower())) NameToItemName.Add(itemtype.Skinnable.Name.ToLower(), itemtype.Skinnable.ItemName.ToLower());
                if (!ItemNameToName.ContainsKey(itemtype.Skinnable.ItemName.ToLower()))                 
                    ItemNameToName.Add(itemtype.Skinnable.ItemName.ToLower(), itemtype.Skinnable.Name.ToLower());                                                
            }
            
            var tempMissing = new Dictionary<string, object>(configData.missingSkinNames);            
			tempMissing["rifle.lr300"] = "Lr300";
            foreach (var skin in tempMissing) 
            {
                var itemname = skin.Key.ToLower();
                var itemDef = ItemManager.FindItemDefinition(itemname);
                if (itemDef == null) continue;
                var workshopname = ((string)skin.Value).ToLower();
                NameToItemName[workshopname] = itemname;
                ItemNameToName[itemname] = workshopname;
            }
            
            foreach (var manual in configData.manualAddedSkinsPre) manualAddedSkins.Add(manual.Key.ToString(), (manual.Value as List<ulong>).ConvertAll(obj => Convert.ToUInt64(obj)));
            excludedSkins = configData.excludedSkinsPre.ConvertAll(obj => Convert.ToUInt64(obj));
            _validateManualSkins = ServerMgr.Instance.StartCoroutine(ValidateManualSkins(new Dictionary <string, List<ulong>>(manualAddedSkins), done => 
            {
                int result1 = manualAddedSkins.Values.Sum(list => list.Count);
                int result2 = done.Values.Sum(list => list.Count);
                if (result1 != result2) 
                {
                    manualAddedSkins = new Dictionary <string, List<ulong>>(done);
                    configData.manualAddedSkinsPre = manualAddedSkins;
                    SaveConfig(configData);
                }
                
                _validateExcludedSkins = ServerMgr.Instance.StartCoroutine(ValidateExcludedSkins(new List<ulong>(excludedSkins), done2 => 
                {
                    if (excludedSkins.Count != done2.Count) 
                    {
                        excludedSkins = new List<ulong>(done2);
                        configData.excludedSkinsPre = excludedSkins;
                        SaveConfig();
                    }
                    
                    _validateExcludedSkins = null;
                    isValidated = true;
                    GetItemSkins();
                }
                
                ));
                _validateManualSkins = null;
            }));
        }
        
        private IEnumerator ValidateManualSkins(Dictionary <string, List<ulong>> skinDict, System.Action<Dictionary <string, List<ulong>>> done) 
        {
            done(skinDict);
            yield return done;
        }
        
        private IEnumerator ValidateExcludedSkins(List<ulong> skinList, System.Action<List<ulong>> done) 
        {            
            done(skinList);
            yield return done;
        }
        
		private static string GetFixedItemName(string name) => name == "lr300.item" ? "rifle.lr300" : name;
		
        private void GetItemSkins() 
        {
            if (skinsLoaded) return;
            int countInbuilt = 0;
            foreach (var itemDef in ItemManager.GetItemDefinitions()) 
            {
                List<ulong> skins = new List<ulong>{0};
                skins.AddRange(ItemSkinDirectory.ForItem(itemDef).Select(skin => Convert.ToUInt64(skin.id)));
                skinsCache.Add(GetFixedItemName(itemDef.shortname), new LinkedList<ulong>(skins));
                if (skins.Count > 1) countInbuilt += (skins.Count -1);
            }
            
            if (configData.showLoadedSkinCounts) Puts($"Загружено {countInbuilt} встроенных скинов.");
            if (configData.useManualAddedSkins) 
            {
                int countManual = 0;
                foreach (var manualskins in manualAddedSkins) 
                {
                    string shortname = GetFixedItemName(manualskins.Key);
                    if (!ItemNameToName.ContainsKey(shortname)) continue;
                    string itemname = ItemNameToName[shortname];
                    List<ulong> fileids = manualskins.Value;
                    foreach (var fileid in fileids) 
                    {
                        if (!skinsCache.ContainsKey(shortname)) 
                        {
                            skinsCache.Add(shortname, new LinkedList<ulong>());
                            skinsCache[shortname].AddLast(0);
                        }
                        
                        if (!skinsCache[shortname].Contains(fileid)) 
                        {
                            skinsCache[shortname].AddLast(fileid);
                            countManual++;
                        }                                                
                    }                                        
                }
                
                if (configData.showLoadedSkinCounts && countManual > 0) Puts($"Загружено {countManual} скинов, добавленных вручную.");
            }
                        
			int countApproved = 0;
			foreach (var shopskin in Rust.Workshop.Approved.All.Where(skin => skin.Value.Skinnable.ItemName != null)) 
			{
				var skinName = GetFixedItemName(shopskin.Value.Skinnable.ItemName);
				if (!approvedSkinsCount.ContainsKey(skinName)) approvedSkinsCount[skinName] = 0;                                       
				if (!skinsCache.ContainsKey(skinName)) skinsCache[skinName] = new LinkedList<ulong>();
				if (!skinsCache[skinName].Contains(shopskin.Value.WorkshopdId)) 
				{
					skinsCache[skinName].AddLast(shopskin.Value.WorkshopdId);
					approvedSkinsCount[skinName]++;
					countApproved++;
				}                                        
			}
			
			if (configData.showLoadedSkinCounts) Puts($"Загружено {countApproved} одобренных скинов.");
                        
			Interface.CallHook("OnSkinCacheUpdate", skinsCache, true);
			skinsLoaded = true;            
        }                
                
		[ConsoleCommand("skins.open")] 
		private void consoleSkinsOpen(ConsoleSystem.Arg arg) => consoleSkinboxOpen(arg);
				
        [ConsoleCommand("skinbox.open")] 
		private void consoleSkinboxOpen(ConsoleSystem.Arg arg) 
        {
            if (arg == null) return;
            if (arg.Connection == null) 
            {
				if (!skinsLoaded)
				{
					SendReply(arg, "Подождите, идет инициализация плагина.");
                    return;
				}
				
                if  (arg.Args == null || arg.Args.Length == 0) 
                {
                    SendReply(arg, $"Команда 'skinbox.open' требует наличия SteamId в качестве параметра.");
                    return;
                }
                
                ulong argId = 0uL;
                if (!ulong.TryParse(arg.Args[0], out argId)) 
                {
                    SendReply(arg, $"Указан некорректный SteamId: '{arg.Args[0]}'.");
                    return;
                }
                
                BasePlayer argPlayer = BasePlayer.FindByID(argId);
                if (argPlayer == null) 
                {
                    SendReply(arg, $"Не найден указанный игрок: '{argId}'.");
                    return;
                }
                
                if (!argPlayer.inventory.loot.IsLooting()) OpenSkinBox(argPlayer);
            }            
            else if(arg.Connection != null && arg.Connection.player != null) 
            {
                BasePlayer player = arg.Player();
                if (player.inventory.loot.IsLooting()) return;
				
                if (!HasPermission(player)) 
                {
                    player.ChatMessage(lang.GetMessage("NoPermission", this, player.UserIDString));
                    return;
                }
				
				if (!skinsLoaded)
				{
					player.ChatMessage("Подождите, идет инициализация плагина.");
                    return;
				}
                                
                if (configData.enableCooldown && !player.IsAdmin)
                {
                    DateTime now = DateTime.UtcNow;
                    DateTime time;
                    var key = player.UserIDString + "-box";
                    if (cooldownTimes.TryGetValue(key, out time)) 
                    {
                        if (time > now.AddSeconds(-configData.cooldownBox)) 
                        {
                            player.ChatMessage(string.Format(lang.GetMessage("CooldownTime", this, player.UserIDString),(time - now.AddSeconds(-configData.cooldownBox)).Seconds));
                            return;
                        }                                                
                    }                                        
                }
                
                OpenSkinBox(player);
            }                        
        }
        
        private void cmdSkinBox(BasePlayer player, string command, string[] args) 
        {
            if (player.inventory.loot.IsLooting()) return;
            if (!HasPermission(player))
            {
                player.ChatMessage(lang.GetMessage("NoPermission", this, player.UserIDString));
                return;
            }
			
			if (!skinsLoaded)
			{
				player.ChatMessage("Подождите, идет инициализация плагина.");
				return;
			}
                        
            if (configData.enableCooldown && !player.IsAdmin) 
            {
                DateTime now = DateTime.UtcNow;
                DateTime time;
                var key = player.UserIDString + "-box";
                if (cooldownTimes.TryGetValue(key, out time)) 
                {
                    if (time > now.AddSeconds(-configData.cooldownBox)) 
                    {
                        player.ChatMessage(string.Format(lang.GetMessage("CooldownTime", this, player.UserIDString),(time - now.AddSeconds(-configData.cooldownBox)).Seconds));
                        return;
                    }                                        
                }                                
            }
            
            timer.Once(0.2f, () => 
            {
                OpenSkinBox(player);
            });
        }      

		private bool HasPermission(BasePlayer player) 
		{
			if (player.IsAdmin)
				return true;
			
			foreach(var permissionName in configData.permissionsUse)
				if (!string.IsNullOrEmpty(permissionName) && permission.UserHasPermission(player.UserIDString, permissionName))
					return true;
			
			return false;
		}	
        
        private sealed class SkinBoxHandler : MonoBehaviour 
        {
            public bool isCreating;
            public bool isBlocked;
            public bool isCleaning;
            public bool isEmptied;
			public bool isPaging;
            public int itemId;
            public Item item;
            public BasePlayer looter;
            public ItemContainer otherLoot;
			public ItemContainer showLoot;
            public BaseEntity entityOwner;
            public ulong skinId;
			public int page;
			public float lastOpen;
			
			public static List<SkinBoxHandler> SkinBoxes = new List<SkinBoxHandler>();
			
            void Awake() 
            {
                isCreating = false;
                isBlocked = false;
                isCleaning = false;
                isEmptied = false;
				isPaging = false;
                showLoot = GetComponent<DroppedItemContainer>().inventory;
                entityOwner = showLoot.entityOwner;
				page = 1;
				otherLoot = new ItemContainer();
				otherLoot.ServerInitialize(null, 1000);
				otherLoot.GiveUID();
				lastOpen = UnityEngine.Time.realtimeSinceStartup;				
				try { SkinBoxes.RemoveAll(x=> x == null); } catch {}
				SkinBoxes.Add(this);
            }
            
            public void PlayerStoppedLooting(BasePlayer player) 
            {				
                activeBoxUsers.Remove(player.userID);
                if (!isEmptied && item != null) 
                {
                    isEmptied = true;
                    player.GiveItem(item);
                }
				ClearContainer(otherLoot);
				CuiHelper.DestroyUi(looter, "Buttons");		
                if (activeBoxUsers.Count() == 0 && !Interface.Oxide.IsShuttingDown) skinBox.UnsubscribeAll();
                if (!GetComponent<BaseEntity>().IsDestroyed) GetComponent<BaseEntity>().Kill(BaseNetworkable.DestroyMode.None);
                if (configData.enableCooldown) cooldownTimes[player.UserIDString + "-box"] = DateTime.UtcNow;
            }
            
            void OnDestroy() 
            {											
                activeBoxUsers.Remove(looter.userID);
                if (!isEmptied && item!= null) 
                {
                    isEmptied = true;
                    looter.GiveItem(item);
                }				
				ClearContainer(otherLoot);
				CuiHelper.DestroyUi(looter, "Buttons");		
                looter.EndLooting();
				
				if (entityOwner != null)
					GameObject.Destroy(entityOwner);
				
				/*if ((UnityEngine.Time.realtimeSinceStartup - lastOpen) <= 0.5f)
				{
					if (looter != null)
						instance.OpenSkinBox(looter);
				}*/
            }                        
        }                
        
        private void OpenSkinBox(BasePlayer player) 
        {
			if (player == null) return;
			
			var ret = Interface.CallHook("SkinsCanUseSkins", player) as object;
			if (ret != null)
			{
				if (ret is string)
					SendReply(player, (string)ret);
				return;
			}

            if (activeBoxUsers.Count() == 0) SubscribeAll();
            			
			var skinBox = GameManager.server.CreateEntity("assets/prefabs/misc/item drop/item_drop_backpack.prefab", new Vector3(player.transform.position.x, -60f + UnityEngine.Random.Range(-4f, 4f), player.transform.position.z));
			
            var drop = skinBox as DroppedItemContainer;
			drop.playerName = configData.skinBoxTitle;	
			drop.playerSteamID = player.userID;			
			
			drop.Spawn();
														
			drop.inventory = new ItemContainer();
            drop.inventory.ServerInitialize(null, 36);
			drop.inventory.entityOwner = drop;
            drop.inventory.GiveUID();
			
			Rigidbody rigidBody = drop.GetComponent<Rigidbody>();
			rigidBody.useGravity = false;
			rigidBody.isKinematic = true;
            
			drop.SetFlag(BaseEntity.Flags.Open, true, false);						
			
            drop.gameObject.AddComponent<SkinBoxHandler>().looter = player;            
            drop.inventory.capacity = 36;						
            drop.SetFlag(BaseEntity.Flags.Open, true, false);
			
			player.inventory.loot.StartLootingEntity(drop, false);						
            player.inventory.loot.AddContainer(drop.inventory);						
            player.inventory.loot.SendImmediate();
			
			player.ClientRPCPlayer(null, player, "RPC_OpenLootPanel", drop.lootPanelName);			
            drop.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);			

            activeBoxUsers[player.userID] = player.transform.position;
        }
        
        private void StartLootingEntity(PlayerLoot loot, BaseEntity targetEntity) 
        {                        
            loot.Clear();
            if (!targetEntity) return;            
			loot.PositionChecks = false;
            loot.entitySource = targetEntity;
            loot.itemSource = null;            
			loot.MarkDirty();
        }
        
        private static void ClearContainer(ItemContainer container) 
        {
            while (container.itemList.Count > 0) 
            {
                var item = container.itemList[0];
                item.RemoveFromContainer();
                item.Remove(0f);
            }                        
        }
        
        private object CanAcceptItem(ItemContainer container, Item item) 
        {
            if (container == null || item == null || container.entityOwner == null || container.entityOwner.GetComponent<SkinBoxHandler>() == null || 
				container.entityOwner != container.entityOwner.GetComponent<SkinBoxHandler>().entityOwner || 
				container.entityOwner.GetComponent<SkinBoxHandler>().isCreating || container.entityOwner.GetComponent<SkinBoxHandler>().isPaging) 
				return null;
            
			if (container.entityOwner.GetComponent<SkinBoxHandler>().isBlocked || item.amount > 1 || item.isBroken || 
				!skinsCache.ContainsKey(item.info.shortname) || (skinsCache[item.info.shortname] as LinkedList<ulong>).Count <= 1) 
				return ItemContainer.CanAcceptResult.CannotAccept;
				
            return null;
        }                
        
        private void OnItemAddedToContainer(ItemContainer container, Item item) 
        {
            if (container == null || item == null || container.entityOwner == null || container.entityOwner.GetComponent<SkinBoxHandler>() == null || 
				container.entityOwner != container.entityOwner.GetComponent<SkinBoxHandler>().entityOwner || 
				container.entityOwner.GetComponent<SkinBoxHandler>().isCreating || container.entityOwner.GetComponent<SkinBoxHandler>().isPaging) 
				return;
				
            var lootHandler = container.entityOwner.GetComponent<SkinBoxHandler>();
            lootHandler.isCreating = true;
            lootHandler.itemId = item.info.itemid;
            lootHandler.isEmptied = false;
            string shortname = item.info.shortname;
            bool hasCondition = item.hasCondition;
            float condition = item.condition;
			//float fuel = item.fuel;
			
			if (item.contents != null && item.contents.itemList.Count > 0)
			{
				var array = item.contents.itemList.ToArray();
				for (int i = 0; i < array.Length; i++)
				{
					if (array[i].info.category == ItemCategory.Weapon) continue;
					var item2 = array[i];
					lootHandler.looter.inventory.GiveItem(item2, null);
				}
			}
			
            float maxCondition = item.maxCondition;
            bool isWeapon = item.GetHeldEntity() != null && item.GetHeldEntity() is BaseProjectile;
            bool hasMods = false;
            int contents = 0;
            int capacity = 0;
            ItemDefinition ammoType = null;
            Dictionary<int, float> itemMods = new Dictionary<int, float>();
            LinkedList<ulong>  itemSkins = skinsCache[shortname] as LinkedList<ulong>;			
			
            if (isWeapon) 
            {
                contents = (item.GetHeldEntity() as BaseProjectile).primaryMagazine.contents;
                capacity = (item.GetHeldEntity() as BaseProjectile).primaryMagazine.capacity;
                ammoType = (item.GetHeldEntity() as BaseProjectile).primaryMagazine.ammoType;
                if (item.contents != null && item.contents.itemList.Count > 0) 
                {
                    hasMods = true;
                    foreach ( var mod in item.contents.itemList) itemMods.Add(mod.info.itemid, mod.condition);
                }                                
            }
            
            item.RemoveFromContainer();
            lootHandler.skinId = item.skin;
            lootHandler.item = item;
            container.capacity = itemSkins.Count();
            var itemDef = ItemManager.FindItemDefinition(shortname);
			int pos = 0;
			bool paged = false;						
			
            foreach (var skin in itemSkins) 
            {                				
                if (excludedSkins.Contains(skin) && !lootHandler.looter.IsAdmin) continue;
                Item newItem = ItemManager.Create(itemDef, 1, skin);
                
				if (hasCondition) 
                {
                    newItem.condition = condition;
                    newItem.maxCondition = maxCondition;
                }
				
				//newItem.fuel = fuel;
                
                if (isWeapon) 
                {
                    (newItem.GetHeldEntity() as BaseProjectile).primaryMagazine.contents = contents;
                    (newItem.GetHeldEntity() as BaseProjectile).primaryMagazine.capacity = capacity;
                    (newItem.GetHeldEntity() as BaseProjectile).primaryMagazine.ammoType = ammoType;
                    if (hasMods) 
                    {
                        foreach ( var mod in itemMods) 
                        {
                            Item newMod = ItemManager.CreateByItemID((int)mod.Key, 1);
                            newMod.condition = Convert.ToSingle(mod.Value);
                            newMod.MoveToContainer(newItem.contents, -1, false);
                        }
                        
                        newItem.contents.SetFlag(ItemContainer.Flag.IsLocked, true);
                        newItem.contents.SetFlag(ItemContainer.Flag.NoItemInput, true);
                    }                                        
                }                				
				
				if (container.itemList.Count < 36)
					newItem.MoveToContainer(container, pos, false);					
				else
				{	
					newItem.MoveToContainer(lootHandler.otherLoot, pos, false);		                
					paged = true;
				}	
				
				pos++;
            }
            
			if (paged) ShowButtons(lootHandler.looter);
			
            lootHandler.isCreating = false;
            lootHandler.isBlocked = true;
        }
        
        private void OnItemRemovedFromContainer(ItemContainer container, Item item) 
        {
            if (container == null || item == null || container.entityOwner == null || container.entityOwner.GetComponent<SkinBoxHandler>() == null || 
				container.entityOwner != container.entityOwner.GetComponent<SkinBoxHandler>().entityOwner || 
				container.entityOwner.GetComponent<SkinBoxHandler>().isCreating || container.entityOwner.GetComponent<SkinBoxHandler>().isCleaning ||
				container.entityOwner.GetComponent<SkinBoxHandler>().isPaging) 
				return;								
				
            var loothandler = container.entityOwner.GetComponent<SkinBoxHandler>();
            if (item.GetHeldEntity() != null && item.GetHeldEntity() is BaseProjectile) 
            {
                if (item.contents != null) 
                {
                    item.contents.SetFlag(ItemContainer.Flag.IsLocked, false);
                    item.contents.SetFlag(ItemContainer.Flag.NoItemInput, false);
                }                                
            }
            
            loothandler.isCleaning = true;
            ClearContainer(container);
			ClearContainer(loothandler.otherLoot);
			CuiHelper.DestroyUi(loothandler.looter, "Buttons");
			loothandler.page = 1;
            loothandler.isCleaning = false;
			
			if (loothandler.skinId != item.skin)
				Interface.CallHook("SkinsOnSkinChanged", loothandler.looter, item, loothandler.skinId);			
			
            if (loothandler.item != null) 
            {
                loothandler.item.Remove(0f);
                loothandler.item = null;
            }
            
            loothandler.isEmptied = true;
            container.capacity = 36;
            loothandler.isBlocked = false;
            if (item.skin == 0uL) 
            {
                loothandler.skinId = 0uL;
                return;
            }                        
            
            if (configData.enableCooldown && configData.activateAfterSkinTaken && !loothandler.looter.IsAdmin && item.skin != loothandler.skinId) 
            {
                activeBoxUsers.Remove(loothandler.looter.userID);
                loothandler.looter.EndLooting();
                cooldownTimes[loothandler.looter.UserIDString + "-box"] = DateTime.UtcNow;
            }
            
            loothandler.skinId = 0uL;
        }
        
        private void UnsubscribeAll() 
        {
			try { Unsubscribe(nameof(CanAcceptItem)); } catch { PrintWarning("Ошибка отписки хука CanAcceptItem"); }
            try { Unsubscribe(nameof(OnItemAddedToContainer)); } catch { PrintWarning("Ошибка отписки хука OnItemAddedToContainer"); }
            try { Unsubscribe(nameof(OnItemRemovedFromContainer)); } catch { PrintWarning("Ошибка отписки хука OnItemRemovedFromContainer"); }
        }
        
        private void SubscribeAll() 
        {
            try { Subscribe(nameof(CanAcceptItem)); } catch { PrintWarning("Ошибка подписки хука CanAcceptItem"); }
            try { Subscribe(nameof(OnItemAddedToContainer)); } catch { PrintWarning("Ошибка подписки хука OnItemAddedToContainer"); }
            try { Subscribe(nameof(OnItemRemovedFromContainer)); } catch { PrintWarning("Ошибка подписки хука OnItemRemovedFromContainer"); }
        }
        
        private void SendReplyCl(ConsoleSystem.Arg arg, string format) 
        {
            if (arg != null && arg.Connection != null) SendReply(arg, format);
            Puts(format);
        }        
		
		#region ExtHooks

		//void SkinsOnSkinChanged(BasePlayer player, Item item, ulong oldSkin);  - вызывается при смене скина у предмета
		
		#endregion
		
		#region GUI

		private void ShowButtons(BasePlayer player)
		{
			if (player == null) return;
			
			CuiHelper.DestroyUi(player, "Buttons");

			CuiElementContainer container = new CuiElementContainer();
            container.Add(new CuiElement
            {
                Name = "Buttons",
				Parent = "Overlay",
                Components =
                {
                    new CuiImageComponent { Color = "0 0 0 0" },										
                    new CuiRectTransformComponent()					
					{
                        AnchorMin = "0.655 0.070",
                        AnchorMax = "0.71 0.103"						
                    }
                }
            });                       

            CreateButton(player, container, "0.01 0.01", "0.40 0.99", true);						
            CreateButton(player, container, "0.60 0.01", "0.99 0.99", false);
            											
			CuiHelper.AddUi(player, container); 
		}
		
		private void ShowDir(BasePlayer player, bool isLeft)
		{			
			if (player == null) return;
			
			var name = player.UserIDString + (isLeft ? "_leftin" : "_rightin");
			CuiHelper.DestroyUi(player, name);
			CuiElementContainer container = new CuiElementContainer();
            container.Add(new CuiElement
            {                
				Name = name,
                Parent = player.UserIDString + (isLeft ? "_left" : "_right"),
                Components =
                {                    
					new CuiRawImageComponent 
					{
						Url = isLeft ? "https://i.imgur.com/OzJdfxx.png" : "https://i.imgur.com/oM5tS89.png",
						Color = "1 1 0 0.6",
						Sprite = "assets/content/textures/generic/fulltransparent.tga"
                    },
                    new CuiRectTransformComponent
                    {
                        AnchorMin = isLeft ? "0.15 0.2" : "0.07 0.2",
                        AnchorMax = isLeft ? "0.9 0.8" : "0.82 0.8"
                    }
                }
            });
			CuiHelper.AddUi(player, container);
			timer.Once(0.3f, ()=>CuiHelper.DestroyUi(player, name));
		}
				
        private void CreateButton(BasePlayer player, CuiElementContainer container, string AnchorMin, string AnchorMax, bool isLeft)
        {            
            container.Add(new CuiElement
            {
                Name = player.UserIDString + (isLeft ? "_left" : "_right"),
                Parent = "Buttons",
                Components =
                {                    
					new CuiRawImageComponent 
					{
						Url = isLeft ? "https://i.imgur.com/a9ofmZk.png" : "https://i.imgur.com/5ZUL5Ao.png",
						Color = "1 1 1 0.6",
						Sprite = "assets/content/textures/generic/fulltransparent.tga"
                    },
                    new CuiRectTransformComponent
                    {
                        AnchorMin = AnchorMin,
                        AnchorMax = AnchorMax
                    }
                }
            });						            
			
			container.Add(new CuiElement
            {
                Name = CuiHelper.GetGuid(),
                Parent = player.UserIDString + (isLeft ? "_left" : "_right"),
                Components =
                {
                    new CuiButtonComponent
                    {
                        Command = "button947283.select " + (isLeft ? "left" : "right"),                        
                        Color = "1 1 1 0"
                    },
                    new CuiRectTransformComponent()                    
                }
            });
        }									
		
		[ConsoleCommand("button947283.select")]
		private void ConsoleCmdSelect(ConsoleSystem.Arg arg)
		{
			if (arg.Connection != null)
            {
				string selectedButton = arg.Args[0];
				var player = arg.Player();
				if (player == null) return;

                switch(selectedButton)
                {
                    case "left":
						ShowDir(player, true);
						foreach(var box in SkinBoxHandler.SkinBoxes.Where(x=> x != null).ToList())
						{
							if (box.looter == player)
							{				
								if (box.page <= 1) return;
																
								int pageItemCount = 36;		

								box.showLoot.capacity = pageItemCount;
								
								int pageReadPos = (box.page-2)*36;
								int pageWritePos = (box.page-1)*36;
								
								box.isPaging = true;
								for(int ii=box.showLoot.itemList.Count-1;ii>=0;ii--)
								{
									var item = box.showLoot.itemList[ii];
									item.MoveToContainer(box.otherLoot, pageWritePos + item.position, false);									
								}	
								for(int ii=box.otherLoot.itemList.Count-1;ii>=0;ii--)
								{
									var item = box.otherLoot.itemList[ii];
									if (item.position >= pageReadPos && item.position < pageReadPos + pageItemCount)									
										item.MoveToContainer(box.showLoot, item.position - pageReadPos, false);									
								}			
								box.page--;								
								box.isPaging = false;								
								break;
							}
						}
						break;
                    case "right":						
						ShowDir(player, false);		
						foreach(var box in SkinBoxHandler.SkinBoxes.Where(x=> x != null).ToList())
						{
							if (box.looter == player)
							{																
								int pageItemCount = (box.showLoot.itemList.Count+box.otherLoot.itemList.Count)-36*box.page > 36 ? 36 : (box.showLoot.itemList.Count+box.otherLoot.itemList.Count)-36*box.page;
								if (pageItemCount <= 0) return;
																					
								box.showLoot.capacity = pageItemCount;
								
								int pageReadPos = box.page*36;
								int pageWritePos = (box.page-1)*36;
								
								box.isPaging = true;
								for(int ii=box.showLoot.itemList.Count-1;ii>=0;ii--)
								{
									var item = box.showLoot.itemList[ii];
									item.MoveToContainer(box.otherLoot, pageWritePos + item.position, false);									
								}	
								for(int ii=box.otherLoot.itemList.Count-1;ii>=0;ii--)
								{
									var item = box.otherLoot.itemList[ii];
									if (item.position >= pageReadPos && item.position < pageReadPos + pageItemCount)									
										item.MoveToContainer(box.showLoot, item.position - pageReadPos, false);									
								}								
								box.page++;
								box.isPaging = false;																
								break;
							}
						}
						break;                                        
                }                
			}
		}
		
		#endregion
		
		#region Config        						
		
        private static ConfigData configData;				
		
        private class ConfigData
        {            												
			[JsonProperty(PropertyName = "Разрешать использовать вручную добавленные скины")]
            public bool useManualAddedSkins;			
			
			[JsonProperty(PropertyName = "Надпись, отображаемая на панели скинов")]
			public string skinBoxTitle;			
			[JsonProperty(PropertyName = "Список привилегий для смены скинов")]
            public List<string> permissionsUse;			
			[JsonProperty(PropertyName = "Показывать счетчик загрузки скинов в консоле")]
            public bool showLoadedSkinCounts;						
			
			[JsonProperty(PropertyName = "Включить задержку перед повторным использованием скинов")]
			public bool enableCooldown;
			[JsonProperty(PropertyName = "Длительность задержки перед повторным использованием скинов (в секундах)")]
            public int cooldownBox;			
			[JsonProperty(PropertyName = "При использовании задержки разрешать менять только один скин")]            
            public bool activateAfterSkinTaken;
			
			[JsonProperty(PropertyName = "Список отсутствующих названий предметов, которым принадлежат скины")]
            public Dictionary<string, object> missingSkinNames;				
			[JsonProperty(PropertyName = "Список скинов, добавленных вручную")]
			public Dictionary<string, List<ulong>> manualAddedSkinsPre;			
			[JsonProperty(PropertyName = "Список скинов для исключения")]
			public List<ulong> excludedSkinsPre;
        }
		
        private void LoadVariables() => configData = Config.ReadObject<ConfigData>();        
		
        protected override void LoadDefaultConfig()
        {
            var config = new ConfigData
            {                											
				useManualAddedSkins = true,								
				skinBoxTitle = "Перетащите предмет, чтобы изменить его модель",
				permissionsUse = new List<string>() { "skinbox.access", "skins.change" },				
				showLoadedSkinCounts = true,																		
				enableCooldown = false,
				cooldownBox = 60,									
				activateAfterSkinTaken = true,
				missingSkinNames = missingWorkshopNames(),
				manualAddedSkinsPre = new Dictionary<string, List<ulong>>(),
				excludedSkinsPre = new List<ulong>()
            };
            SaveConfig(config);
			timer.Once(0.1f, ()=> SaveConfig(config));
        }        
		
        private void SaveConfig(ConfigData config) => Config.WriteObject(config, true);
		
        #endregion
        
    }      

}

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