예제 #1
0
        public static async Task ShopMainMenu(SocketGuildUser user, RestUserMessage message)
        {
            //Get the account information of the command's target
            var account = UserInfoClasses.GetAccount(user);

            // Find both the menu session and item session associated with the current user and store them in variables.
            var menuSession = Global.MenuIdList.SingleOrDefault(x => x.User.Id == user.Id);
            var itemSession = Global.ItemIdList.SingleOrDefault(x => x.User.Id == user.Id);

            var embed  = new EmbedBuilder();
            var author = new EmbedAuthorBuilder
            {
                Name    = "Décor Shop",
                IconUrl = user.GetAvatarUrl()
            };

            embed.WithAuthor(author);

            //Determine color for embeded message
            if (account.Profile_Theme == "P3")
            {
                embed.WithColor(37, 149, 255);
            }
            else if (account.Profile_Theme == "P4")
            {
                embed.WithColor(255, 229, 49);
            }
            else if (account.Profile_Theme == "P5")
            {
                embed.WithColor(213, 27, 4);
            }

            embed.AddField("Wallet", $"<:PMedals:672637091171139615> **{account.P_Medals}**");

            // Create a string variable to store the text that will be displayed on the message's body.
            string displayed_shop_list = "";

            // Create an int variable from the number of items in the list minus the starting index to count from.
            // Since the ItemIndexBase should always initially start at zero, nothing will be subtracted at first but will adjust as the index moves when the page changes.
            int remaining_list_length = itemSession.ItemList.Count - itemSession.ItemIndexBase;

            // Create another int variable that will indicate a subset of the item list that the user is currently viewing.
            int sublist_length = 0;

            // If the remaining number of items in the list is greater than or equal to the max amount of items that should be displayed, make the sublist_length int also equal to max_items_displayed.
            if (remaining_list_length >= itemSession.MaxItemsDisplayed)
            {
                sublist_length = itemSession.MaxItemsDisplayed;
            }
            // Else, if the number of remaining items is less than max_items_displayed, make sublist_length equal to the remaining number of items.
            else
            {
                sublist_length = remaining_list_length;
            }

            // Create an int to properly display the needed emotes when iterating through the item list.
            int displayed_list_counter = 0;

            // Iterate through the item list starting from the ItemBaseIndex and up until sublist_length.
            for (int i = itemSession.ItemIndexBase; i < (itemSession.ItemIndexBase + sublist_length); i++)
            {
                // Increase the displayed_list_counter by one.
                displayed_list_counter += 1;

                // Get the information of the current décor iteration.
                var decor_info = DecorInfoMethods.GetDecorInfo(itemSession.ItemList[i]);

                // Add the entry to the displayed_shop_list string.
                displayed_shop_list += $":{DecorInfoMethods.NumberToWords(displayed_list_counter)}: {decor_info.Title} - <:cost:780352551945895936> **{decor_info.Price}**\n";
            }

            // Add the displayed_shop_list as a new field to the embed.
            embed.AddField("What would you like to purchase? Select a number you wish to view.", $"{displayed_shop_list}");

            // Create a string variable to store text for the footer. This will change depending on the state of the menu.
            string footer_text = "";

            // Check if the starting item index is greater than or equal to max_items_displayed.
            if (itemSession.ItemIndexBase >= itemSession.MaxItemsDisplayed)
            {
                // If so, there will be a "Previous Page" button displayed on the footer.
                footer_text += "◀️ Previous Page | ";
            }
            // Check if the number of items in the list minus the starting item index is more than max_items_displayed.
            if (remaining_list_length > itemSession.MaxItemsDisplayed)
            {
                // If so, there will be a "Next Page" button on the footer.
                footer_text += "▶️ Next Page | ";
            }

            // Calculate the amount of pages there will be in total and store it in a variable.
            int pageCount = (itemSession.ItemList.Count + itemSession.MaxItemsDisplayed - 1) / itemSession.MaxItemsDisplayed;

            // Add two icons to the end of footer_text regardless of the state, plus a page counter on a new line.
            footer_text += $"⚙️ Sort | ❌ Exit Shop\nPage {itemSession.CurrentPage} / {pageCount}";

            // Create the footer object for the embed.
            var footer = new EmbedFooterBuilder
            {
                Text = footer_text
            };

            // Add the footer to the embed.
            embed.WithFooter(footer);

            // Attach a locally generated image to the embed. This image hasn't been created yet, so the filename is just a placeholder for now.
            embed.WithImageUrl($"attachment://preview.png");

            // Create a new stream. We'll use this to create the locally generated image.
            MemoryStream memoryStream = new MemoryStream();

            // Generate a bitmap comprised of thumbnail previews of the décor being listed on the current page.
            Bitmap decor_preview = DecorInfoMethods.DecorPreviews(itemSession, sublist_length);

            // Save the décor preview bitmap to the stream as a PNG.
            decor_preview.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png);

            // Ensure the stream is set to the beginning of itself.
            memoryStream.Seek(0, SeekOrigin.Begin);

            // Attempt deleting the message if it hasn't been deleted by the user yet.
            try
            {
                // Delete the current message from the channel.
                await message.DeleteAsync();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }

            // If the bot lacks permission to attach files, catch the exception, send an error message, and return.
            try
            {
                // Reassign the menu session's message to a new message generated from the created embed and preview image.
                menuSession.MenuMessage = (RestUserMessage)await message.Channel.SendFileAsync(memoryStream, "preview.png", "", false, embed.Build());
            }
            catch (Exception ex)
            {
                await ErrorHandling.AttachFilesError((SocketTextChannel)message.Channel);

                Console.WriteLine(ex);
                return;
            }

            // Set the "message" variable to the menu session's message.
            message = menuSession.MenuMessage;

            // Edit the menu session according to the current message.
            menuSession.CurrentMenu = "Shop_Main_Menu";
            menuSession.MenuTimer   = new Timer()
            {
                // Create a timer that expires as a "time out" duration for the user.
                Interval  = MenuConfig.menu.timerDuration,
                AutoReset = false,
                Enabled   = true
            };

            // If the timer runs out, activate a function.
            menuSession.MenuTimer.Elapsed += (sender, e) => MenuTimer_Elapsed(sender, e, menuSession, itemSession);

            // Create an empty list for reactions.
            List <IEmote> reaction_list = new List <IEmote> {
            };

            // Add needed emote reactions for the menu.
            // Check if the starting item index is greater than or equal to max_items_displayed.
            if (itemSession.ItemIndexBase >= itemSession.MaxItemsDisplayed)
            {
                // If so, there will be a "Previous Page" button added as a reaction.
                reaction_list.Add(new Emoji("◀️"));
            }

            // Check if the number of items in the list minus the starting item index is more than max_items_displayed.
            if (remaining_list_length > itemSession.MaxItemsDisplayed)
            {
                // If so, there will be a "Next Page" button added as a reaction.
                reaction_list.Add(new Emoji("▶️"));
            }

            // Reset the displayed_list_counter to zero.
            displayed_list_counter = 0;

            for (int i = 0; i < sublist_length; i++)
            {
                // Increase the displayed_list_counter by one.
                displayed_list_counter += 1;

                // For each loop iteration, add a keycap emote representing an item entry being displayed to the user.
                reaction_list.Add(new Emoji($"{DecorInfoMethods.NumberToKeycapEmoji(displayed_list_counter)}"));
            }

            // Add two more reactions to the end of the message.
            reaction_list.Add(new Emoji("⚙️"));
            reaction_list.Add(new Emoji("❌"));

            // Add the reactions to the message.
            _ = ReactionHandling.AddReactionsToMenu(message, reaction_list);
        }
