Exemple #1
0
        /// <summary>
        /// Delete local "KLOG_A_$(guid).txt" files that exceed the provided retention period (in days).
        /// </summary>
        /// <param name="retentionFiles"></param>
        public static void Retention(IEnumerable <FileModel> retentionFiles)
        {
            using (KLog logRetention = new KLog("ClassProcessor-MethodRetention"))
            {
                try
                {
                    foreach (var retentionFile in retentionFiles)
                    {
                        // TODO: clean-up check + checkBool
                        var check = ((DateTime.UtcNow.AddDays(Configuration.RetentionDays)) < retentionFile.FileDate) ? "Hold" : "Delete";

                        var checkBool = ((DateTime.UtcNow.AddDays(Configuration.RetentionDays)) < retentionFile.FileDate);

                        logRetention.Info($"Retention File Operation => Time: {retentionFile.FileDate.ToString()}, Result: {check.ToString()}, File: {retentionFile.FileName}");

                        if (!checkBool)
                        {
                            File.Delete(retentionFile.FullPath);

                            logRetention.Info($"Retention File Operation => |- Delete File: {retentionFile.FileName}");
                        }
                    }
                }
                catch (Exception ex)
                {
                    logRetention.Error($"{ex.ToString()}");
                }
            }
        }
        public static void Execute()
        {
            using (KLog collectorLog = new KLog("ClassBlobFileCollector-MethodExecute"))
            {
                try
                {
                    var token = new BlobContinuationToken();

                    var blobCollection = BlobClient.BlobContainer.ListBlobsSegmentedAsync(null, token).GetAwaiter().GetResult();

                    List <string> blobPrefixNames = blobCollection.Results.OfType <CloudBlobDirectory>().Select(b => b.Prefix).ToList();

                    collectorLog.Info($"Collector => Prefix Count: {blobPrefixNames.Count()}");

                    // flush static object
                    BlobFileCollection.StaticFlush();

                    // for each dir in the blob container
                    foreach (var blobPrefixName in blobPrefixNames)
                    {
                        var prefixblobCollection = BlobClient.BlobContainer.ListBlobsSegmentedAsync(blobPrefixName, token).GetAwaiter().GetResult();

                        List <string> prefixblobFileNames = prefixblobCollection.Results.OfType <CloudBlockBlob>().Select(b => b.Name).ToList();

                        collectorLog.Info($"Collector => Parsing Prefix: {blobPrefixName}");

                        BlobFileParser.Execute(blobPrefixName, prefixblobFileNames);
                    }
                }
                catch (Exception ex)
                {
                    collectorLog.Error($"BlobFileCollector Exception: {ex.ToString()}");
                }
            }
        }
        public static void Execute()
        {
            // Blob retention
            using (KLog blobRetention = new KLog("BlobFileRetention-BlobRetention"))
            {
                try
                {
                    IEnumerable <BlobFileModel> retentionFileCollection = BlobFileCollection.CurrentRetentionCount();

                    blobRetention.Info($"Retention Count: {retentionFileCollection.Count()}");

                    foreach (BlobFileModel blobFile in retentionFileCollection)
                    {
                        // for each file, confim check one more
                        blobRetention.Info($"Retention => File Name: {blobFile.CloudFile}");

                        string cloudFile = blobFile.CloudFile;

                        try
                        {
                            BlobClient.DeleteBlobFile(cloudFile);

                            blobRetention.Info($"File Deleted => File Name: {blobFile.CloudFile}");
                        }
                        catch (Exception ex)
                        {
                            blobRetention.Error($"Delete Failure: {blobFile.CloudFile} Exception: {ex}");
                        }
                    }
                }
                catch (Exception ex)
                {
                    blobRetention.Error($"BlobFileRetention Exception: {ex.ToString()}");
                }
            }

            // SQL Retention
            using (KLog sqlRetention = new KLog("BlobFileRetention-SQLRetention"))
            {
                try
                {
                    SQLResponseModel checkRetention = DataAccessor.Retention(Configuration.RetentionDays);

                    if (!checkRetention.Success)
                    {
                        sqlRetention.Error($"SQL Expection on [BlobFileRetention].[Retention] - Message: {checkRetention.Message}");
                    }
                }
                catch (Exception ex)
                {
                    sqlRetention.Error($"BlobFileRetention Exception: {ex.ToString()}");
                }
            }
        }
        // TODO: *** Application entry point exposed to Function ***
        /// <summary>
        ///
        /// </summary>
        public static bool Execute()
        {
            if (!IsInitialized)
            {
                return(false);
            }

            try
            {
                using (KLog klog = new KLog("KLogging"))
                {
                    Configuration.StartLogging();

                    // TODO: *** entry point into core application logic ***

                    klog.Info($"Logging.");

                    Configuration.StopLogging();

                    return(true);
                }
            }
            catch (Exception ex)
            {
                throw new Exception($"EXCEPTION: {ex.ToString()}");
            }
        }
        public static void AddBan(ulong id, BanDataNode ban, string username = "")
        {
            int        pos   = 2;
            ExcelRange cells = StrikeLog.Workbook.Worksheets[StrikeLogPage].Cells;

            while (cells["A" + pos].Value != null)
            {
                if (Convert.ToUInt64(cells["A" + pos].Value.ToString()) == id)
                {
                    cells[$"J{pos}:L{pos}"].LoadFromArrays(ban.GetBanForExcel());
                    KLog.Info($"Banned user {(string.IsNullOrWhiteSpace(username) ? id.ToString() : username)} by {ban.Moderator} for reason: {ban.Reason}. Ban added in cell range J{pos}:L{pos}.");
                    SaveExcel();
                    return;
                }
                pos++;
            }

            // User doesn't have an entry, so is likely just a troll.
            GenUserStrike(pos, id);
            cells[$"J{pos}:L{pos}"].LoadFromArrays(ban.GetBanForExcel());
            // Set auto fit
            cells[StrikeLog.Workbook.Worksheets[StrikeLogPage].Dimension.Address].AutoFitColumns();
            KLog.Info($"Banned user {(string.IsNullOrWhiteSpace(username) ? id.ToString() : username)} by {ban.Moderator} for reason: {ban.Reason}. Ban added in cell range J{pos}:L{pos}.");
            SaveExcel();
        }
