Online PHP and Javascript Decoder decode hidden script to uncover its real functionality


	{
	        private const string commandWipe = "kits.wipe";
	        private const string commandConstant = "kits.core";
	        private const string commandGiveConstant = "kits.give";
	        private const string commandConvertConstant = "kits.convert";
		                private class KitInfo        {
		            public DateTime lastUse;
		            public int uses;
		        
	}
		                        private void Init()        {
			            foreach (var kit in config.kits)            {
				                if (permission.PermissionExists(kit.permission) == false)                {
				                    permission.RegisterPermission(kit.permission, this);
				                
			}
			            
		}
			            foreach (var command in config.commands)            {
			                cmd.AddChatCommand(command, this, nameof(cmdControlChat));
			                cmd.AddConsoleCommand(command, this, nameof(cmdControlConsole));
			            
		}
		                        cmd.AddConsoleCommand(commandConstant, this, nameof(cmdControlConsole));
		            cmd.AddConsoleCommand(commandWipe, this, nameof(cmdControlConsole));
		            cmd.AddConsoleCommand(commandGiveConstant, this, nameof(cmdControlConsole));
		            cmd.AddConsoleCommand(commandConvertConstant, this, nameof(cmdControlConsole));
		        
	}
		        private void OnServerInitialized()        {
		            LoadData();
		            timer.Once(3f, LoadImages);
		        
	}
		        private void Unload()        {
		            SaveData();
		        
	}
		                private void cmdControlConsole(ConsoleSystem.Arg arg)        {
			            var args = arg.Args ?? new string[] {
			 
		};
		            var command = arg.cmd?.FullName;
			            if (command == commandWipe && arg.IsAdmin == true)            {
			                Data = new PluginData();
			                SaveData();
			                SendReply(arg, "Cooldown data was cleared for all!");
			                return;
			            
		}
			            if (command == commandGiveConstant && arg.IsAdmin == true)            {
			                var playerName = args.Length > 0 ? args[0] : "null";
			                var kitName = args.Length > 1 ? args[1] : "null";
			                var player = FindPlayer(playerName);
				                if (player == null)                {
					                    SendReply(arg, $"Can't find player with name '{
					playerName
				}
				'");
				                    return;
				                
			}
			                var kit = FindKitByName(kitName);
				                if (kit == null)                {
					                    SendReply(arg, $"Can't find kit with name '{
					kitName
				}
				'");
				                    return;
				                
			}
			                                GiveKit(player, kitName);
				                SendReply(arg, $"You gave kit {
				kitName
			}
				 to {
				player.displayName
			}
			!");
			                return;
			            
		}
			            if (command == commandConvertConstant && arg.IsAdmin)            {
			                var before = config.kits.Length;
			                ConvertUmodKits();
			                var after = config.kits.Length;
				                SendReply(arg, $"{
				after - before
			}
			 was converted!");
			                return;
			            
		}
		                        cmdControlChat(arg.Player(), command, args);
		        
	}
		        private void cmdControlChat(BasePlayer player, string command, string[] args)        {
			            args = args ?? new string[] {
			 
		};
		            var action = args.Length > 0 ? args[0].ToLower() : "true";
		            var name = args.Length > 1 ? args[1] : "null";
		            var refreshUI = args.Contains("ui.refresh");
		            var sendContent = args.Contains("items") || args.Contains("info") || args.Contains("content");
			            if (sendContent == true)            {
			                SendInfo(player, name);
			                return;
			            
		}
			                        switch (action)            {
			                case "true":                    SendKits(player);
			                    break;
			                case "add":                case "create":                case "new":                    AddNewKit(player, name);
			                    break;
			                case "remove":                case "delete":                case "destroy":                case "del":                    RemoveExistingKit(player, name);
			                    break;
			                case "update":                case "updateitems":                    UpdateKitItems(player, name);
			                    break;
			                case "reload":                case "load":                    LoadKits(player);
			                    break;
			                                case "page":                    var page = 0;
			                    int.TryParse(name, out page);
			                    Interface.CallHook("OpenKitUIPage", player, page);
			                    break;
			                default:                    TryToClaimKit(player, action, refreshUI);
			                    break;
			            
		}
		        
	}
		                private void TryToClaimKit(BasePlayer player, string name, bool refreshUI)        {
			            if (config.useUi == true && refreshUI == true)            {
				                NextTick(() =>                {
				                    Interface.CallHook("OnKitUIRefreshRequested", player);
				                
			}
			);
			            
		}
		                        var kit = FindKitByName(name);
			            if (kit == null)            {
				                SendMessage(player, MessageType.NoKit, "{
				name
			}
			", name);
			                return;
			            
		}
			            if (config.bypassAllChecksForAdmins == true && player.IsAdmin == true)            {
			                GiveKit(player, kit);
			                return;
			            
		}
			                        if (CanUse(player) == false)            {
			                SendMessage(player, MessageType.CantUse);
			                return;
			            
		}
			                        if (HasPermission(player, kit.permission) == false || kit.forAPI == true)            {
			                SendMessage(player, MessageType.Permission);
			                return;
			            
		}
		            var kitInfo = GetDataKitInfo(player, kit.name);
			            if (kit.uses > 0)            {
			                var left = kit.uses - kitInfo.uses;
				                if (left <= 0)                {
					                    SendMessage(player, MessageType.UsesLimitChat, "{
					limit
				}
				", kit.uses);
				                    return;
				                
			}
				                                SendMessage(player, MessageType.UsesLeftChat, "{
				left
			}
			", left - 1);
			            
		}
			            if (kit.block > 0 && kit.blockBypass == false)            {
			                var unblockDate = SaveRestore.SaveCreatedTime.AddSeconds(kit.block);
			                var leftSpan = unblockDate - DateTime.UtcNow;
				                                if (leftSpan.TotalSeconds > 0)                {
					                    SendMessage(player, MessageType.WipeblockChat, "{
					d
				}
					", leftSpan.Days, "{
					h
				}
					", leftSpan.Hours, "{
					m
				}
					", leftSpan.Minutes, "{
					s
				}
				", leftSpan.Seconds);
				                    return;
				                
			}
				                else                {
				                    kit.blockBypass = true;
				                
			}
			            
		}
			            if (kit.cooldown > 0)            {
			                var unblockDate = kitInfo.lastUse.AddSeconds(kit.cooldown);
			                var leftSpan = unblockDate - DateTime.UtcNow;
				                if (leftSpan.TotalSeconds > 0)                {
					                    SendMessage(player, MessageType.CooldownChat, "{
					d
				}
					", leftSpan.Days, "{
					h
				}
					", leftSpan.Hours, "{
					m
				}
					", leftSpan.Minutes, "{
					s
				}
				", leftSpan.Seconds);
				                    return;
				                
			}
			            
		}
			            if (config.checkForFreeSpace == true)            {
			                var need = 0;
			                var needWear = kit.items.Where(x => x.container.ToLower() == "wear").Count();
			                var needMain = kit.items.Where(x => x.container.ToLower() == "main").Count();
			                var needBelt = kit.items.Where(x => x.container.ToLower() == "belt").Count();
			                var freeWear = player.inventory.containerWear.capacity - player.inventory.containerWear.itemList.Count;
			                var freeMain = player.inventory.containerMain.capacity - player.inventory.containerMain.itemList.Count;
			                var freeBelt = player.inventory.containerBelt.capacity - player.inventory.containerBelt.itemList.Count;
				                                if (needWear > freeWear)                {
				                    need += needWear - freeWear;
				                
			}
				                                if (needMain > freeMain)                {
				                    need += needMain - freeMain;
				                
			}
				                                if (needBelt > freeBelt)                {
				                    need += needBelt - freeBelt;
				                
			}
				                if (need > 0)                {
					                    SendMessage(player, MessageType.NoFreeSpace, "{
					amount
				}
				", need);
				                    return;
				                
			}
			            
		}
		            kitInfo.lastUse = DateTime.UtcNow;
		            kitInfo.uses += 1;
		            GiveKit(player, kit);
		        
	}
		        private void SendKits(BasePlayer player)        {
			            if (config.useUi == false || Interface.Oxide.CallHook("CanSeeKits", player) == null)            {
			                SendKitsInChat(player);
			            
		}
		        
	}
		                private void SendInfo(BasePlayer player, string name)        {
			            if (config.useUi == false || Interface.Oxide.CallHook("CanSeeKitsInfo", player, name) == null)            {
			                SendKitContentText(player, name);
			            
		}
		        
	}
		        private void SendKitsInChat(BasePlayer player)        {
		            var kitsString = string.Empty;
			            foreach (var kit in GetAvailableKits(player))            {
				                kitsString += GetMessage(MessageType.KitChatEntry, player.UserIDString,                     "{
				name
			}
				", kit.displayName,                     "{
				description
			}
				", kit.description,                    "{
				cooldown
			}
			", kit.cooldown);
			            
		}
			                            SendMessage(player, MessageType.KitsListChat, "{
			list
		}
		", kitsString);
		        
	}
		        private void SendKitContentText(BasePlayer player, string name)        {
		            var kit = FindKitByName(name);
			            if (kit == null)            {
				                SendMessage(player, MessageType.NoKit, "{
				name
			}
			", name);
			                return;
			            
		}
		                            var contentString = string.Empty;
			                            foreach (var item in kit.items)            {
				                contentString += GetMessage(MessageType.ItemChatEntry, player.UserIDString,                     "{
				name
			}
				", item.shortname,                     "{
				amount
			}
			", item.amount);
			            
		}
			                            SendMessage(player, MessageType.KitsContentChat, "{
			name
		}
			", kit.displayName, "{
			list
		}
		", contentString);
		        
	}
		        private void ConvertUmodKits()        {
		            var obj = Interface.Oxide.DataFileSystem.ReadObject<uModData>("Kits");
		            var kits = obj.Kits.Values.Select(x => x.ToNormalKit()).ToArray();
		            config.kits = config.kits.Concat(kits).ToArray();
		            SaveConfig();
		        
	}
		        private Kit[] GetAvailableKits(BasePlayer player)        {
		            var list = new List<Kit>();
			            foreach (var kit in config.kits)            {
				                if (config.bypassAllChecksForAdmins == true && player.IsAdmin == true)                {
				                    list.Add(kit);
				                    continue;
				                
			}
				                                if (kit.forAPI == true)                {
				                    continue;
				                
			}
				                                if (kit.showWithoutPermission == false && HasPermission(player.UserIDString, kit.permission) == false)                {
				                    continue;
				                
			}
			                list.Add(kit);
			            
		}
		                        return list.ToArray();
		        
	}
		        private static KitInfo GetDataKitInfo(BasePlayer player, string kitName, DataEntry data = null)        {
		            data = data ?? Data.Get(player.UserIDString, true);
		            var kitInfo = (KitInfo) null;
			            if (data.kitsInfo.TryGetValue(kitName, out kitInfo) == false)            {
			                kitInfo = new KitInfo();
			                data.kitsInfo.Add(kitName, kitInfo);
			            
		}
		            return kitInfo;
		        
	}
		        private void LoadImages()        {
		            var previews = config.kits.Where(x => string.IsNullOrEmpty(x.url) == false).Select(xx => xx.url).ToArray();
		            var contents = config.kits.SelectMany(x => x.items).Select(x => x.shortname).Distinct().ToArray();
		            var total = previews.Concat(contents).Distinct().ToArray();
			                        foreach (var url in total)            {
				                if (string.IsNullOrEmpty(url) == true)                {
				                    continue;
				                
			}
			                                AddImage(url);
			            
		}
			                        Puts($"Loaded {
			total.Count()
		}
		 images");
		        
	}
		                private void LoadKits(BasePlayer player = null)        {
			            if (player != null && player.IsAdmin == false)            {
			                SendMessage(player, MessageType.Permission);
			                return;
			            
		}
		                        LoadConfig();
		            Interface.CallHook("OnKitsLoaded");
		        
	}
		                private void UpdateKitItems(BasePlayer player, string name)        {
			            if (player.IsAdmin == false)            {
			                SendMessage(player, MessageType.Permission);
			                return;
			            
		}
		                        LoadConfig();
		                        var kit = FindKitByName(name);
			            if (kit == null)            {
				                SendMessage(player, MessageType.NoKit, "{
				name
			}
			", name);
			                return;
			            
		}
		                        kit.items = GetPlayerItems(player);
			            SendMessage(player, $"{
			kit.displayName
		}
			 [{
			kit.name
		}
		] items was updated!");
		            SaveConfig();
		        
	}
		                private void RemoveExistingKit(BasePlayer player, string name)        {
			            if (player.IsAdmin == false)            {
			                SendMessage(player, MessageType.Permission);
			                return;
			            
		}
		                        LoadConfig();
		            var kit = FindKitByName(name);
			            if (kit == null)            {
				                SendMessage(player, MessageType.NoKit, "{
				name
			}
			", name);
			                return;
			            
		}
		                        RemoveKit(kit);
			            SendMessage(player, MessageType.KitRemoved, "{
			name
		}
		", name);
		        
	}
		                private void AddNewKit(BasePlayer player, string name)        {
			            if (player.IsAdmin == false)            {
			                SendMessage(player, MessageType.Permission);
			                return;
			            
		}
		            LoadConfig();
			                        var kit = new Kit            {
				                name = name,                displayName = name,                items = GetPlayerItems(player),                description = $"Created by {
				player.displayName
			}
				 at {
				DateTime.UtcNow
			}
			"            
		};
		                        AddKit(kit);
			            SendMessage(player, MessageType.KitAdded, "{
			name
		}
			", name, "{
			amount
		}
		", kit.items.Length);
		        
	}
		                private BaseItem[] GetPlayerItems(BasePlayer player)        {
		            var inventory = player.inventory;
		            var items = new List<BaseItem>();
			            foreach (var item in inventory.containerBelt.itemList)            {
			                items.Add(new BaseItem().Create(item, "Belt"));
			            
		}
			                        foreach (var item in inventory.containerWear.itemList)            {
			                items.Add(new BaseItem().Create(item, "Wear"));
			            
		}
			                        foreach (var item in inventory.containerMain.itemList)            {
				                if (item.position < 24)                {
				                    items.Add(new BaseItem().Create(item, "Main"));
				                
			}
			            
		}
		            return items.ToArray();
		        
	}
		                private void GiveKit(BasePlayer player, Kit kit)        {
			            if (kit == null)            {
			                return;
			            
		}
			            foreach (var value in kit.items)            {
			                value.GiveTo(player);
			            
		}
			            if (kit.forAPI == false)            {
				                SendMessage(player, MessageType.KitReceived, "{
				name
			}
			", kit.name);
			            
		}
		                        Interface.Oxide.CallHook("OnKitRedeemed", player, kit.name);
		        
	}
		                private static Kit FindKitByName(string name)        {
		            return config.kits.FirstOrDefault(x => string.Equals(x.name, name, StringComparison.OrdinalIgnoreCase));
		        
	}
		        private void GiveKit(BasePlayer player, string name)        {
		            GiveKit(player, FindKitByName(name));
		        
	}
		                    private void AddKit(Kit kit)        {
			            config.kits = config.kits.Concat(new Kit[]{
			kit
		}
		).ToArray();
		            SaveConfig();
		            Interface.CallHook("OnKitAdded", kit.name);
		        
	}
		        private void RemoveKit(Kit kit)        {
		            config.kits = config.kits.Where(x => x != kit).ToArray();
		            SaveConfig();
		            Interface.CallHook("OnKitRemoved", kit.name);
		        
	}
		                private bool HasPermission(string userID, string perm)        {
		            return string.IsNullOrEmpty(perm) || permission.UserHasPermission(userID, perm);
		        
	}
		                private bool HasPermission(BasePlayer player, string perm)        {
		            return HasPermission(player.UserIDString, perm);
		        
	}
		                    private static BasePlayer FindPlayer(string nameOrID)        {
		            var players = BasePlayer.activePlayerList;
		            var targets = players.Where(x => x.UserIDString == nameOrID || x.displayName.ToLower().Contains(nameOrID.ToLower())).ToList();
			                        if (targets.Count == 0 || targets.Count > 1)            {
			                return null;
			            
		}
		            return targets[0];
		        
	}
	                private static ConfigData config = new ConfigData();
		        private class ConfigData        {
			            [JsonProperty(PropertyName = "Command")]            public string[] commands =            {
			                "kit",                "kits"            
		};
		            [JsonProperty(PropertyName = "Check for free space in inventory")]            public bool checkForFreeSpace = false;
		            [JsonProperty(PropertyName = "Use UI plugin if its installed")]            public bool useUi = true;
		            [JsonProperty(PropertyName = "Bypass all checks for admins")]            public bool bypassAllChecksForAdmins = false;
		            [JsonProperty(PropertyName = "[Data] Wipe on new map")]            public bool autoWipeData = false;
		                        [JsonProperty(PropertyName = "[Data] Remove values that was not used more than 14 days")]            public bool autoCleanData = false;
			                        [JsonProperty(PropertyName = "Kit list")]            public Kit[] kits =            {
				                new Kit                {
				                    displayName = "Test Kit #1",                    cooldown = 300,                    block = 600,                    description = "Test kit #1",                    name = "test1",                    permission = "",                
			}
				,                 new Kit                {
				                    displayName = "Test Kit #2",                    cooldown = 300,                    block = 86400 * 5,                    description = "Test kit #2",                    name = "test2",                    permission = "",                
			}
			,             
		};
		        
	}
		        protected override void LoadConfig()        {
		            base.LoadConfig();
			            try            {
			                config = Config.ReadObject<ConfigData>();
				                if (config == null)                {
				                    LoadDefaultConfig();
				                
			}
			            
		}
			            catch            {
			                for (var i = 0;
			 i < 3;
				 i++)                {
				                    PrintError("Configuration file is corrupt! Check your config file at https://jsonlint.com/");
				                
			}
			                                LoadDefaultConfig();
			                return;
			            
		}
		            ValidateConfig();
		            SaveConfig();
		        
	}
		        private static void ValidateConfig()        {
			            if (ConVar.Server.hostname.Contains("[DEBUG]") == true)            {
			                config = new ConfigData();
			            
		}
			            foreach (var kit in config.kits)            {
				                if (string.IsNullOrEmpty(kit.name))                {
				                    kit.name = "Kit " + Core.Random.Range(0, 99999).ToString();
				                
			}
			            
		}
		        
	}
		        protected override void LoadDefaultConfig()        {
		            config = new ConfigData();
		        
	}
		        protected override void SaveConfig()        {
		            Config.WriteObject(config);
		        
	}
		                private Dictionary<object, string> langMessages = new Dictionary<object, string>        {
			            {
			MessageType.Usage, "Usage:\n"
		}
			,            {
			MessageType.Permission, "<color=#ff0000>You don't have permission to use that!</color>"
		}
			,            {
			MessageType.CantUse, "You can't use it right now"
		}
			,            {
				MessageType.NoKit, "Can't find kit with name '{
				name
			}
			'"
		}
			,            {
			MessageType.AvailableUI, "Click to earn"
		}
			,                        {
			MessageType.PermissionChat, "You don't have permission to use that!"
		}
			,            {
			MessageType.PermissionUI, "No Permission"
		}
			,                        {
				MessageType.CooldownChat, "Cooldown for {
				d
			}
				d {
				h
			}
				h {
				m
			}
				m {
				s
			}
			s !"
		}
			,            {
				MessageType.CooldownUI, "Cooldown: {
				d
			}
				d {
				h
			}
				h {
				m
			}
				m {
				s
			}
			s"
		}
			,                        {
				MessageType.WipeblockChat, "That kit is blocked since wipe. {
				d
			}
				d {
				h
			}
				h {
				m
			}
				m {
				s
			}
			s left"
		}
			,            {
				MessageType.WipeblockUI, "Wipe block: {
				h
			}
				h {
				m
			}
				m {
				s
			}
			s"
		}
			,                        {
				MessageType.UsesLimitChat, "You already used maximal amount of that kit! (Limit: {
				limit
			}
			)"
		}
			,            {
				MessageType.UsesLeftChat, "Uses left: {
				left
			}
			"
		}
			,            {
				MessageType.UsesLeftUI, "Uses: {
				left
			}
			"
		}
			,                        {
				MessageType.KitAdded, "You successfully added kit '{
				name
			}
				' with '{
				count
			}
			' items"
		}
			,            {
				MessageType.KitRemoved, "You successfully removed kit '{
				name
			}
			'"
		}
			,            {
			MessageType.KitReceived, "You successfully get kit!"
		}
			,                        {
				MessageType.KitsListChat, "Currents kits:\n{
				list
			}
			"
		}
			,            {
				MessageType.KitsContentChat, "Kit {
				name
			}
				 including:\n{
				list
			}
			"
		}
			,                        {
				MessageType.KitChatEntry, "<color=#ff0000> {
				name
			}
				</color> - {
				description
			}
				 (Cooldown: {
				cooldown
			}
			)\n"
		}
			,            {
				MessageType.ItemChatEntry, " {
				name
			}
				 x{
				amount
			}
			\n"
		}
			,            {
				MessageType.NoFreeSpace, "You dont have free space in your inventory! More {
				amount
			}
			 needed!"
		}
		        
	};
		                private enum MessageType        {
		            Usage,            Permission,            CantUse,            AvailableUI,            NoKit,            KitsListChat,            KitsContentChat,                        PermissionChat,            PermissionUI,            CooldownChat,            CooldownUI,            WipeblockChat,            WipeblockUI,            UsesLimitChat,            UsesLeftChat,            UsesLeftUI,                        KitAdded,            KitRemoved,            KitReceived,                        KitChatEntry,            ItemChatEntry,            NoFreeSpace,        
	}
		                protected override void LoadDefaultMessages()        {
		            lang.RegisterMessages(langMessages.ToDictionary(x => x.Key.ToString(), y => y.Value), this);
		        
	}
		        private string GetMessage(MessageType key, string playerID = null, params object[] args)        {
		            var message = lang.GetMessage(key.ToString(), this, playerID);
		            var dic = OrganizeArgs(args);
			            if (dic != null)            {
				                foreach (var pair in dic)                {
					                    var s0 = "{
					" + pair.Key + "
				}
				";
				                    var s1 = pair.Key;
				                    var s2 = pair.Value != null ? pair.Value.ToString() : "null";
				                    message = message.Replace(s0, s2, StringComparison.InvariantCultureIgnoreCase);
				                    message = message.Replace(s1, s2, StringComparison.InvariantCultureIgnoreCase);
				                
			}
			            
		}
		            return message;
		        
	}
		        private void SendMessage(object receiver, string message)        {
			            if (receiver == null)            {
			                Puts(message);
			                return;
			            
		}
		                        var console = receiver as ConsoleSystem.Arg;
			            if (console != null)            {
			                SendReply(console, message);
			                return;
			            
		}
		                        var player = receiver as BasePlayer;
			            if (player != null)            {
			                player.ChatMessage(message);
			                return;
			            
		}
		        
	}
		        private void SendMessage(object receiver, MessageType key, params object[] args)        {
		            var userID = (receiver as BasePlayer)?.UserIDString;
		            var message = GetMessage(key, userID, args);
		            SendMessage(receiver, message);
		        
	}
		        private static Dictionary<string, object> OrganizeArgs(object[] args)        {
		            var dic = new Dictionary<string, object>();
		            for (var i = 0;
		 i < args.Length;
			 i += 2)            {
			                var value = args[i].ToString();
			                var nextValue = i + 1 < args.Length ? args[i + 1] : null;
			                dic.TryAdd(value, nextValue);
			            
		}
		            return dic;
		        
	}
	                private static PluginData Data = new PluginData();
		        private string dataFilename => $"{
		Name
	}
	\\data";
	        private bool dataValid = false;
		        private class DataEntry        {
		            [JsonProperty] private DateTime lastUse = DateTime.UtcNow;
		            [JsonProperty] private int loadsCount = 0;
		            [JsonIgnore] public double daysSinceLastUse => (DateTime.UtcNow - lastUse).TotalDays;
		            [JsonProperty] public Dictionary<string, KitInfo> kitsInfo = new Dictionary<string, KitInfo>();
			            public void MarkUsed()            {
			                lastUse = DateTime.UtcNow;
			                loadsCount++;
			            
		}
		        
	}
		                private class PluginData        {
		            [JsonProperty] private Dictionary<string, DataEntry> values = new Dictionary<string, DataEntry>();
		            [JsonProperty] public readonly DateTime creationTime = SaveRestore.SaveCreatedTime;
		            [JsonIgnore] private Dictionary<string, DataEntry> cache = new Dictionary<string, DataEntry>();
		                        [JsonIgnore] public bool needWipe => config.autoWipeData && SaveRestore.SaveCreatedTime > creationTime && differentCreationDates;
		            [JsonIgnore] public bool needCleanup => config.autoCleanData && values.Count > minimalLimitForCleanup;
		            [JsonIgnore] private bool differentCreationDates => (SaveRestore.SaveCreatedTime - creationTime).TotalHours > 1;
		            [JsonIgnore] private static int cacheLifeSpan => 300;
		            [JsonIgnore] public static int unusedDataLifeSpanDays => 14;
		            [JsonIgnore] private static int minimalLimitForCleanup => 500;
		            [JsonIgnore] public int valuesCount => values.Count;
			                        public DataEntry Get(object param, bool createNewOnMissing)            {
			                var key = GetKeyFrom(param);
				                if (string.IsNullOrEmpty(key) == true)                {
				                    return null;
				                
			}
			                                var value = (DataEntry) null;
				                if (cacheLifeSpan > 0 && cache.TryGetValue(key, out value) == true)                {
				                    return value;
				                
			}
				                if (values.TryGetValue(key, out value) == false && createNewOnMissing == true)                {
				                    value = new DataEntry();
				                    values.Add(key, value);
				                
			}
				                if (value != null)                {
				                    value.MarkUsed();
					                    if (cacheLifeSpan > 0)                    {
					                        cache.TryAdd(key, value);
					                    
				}
				                
			}
			                                return value;
			            
		}
			                        public void Set(object param, DataEntry value)            {
			                var key = GetKeyFrom(param);
				                if (string.IsNullOrEmpty(key) == true)                {
				                    return;
				                
			}
				                if (value == null)                {
					                    if (values.ContainsKey(key) == true)                    {
					                        values.Remove(key);
					                    
				}
					                                        if (cache.ContainsKey(key) == true)                    {
					                        cache.Remove(key);
					                    
				}
				                
			}
				                else                {
					                    if (values.TryAdd(key, value) == false)                    {
					                        values[key] = value;
						                                            if (cache.ContainsKey(key) == true)                        {
						                            cache[key] = value;
						                        
					}
					                    
				}
				                
			}
			            
		}
			            public void Cleanup()            {
			                var keys = new List<string>();
				                foreach (var pair in values)                {
				                    var key = pair.Key;
				                    var value = pair.Value;
					                                        if (value.daysSinceLastUse > unusedDataLifeSpanDays)                    {
					                        keys.Add(key);
					                    
				}
				                
			}
				                foreach (var key in keys)                {
				                    Set(key, null);
				                
			}
			            
		}
			            public void ResetCache()            {
			                cache.Clear();
			            
		}
			            private static string GetKeyFrom(object obj)            {
				                if (obj == null)                {
				                    return null;
				                
			}
				                if (obj is string)                {
				                    return obj as string;
				                
			}
				                if (obj is BasePlayer)                {
				                    return (obj as BasePlayer).UserIDString;
				                
			}
				                if (obj is BaseNetworkable)                {
				                    return (obj as BaseNetworkable).net?.ID.ToString();
				                
			}
			                return obj.ToString();
			            
		}
		        
	}
		        private void LoadData()        {
			            try            {
				                Data = Interface.Oxide.DataFileSystem.ReadObject<PluginData>($"{
				dataFilename
			}
			");
				                                if (Data.needWipe == true)                {
					                    Interface.Oxide.DataFileSystem.WriteObject($"{
					dataFilename
				}
				_old", Data);
				                    Data = new PluginData();
					                    PrintWarning($"Data was wiped by auto-wiping function (Old: {
					Data.creationTime
				}
					, New: {
					SaveRestore.SaveCreatedTime
				}
				)");
				                
			}
				                if (Data.needCleanup == true)                {
				                    var oldCount = Data.valuesCount;
				                    Data.Cleanup();
				                    var newCount = Data.valuesCount;
					                    PrintWarning($"Removed {
					oldCount - newCount
				}
					 values that are older than {
					PluginData.unusedDataLifeSpanDays
				}
					 days (Was: {
					oldCount
				}
					, Now: {
					newCount
				}
				)");
				                
			}
			                dataValid = true;
			                timer.Every(Core.Random.Range(500, 700), SaveData);
			                SaveData();
			            
		}
			            catch (Exception e)            {
			                Data = new PluginData();
			                dataValid = false;
			                for (var i = 0;
			 i < 5;
				 i++)                {
				                    PrintError("!!! CRITICAL DATA ERROR !!!\n * Data was not loaded!\n * Data auto-save was disabled!");
				                
			}
				                                LogToFile("errors", $"\n\nError: {
				e.Message
			}
				\n\nTrace: {
				e.StackTrace
			}
			\n\n", this);
			            
		}
		        
	}
		        private void SaveData()        {
			            if (Data != null && dataValid == true)            {
			                Data.ResetCache();
			                Interface.Oxide.DataFileSystem.WriteObject(dataFilename, Data);
			            
		}
		        
	}
		                private class BaseItem        {
		            [JsonProperty(PropertyName = "Command")]            public string command = string.Empty;
		            [JsonProperty(PropertyName = "Shortname")]            public string shortname = string.Empty;
		            [JsonProperty(PropertyName = "Amount")]            public int amount = 1;
		            [JsonProperty(PropertyName = "Skin")]             public ulong skinId;
		            [JsonProperty(PropertyName = "Random skin")]             public bool randomizeSkin = false;
		            [JsonProperty(PropertyName = "Display name")]            public string displayName;
		            [JsonProperty(PropertyName = "Blueprint")]            public bool isBlueprint;
		            [JsonProperty(PropertyName = "Container")]            public string container = string.Empty;
		            [JsonProperty(PropertyName = "Slot")]             public int slot;
		            [JsonProperty(PropertyName = "Fuel")]             public float fuel;
		            [JsonProperty(PropertyName = "Contents")]            public Dictionary<string, int> contents = new Dictionary<string, int>();
		            [JsonProperty(PropertyName = "Condition (don't change me)")]            public float condition;
		            [JsonProperty(PropertyName = "Maximal Condition (don't change me)")]            public float maxCondition;
			            public void GiveTo(BasePlayer player)            {
				                if (player == null)                {
				                    return;
				                
			}
			                                var item = Create();
				                if (item != null)                {
				                    var container = (ItemContainer) null;
					                                        switch (this.container.ToLower())                    {
					                        case "belt":                            container = player.inventory.containerBelt;
					                            break;
					                        case "main":                            container = player.inventory.containerMain;
					                            break;
					                                                case "wear":                            container = player.inventory.containerWear;
					                            break;
					                    
				}
					                    if (container == null || item.MoveToContainer(container, slot) == false)                    {
					                        player.GiveItem(item);
					                    
				}
				                
			}
				                if (string.IsNullOrEmpty(command) == false)                {
				                    RunCommand(player);
				                
			}
			            
		}
			            public void GiveTo(string playerID)            {
			                var player = BasePlayer.Find(playerID) ?? BasePlayer.FindSleeping(playerID);
				                if (player == null)                {
				                    RunCommand(playerID);
				                
			}
				                else                {
				                    GiveTo(player);
				                
			}
			            
		}
			            private Item Create()            {
				                if (isBlueprint)                {
				                    var blueprint = ItemManager.CreateByName("blueprintbase", amount);
				                    blueprint.blueprintTarget = ItemManager.FindItemDefinition(shortname).itemid;
				                    return blueprint;
				                
			}
			                var item = ItemManager.CreateByName(shortname, amount, skinId);
				                if (item == null)                {
				                    return null;
				                
			}
				                if (randomizeSkin == true)                {
				                    Interface.CallHook("SetRandomSkin", null, item);
				                
			}
			                item.name = displayName;
				                if (maxCondition > 0)                {
				                    item.maxCondition = maxCondition;
				                    item.condition = condition;
				                
			}
			                                item.fuel = fuel;
			                var weapon = item?.GetHeldEntity()?.GetComponent<BaseProjectile>();
				                foreach (var defC in contents)                {
				                    var name = defC.Key;
				                    var amount = defC.Value;
					                    if ((name.StartsWith("arrow.") || name.StartsWith("ammo.")) && weapon != null)                    {
					                        weapon.primaryMagazine.ammoType = ItemManager.FindItemDefinition(name);
					                        weapon.primaryMagazine.contents = amount;
					                        continue;
					                    
				}
				                    var content = ItemManager.CreateByName(name, amount);
				                    content?.MoveToContainer(item.contents);
				                
			}
			                weapon?.SendNetworkUpdateImmediate();
			                return item;
			            
		}
			            public BaseItem Create(Item item, string rootContainer = null)            {
				                var value = new BaseItem                {
				                    shortname = item.blueprintTarget != 0                        ? ItemManager.FindItemDefinition(item.blueprintTarget).shortname                        : item.info.shortname,                    amount = item.amount,                    skinId = item.skin,                    displayName = item.name,                    condition = item.condition,                    maxCondition = item.maxCondition,                    fuel = item.fuel,                    isBlueprint = item.blueprintTarget != 0,                    slot = item.position,                    container = rootContainer,                
			};
				                foreach (var subItem in item.contents?.itemList ?? new List<Item>())                {
				                    value.contents.Add(subItem.info.shortname, subItem.amount);
				                
			}
			                var weapon = item.GetHeldEntity()?.GetComponent<BaseProjectile>()?.primaryMagazine;
				                if (weapon != null)                {
				                    value.contents.Add(weapon.ammoType.shortname, weapon.contents);
				                
			}
			                return value;
			            
		}
			            private void RunCommand(BasePlayer player)            {
			                RunCommand(player.UserIDString);
			            
		}
			            private void RunCommand(string playerID)            {
				                if (string.IsNullOrEmpty(command))                {
				                    return;
				                
			}
				                var cmd = command                    .Replace("{
				userid
			}
				", playerID, StringComparison.OrdinalIgnoreCase)                    .Replace("{
				playerid
			}
			", playerID, StringComparison.OrdinalIgnoreCase);
			                ConsoleSystem.Run(ConsoleSystem.Option.Server, cmd);
			            
		}
		        
	}
		        private class Kit        {
		            [JsonProperty(PropertyName = "Shortname", Order = 1)]            public string name = string.Empty;
		            [JsonProperty(PropertyName = "Display name", Order = 2)]            public string displayName = string.Empty;
		            [JsonProperty(PropertyName = "Permission", Order = 3)]            public string permission = "kits.new";
		            [JsonProperty(PropertyName = "Cooldown", Order = 4)]            public int cooldown = 3600;
		            [JsonProperty(PropertyName = "Wipe-block time", Order = 5)]            public int block = 0;
		            [JsonProperty(PropertyName = "Icon", Order = 6)]            public string url = string.Empty;
		            [JsonProperty(PropertyName = "Description", Order = 7)]            public string description = string.Empty;
		            [JsonProperty(PropertyName = "Max uses", Order = 8)]            public int uses = 0;
		            [JsonProperty(PropertyName = "API Kit", Order = 800)]            public bool forAPI = false;
		            [JsonProperty(PropertyName = "Show without uses", Order = 801)]            public bool showWithoutUses = false;
		            [JsonProperty(PropertyName = "Show without permission", Order = 802)]            public bool showWithoutPermission = false;
		            [JsonProperty(PropertyName = "Show if wipe-blocked", Order = 803)]            public bool showIfWipeBlocked = true;
		            [JsonProperty(PropertyName = "Show if on cooldown", Order = 804)]            public bool showIfOnCooldown = true;
		            [JsonProperty(PropertyName = "Custom message if doesn't have permission", Order = 900)]            public string messageForNoPermission = string.Empty;
			            [JsonProperty(PropertyName = "Items", Order = 999)]            public BaseItem[] items =            {
				                new BaseItem                {
				                    shortname = "stonehatchet"                
			}
				,                new BaseItem                {
				                    shortname = "pickaxe"                
			}
			            
		};
		            [JsonIgnore]             public bool blockBypass = false;
		        
	}
		        private class uModData        {
		            public Dictionary<string, uModKit> Kits = new Dictionary<string, uModKit>();
		        
	}
		                private class uModKit        {
		            public string name;
		            public string description;
		            public int max;
		            public double cooldown;
		            public int authlevel;
		            public bool hide;
		            public bool npconly;
		            public string permission;
		            public string image;
		            public string building;
		            public List<uModKitItem> items = new List<uModKitItem>();
			            public Kit ToNormalKit()            {
				                return new Kit                {
				                    name = name,                     description = description,                    uses = max,                    cooldown = Convert.ToInt32(cooldown),                    forAPI = hide || npconly,                    permission = permission,                    url = image,                    items = items.Select(x => x.ToBaseItem()).ToArray()                
			};
			            
		}
		        
	}
		                private class uModKitItem        {
		            public int itemid;
		            public string container;
		            public int amount;
		            public ulong skinid;
		            public bool weapon;
		            public int blueprintTarget;
		            public List<int> mods = new List<int>();
			            public BaseItem ToBaseItem()            {
				                return new BaseItem                {
				                    shortname = ItemManager.FindItemDefinition(itemid)?.shortname,                    container = container,                    amount = amount,                    skinId = skinid,                    isBlueprint = blueprintTarget != 0,                    contents = mods.ToDictionary(x => ItemManager.FindItemDefinition(x)?.shortname, y => 1)                
			};
			            
		}
		        
	}
	                [PluginReference] private Plugin ImageLibrary;
		        private void AddImage(string url)        {
			            if (ImageLibrary == null)            {
			                return;
			            
		}
			            if (string.IsNullOrWhiteSpace(url) == true)            {
			                return;
			            
		}
			            if (url.StartsWith("http") == false && url.StartsWith("www") == false)            {
				                url = $"https://rustlabs.com/img/items180/{
				url
			}
			.png";
			            
		}
		                        var obj = ImageLibrary.Call("HasImage", url, (ulong) 0);
			            if (obj != null && (bool) obj == false)            {
			                ImageLibrary.CallHook("AddImage", url, url, (ulong) 0);
			            
		}
		        
	}
		        private string GetImage(string url)        {
		            var obj = ImageLibrary?.Call("GetImage", url);
		            return obj?.ToString();
		        
	}
		                private static bool CanUse(BasePlayer player)        {
		            return Interface.Oxide.CallHook("canRedeemKit", player) == null &&                   Interface.Oxide.CallHook("CanUseKit", player) == null;
		        
	}
		        private bool isKit(string kitname)        {
		            return FindKitByName(kitname) != null;
		        
	}
		        private string[] GetKitContents(string kitname, bool random = false)        {
		            var kit = FindKitByName(kitname);
			            if (kit == null)            {
			                return null;
			            
		}
		                        var items = new List<string>();
			            foreach (var item in kit.items)            {
				                var itemString = $"{
				ItemManager.FindItemDefinition(item.shortname)?.itemid
			}
				_{
				item.amount
			}
			";
				                if (item.contents.Count > 0)                    foreach (var mod in item.contents)                    {
					                        itemString += $"_{
					mod
				}
				";
				                    
			}
			                                items.Add(itemString);
			            
		}
		            return items.Count > 0 ? items.ToArray() : null;
		        
	}
		                private object GetKitInfo(string kitname)        {
		            var kit = FindKitByName(kitname);
			            if (kit == null)            {
			                return null;
			            
		}
			            var obj = new JObject            {
			                ["name"] = kit.name,                ["permission"] = kit.permission,                ["npconly"] = kit.forAPI,                ["max"] = kit.uses,                ["image"] = kit.url,                ["hide"] = kit.forAPI,                ["description"] = kit.description,                ["cooldown"] = kit.cooldown,                ["building"] = false,                ["authlevel"] = 0            
		};
		                        var items = new JArray();
			            foreach (var itemEntry in kit.items)            {
			                var item = new JObject();
			                item["amount"] = itemEntry.amount;
			                item["container"] = itemEntry.container;
			                item["itemid"] = ItemManager.FindItemDefinition(itemEntry.shortname)?.itemid;
			                item["skinid"] = itemEntry.skinId;
			                item["weapon"] =  ItemManager.FindItemDefinition(itemEntry.shortname)?.GetComponent<HeldEntity>() != null;
			                item["blueprint"] = itemEntry.isBlueprint;
			                item["mods"] = null;
			                items.Add(item);
			            
		}
		            obj["items"] = items;
		            return obj;
		        
	}
		        private string API_GetPlayerUIKits(BasePlayer player)        {
		            return GetPlayerKitsForUI(player);
		        
	}
		        private string API_GetKitForUI(BasePlayer player, string kit)        {
		            return GetKitForUI(player, kit);
		        
	}
		        private string[] GetAllKits()        {
		            return config.kits.Select(x => x.name).Where(x => string.IsNullOrEmpty(x) == false).ToArray();
		        
	}
		        private string GetPlayerKitsForUI(BasePlayer player)        {
		            var kits = config.kits.Where(x => x.forAPI == false);
		            var list = new List<KitUI>();
		            var data = Data.Get(player.UserIDString, true);
			            foreach (var kit in kits)            {
			                var kitInfo = GetDataKitInfo(player, kit.name, data);
			                var message = GetUIMessage(player, kit, kitInfo);
				                if (message == null)                {
				                    continue;
				                
			}
				                                var obj = new KitUI                {
				                    block = kit.block,                    cooldown = kit.cooldown,                    description = kit.description,                    name = kit.name,                    items = new Dictionary<string, int>(),                    url = kit.url,                    uses = kit.uses,                    displayName = kit.displayName,                    messageOnButton = message                
			};
				                foreach (var item in kit.items)                {
					                    if (obj.items.TryAdd(item.shortname, item.amount) == false)                    {
					                        obj.items[item.shortname] += item.amount;
					                    
				}
				                
			}
			                                list.Add(obj);
			            
		}
		                        var array = list.ToArray();
		            return JsonConvert.SerializeObject(array);
		        
	}
		        private string GetKitForUI(BasePlayer player, string name)        {
		            var kit = FindKitByName(name);
			            if (kit == null)            {
			                return null;
			            
		}
		            var data = GetDataKitInfo(player, name);
			            var obj = new KitUI            {
			                block = kit.block,                cooldown = kit.cooldown,                uses = kit.uses - data.uses,                displayName = kit.displayName,                description = kit.description,                items = new Dictionary<string, int>(),            
		};
			            foreach (var item in kit.items)            {
				                if (obj.items.ContainsKey(item.shortname))                {
				                    obj.items[item.shortname] += item.amount;
				                
			}
				                else                {
				                    obj.items.Add(item.shortname, item.amount);
				                
			}
			            
		}
		            return JsonConvert.SerializeObject(obj);
		        
	}
		                private string GetUIMessage(BasePlayer player, Kit kit, KitInfo kitInfo)        {
			            if (HasPermission(player, kit.permission) == false)            {
				                if (kit.showWithoutPermission == false)                {
				                    return null;
				                
			}
			                                return string.IsNullOrEmpty(kit.messageForNoPermission) ? GetMessage(MessageType.PermissionUI, player.UserIDString) : kit.messageForNoPermission;
			            
		}
			                    if (kit.uses > 0)            {
			                var left = kit.uses - kitInfo.uses;
				                if (left <= 0)                {
					                    return kit.showWithoutUses == false ? null : GetMessage(MessageType.UsesLeftUI, "{
					limit
				}
				", 0);
				                
			}
			            
		}
			            if (kit.block > 0 && kit.blockBypass == false)            {
			                var unblockDate = SaveRestore.SaveCreatedTime.AddSeconds(kit.block);
			                var leftSpan = unblockDate - DateTime.UtcNow;
				                if (leftSpan.TotalSeconds > 0)                {
					                    return kit.showIfWipeBlocked == false ? null : GetMessage(MessageType.WipeblockUI, player.UserIDString, "{
					d
				}
					", leftSpan.Days, "{
					h
				}
					", leftSpan.Hours, "{
					m
				}
					", leftSpan.Minutes, "{
					s
				}
				", leftSpan.Seconds);
				                
			}
				                else                {
				                    kit.blockBypass = true;
				                
			}
			            
		}
			            if (kit.cooldown > 0)            {
			                var unblockDate = kitInfo.lastUse.AddSeconds(kit.cooldown);
			                var leftSpan = unblockDate - DateTime.UtcNow;
				                if (leftSpan.TotalSeconds > 0)                {
					                    return kit.showIfOnCooldown == false ? null : GetMessage(MessageType.CooldownUI, player.UserIDString, "{
					d
				}
					", leftSpan.Days, "{
					h
				}
					", leftSpan.Hours, "{
					m
				}
					", leftSpan.Minutes, "{
					s
				}
				", leftSpan.Seconds);
				                
			}
			            
		}
		            return GetMessage(MessageType.AvailableUI, player.UserIDString);
		        
	}
		        private class KitUI        {
		            public string name = string.Empty;
		            public string displayName = string.Empty;
		            public int cooldown = 3600;
		            public int block = 0;
		            public string url = string.Empty;
		            public string description = string.Empty;
		            public int uses = 0;
		            public string messageOnButton;
		            public Dictionary<string, int> items = new Dictionary<string, int>();
		        
	}
	    
}
}



© 2020 Quttera Ltd. All rights reserved.