예제 #2
0
        public static async Task Status_Decor_Main(SocketGuildUser user, RestUserMessage message)
        {
            // Get the account information of the command's user.
            var account = UserInfoClasses.GetAccount(user);

            // Find both the menu session and item session associated with the current user and store them in variables.
            var menuSession = Global.MenuIdList.SingleOrDefault(x => x.User.Id == user.Id);
            var itemSession = Global.ItemIdList.SingleOrDefault(x => x.User.Id == user.Id);

            var embed  = new EmbedBuilder();
            var author = new EmbedAuthorBuilder
            {
                Name    = "Status Screen Décor",
                IconUrl = user.GetAvatarUrl()
            };

            embed.WithAuthor(author);

            // Determine the color and thumbnail for the embeded message.
            embed.WithColor(EmbedSettings.Get_Profile_Embed_Color(account));
            embed.WithThumbnailUrl(EmbedSettings.Get_Profile_Config_Thumbnail(account));

            // Create a string variable to store the text that will be displayed on the message's body.
            string displayed_decor_list = "";

            // Create an int variable from the number of items in the list minus the starting index to count from.
            // Since the ItemIndexBase should always initially start at zero, nothing will be subtracted at first but will adjust as the index moves when the page changes.
            int remaining_list_length = itemSession.ItemList.Count - itemSession.ItemIndexBase;

            // Create another int variable that will indicate a subset of the item list that the user is currently viewing.
            int sublist_length = 0;

            // If the remaining number of items in the list is greater than or equal to the max amount of items that should be displayed, make the sublist_length int also equal to max_items_displayed.
            if (remaining_list_length >= itemSession.MaxItemsDisplayed)
            {
                sublist_length = itemSession.MaxItemsDisplayed;
            }
            // Else, if the number of remaining items is less than max_items_displayed, make sublist_length equal to the remaining number of items.
            else
            {
                sublist_length = remaining_list_length;
            }

            // Create an int to properly display the needed emotes when iterating through the item list.
            int displayed_list_counter = 0;

            // Iterate through the item list starting from the ItemBaseIndex and up until sublist_length.
            for (int i = itemSession.ItemIndexBase; i < (itemSession.ItemIndexBase + sublist_length); i++)
            {
                // Increase the displayed_list_counter by one.
                displayed_list_counter += 1;

                // Get the information of the current décor iteration.
                var decor_info = DecorInfoMethods.GetDecorInfo(itemSession.ItemList[i]);

                // Add the entry to the displayed_shop_list string.
                displayed_decor_list += $":{DecorInfoMethods.NumberToWords(displayed_list_counter)}: {decor_info.Title}\n";
            }

            // Create a string variable to store text for the footer. This will change depending on the state of the menu.
            string footer_text = "";

            // Depending on whether or not the user owns or can set any décor, perform different actions.
            if (displayed_decor_list.Length > 0)
            {
                // Add a "Back" button to be displayed on the footer.
                footer_text += "↩️ Profile Settings | ";

                // Check if the starting item index is greater than or equal to max_items_displayed.
                if (itemSession.ItemIndexBase >= itemSession.MaxItemsDisplayed)
                {
                    // If so, there will be a "Previous Page" button displayed on the footer.
                    footer_text += "◀️ Previous Page | ";
                }
                // Check if the number of items in the list minus the starting item index is more than max_items_displayed.
                if (remaining_list_length > itemSession.MaxItemsDisplayed)
                {
                    // If so, there will be a "Next Page" button on the footer.
                    footer_text += "▶️ Next Page | ";
                }

                // Calculate the amount of pages there will be in total and store it in a variable.
                int pageCount = (itemSession.ItemList.Count + itemSession.MaxItemsDisplayed - 1) / itemSession.MaxItemsDisplayed;

                // Add two icons to the end of footer_text regardless of the state, plus a page counter on a new line.
                footer_text += $"⚙️ Sort\nPage {itemSession.CurrentPage} / {pageCount}";

                // Create the footer object for the embed.
                var footer = new EmbedFooterBuilder
                {
                    Text = footer_text
                };

                // Add the footer to the embed.
                embed.WithFooter(footer);

                // Create an empty string variable. This will hold part of the embeded message's description
                string description_text = "";

                // If the user has a décor and a profile theme currently set, create a description text explaining how to remove the currently set décor.
                if (account.Decor_Setting != "" && account.Profile_Theme != "")
                {
                    description_text = "" +
                                       "**Select a décor to view.**\n" +
                                       "**To remove your current décor and set the default one for your profile theme, select :white_square_button:.**";
                }
                // If not, create a default description text instructing to select a décor.
                else
                {
                    description_text = "**Select a décor to view.**";
                }

                // Create a string variable that will hold the title of the user's currently set décor.
                string set_decor_title = DecorInfoMethods.GetDecorTitle(user);

                embed.WithDescription("" +
                                      $"{description_text}\n" +
                                      "\n" +
                                      $"⚙️ **Current setting:** **`{set_decor_title}`**\n" +
                                      "\n" +
                                      $"{displayed_decor_list}");

                // Attach a locally generated image to the embed.
                embed.WithImageUrl($"attachment://preview.png");

                // Create a new stream. We'll use this to create the locally generated image.
                MemoryStream memoryStream = new MemoryStream();

                // Generate a bitmap comprised of thumbnail previews of the décor being listed on the current page.
                Bitmap decor_preview = DecorInfoMethods.DecorPreviews(itemSession, sublist_length);

                // Save the décor preview bitmap to the stream as a PNG.
                decor_preview.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png);

                // Ensure the stream is set to the beginning of itself.
                memoryStream.Seek(0, SeekOrigin.Begin);

                // Attempt deleting the message if it hasn't been deleted by the user yet.
                try
                {
                    // Delete the current message from the channel.
                    await message.DeleteAsync();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }

                // If the bot lacks permission to attach files, catch the exception, send an error message, and return.
                try
                {
                    // Reassign the menu session's message to a new message generated from the created embed and preview image.
                    menuSession.MenuMessage = (RestUserMessage)await message.Channel.SendFileAsync(memoryStream, "preview.png", "", false, embed.Build());
                }
                catch (Exception ex)
                {
                    await ErrorHandling.AttachFilesError((SocketTextChannel)message.Channel);

                    Console.WriteLine(ex);
                    return;
                }

                // Set the "message" variable to the menu session's message.
                message = menuSession.MenuMessage;
            }
            else
            {
                // Add a "Back" button to be displayed on the footer.
                footer_text += "↩️ Profile Settings";

                // Create the footer object for the embed.
                var footer = new EmbedFooterBuilder
                {
                    Text = footer_text
                };

                // Add the footer to the embed.
                embed.WithFooter(footer);

                embed.WithDescription("You don't have any other décor to set. Visit the Décor Shop with the **`>shop`** command to browse and buy décor for your collection.");

                // Attempt editing the message if it hasn't been deleted by the user yet. If it has, catch the exception, send an error message, and return.
                try
                {
                    // Remove all reactions from the current message.
                    await message.RemoveAllReactionsAsync();

                    // Edit the current active message by replacing it with the recently created embed.
                    await message.ModifyAsync(x => {
                        x.Embed = embed.Build();
                    });
                }
                catch (Exception ex)
                {
                    await ErrorHandling.MissingMessageError((SocketTextChannel)message.Channel);

                    Console.WriteLine(ex);
                    return;
                }
            }

            // Edit the menu session according to the current message.
            menuSession.CurrentMenu = "Status_Decor_Main";
            menuSession.MenuTimer   = new Timer()
            {
                // Create a timer that expires as a "time out" duration for the user.
                Interval  = MenuConfig.menu.timerDuration,
                AutoReset = false,
                Enabled   = true
            };

            // If the timer runs out, activate a function.
            menuSession.MenuTimer.Elapsed += (sender, e) => MenuTimer_Elapsed(sender, e, menuSession, itemSession);

            // Create an empty list for reactions.
            List <IEmote> reaction_list = new List <IEmote> {
            };

            // Add needed emote reactions for the menu.
            reaction_list.Add(new Emoji("↩️"));

            // Check if the starting item index is greater than or equal to max_items_displayed.
            if (itemSession.ItemIndexBase >= itemSession.MaxItemsDisplayed)
            {
                // If so, there will be a "Previous Page" button added as a reaction.
                reaction_list.Add(new Emoji("◀️"));
            }

            // Check if the number of items in the list minus the starting item index is more than max_items_displayed.
            if (remaining_list_length > itemSession.MaxItemsDisplayed)
            {
                // If so, there will be a "Next Page" button added as a reaction.
                reaction_list.Add(new Emoji("▶️"));
            }

            // Reset the displayed_list_counter to zero.
            displayed_list_counter = 0;

            for (int i = 0; i < sublist_length; i++)
            {
                // Increase the displayed_list_counter by one.
                displayed_list_counter += 1;

                // For each loop iteration, add a keycap emote representing an item entry being displayed to the user.
                reaction_list.Add(new Emoji($"{DecorInfoMethods.NumberToKeycapEmoji(displayed_list_counter)}"));
            }

            // If the user owns any décor, add a gear reaction in order to sort entries.
            if (displayed_decor_list.Length > 0)
            {
                reaction_list.Add(new Emoji("⚙️"));
            }

            // If the user has a décor and a profile theme currently set, add a box reaction. This gives the option to remove the set décor and return to the default one.
            if (account.Decor_Setting != "" && account.Profile_Theme != "")
            {
                reaction_list.Add(new Emoji("🔳"));
            }

            // Add the reactions to the message.
            _ = ReactionHandling.AddReactionsToMenu(message, reaction_list);
        }