Exemple #6
0
        public static void SetAvailability(uint id, bool a)
        {
            KLog.Info($"{(a ? "Enabled":"Disabled")} the item at id {id} in the shop");

            ItemManager.GetItem(id).Buyable = a;
            ValidateShopSelection();
        }
Exemple #7
0
        /// <summary>
        /// This method initializes all items to the dictionary, and sets up the shop
        /// </summary>
        public static void SetupItems()
        {
            Items = new Dictionary <uint, Item>();

            string j = FileManager.ReadFullFile(DataFileNames.ItemMapFile);

            Dictionary <uint, ItemInfoNode> data = JsonConvert.DeserializeObject <Dictionary <uint, ItemInfoNode> >(j) ?? new Dictionary <uint, ItemInfoNode>();

            AddSpecialItems();

            foreach (uint k in data.Keys)
            {
                ItemInfoNode i = data[k];

                if (Items.ContainsKey(k))
                {
                    Item it = Items[k];

                    it.Id          = k;
                    it.Name        = i.Name;
                    it.Description = i.Description;
                    it.Rarity      = i.Rarity;
                    it.BuyPrice    = i.BuyPrice;
                    it.Buyable     = i.Buyable;
                    it.ImageUrl    = i.ImageUrl;
                    it.SetRecipe(i.Recipe);
                    continue;
                }

                Items.Add(k, new Item(k, i.Name, i.Description, i.Rarity, i.Buyable, i.BuyPrice, i.Recipe, i.ImageUrl));
            }

            KLog.Info("Loaded Items.");
        }
        public static void LoadReminders()
        {
            string json = FileManager.ReadFullFile(DataFileNames.UserRemindersFile);

            Reminders = JsonConvert.DeserializeObject <Dictionary <ulong, Dictionary <string, List <ReminderNode> > > >(json) ?? new Dictionary <ulong, Dictionary <string, List <ReminderNode> > >();
            KLog.Info("Reminders Loaded");
        }
