예제 #1
0
        internal static async void RenderImage(SocketUser user, ISocketMessageChannel channel)
        {
            RestUserMessage loader = await channel.SendMessageAsync("", false, LoadingMessage().Build());

            // Place the bulk of the function in a try-catch block in case something fails and an error message needs to be sent
            try
            {
                // Grab the user's account information
                var account = UserInfoClasses.GetAccount(user);

                //Establish variables to write on the template
                string username = "";

                //If the username is over 12 characters, replace the last parts with an ellipsis
                if (user.Username.Length > 12)
                {
                    username = $"{username.Substring(0, 12)}...";
                }
                else
                {
                    username = $"{user.Username}";
                }

                //Establish other variables of the user's data
                string level             = $"{account.Level}";
                string profile_picture   = user.GetAvatarUrl();
                string pmedals           = $"{account.P_Medals}";
                string proficiency_title = Core.LevelSystem.SocialStats.ProficiencyRankTitle(account.Proficiency_Rank);
                string diligence_title   = Core.LevelSystem.SocialStats.DiligenceRankTitle(account.Diligence_Rank);
                string expression_title  = Core.LevelSystem.SocialStats.ExpressionRankTitle(account.Expression_Rank);

                //Determine the Next Exp value
                int next_exp = 0;
                if (account.Level != 99)
                {
                    next_exp = Core.LevelSystem.Leveling.CalculateExp(account.Level + 1) - account.Total_Exp;
                }

                //If the user doesn't have a profile picture, use a default one
                if (profile_picture == null)
                {
                    profile_picture = "https://i.imgur.com/T0AjCLh.png";
                }

                // Create a base bitmap to render all the elements on
                Bitmap p4_template = new Bitmap(1920, 1080);

                //Copy the P4 status background to a bitmap
                Bitmap base_layer = (Bitmap)System.Drawing.Image.FromFile($@"{AssetDirectoryConfig.assetDirectory.assetFolderPath}//Profile//StatusScreens//Default//P4//layer_1.png");

                //Copy the P4 status info fields to a bitmap
                Bitmap info_layer = (Bitmap)System.Drawing.Image.FromFile($@"{AssetDirectoryConfig.assetDirectory.assetFolderPath}//Profile//StatusScreens//Default//P4//layer_2.png");

                //Copy the plot point overlay to a bitmap
                Bitmap graph_overlay = (Bitmap)System.Drawing.Image.FromFile($@"{AssetDirectoryConfig.assetDirectory.assetFolderPath}//Profile//StatusScreens//Default//P4//layer_3.png");

                //Copy the P-Medal icon to a bitmap
                Bitmap pmedal_icon = (Bitmap)System.Drawing.Image.FromFile($@"{AssetDirectoryConfig.assetDirectory.assetFolderPath}//Profile//StatusScreens//Default//P4//pmedal_icon.png");

                //Use a graphics object to edit the bitmap
                using (Graphics graphics = Graphics.FromImage(p4_template))
                {
                    //Set text rendering to have antialiasing
                    graphics.TextRenderingHint = TextRenderingHint.AntiAlias;

                    // Draw the first bitmap layer to the template
                    graphics.DrawImage(base_layer, 0, 0, base_layer.Width, base_layer.Height);

                    //Draw the randomized elements to the template first
                    graphics.DrawImage(RandomizeWaveAndWindow(), 0, 0, 1920, 1080);

                    //Draw the information fields
                    graphics.DrawImage(info_layer, 0, 0, 1920, 1080);

                    //Using a font object, draw the user's username value to the template
                    using (Font p4g_font = new Font("P4G", 37))
                    {
                        graphics.DrawString(username, p4g_font, System.Drawing.Brushes.Black, new Point(276, 139));
                    }

                    //Create text boxes to place the user's level and P-Medal values in
                    Rectangle level_box    = new Rectangle(70, 84, 210, 100);
                    Rectangle pmedal_box   = new Rectangle(50, 180, 210, 100);
                    Rectangle next_exp_box = new Rectangle(575, 222, 1000, 100);

                    //Create new colors to shade the level and P-Medal values with
                    System.Drawing.Color level_color  = System.Drawing.Color.FromArgb(255, 247, 130);
                    System.Drawing.Color pmedal_color = System.Drawing.Color.FromArgb(225, 108, 1);

                    //Create new brushes so that the colors can be used on a font object
                    SolidBrush level_brush  = new SolidBrush(level_color);
                    SolidBrush pmedal_brush = new SolidBrush(pmedal_color);

                    //Using a font object, draw the user's level value to the template
                    using (Font p4g_stats_font = new Font("P4G Stats", 68))
                    {
                        //Format the string so that its placement is on the right side of the text box
                        StringFormat stringFormat = new StringFormat();
                        stringFormat.Alignment = StringAlignment.Far;

                        graphics.DrawString(level, p4g_stats_font, level_brush, level_box, stringFormat);
                    }

                    //Draw P-Medal text and graphic information within this font object
                    using (Font p4g_stats_font = new Font("P4G Stats", 48))
                    {
                        //Format the string so that its placement is on the right side of the text box
                        StringFormat stringFormat = new StringFormat();
                        stringFormat.Alignment = StringAlignment.Far;

                        //If the user's P-Medal count has 2 or less digits, draw the P-Medal icon in a specific place
                        if (pmedals.Length <= 2)
                        {
                            graphics.DrawImage(pmedal_icon, 85, 189, 72, 52);
                        }
                        //Else, if the user's P-Medal count has 3 digits, draw the P-Medal icon in a different place
                        else if (pmedals.Length == 3)
                        {
                            graphics.DrawImage(pmedal_icon, 55, 189, 72, 52);
                        }

                        //Draw the user's P-Medal value to the screen
                        graphics.DrawString(pmedals, p4g_stats_font, pmedal_brush, pmedal_box, stringFormat);
                    }

                    //Draw the user's next EXP value to the template within this font object
                    using (Font p4g_stats_font = new Font("P4G Stats", 47))
                    {
                        //Format the string so that its placement is on the left side of the text box
                        StringFormat stringFormat = new StringFormat();
                        stringFormat.Alignment = StringAlignment.Near;

                        graphics.DrawString($"{next_exp}", p4g_stats_font, System.Drawing.Brushes.Black, next_exp_box, stringFormat);
                    }

                    //Create text boxes to draw the social link rank titles
                    Rectangle proficiency_title_box = new Rectangle(1163, 233, 309, 53);
                    Rectangle diligence_title_box   = new Rectangle(834, 860, 309, 53);
                    Rectangle expression_title_box  = new Rectangle(1493, 859, 309, 53);

                    //Draw the rank titles onto the template
                    using (Font p4g_font = new Font("P4G", 31))
                    {
                        //Format the strings so that their placements are at the center of the text boxes
                        StringFormat stringFormat = new StringFormat();
                        stringFormat.Alignment = StringAlignment.Center;

                        graphics.DrawString(proficiency_title, p4g_font, System.Drawing.Brushes.White, proficiency_title_box, stringFormat);
                        graphics.DrawString(diligence_title, p4g_font, System.Drawing.Brushes.White, diligence_title_box, stringFormat);
                        graphics.DrawString(expression_title, p4g_font, System.Drawing.Brushes.White, expression_title_box, stringFormat);
                    }

                    //Create points that define radar chart
                    Point proficiency_point = ProficiencyGraphPoint(account.Proficiency_Rank);
                    Point diligence_point   = DiligenceGraphPoint(account.Diligence_Rank);
                    Point expression_point  = ExpressionGraphPoint(account.Expression_Rank);

                    //Create rectangles for large endpoints that emphasize where the radar points are
                    Rectangle proficiency_endpoint = ProficiencyEndpoint(account.Proficiency_Rank);
                    Rectangle diligence_endpoint   = DiligenceEndpoint(account.Diligence_Rank);
                    Rectangle expression_endpoint  = ExpressionEndpoint(account.Expression_Rank);

                    //Create a color for the radar chart
                    SolidBrush orangeBrush = new SolidBrush(System.Drawing.Color.Orange);

                    //Bind radar chart points
                    Point[] curvePoints = { proficiency_point, diligence_point, expression_point };

                    //Draw radar chart to screen
                    graphics.FillPolygon(orangeBrush, curvePoints);

                    //Draw the plot point overlay to the template
                    graphics.DrawImage(graph_overlay, 0, 0, 1920, 1080);

                    //Create a black pen to draw large endpoints over the plot point overlay
                    System.Drawing.Pen blackPen = new System.Drawing.Pen(System.Drawing.Color.Black, 10);

                    //Draw the large endpoints to the template
                    graphics.DrawEllipse(blackPen, proficiency_endpoint);
                    graphics.DrawEllipse(blackPen, diligence_endpoint);
                    graphics.DrawEllipse(blackPen, expression_endpoint);

                    //Use a web client to download the user's profile picture and draw it to the template
                    using (var wc = new WebClient())
                    {
                        using (var imgStream = new MemoryStream(wc.DownloadData(profile_picture)))
                        {
                            using (var objImage = System.Drawing.Image.FromStream(imgStream))
                            {
                                graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
                                graphics.DrawImage(objImage, 250, 447, 440, 440);
                            }
                        }
                    }

                    // If the user has ever reset their level, render a prestige counter to the template
                    if (account.Level_Resets > 0)
                    {
                        graphics.DrawImage(RenderPrestigeCounter(account.Level_Resets), 0, 0, 1920, 1080);
                    }
                }

                //Save the bitmap to a data stream
                MemoryStream memoryStream = new MemoryStream();
                p4_template.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png);
                memoryStream.Seek(0, SeekOrigin.Begin);

                //Send the image
                await channel.SendFileAsync(memoryStream, $"status_{user.Id}_{DateTime.UtcNow}.png");

                //Delete the loading message
                await loader.DeleteAsync();
            }
            catch (Exception ex)
            {
                //Send an error message to the user
                _ = ErrorHandling.Scene_Upload_Failed(user, channel);
                Console.WriteLine(ex);

                //Delete the loading message
                await loader.DeleteAsync();

                return;
            }
        }