Ejemplo n.º 1
0
        public async Task PlaceImage(int x, int y, [Remainder] string image)
        {
            if (x <= 0 || y <= 0)
            {
                await EmbedExtensions.FromError("I can't process coordinates below 0", Context).QueueMessageAsync(Context);

                return;
            }
            if (x > SkuldAppContext.PLACEIMAGESIZE || y > SkuldAppContext.PLACEIMAGESIZE)
            {
                await EmbedExtensions.FromError("I can't process coordinates above " + SkuldAppContext.PLACEIMAGESIZE, Context).QueueMessageAsync(Context);

                return;
            }

            if (!image.IsWebsite() && !image.IsImageExtension())
            {
                await EmbedExtensions.FromError("You haven't provided an image link", Context).QueueMessageAsync(Context);

                return;
            }

            Bitmap bitmapImage;

            try
            {
                bitmapImage = new(await HttpWebClient.GetStreamAsync(new Uri(image)));
            }
            catch (Exception ex)
            {
                await EmbedExtensions.FromError("Couldn't process image", Context).QueueMessageAsync(Context);

                Log.Error("ThePlace", ex.Message, Context, ex);
                return;
            }

            if (bitmapImage is null)
            {
                await EmbedExtensions.FromError("Couldn't process image", Context).QueueMessageAsync(Context);

                Log.Error("ThePlace", "Couldn't load image", Context);
                return;
            }

            double aspectRatio = (double)bitmapImage.Width / bitmapImage.Height;

            if (bitmapImage.Width > SkuldAppContext.PLACEIMAGESIZE - x)
            {
                double otherAspect = (double)bitmapImage.Height / bitmapImage.Width;

                int newHeight = (int)Math.Min(Math.Round(SkuldAppContext.PLACEIMAGESIZE - y * otherAspect), SkuldAppContext.PLACEIMAGESIZE - y);
                bitmapImage = bitmapImage.ResizeBitmap(SkuldAppContext.PLACEIMAGESIZE - x, newHeight);
            }

            if (bitmapImage.Height > SkuldAppContext.PLACEIMAGESIZE - y)
            {
                int newWidth = (int)Math.Min(Math.Round(SkuldAppContext.PLACEIMAGESIZE - x * aspectRatio), SkuldAppContext.PLACEIMAGESIZE - x);
                bitmapImage = bitmapImage.ResizeBitmap(newWidth, SkuldAppContext.PLACEIMAGESIZE - y);
            }

            ulong pixelCost = 0;

            for (int bx = 0; bx < bitmapImage.Width; bx++)
            {
                for (int by = 0; by < bitmapImage.Height; by++)
                {
                    pixelCost += GetPixelCost(x + bx, y + by);
                }
            }

            using var Database = new SkuldDbContextFactory().CreateDbContext();

            string prefix = (await Database.InsertOrGetConfigAsync(SkuldAppContext.ConfigurationId)).Prefix;

            if (!Context.IsPrivate)
            {
                prefix = (await Database.InsertOrGetGuildAsync(Context.Guild)).Prefix;
            }

            var dbUser = await Database.InsertOrGetUserAsync(Context.User).ConfigureAwait(false);

            TransactionService.DoTransaction(new TransactionStruct
            {
                Sender = dbUser,
                Amount = pixelCost
            })
            .IsSuccessAsync(async _ =>
            {
                using var PixelDb   = new SkuldDbContextFactory().CreateDbContext();
                using var historyDb = new SkuldDbContextFactory().CreateDbContext();

                for (int bx = 0; bx < bitmapImage.Width; bx++)
                {
                    for (int by = 0; by < bitmapImage.Height; by++)
                    {
                        var pixel = PixelDb.PlacePixelData.FirstOrDefault(p => p.XPos == x + bx && p.YPos == y + by);

                        var colour = bitmapImage.GetPixel(bx, by);

                        pixel.R = colour.R;
                        pixel.G = colour.G;
                        pixel.B = colour.B;

                        historyDb.PlacePixelHistory.Add(new PixelHistory
                        {
                            PixelId          = pixel.Id,
                            ChangedTimestamp = DateTime.UtcNow.ToEpoch(),
                            CostToChange     = pixelCost,
                            ModifierId       = Context.User.Id
                        });
                    }
                }

                await PixelDb.SaveChangesAsync().ConfigureAwait(false);
                await historyDb.SaveChangesAsync().ConfigureAwait(false);

                await $"Set it, use `{prefix}theplace view` to view it".QueueMessageAsync(Context).ConfigureAwait(false);
            })
            .IsErrorAsync(async _ =>
            {
                await "You don't have enough currency".QueueMessageAsync(Context).ConfigureAwait(false);
            });

            await Database.SaveChangesAsync().ConfigureAwait(false);
        }