Exemple #9
0
        public async Task ReplaceSettingsFileAsync([Remainder] string message = "")
        {
            if (!ServerData.HasPermissionLevel(BotUtils.GetGUser(Context), ServerData.PermissionLevel.ADMIN))
            {
                return;                                                                                                // This is an admin only command
            }
            if (Context.Message.Attachments.Count == 1)
            {
                Attachment file = Context.Message.Attachments.ElementAt(0);

                if (file.Filename != "settings.json")
                {
                    await ReplyAsync(BotUtils.KamtroText("The settings file must be a json file named settings.json!"));

                    return;
                }

                // At this point, the file is valid
                string url = file.Url;

                WebClient wc = new WebClient();
                wc.DownloadFile(url, AdminDataManager.StrikeLogPath);

                KLog.Info($"Settings file updated by {BotUtils.GetFullUsername(Context.User)}");
                await ReplyAsync(BotUtils.KamtroText("The settings file has been updated!"));
            }
        }
        public static void LoadInventories()
        {
            string data = FileManager.ReadFullFile(DataFileNames.UserInventoriesFile);
            Dictionary <ulong, UserInventoryNode> UserInventories = JsonConvert.DeserializeObject <Dictionary <ulong, UserInventoryNode> >(data) ?? new Dictionary <ulong, UserInventoryNode>();

            foreach (ulong id in UserInventories.Keys)
            {
                if (BotUtils.GetGUser(id) == null)
                {
                    continue;
                }

                if (UserDataManager.UserData.ContainsKey(id))
                {
                    // User has a data file, things are all good
                    UserDataManager.GetUserData(BotUtils.GetGUser(id)).Inventory = UserInventories[id];
                }
                else
                {
                    // wacky things are going on, create a user profile and then load inventory
                    UserDataManager.AddUser(BotUtils.GetGUser(id));
                    UserDataManager.GetUserData(BotUtils.GetGUser(id)).Inventory = UserInventories[id];
                }
            }

            KLog.Info("Loaded Inventories.");
        }
        public static void SaveRoleMap()
        {
            string json = JsonConvert.SerializeObject(RoleMap, Formatting.Indented);

            File.WriteAllText(DataFileNames.RoleSelectMapFile, json);

            KLog.Info("Role Map Saved.");
        }
 public static void FullSave()
 {
     KLog.Info("Beginning full save...\n---------------");
     SaveUserData();
     SaveUserSettings();
     UserInventoryManager.SaveInventories();
     KLog.Info("---------------");
 }
        /// <summary>
        /// Delete local "KLOG_A_$(guid).txt" files that exceed the configured retention period (in days).
        /// </summary>
        /// <param name="retentionFiles"></param>
        public static void Execute()
        {
            using (KLog logRetention = new KLog("ClassDeleteLogs-MethodExecute"))
            {
                try
                {
                    if (Capsule.DeleteFileCount() > 0)
                    {
                        foreach (var retentionFile in Capsule.DeleteFiles)
                        {
                            // TODO: clean-up check + checkBool

                            if (Configuration.RetentionDays < 0)
                            {
                                var check     = ((DateTime.UtcNow.AddDays(Configuration.RetentionDays)) < retentionFile.FileDate) ? "Hold" : "Delete";
                                var checkBool = ((DateTime.UtcNow.AddDays(Configuration.RetentionDays)) < retentionFile.FileDate);

                                logRetention.Info($"Retention File Operation => Time: {retentionFile.FileDate.ToString()}, Result: {check.ToString()}, File: {retentionFile.FileName}");

                                if (!checkBool)
                                {
                                    File.Delete(retentionFile.FullPath);

                                    logRetention.Info($"Retention File Operation => |- Delete File: {retentionFile.FileName}");
                                }
                            }
                            else
                            {
                                File.Delete(retentionFile.FullPath);

                                logRetention.Info($"Retention File Operation => |- Delete File: {retentionFile.FileName}");
                            }
                        }
                    }
                    else
                    {
                        logRetention.Info("No files were marked for retention.");
                    }
                }
                catch (Exception ex)
                {
                    logRetention.Error($"{ex.ToString()}");
                }
            }
        }
        public static void LoadNodeMap()
        {
            string json = FileManager.ReadFullFile(DataFileNames.TitleListFile);

            NodeMap = JsonConvert.DeserializeObject <Dictionary <int, TitleNode> >(json) ?? new Dictionary <int, TitleNode>();

            KLog.Info($"Title node map {(Loaded ? "Reloaded":"Loaded")}");
            Loaded = true;
        }
        private static void GenUserStrike(int pos, ulong target, string username = "", int strikes = 1)
        {
            KLog.Info($"User {(string.IsNullOrEmpty(username) ? target.ToString() : username)} doesn't have a strike entry, creating one...");
            List <string[]> entry = new List <string[]>();

            entry.Add(new string[] { target.ToString(), username, strikes.ToString() });

            StrikeLog.Workbook.Worksheets[StrikeLogPage].Cells[$"A{pos}:C{pos}"].LoadFromArrays(entry);
        }
        public static void ResetWeekly()
        {
            foreach (ulong key in UserData.Keys)
            {
                UserData[key].WeeklyScore = 0;
            }

            KLog.Info("Reset weekly message scores");
        }
        /// <summary>
        /// Generates the base for a user entry. Does not generate the strike, only columns A through C
        /// </summary>
        /// <param name="pos">Row in the spreadsheet</param>
        /// <param name="target">Target user for entry</param>
        private static void GenUserStrike(int pos, SocketUser target, int strikes = 1)
        {
            KLog.Info($"User {BotUtils.GetFullUsername(target)} doesn't have a strike entry, creating one...");
            List <string[]> entry = new List <string[]>();

            entry.Add(new string[] { target.Id.ToString(), BotUtils.GetFullUsername(target), strikes.ToString() });

            StrikeLog.Workbook.Worksheets[StrikeLogPage].Cells[$"A{pos}:C{pos}"].LoadFromArrays(entry);
        }
        public static void Execute()
        {
            using (KLog checkLog = new KLog("ClassBlobFileCheck-MethodExecute"))
            {
                try
                {
                    foreach (var file in BlobFileCollection.GetFiles())
                    {
                        if (file.FileGuid != Guid.Empty)
                        {
                            var resultResponse = DataAccessor.CheckInstanceId(file.FileGuid);

                            if (!resultResponse.Success)
                            {
                                checkLog.Error($"SQL Expection on [BlobFileCheck].[CheckInstance] - Message: {resultResponse.Message}");
                                break;
                            }

                            if (resultResponse.Id != Guid.Empty)
                            {
                                BlobFileCollection.GetFiles().First(d => d.FileGuid == file.FileGuid).Exist = true;
                                checkLog.Info($"Instance Check => Guid: {file.FileGuid.ToString()} Result: true");
                            }
                            else
                            {
                                BlobFileCollection.GetFiles().First(d => d.FileGuid == file.FileGuid).Exist = false;
                                checkLog.Info($"Instance Check => Guid: {file.FileGuid.ToString()} Result: false");
                            }
                        }
                        else
                        {
                            BlobFileCollection.GetFiles().First(d => d.FileGuid == file.FileGuid).Exist = true;
                            checkLog.Info($"Instance Check => Guid: {file.FileGuid.ToString()} Result: true (empty guid)");
                        }
                    }
                }
                catch (Exception ex)
                {
                    checkLog.Error($"BlobfileCheck Expection: {ex.ToString()}");
                }
            }
        }
        public static void ResetRep()
        {
            foreach (ulong key in UserData.Keys)
            {
                UserData[key].ReputationToGive = Math.Max(UserData[key].MaxReputation, UserData[key].ReputationToGive);
            }

            SaveUserData();

            KLog.Info("Reset giveable reputation stats");
        }
Exemple #20
0
        /// <summary>
        /// Test method for dynamic KLOG creation.
        /// </summary>
        /// <param name="instanceIteration"></param>
        public static void DynamicLog(string instanceIteration)
        {
            using (KLog klog = new KLog($"Dynamic KFlow -- Primary Node -- {instanceIteration}"))
            {
                klog.Info("Testing primary block");

                using (KLog nestedKLog = new KLog($"Dynamic KFlow -- Nested Node -- {instanceIteration}", klog))
                {
                    nestedKLog.Info("Testing nested block");
                }
            }
        }
        /// <summary>
        /// Happens when a user is unbanned from a server the bot is in.
        /// </summary>
        /// <param name="user">The user that was unbanned</param>
        /// <param name="server">The server they were unbanned from</param>
        /// <returns></returns>
        public async Task OnMemberUnban(SocketUser user, SocketGuild server) {
            if(CrossBan == null) {
                CrossBan = new Dictionary<ulong, CrossBanDataNode>();
                SaveList();
            }

            if (CrossBan.ContainsKey(user.Id) && server.Id == ServerData.Server.Id) {
                CrossBan.Remove(user.Id);
                KLog.Info($"Removed user {BotUtils.GetFullUsername(user)} from cross-ban list");
                SaveList();
            }
        }
        /// <summary>
        /// Adds a strike to a user
        /// </summary>
        /// <param name="target"></param>
        /// <param name="strike"></param>
        /// <returns>The number of strikes the user has.</returns>
        public static int AddStrike(SocketUser target, StrikeDataNode strike)
        {
            ulong targetId = target.Id;
            int   pos      = GetEntryPos(targetId);

            ExcelRange cells = StrikeLog.Workbook.Worksheets[StrikeLogPage].Cells;

            if (!IsRowNew(pos))
            {
                // Add the srike to this row.
                // First, check the username.
                if (cells["B" + pos].Text != BotUtils.GetFullUsername(target))
                {
                    // if it doesn't check out, update it.
                    cells["B" + pos].Value = BotUtils.GetFullUsername(target);
                }

                // now for the strike address. This will be based off of the number of strikes.
                // This is in column C
                int strikes = cells["C" + pos].GetValue <int>();

                if (strikes == 2)
                {
                    return(4);               // 4 is the signal
                }
                // now to get the column. Fun ascii math.
                // 68 = ASCII for capital D.
                string range = char.ConvertFromUtf32(68 + strikes * 3) + pos + ":" + char.ConvertFromUtf32(70 + strikes * 3) + pos;

                cells[range].LoadFromArrays(strike.GetStrikeForExcel());

                cells[$"C:{pos}"].Value = (Convert.ToInt32(cells[$"C{pos}"].Text) + 1).ToString();
                StrikeLog.Save();

                KLog.Info($"Added strike {cells[$"C:{pos}"].Value.ToString()} for {BotUtils.GetFullUsername(target)} in cell range {range}");

                return(Convert.ToInt32(cells[$"C{pos}"].Text));
            }

            // The user doesn't have an entry. So make one.
            GenUserStrike(pos, target);

            // Now add the strike
            ExcelRange er = cells[$"D{pos}:F{pos}"];

            er.LoadFromArrays(strike.GetStrikeForExcel());
            // Set auto fit
            cells[StrikeLog.Workbook.Worksheets[StrikeLogPage].Dimension.Address].AutoFitColumns();
            StrikeLog.Save();
            KLog.Info($"Added strike for {BotUtils.GetFullUsername(target)} in cell range D{pos}:F{pos}");

            return(1);
        }
        public static void ResetKamtrokenEarns()
        {
            foreach (ulong key in UserData.Keys)
            {
                UserData[key].KamtrokensEarned      = 0;
                UserData[key].KamtrokenEarnProgress = 0;
            }

            SaveUserData();

            KLog.Info("Reset daily earned kamtrokens");
        }
        /// <summary>
        /// Execute the KCopy application.
        /// </summary>
        /// <returns></returns>
        public static bool Execute()
        {
            if (!_configOnline)
            {
                return(false);
            }

            try
            {
                // Start instance level logging
                Configuration.StartLogging();

                // Log global properties
                using (KLog logConfig = new KLog("ClassExecute-LogicConfig"))
                {
                    logConfig.Info($"Config Local Directory: {Configuration.LocalDirectory}");
                    logConfig.Info($"Config Azure Container: {Configuration.AzureContainer}");
                    logConfig.Info($"Config Retention: {Configuration.RetentionDays}");
                    logConfig.Info($"Config Cleanse: {Configuration.CleanseHours}");
                }

                Capsule.AddLogFiles(CollectLogs.Execute(Configuration.LocalDirectory));

                DeleteLogs.Execute();

                SendLogs.Execute();

                CleanseLogs.Execute();

                Configuration.StopLogging();

                return(true);
            }
            catch (Exception ex)
            {
                throw new Exception($"KCOPY EXCEPTION: {ex}");
            }
        }
Exemple #25
0
        /// <summary>
        /// Identify local "KLOG_W_$(guid).txt" files (orpahned) that exceed the configured retention period (in hours). The files are renamed (re-queued) to "KLOG_S_$(guid).txt" for sending.
        /// </summary>
        /// <param name="cleanupFiles"></param>
        public static void Execute()
        {
            using (KLog logCleanse = new KLog("ClassCleanseLogs-MethodExecute"))
            {
                try
                {
                    if (Capsule.CleanUpFileCount() > 0)
                    {
                        foreach (var cleanseFile in Capsule.CleanUpFiles)
                        {
                            // TODO: clean-up check + checkBool
                            var check = ((DateTime.UtcNow.AddHours(Configuration.CleanseHours)) < cleanseFile.FileDate) ? "Hold" : "Rename";

                            var checkBool = ((DateTime.UtcNow.AddHours(Configuration.CleanseHours)) < cleanseFile.FileDate);

                            logCleanse.Info($"Cleanse File Operation => Time: {cleanseFile.FileDate.ToString()}, Result: {check.ToString()}, File: {cleanseFile.FileName}");

                            if (!checkBool)
                            {
                                var renamefileName = cleanseFile.Path + @"\KLOG_S_" + cleanseFile.FileGuid.ToString() + ".txt";

                                File.Move(cleanseFile.FullPath, renamefileName);

                                logCleanse.Info($"Cleanse File Operation => |- Rename File: {renamefileName}");
                            }
                        }
                    }
                    else
                    {
                        logCleanse.Info("No files required clean-up.");
                    }
                }
                catch (Exception ex)
                {
                    logCleanse.Error($"{ex.ToString()}");
                }
            }
        }
        private async Task StrikeUser(SocketUser user)
        {
            // First, the classic null check
            if (BotUtils.GetGUser(Context) == null)
            {
                await Context.Channel.SendMessageAsync(BotUtils.KamtroText("That user does not exist!"));

                KLog.Info($"User {BotUtils.GetFullUsername(Context.User)} attempted to strike non-existant member {BotUtils.GetFullUsername(user)}");
                return;
            }

            // Flavor text for trying to strike yourself
            if (user.Id == Context.User.Id)
            {
                await Context.Channel.SendMessageAsync(BotUtils.KamtroText("We would like to save the strikes for those that deserve it."));

                return;
            }

            // next, check to see if Kamtro has perms to ban the user
            if (!BotUtils.HighestUser(BotUtils.GetGUser(Context.Client.CurrentUser.Id), BotUtils.GetGUser(user.Id)))
            {
                await Context.Channel.SendMessageAsync(BotUtils.KamtroText("The user is higher than me, so I cannot strike them."));

                KLog.Info($"User {BotUtils.GetFullUsername(Context.User)} attempted to strike member {BotUtils.GetFullUsername(user)} of higher status than bot");
                return;
            }

            // next, check if the caller can ban the user
            if (!ServerData.HasPermissionLevel(BotUtils.GetGUser(Context), ServerData.PermissionLevel.ADMIN))
            {
                if (BotUtils.HighestUser(BotUtils.GetGUser(user.Id), BotUtils.GetGUser(Context), true))
                {
                    await Context.Channel.SendMessageAsync(BotUtils.KamtroText("This user is higher or equal than you, and as such, you cannot strike them."));

                    KLog.Info($"User {BotUtils.GetFullUsername(Context.User)} attempted to strike member {BotUtils.GetFullUsername(user)} of higher status than caller");
                    return;
                }
            }

            if (AdminDataManager.GetStrikes(user) >= 2)
            {
                await BanUser(user);

                return;
            }

            StrikeEmbed se = new StrikeEmbed(Context, user);
            await se.Display();
        }
Exemple #27
0
        /// <summary>
        /// Crafts the item. No checks in method
        /// </summary>
        /// <param name="item">The item to craft</param>
        private void Craft(uint itemId)
        {
            Item item = ItemManager.GetItem(itemId);

            foreach (uint k in item.GetRecipe().Keys)
            {
                LoseItem(k, item.GetRecipe()[k]);
            }

            AddItem(itemId);

            KLog.Info($"User {BotUtils.GetFullUsername(BotUtils.GetGUser(UserDataManager.UserData.FirstOrDefault(x => x.Value.Inventory == this).Key))} crafted item {item.Name} (ID: {itemId})");

            ParseInventory();
        }
        public static void SaveInventories()
        {
            Dictionary <ulong, UserInventoryNode> UserInventories = new Dictionary <ulong, UserInventoryNode>();

            foreach (ulong i in UserDataManager.UserData.Keys)
            {
                if (BotUtils.GetGUser(i) == null)
                {
                    continue;                                // null checking.
                }
                UserInventories.Add(i, UserDataManager.GetUserData(BotUtils.GetGUser(i)).Inventory ?? new UserInventoryNode());
            }

            BotUtils.WriteToJson(UserInventories, DataFileNames.UserInventoriesFile);
            KLog.Info("Saved Inventories.");
        }
        public static void AddBan(SocketUser target, BanDataNode ban)
        {
            int        pos   = GetEntryPos(target.Id);
            ExcelRange cells = StrikeLog.Workbook.Worksheets[StrikeLogPage].Cells;

            cells[$"J{pos}:L{pos}"].LoadFromArrays(ban.GetBanForExcel());
            KLog.Info($"Banned user {BotUtils.GetFullUsername(target)} by {ban.Moderator} for reason: {ban.Reason}. Ban added in cell range J{pos}:L{pos}.");
            SaveExcel();

            // User doesn't have an entry, so is likely just a troll.
            GenUserStrike(pos, target);
            cells[$"J{pos}:L{pos}"].LoadFromArrays(ban.GetBanForExcel());
            // Set auto fit
            cells[StrikeLog.Workbook.Worksheets[StrikeLogPage].Dimension.Address].AutoFitColumns();
            KLog.Info($"Banned user {BotUtils.GetFullUsername(target)} by {ban.Moderator} for reason: {ban.Reason}. Ban added in cell range J{pos}:L{pos}.");
            SaveExcel();
        }
        private async Task BanUser(SocketUser user)
        {
            // First, the classic null check
            if (BotUtils.GetGUser(Context) == null)
            {
                await Context.Channel.SendMessageAsync(BotUtils.KamtroText("That user does not exist!"));

                KLog.Info($"User {BotUtils.GetFullUsername(Context.User)} attempted to ban non-existant member {BotUtils.GetFullUsername(user)}");
                return;
            }

            // Flavor text for trying to ban yourself
            if (user.Id == Context.User.Id)
            {
                await Context.Channel.SendMessageAsync(BotUtils.KamtroText("Sorry, but we still need you."));

                return;
            }

            // next, check to see if Kamtro has perms to ban the user
            if (!BotUtils.HighestUser(BotUtils.GetGUser(Context.Client.CurrentUser.Id), BotUtils.GetGUser(user.Id)))
            {
                await Context.Channel.SendMessageAsync(BotUtils.KamtroText("The user is higher than me, so I cannot ban them."));

                KLog.Info($"User {BotUtils.GetFullUsername(Context.User)} attempted to ban member {BotUtils.GetFullUsername(user)} of higher status than bot");
                return;
            }

            // next, check if the caller can ban the user
            if (!ServerData.HasPermissionLevel(BotUtils.GetGUser(Context), ServerData.PermissionLevel.ADMIN))
            {
                if (BotUtils.HighestUser(BotUtils.GetGUser(user.Id), BotUtils.GetGUser(Context), true))
                {
                    await Context.Channel.SendMessageAsync(BotUtils.KamtroText("This user is higher or equal than you, and as such, you cannot ban them."));

                    KLog.Info($"User {BotUtils.GetFullUsername(Context.User)} attempted to ban member {BotUtils.GetFullUsername(user)} of higher status than caller");
                    return;
                }
            }

            BanEmbed be = new BanEmbed(Context, user);
            await be.Display();
        }