Esempio n. 1
0
        private async Task Start()
        {
            CurrentPhase = Phase.Running;
            if (_users.Count <= 1)
            {
                foreach (var user in _users)
                {
                    if (user.Bet > 0)
                    {
                        await _currency.AddAsync(user.UserId, "Race refund", user.Bet).ConfigureAwait(false);
                    }
                }

                var _sf = OnStartingFailed?.Invoke(this);
                CurrentPhase = Phase.Ended;
                return;
            }

            var _  = OnStarted?.Invoke(this);
            var _t = Task.Run(async() =>
            {
                var rng = new NadekoRandom();
                while (!_users.All(x => x.Progress >= 60))
                {
                    foreach (var user in _users)
                    {
                        user.Progress += rng.Next(1, 11);
                        if (user.Progress >= 60)
                        {
                            user.Progress = 60;
                        }
                    }

                    var finished = _users.Where(x => x.Progress >= 60 && !FinishedUsers.Contains(x))
                                   .Shuffle();

                    FinishedUsers.AddRange(finished);

                    var _ignore = OnStateUpdate?.Invoke(this);
                    await Task.Delay(2500).ConfigureAwait(false);
                }

                if (FinishedUsers[0].Bet > 0)
                {
                    await _currency.AddAsync(FinishedUsers[0].UserId, "Won a Race", FinishedUsers[0].Bet * (_users.Count - 1))
                    .ConfigureAwait(false);
                }

                var _ended = OnEnded?.Invoke(this);
            });
        }
Esempio n. 2
0
            public async Task Pick()
            {
                var channel = (ITextChannel)Context.Channel;

                ///waaaaaat
                if (!(await channel.Guild.GetCurrentUserAsync()).GetPermissions(channel).ManageMessages)
                {
                    return;
                }

                try { await Context.Message.DeleteAsync().ConfigureAwait(false); } catch { }
                if (!_service.PlantedFlowers.TryRemove(channel.Id, out List <IUserMessage> msgs))
                {
                    return;
                }

                await Task.WhenAll(msgs.Where(m => m != null).Select(toDelete => toDelete.DeleteAsync())).ConfigureAwait(false);

                await _cs.AddAsync((IGuildUser)Context.User, $"Picked {_bc.BotConfig.CurrencyPluralName}", msgs.Count, false).ConfigureAwait(false);

                var msg = await ReplyConfirmLocalized("picked", msgs.Count + _bc.BotConfig.CurrencySign)
                          .ConfigureAwait(false);

                msg.DeleteAfter(10);
            }
Esempio n. 3
0
        public async Task Timely()
        {
            var val    = _bc.BotConfig.TimelyCurrency;
            var period = _bc.BotConfig.TimelyCurrencyPeriod;

            if (val <= 0 || period <= 0)
            {
                await ReplyErrorLocalized("timely_none").ConfigureAwait(false);

                return;
            }

            TimeSpan?rem;

            if ((rem = _cache.AddTimelyClaim(Context.User.Id, period)) != null)
            {
                await ReplyErrorLocalized("timely_already_claimed", rem?.ToString(@"dd\d\ hh\h\ mm\m\ ss\s")).ConfigureAwait(false);

                return;
            }

            await _cs.AddAsync(Context.User.Id, "Timely claim", val).ConfigureAwait(false);

            await ReplyConfirmLocalized("timely", val + _bc.BotConfig.CurrencySign, period).ConfigureAwait(false);
        }
        public async Task <ActionResult <Flow> > PostCurrency(Currency model)
        {
            var currency = await _currencyService.AddAsync(new CurrencyDto {
                Code   = model.Code,
                Scale  = model.Scale,
                Symbol = model.Symbol
            });

            return(CreatedAtAction(nameof(GetCurrency), new { code = currency.Code }, Mapper.Map(currency)));
        }
Esempio n. 5
0
        public async Task <bool> GetTreat(ulong userId)
        {
            if (_rng.Next(0, 10) != 0)
            {
                await _cs.AddAsync(userId, "Halloween 2017 Treat", 10)
                .ConfigureAwait(false);

                return(true);
            }

            return(false);
        }
Esempio n. 6
0
        public async Task Give(long amount, [Remainder] IGuildUser receiver)
        {
            if (amount > 0)
            {
                if (Context.User.Id != receiver.Id)
                {
                    var reason = $"Gift to {receiver.Username} ({receiver.Id}).";

                    if (await _currency.RemoveAsync((IGuildUser)Context.User, reason, amount).ConfigureAwait(false))
                    {
                        await _currency.AddAsync(receiver, $"Gift from {Context.User.Username} ({Context.User.Id}).", amount).ConfigureAwait(false);
                        await ReplyConfirmLocalized("gifted", $"{amount}{CurrencySign}", Format.Bold(receiver.ToString())).ConfigureAwait(false);

                        try {
                            await receiver.SendConfirmAsync($"`You received:` {amount}{CurrencySign} on Server with ID {receiver.GuildId}.\n`Reason:` {reason}").ConfigureAwait(false);
                        } catch { }
                    }
                    else
                    {
                        await ReplyErrorLocalized("not_enough", CurrencyPluralName).ConfigureAwait(false);
                    }
                }
                else
                {
                    // FIXME: Use translations.
                    await Context.Channel.SendMessageAsync("Geld kann man nicht an sich selbst verschenken!");
                }
            }
            else
            {
                // FIXME: Use translations.
                await Context.Channel.SendMessageAsync($"Geldbeträge von 0{CurrencySign} oder weniger können nicht verschenkt werden!");
            }
        }
Esempio n. 7
0
        public async Task Give(long amount, [Remainder] IGuildUser receiver)
        {
            if (amount <= 0)
            {
                await Context.Channel.SendMessageAsync($"Geldbeträge von 0{CurrencySign} oder weniger können nicht verschenkt werden!");

                return;
            }
            if (Context.User.Id == receiver.Id)
            {
                await Context.Channel.SendMessageAsync("Geld kann man nicht an sich selbst verschenken!");

                return;
            }
            var success = await _currency.RemoveAsync((IGuildUser)Context.User, $"Gift to {receiver.Username} ({receiver.Id}).", amount, false).ConfigureAwait(false);

            if (!success)
            {
                await ReplyErrorLocalized("not_enough", CurrencyPluralName).ConfigureAwait(false);

                return;
            }
            await _currency.AddAsync(receiver, $"Gift from {Context.User.Username} ({Context.User.Id}).", amount, true).ConfigureAwait(false);

            await ReplyConfirmLocalized("gifted", amount + CurrencySign, Format.Bold(receiver.ToString())).ConfigureAwait(false);
        }
Esempio n. 8
0
            public async Task Betflip(long amount, BetFlipGuess guess)
            {
                if (amount < _bc.BotConfig.MinimumBetAmount)
                {
                    await ReplyErrorLocalized("min_bet_limit", _bc.BotConfig.MinimumBetAmount + _bc.BotConfig.CurrencySign).ConfigureAwait(false);

                    return;
                }
                var removed = await _cs.RemoveAsync(Context.User, "Betflip Gamble", amount, false, gamble : true).ConfigureAwait(false);

                if (!removed)
                {
                    await ReplyErrorLocalized("not_enough", _bc.BotConfig.CurrencyPluralName).ConfigureAwait(false);

                    return;
                }
                BetFlipGuess result;
                string       imageToSend;
                var          coins = _images.ImageUrls.Coins;

                if (rng.Next(0, 2) == 1)
                {
                    imageToSend = coins.Heads[rng.Next(0, coins.Heads.Length)];
                    result      = BetFlipGuess.Heads;
                }
                else
                {
                    imageToSend = coins.Tails[rng.Next(0, coins.Tails.Length)];
                    result      = BetFlipGuess.Tails;
                }

                string str;

                if (guess == result)
                {
                    var toWin = (int)Math.Round(amount * _bc.BotConfig.BetflipMultiplier);
                    str = Context.User.Mention + " " + GetText("flip_guess", toWin + _bc.BotConfig.CurrencySign);
                    await _cs.AddAsync(Context.User, "Betflip Gamble", toWin, false, gamble : true).ConfigureAwait(false);
                }
                else
                {
                    str = Context.User.Mention + " " + GetText("better_luck");
                }

                await Context.Channel.EmbedAsync(new EmbedBuilder()
                                                 .WithDescription(str)
                                                 .WithOkColor()
                                                 .WithImageUrl(imageToSend));
            }
Esempio n. 9
0
            public async Task Betflip(int amount, BetFlipGuess guess)
            {
                if (amount < _bc.BotConfig.MinimumBetAmount)
                {
                    await ReplyErrorLocalized("min_bet_limit", _bc.BotConfig.MinimumBetAmount + _bc.BotConfig.CurrencySign).ConfigureAwait(false);

                    return;
                }
                var removed = await _cs.RemoveAsync(Context.User, "Betflip Gamble", amount, false).ConfigureAwait(false);

                if (!removed)
                {
                    await ReplyErrorLocalized("not_enough", _bc.BotConfig.CurrencyPluralName).ConfigureAwait(false);

                    return;
                }
                BetFlipGuess       result;
                IEnumerable <byte> imageToSend;

                if (rng.Next(0, 2) == 1)
                {
                    imageToSend = _images.Heads;
                    result      = BetFlipGuess.Heads;
                }
                else
                {
                    imageToSend = _images.Tails;
                    result      = BetFlipGuess.Tails;
                }

                string str;

                if (guess == result)
                {
                    var toWin = (int)Math.Round(amount * _bc.BotConfig.BetflipMultiplier);
                    str = Context.User.Mention + " " + GetText("flip_guess", toWin + _bc.BotConfig.CurrencySign);
                    await _cs.AddAsync(Context.User, "Betflip Gamble", toWin, false).ConfigureAwait(false);
                }
                else
                {
                    str = Context.User.Mention + " " + GetText("better_luck");
                }
                using (var toSend = imageToSend.ToStream())
                {
                    await Context.Channel.SendFileAsync(toSend, "result.png", str).ConfigureAwait(false);
                }
            }
Esempio n. 10
0
            private Task SneakyGameMessageReceivedEventHandler(SocketMessage arg)
            {
                if (arg.Author is IGuildUser guildUser && arg.Content == _secretCode && SneakyGameAwardedUsers.Add(arg.Author.Id))
                {
                    var _ = Task.Run(async() => {
                        await _cs.AddAsync(guildUser, "Sneaky Game Event", 100).ConfigureAwait(false);

                        try {
                            await arg.DeleteAsync(new RequestOptions {
                                RetryMode = RetryMode.AlwaysFail
                            }).ConfigureAwait(false);
                        } catch { }
                    });
                }

                return(Task.CompletedTask);
            }
            public async Task DailyMoney()
            {
                var user = (IGuildUser)Context.User;

                bool canReceiveDailyMoney;

                using (var uow = _db.UnitOfWork)
                {
                    canReceiveDailyMoney = uow.DailyMoney.TryUpdateState(user.Id);
                    await uow.CompleteAsync().ConfigureAwait(false);
                }
                if (canReceiveDailyMoney)
                {
                    IEnumerable <IRole>     userRolesAll = user.GetRoles().OrderBy(r => - r.Position);
                    IEnumerable <RoleMoney> roleMoneysAll;
                    using (var uow = _db.UnitOfWork)
                    {
                        roleMoneysAll = uow.RoleMoney.GetAll();
                        await uow.CompleteAsync().ConfigureAwait(false);
                    }
                    var userRoles  = userRolesAll.Where(r => roleMoneysAll.FirstOrDefault(m => m.RoleId == r.Id) != null).OrderBy(r => - r.Position);
                    var roleMoneys = roleMoneysAll.Where(m => userRolesAll.FirstOrDefault(r => r.Id == m.RoleId) != null).OrderByDescending(m => m.Priority);
                    if (!roleMoneys.Any())
                    {
                        await Context.Channel.SendMessageAsync($"Deine Rollen erlauben kein DailyMoney, also bekommst du nichts, {Context.User.Mention}!");

                        using (var uow = _db.UnitOfWork)
                        {
                            uow.DailyMoney.TryResetReceived(user.Id);
                            await uow.CompleteAsync().ConfigureAwait(false);
                        }
                    }
                    else
                    {
                        var rm   = roleMoneys.Where(m => m.Priority == roleMoneys.First().Priority).OrderBy(m => - userRoles.First(r => r.Id == m.RoleId).Position).First();
                        var role = userRoles.First(r => r.Id == rm.RoleId);
                        await _currency.AddAsync(user, $"Daily Reward ({role.Name})", rm.Money, false).ConfigureAwait(false);

                        await Context.Channel.SendMessageAsync($"{Context.User.Mention} hat sich seinen täglichen \"{role.Name}\"-Anteil von {rm.Money} {CurrencySign} abgeholt.");
                    }
                }
                else
                {
                    await Context.Channel.SendMessageAsync($"Du hast deinen täglichen Anteil heute bereits abgeholt, {Context.User.Mention}");
                }
            }
            public async Task Pick()
            {
                try {
                    await Context.Message.DeleteAsync().ConfigureAwait(false);
                } catch { }

                if (Service.PlantedFlowers.TryRemove(Context.Channel.Id, out List <IUserMessage> msgs))
                {
                    await Task.WhenAll(msgs.Where(m => m != null).Select(toDelete => toDelete.DeleteAsync())).ConfigureAwait(false);

                    await _cs.AddAsync((IGuildUser)Context.User, $"Picked {_bc.BotConfig.CurrencyPluralName}", msgs.Count).ConfigureAwait(false);

                    var msg = await ReplyConfirmLocalized("picked", msgs.Count + _bc.BotConfig.CurrencySign).ConfigureAwait(false);

                    msg.DeleteAfter(10);
                }
            }
Esempio n. 13
0
        private async Task PayoutRewards()
        {
            if (string.IsNullOrWhiteSpace(_creds.MiningProxyUrl))
            {
                return;
            }

            try
            {
                _log.Info("Paying out mining rewards.");
                var res = await _http.GetStringAsync(_creds.MiningProxyUrl).ConfigureAwait(false);

                var data = JsonConvert.DeserializeObject <Payout[]>(res);
                if (data.Length == 0)
                {
                    _log.Info("No payouts sent out.");
                    return;
                }

                using (var uow = _db.UnitOfWork)
                {
                    foreach (var p in data)
                    {
                        if (!ulong.TryParse(p.User, out var userId) || p.Amount <= 0)
                        {
                            continue;
                        }

                        _log.Info("Paying out {0}🌸 to {1}", p.Amount, userId);
                        if (p.Amount > 0)
                        {
                            await _cs.AddAsync(userId, "Mining payout", p.Amount, uow, gamble : true);
                        }
                    }
                    uow.Complete();
                }
            }
            catch (Exception ex)
            {
                _log.Warn(ex);
            }
        }
        public virtual async Task <ActionResult> Editor(CurrencyModel model, bool?saveAndContinue)
        {
            if (!ModelState.IsValid)
            {
                return(View(model));
            }

            var record   = _currencyModelFactory.PrepareTblCurrencies(model);
            var recordId = model.Id;

            try
            {
                if (model.Id == null)
                {
                    //Add new record
                    recordId = await CurrencyService.AddAsync(record);
                }
                else
                {
                    //Edit record
                    await CurrencyService.UpdateAsync(record);
                }

                await _localizedEntityService.SaveAllLocalizedStringsAsync(record, model);
            }
            catch (Exception e)
            {
                var errorCode = ErrorLog.GetDefault(System.Web.HttpContext.Current).Log(new Error(e, System.Web.HttpContext.Current));
                ModelState.AddModelError("", string.Format(_localizationService.GetResource("ErrorOnOperation"), e.Message, errorCode));
                return(View(model));
            }

            if (saveAndContinue != null && saveAndContinue.Value)
            {
                return(RedirectToAction("Editor", "ManageCurrencies", new { id = recordId }));
            }

            return(Content(@"<script language='javascript' type='text/javascript'>
                                window.close();
                                window.opener.refreshCurrenciesGrid();
                             </script>"));
        }
            public async Task DailyMoney()
            {
                var guildUser = (IGuildUser)Context.User;

                var canReceiveDailyMoney = uow.DailyMoney.CanReceive(guildUser.GuildId, guildUser.Id, _gts.GetTimeZoneOrUtc(Context.Guild.Id));

                if (canReceiveDailyMoney)
                {
                    var userRolesAll  = guildUser.GetRoles().OrderBy(r => - r.Position);
                    var roleMoneysAll = uow.RoleMoney.GetAll();
                    var userRoles     = userRolesAll.OrderBy(r => - r.Position).AsEnumerable().Where(r => roleMoneysAll.FirstOrDefault(m => m.RoleId == r.Id) != null).ToList();
                    var roleMoneys    = roleMoneysAll.OrderByDescending(m => m.Priority).AsEnumerable().Where(m => userRolesAll.FirstOrDefault(r => r.Id == m.RoleId) != null).ToList();

                    if (!roleMoneys.Any())
                    {
                        await ReplyLocalized("dm_no_role").ConfigureAwait(false);
                    }
                    else
                    {
                        var rm = roleMoneys
                                 .Where(m => m.Priority == roleMoneys.First().Priority)
                                 .OrderBy(m => - userRoles.First(r => r.Id == m.RoleId).Position)
                                 .First();
                        var role = userRoles.First(r => r.Id == rm.RoleId);
                        var time = uow.DailyMoney.UpdateState(guildUser.GuildId, guildUser.Id);
                        await _currency.AddAsync(guildUser, $"Daily Reward ({role.Name})", rm.Money, uow).ConfigureAwait(false);

                        uow.DailyMoneyStats.Add(guildUser.GuildId, guildUser.Id, time, rm.Money);

                        await uow.SaveChangesAsync(false).ConfigureAwait(false);

                        await ReplyLocalized("dm_received", role.Name, rm.Money, CurrencySign).ConfigureAwait(false);
                    }
                }
                else
                {
                    await ReplyLocalized("dm_already_received").ConfigureAwait(false);
                }
            }
Esempio n. 16
0
        public async Task Add_ShouldAddCurrency()
        {
            var options = BuildContextOptions();

            // Arrange
            // Act
            using (var context = new BorrowBuddyContext(options)) {
                var service = new CurrencyService(context);

                await service.AddAsync(new CurrencyDto {
                    Code = "code"
                });
            }

            // Assert
            using (var context = new BorrowBuddyContext(options)) {
                // Assert
                var result = context.Currencies.FirstOrDefault();
                Assert.NotNull(result);
                Assert.Equal("code", result.Code);
            }
        }
Esempio n. 17
0
        private Task SneakyGameMessageReceivedEventHandler(SocketMessage arg)
        {
            if (arg.Content == Code &&
                _sneakyGameAwardedUsers.Add(arg.Author.Id))
            {
                var _ = Task.Run(async() =>
                {
                    await _cs.AddAsync(arg.Author, "Sneaky Game Event", 20, false)
                    .ConfigureAwait(false);

                    try { await arg.DeleteAsync(new RequestOptions()
                        {
                            RetryMode = RetryMode.AlwaysFail
                        }).ConfigureAwait(false); }
                    catch
                    {
                        // ignored
                    }
                });
            }

            return(Task.CompletedTask);
        }
Esempio n. 18
0
            public async Task Betflip(int amount, BetFlipGuess guess)
            {
                var user = (IGuildUser)Context.User;

                if (amount < _bc.BotConfig.MinimumBetAmount)
                {
                    await ReplyErrorLocalized("min_bet_limit", $"{_bc.BotConfig.MinimumBetAmount}{_bc.BotConfig.CurrencySign}").ConfigureAwait(false);

                    return;
                }
                var removed = await _cs.RemoveAsync(user, "Betflip Gamble", amount).ConfigureAwait(false);

                if (!removed)
                {
                    await ReplyErrorLocalized("not_enough", _bc.BotConfig.CurrencyPluralName).ConfigureAwait(false);

                    return;
                }

                (IEnumerable <byte> imageToSend, var result) = rng.Next(0, 2) == 1 ? (_images.Heads, BetFlipGuess.Heads) : (_images.Tails, BetFlipGuess.Tails);

                string str;

                if (guess == result)
                {
                    var toWin = (int)Math.Round(amount * _bc.BotConfig.BetflipMultiplier);
                    str = $"{user.Mention} {GetText("flip_guess", $"{toWin}{_bc.BotConfig.CurrencySign}")}";
                    await _cs.AddAsync(user, "Betflip Gamble", toWin).ConfigureAwait(false);
                }
                else
                {
                    str = $"{user.Mention} {GetText("better_luck")}";
                }

                using var toSend = imageToSend.ToStream();
                await Context.Channel.SendFileAsync(toSend, "result.png", str).ConfigureAwait(false);
            }
            public async Task WheelOfFortune(long bet)
            {
                const int minBet = 10;

                if (bet < minBet)
                {
                    await ReplyErrorLocalized("min_bet_limit", minBet + _bc.BotConfig.CurrencySign).ConfigureAwait(false);

                    return;
                }

                if (!_cs.Remove(Context.User.Id, "Wheel Of Fortune - bet", bet, gamble: true))
                {
                    await ReplyErrorLocalized("not_enough", _bc.BotConfig.CurrencySign).ConfigureAwait(false);

                    return;
                }

                var wof = new WheelOfFortune();

                var amount = (int)(bet * wof.Multiplier);

                if (amount > 0)
                {
                    await _cs.AddAsync(Context.User.Id, "Wheel Of Fortune - won", amount, gamble : true).ConfigureAwait(false);
                }

                await Context.Channel.SendConfirmAsync(
                    Format.Bold($@"{Context.User.ToString()} won: {amount + _bc.BotConfig.CurrencySign}

   『{Wof.Multipliers[1]}』   『{Wof.Multipliers[0]}』   『{Wof.Multipliers[7]}』

『{Wof.Multipliers[2]}』      {wof.Emoji}      『{Wof.Multipliers[6]}』

     『{Wof.Multipliers[3]}』   『{Wof.Multipliers[4]}』   『{Wof.Multipliers[5]}』")).ConfigureAwait(false);
            }
        public async Task Give(long amount, [Remainder] IGuildUser receiver)
        {
            if (amount <= 0 || Context.User.Id == receiver.Id)
            {
                return;
            }
            var success = await _currency.RemoveAsync((IGuildUser)Context.User, $"Gift to {receiver.Username} ({receiver.Id}).", amount, false).ConfigureAwait(false);

            if (!success)
            {
                await ReplyErrorLocalized("not_enough", CurrencyPluralName).ConfigureAwait(false);

                return;
            }
            await _currency.AddAsync(receiver, $"Gift from {Context.User.Username} ({Context.User.Id}).", amount, true).ConfigureAwait(false);

            await ReplyConfirmLocalized("gifted", amount + CurrencySign, Format.Bold(receiver.ToString()))
            .ConfigureAwait(false);
        }
Esempio n. 21
0
        public async Task <int> ClaimReward(ulong userId)
        {
            await claimLockJustInCase.WaitAsync();

            var now = DateTime.UtcNow;

            try
            {
                var data = Pledges?.FirstOrDefault(x => x.User.attributes?.social_connections?.discord?.user_id == userId.ToString());

                if (data == null)
                {
                    return(0);
                }

                var amount = data.Reward.attributes.amount_cents;

                using (var uow = _db.UnitOfWork)
                {
                    var users = uow._context.Set <RewardedUser>();
                    var usr   = users.FirstOrDefault(x => x.PatreonUserId == data.User.id);

                    if (usr == null)
                    {
                        users.Add(new RewardedUser()
                        {
                            UserId                  = userId,
                            PatreonUserId           = data.User.id,
                            LastReward              = now,
                            AmountRewardedThisMonth = amount,
                        });

                        await _currency.AddAsync(userId, "Patreon reward - new", amount, uow).ConfigureAwait(false);

                        await uow.CompleteAsync().ConfigureAwait(false);

                        return(amount);
                    }

                    if (usr.LastReward.Month != now.Month)
                    {
                        usr.LastReward = now;
                        usr.AmountRewardedThisMonth = amount;
                        usr.PatreonUserId           = data.User.id;

                        await _currency.AddAsync(userId, "Patreon reward - recurring", amount, uow).ConfigureAwait(false);

                        await uow.CompleteAsync().ConfigureAwait(false);

                        return(amount);
                    }

                    if (usr.AmountRewardedThisMonth < amount)
                    {
                        var toAward = amount - usr.AmountRewardedThisMonth;

                        usr.LastReward = now;
                        usr.AmountRewardedThisMonth = amount;
                        usr.PatreonUserId           = data.User.id;

                        await _currency.AddAsync(usr.UserId, "Patreon reward - update", toAward, uow).ConfigureAwait(false);

                        await uow.CompleteAsync().ConfigureAwait(false);

                        return(toAward);
                    }
                }
                return(0);
            }
            finally
            {
                claimLockJustInCase.Release();
            }
        }
        public async Task <(CurrencyRaffleGame, JoinErrorType?)> JoinOrCreateGame(ulong channelId, IUser user, int amount, Func <IUser, int, Task> onEnded)
        {
            await _locker.WaitAsync().ConfigureAwait(false);

            try
            {
                var newGame = false;
                if (!Games.TryGetValue(channelId, out var crg))
                {
                    newGame = true;
                    crg     = new CurrencyRaffleGame(amount);
                }
                using (var uow = _db.UnitOfWork)
                {
                    //remove money, and stop the game if this
                    // user created it and doesn't have the money
                    if (!await _cs.RemoveAsync(user.Id, "Currency Raffle Join", amount, uow).ConfigureAwait(false))
                    {
                        if (newGame)
                        {
                            Games.Remove(channelId);
                        }
                        return(null, JoinErrorType.NotEnoughCurrency);
                    }

                    if (!crg.AddUser(user))
                    {
                        await _cs.AddAsync(user.Id, "Curency Raffle Refund", amount, uow).ConfigureAwait(false);

                        return(null, JoinErrorType.AlreadyJoined);
                    }
                }
                if (newGame)
                {
                    var _t = new Timer(async state =>
                    {
                        await _locker.WaitAsync().ConfigureAwait(false);
                        try
                        {
                            var users = crg.Users.ToArray();
                            var rng   = new NadekoRandom();
                            var usr   = users[rng.Next(0, users.Length)];

                            using (var uow = _db.UnitOfWork)
                            {
                                await _cs.AddAsync(usr.Id, "Currency Raffle Win",
                                                   amount * users.Length, uow);
                            }
                            Games.Remove(channelId, out _);
                            var oe = onEnded(usr, users.Length * amount);
                        }
                        catch { }
                        finally { _locker.Release(); }
                    }, null, 30000, Timeout.Infinite);
                }
                return(crg, null);
            }
            finally
            {
                _locker.Release();
            }
        }
Esempio n. 23
0
        public XpService(CommandHandler cmd, IBotConfigProvider bc,
                         NadekoBot bot, DbService db, NadekoStrings strings, IDataCache cache,
                         FontProvider fonts, IBotCredentials creds, CurrencyService cs)
        {
            _db      = db;
            _cmd     = cmd;
            _bc      = bc;
            _images  = cache.LocalImages;
            _log     = LogManager.GetCurrentClassLogger();
            _strings = strings;
            _cache   = cache;
            _fonts   = fonts;
            _creds   = creds;
            _cs      = cs;

            //load settings
            var allGuildConfigs = bot.AllGuildConfigs.Where(x => x.XpSettings != null);

            _excludedChannels = allGuildConfigs
                                .ToDictionary(
                x => x.GuildId,
                x => new ConcurrentHashSet <ulong>(x.XpSettings
                                                   .ExclusionList
                                                   .Where(ex => ex.ItemType == ExcludedItemType.Channel)
                                                   .Select(ex => ex.ItemId)
                                                   .Distinct()))
                                .ToConcurrent();

            _excludedRoles = allGuildConfigs
                             .ToDictionary(
                x => x.GuildId,
                x => new ConcurrentHashSet <ulong>(x.XpSettings
                                                   .ExclusionList
                                                   .Where(ex => ex.ItemType == ExcludedItemType.Role)
                                                   .Select(ex => ex.ItemId)
                                                   .Distinct()))
                             .ToConcurrent();

            _excludedServers = new ConcurrentHashSet <ulong>(
                allGuildConfigs.Where(x => x.XpSettings.ServerExcluded)
                .Select(x => x.GuildId));

            _cmd.OnMessageNoTrigger += _cmd_OnMessageNoTrigger;

            _updateXpTimer = new Timer(async _ =>
            {
                try
                {
                    var toNotify    = new List <(IMessageChannel MessageChannel, IUser User, int Level, XpNotificationType NotifyType, NotifOf NotifOf)>();
                    var roleRewards = new Dictionary <ulong, List <XpRoleReward> >();
                    var curRewards  = new Dictionary <ulong, List <XpCurrencyReward> >();

                    var toAddTo = new List <UserCacheItem>();
                    while (_addMessageXp.TryDequeue(out var usr))
                    {
                        toAddTo.Add(usr);
                    }

                    var group = toAddTo.GroupBy(x => (GuildId: x.Guild.Id, User: x.User));
                    if (toAddTo.Count == 0)
                    {
                        return;
                    }

                    using (var uow = _db.UnitOfWork)
                    {
                        foreach (var item in group)
                        {
                            var xp = item.Select(x => bc.BotConfig.XpPerMessage).Sum();

                            //1. Mass query discord users and userxpstats and get them from local dict
                            //2. (better but much harder) Move everything to the database, and get old and new xp
                            // amounts for every user (in order to give rewards)

                            var usr = uow.Xp.GetOrCreateUser(item.Key.GuildId, item.Key.User.Id);
                            var du  = uow.DiscordUsers.GetOrCreate(item.Key.User);

                            var globalXp           = du.TotalXp;
                            var oldGlobalLevelData = new LevelStats(globalXp);
                            var newGlobalLevelData = new LevelStats(globalXp + xp);

                            var oldGuildLevelData = new LevelStats(usr.Xp + usr.AwardedXp);
                            usr.Xp     += xp;
                            du.TotalXp += xp;
                            if (du.Club != null)
                            {
                                du.Club.Xp += xp;
                            }
                            var newGuildLevelData = new LevelStats(usr.Xp + usr.AwardedXp);

                            if (oldGlobalLevelData.Level < newGlobalLevelData.Level)
                            {
                                du.LastLevelUp = DateTime.UtcNow;
                                var first      = item.First();
                                if (du.NotifyOnLevelUp != XpNotificationType.None)
                                {
                                    toNotify.Add((first.Channel, first.User, newGlobalLevelData.Level, du.NotifyOnLevelUp, NotifOf.Global));
                                }
                            }

                            if (oldGuildLevelData.Level < newGuildLevelData.Level)
                            {
                                usr.LastLevelUp = DateTime.UtcNow;
                                //send level up notification
                                var first = item.First();
                                if (usr.NotifyOnLevelUp != XpNotificationType.None)
                                {
                                    toNotify.Add((first.Channel, first.User, newGuildLevelData.Level, usr.NotifyOnLevelUp, NotifOf.Server));
                                }

                                //give role
                                if (!roleRewards.TryGetValue(usr.GuildId, out var rrews))
                                {
                                    rrews = uow.GuildConfigs.XpSettingsFor(usr.GuildId).RoleRewards.ToList();
                                    roleRewards.Add(usr.GuildId, rrews);
                                }

                                if (!curRewards.TryGetValue(usr.GuildId, out var crews))
                                {
                                    crews = uow.GuildConfigs.XpSettingsFor(usr.GuildId).CurrencyRewards.ToList();
                                    curRewards.Add(usr.GuildId, crews);
                                }

                                var rrew = rrews.FirstOrDefault(x => x.Level == newGuildLevelData.Level);
                                if (rrew != null)
                                {
                                    var role = first.User.Guild.GetRole(rrew.RoleId);
                                    if (role != null)
                                    {
                                        var __ = first.User.AddRoleAsync(role);
                                    }
                                }
                                //get currency reward for this level
                                var crew = crews.FirstOrDefault(x => x.Level == newGuildLevelData.Level);
                                if (crew != null)
                                {
                                    //give the user the reward if it exists
                                    await _cs.AddAsync(item.Key.User.Id, "Level-up Reward", crew.Amount, uow);
                                }
                            }
                        }

                        uow.Complete();
                    }

                    await Task.WhenAll(toNotify.Select(async x =>
                    {
                        if (x.NotifOf == NotifOf.Server)
                        {
                            if (x.NotifyType == XpNotificationType.Dm)
                            {
                                var chan = await x.User.GetOrCreateDMChannelAsync().ConfigureAwait(false);
                                if (chan != null)
                                {
                                    await chan.SendConfirmAsync(_strings.GetText("level_up_dm",
                                                                                 (x.MessageChannel as ITextChannel)?.GuildId,
                                                                                 "xp",
                                                                                 x.User.Mention, Format.Bold(x.Level.ToString()),
                                                                                 Format.Bold((x.MessageChannel as ITextChannel)?.Guild.ToString() ?? "-")))
                                    .ConfigureAwait(false);
                                }
                            }
                            else // channel
                            {
                                await x.MessageChannel.SendConfirmAsync(_strings.GetText("level_up_channel",
                                                                                         (x.MessageChannel as ITextChannel)?.GuildId,
                                                                                         "xp",
                                                                                         x.User.Mention, Format.Bold(x.Level.ToString())))
                                .ConfigureAwait(false);
                            }
                        }
                        else
                        {
                            IMessageChannel chan;
                            if (x.NotifyType == XpNotificationType.Dm)
                            {
                                chan = await x.User.GetOrCreateDMChannelAsync().ConfigureAwait(false);
                            }
                            else // channel
                            {
                                chan = x.MessageChannel;
                            }
                            await chan.SendConfirmAsync(_strings.GetText("level_up_global",
                                                                         (x.MessageChannel as ITextChannel)?.GuildId,
                                                                         "xp",
                                                                         x.User.Mention, Format.Bold(x.Level.ToString())))
                            .ConfigureAwait(false);
                        }
                    }));
                }
                catch (Exception ex)
                {
                    _log.Warn(ex);
                }
            }, null, TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(5));

            _clearRewardTimerTokenSource = new CancellationTokenSource();
            var token = _clearRewardTimerTokenSource.Token;

            //just a first line, in order to prevent queries. But since other shards can try to do this too,
            //i'll check in the db too.
            _clearRewardTimer = Task.Run(async() =>
            {
                while (!token.IsCancellationRequested)
                {
                    _rewardedUsers.Clear();

                    await Task.Delay(TimeSpan.FromMinutes(_bc.BotConfig.XpMinutesTimeout));
                }
            }, token);
        }
            public async Task Slot(int amount = 0)
            {
                if (!_runningUsers.Add(Context.User.Id))
                {
                    return;
                }
                try
                {
                    if (amount < 1)
                    {
                        await ReplyErrorLocalized("min_bet_limit", 1 + _bc.BotConfig.CurrencySign).ConfigureAwait(false);

                        return;
                    }
                    const int maxAmount = 9999;
                    if (amount > maxAmount)
                    {
                        GetText("slot_maxbet", maxAmount + _bc.BotConfig.CurrencySign);
                        await ReplyErrorLocalized("max_bet_limit", maxAmount + _bc.BotConfig.CurrencySign).ConfigureAwait(false);

                        return;
                    }

                    if (!await _cs.RemoveAsync(Context.User, "Slot Machine", amount, false))
                    {
                        await ReplyErrorLocalized("not_enough", _bc.BotConfig.CurrencySign).ConfigureAwait(false);

                        return;
                    }
                    Interlocked.Add(ref _totalBet, amount);
                    using (var bgFileStream = _images.SlotBackground.ToStream())
                    {
                        var bgImage = ImageSharp.Image.Load(bgFileStream);

                        var   result  = SlotMachine.Pull();
                        int[] numbers = result.Numbers;

                        for (int i = 0; i < 3; i++)
                        {
                            using (var file = _images.SlotEmojis[numbers[i]].ToStream())
                                using (var randomImage = ImageSharp.Image.Load(file))
                                {
                                    bgImage.DrawImage(randomImage, 100, default(Size), new Point(95 + 142 * i, 330));
                                }
                        }

                        var won      = amount * result.Multiplier;
                        var printWon = won;
                        var n        = 0;
                        do
                        {
                            var digit = printWon % 10;
                            using (var fs = _images.SlotNumbers[digit].ToStream())
                                using (var img = ImageSharp.Image.Load(fs))
                                {
                                    bgImage.DrawImage(img, 100, default(Size), new Point(230 - n * 16, 462));
                                }
                            n++;
                        } while ((printWon /= 10) != 0);

                        var printAmount = amount;
                        n = 0;
                        do
                        {
                            var digit = printAmount % 10;
                            using (var fs = _images.SlotNumbers[digit].ToStream())
                                using (var img = ImageSharp.Image.Load(fs))
                                {
                                    bgImage.DrawImage(img, 100, default(Size), new Point(395 - n * 16, 462));
                                }
                            n++;
                        } while ((printAmount /= 10) != 0);

                        var msg = GetText("better_luck");
                        if (result.Multiplier != 0)
                        {
                            await _cs.AddAsync(Context.User, $"Slot Machine x{result.Multiplier}", amount *result.Multiplier, false);

                            Interlocked.Add(ref _totalPaidOut, amount * result.Multiplier);
                            if (result.Multiplier == 1)
                            {
                                msg = GetText("slot_single", _bc.BotConfig.CurrencySign, 1);
                            }
                            else if (result.Multiplier == 4)
                            {
                                msg = GetText("slot_two", _bc.BotConfig.CurrencySign, 4);
                            }
                            else if (result.Multiplier == 10)
                            {
                                msg = GetText("slot_three", 10);
                            }
                            else if (result.Multiplier == 30)
                            {
                                msg = GetText("slot_jackpot", 30);
                            }
                        }

                        await Context.Channel.SendFileAsync(bgImage.ToStream(), "result.png", Context.User.Mention + " " + msg + $"\n`{GetText("slot_bet")}:`{amount} `{GetText("slot_won")}:` {amount * result.Multiplier}{_bc.BotConfig.CurrencySign}").ConfigureAwait(false);
                    }
                }
                finally
                {
                    var _ = Task.Run(async() =>
                    {
                        await Task.Delay(1500);
                        _runningUsers.Remove(Context.User.Id);
                    });
                }
            }
Esempio n. 25
0
            public async Task Divorce([Remainder] ulong targetId)
            {
                if (targetId == Context.User.Id)
                {
                    return;
                }

                DivorceResult result;
                var           difference = TimeSpan.Zero;
                var           amount     = 0;
                WaifuInfo     w          = null;

                using (var uow = _db.UnitOfWork)
                {
                    w = uow.Waifus.ByWaifuUserId(targetId);
                    var now = DateTime.UtcNow;
                    if (w?.Claimer == null || w.Claimer.UserId != Context.User.Id)
                    {
                        result = DivorceResult.NotYourWife;
                    }
                    else if (_service.DivorceCooldowns.AddOrUpdate(Context.User.Id,
                                                                   now,
                                                                   (key, old) => ((difference = now.Subtract(old)) > _divorceLimit) ? now : old) != now)
                    {
                        result = DivorceResult.Cooldown;
                    }
                    else
                    {
                        amount = w.Price / 2;

                        if (w.Affinity?.UserId == Context.User.Id)
                        {
                            await _cs.AddAsync(w.Waifu.UserId, "Waifu Compensation", amount, uow).ConfigureAwait(false);

                            w.Price = (int)Math.Floor(w.Price * 0.75f);
                            result  = DivorceResult.SucessWithPenalty;
                        }
                        else
                        {
                            await _cs.AddAsync(Context.User.Id, "Waifu Refund", amount, uow).ConfigureAwait(false);

                            result = DivorceResult.Success;
                        }
                        var oldClaimer = w.Claimer;
                        w.Claimer = null;

                        uow._context.WaifuUpdates.Add(new WaifuUpdate()
                        {
                            User       = w.Waifu,
                            Old        = oldClaimer,
                            New        = null,
                            UpdateType = WaifuUpdateType.Claimed
                        });
                    }

                    await uow.CompleteAsync().ConfigureAwait(false);
                }

                if (result == DivorceResult.SucessWithPenalty)
                {
                    await ReplyConfirmLocalized("waifu_divorced_like", Format.Bold(w.Waifu.ToString()), amount + _bc.BotConfig.CurrencySign).ConfigureAwait(false);
                }
                else if (result == DivorceResult.Success)
                {
                    await ReplyConfirmLocalized("waifu_divorced_notlike", amount + _bc.BotConfig.CurrencySign).ConfigureAwait(false);
                }
                else if (result == DivorceResult.NotYourWife)
                {
                    await ReplyErrorLocalized("waifu_not_yours").ConfigureAwait(false);
                }
                else
                {
                    var remaining = _divorceLimit.Subtract(difference);
                    await ReplyErrorLocalized("waifu_recent_divorce",
                                              Format.Bold(((int)remaining.TotalHours).ToString()),
                                              Format.Bold(remaining.Minutes.ToString())).ConfigureAwait(false);
                }
            }
        public async Task <(CurrencyRaffleGame, JoinErrorType?)> JoinOrCreateGame(ulong channelId, IUser user, int amount, bool mixed, Func <IUser, int, Task> onEnded)
        {
            await _locker.WaitAsync().ConfigureAwait(false);

            try
            {
                var newGame = false;
                if (!Games.TryGetValue(channelId, out var crg))
                {
                    newGame = true;
                    crg     = new CurrencyRaffleGame(mixed
                        ? CurrencyRaffleGame.Type.Mixed
                        : CurrencyRaffleGame.Type.Normal);
                    Games.Add(channelId, crg);
                }
                using (var uow = _db.UnitOfWork)
                {
                    //remove money, and stop the game if this
                    // user created it and doesn't have the money
                    if (!_cs.Remove(user.Id, "Currency Raffle Join", amount, uow))
                    {
                        if (newGame)
                        {
                            Games.Remove(channelId);
                        }
                        return(null, JoinErrorType.NotEnoughCurrency);
                    }

                    if (!crg.AddUser(user, amount))
                    {
                        await _cs.AddAsync(user.Id, "Curency Raffle Refund", amount, uow).ConfigureAwait(false);

                        return(null, JoinErrorType.AlreadyJoinedOrInvalidAmount);
                    }

                    uow.Complete();
                }
                if (newGame)
                {
                    var _t = Task.Run(async() =>
                    {
                        await Task.Delay(60000).ConfigureAwait(false);
                        await _locker.WaitAsync().ConfigureAwait(false);
                        try
                        {
                            var winner = crg.GetWinner();
                            var won    = crg.Users.Sum(x => x.Amount);

                            using (var uow = _db.UnitOfWork)
                            {
                                await _cs.AddAsync(winner.DiscordUser.Id, "Currency Raffle Win",
                                                   won, uow);

                                uow.Complete();
                            }
                            Games.Remove(channelId, out _);
                            var oe = onEnded(winner.DiscordUser, won);
                        }
                        catch { }
                        finally { _locker.Release(); }
                    });
                }
                return(crg, null);
            }
            finally
            {
                _locker.Release();
            }
        }
            public async Task Slot(int amount = 0)
            {
                if (!RunningUsers.Add(Context.User.Id))
                {
                    return;
                }

                try {
                    if (amount < 1)
                    {
                        await ReplyErrorLocalized("min_bet_limit", $"{1}{_bc.BotConfig.CurrencySign}").ConfigureAwait(false);

                        return;
                    }
                    const int maxAmount = 9999;
                    if (amount > maxAmount)
                    {
                        GetText("slot_maxbet", $"{maxAmount}{_bc.BotConfig.CurrencySign}");
                        await ReplyErrorLocalized("max_bet_limit", $"{maxAmount}{_bc.BotConfig.CurrencySign}").ConfigureAwait(false);

                        return;
                    }

                    var guildUser = (IGuildUser)Context.User;

                    if (!await _cs.RemoveAsync(guildUser, "Slot Machine", amount))
                    {
                        await ReplyErrorLocalized("not_enough", _bc.BotConfig.CurrencySign).ConfigureAwait(false);

                        return;
                    }

                    Interlocked.Add(ref _totalBet, amount);
                    var result  = SlotMachineResult.Pull();
                    var numbers = result.Numbers;
                    var won     = amount * result.Multiplier;

                    var msg = result.Multiplier != 0 ? "" : GetText("better_luck");
                    if (result.Multiplier != 0)
                    {
                        await _cs.AddAsync(guildUser, $"Slot Machine x{result.Multiplier}", amount *result.Multiplier);

                        Interlocked.Add(ref _totalPaidOut, amount * result.Multiplier);
                        switch (result.Multiplier)
                        {
                        case 1:
                            msg = GetText("slot_single", _bc.BotConfig.CurrencySign, 1);
                            break;

                        case 4:
                            msg = GetText("slot_two", _bc.BotConfig.CurrencySign, 4);
                            break;

                        case 10:
                            msg = GetText("slot_three", 10);
                            break;

                        case 30:
                            msg = GetText("slot_jackpot", 30);
                            break;
                        }
                    }

                    await Context.Channel.SendMessageAsync($"{Context.User.Mention} {msg}\n`{GetText("slot_bet")}:`{amount} `{GetText("slot_won")}:` {won}{_bc.BotConfig.CurrencySign}\n{_emojis[numbers[0]] + _emojis[numbers[1]] + _emojis[numbers[2]]}").ConfigureAwait(false);
                } finally {
                    var _ = Task.Run(async() => {
                        await Task.Delay(1500);
                        RunningUsers.Remove(Context.User.Id);
                    });
                }
            }
Esempio n. 28
0
        private async Task DealerMoves()
        {
            var hw = Dealer.GetHandValue();

            while (hw < 17 ||
                   (hw == 17 && Dealer.Cards.Count(x => x.Number == 1) > (Dealer.GetRawHandValue() - 17) / 10))// hit on soft 17
            {
                /* Dealer has
                 *   A 6
                 *   That's 17, soft
                 *   hw == 17 => true
                 *   number of aces = 1
                 *   1 > 17-17 /10 => true
                 *
                 *   AA 5
                 *   That's 17, again soft, since one ace is worth 11, even though another one is 1
                 *   hw == 17 => true
                 *   number of aces = 2
                 *   2 > 27 - 17 / 10 => true
                 *
                 *   AA Q 5
                 *   That's 17, but not soft, since both aces are worth 1
                 *   hw == 17 => true
                 *   number of aces = 2
                 *   2 > 37 - 17 / 10 => false
                 * */
                Dealer.Cards.Add(Deck.Draw());
                hw = Dealer.GetHandValue();
            }

            if (hw > 21)
            {
                foreach (var usr in Players)
                {
                    if (usr.State == User.UserState.Stand || usr.State == User.UserState.Blackjack)
                    {
                        usr.State = User.UserState.Won;
                    }
                    else
                    {
                        usr.State = User.UserState.Lost;
                    }
                }
            }
            else
            {
                foreach (var usr in Players)
                {
                    if (usr.State == User.UserState.Blackjack)
                    {
                        usr.State = User.UserState.Won;
                    }
                    else if (usr.State == User.UserState.Stand)
                    {
                        usr.State = hw < usr.GetHandValue()
                            ? User.UserState.Won
                            : User.UserState.Lost;
                    }
                    else
                    {
                        usr.State = User.UserState.Lost;
                    }
                }
            }
            using (var uow = _db.UnitOfWork)
            {
                uow._context.Set <Stake>().RemoveRange(_stakes);
                foreach (var usr in Players)
                {
                    if (usr.State == User.UserState.Won || usr.State == User.UserState.Blackjack)
                    {
                        await _cs.AddAsync(usr.DiscordUser.Id, "BlackJack-win", usr.Bet * 2, uow, gamble : true);
                    }
                }
                uow.Complete();
            }
        }
Esempio n. 29
0
            public async Task Buy(int index, [Remainder] string message = null)
            {
                index -= 1;
                if (index < 0)
                {
                    return;
                }
                ShopEntry entry;

                using (var uow = _db.UnitOfWork)
                {
                    var config = uow.GuildConfigs.For(Context.Guild.Id, set => set
                                                      .Include(x => x.ShopEntries)
                                                      .ThenInclude(x => x.Items));
                    var entries = new IndexedCollection <ShopEntry>(config.ShopEntries);
                    entry = entries.ElementAtOrDefault(index);
                    uow.Complete();
                }

                if (entry == null)
                {
                    await ReplyErrorLocalized("shop_item_not_found").ConfigureAwait(false);

                    return;
                }

                if (entry.Type == ShopEntryType.Role)
                {
                    var guser = (IGuildUser)Context.User;
                    var role  = Context.Guild.GetRole(entry.RoleId);

                    if (role == null)
                    {
                        await ReplyErrorLocalized("shop_role_not_found").ConfigureAwait(false);

                        return;
                    }

                    if (_cs.Remove(Context.User.Id, $"Shop purchase - {entry.Type}", entry.Price))
                    {
                        try
                        {
                            await guser.AddRoleAsync(role).ConfigureAwait(false);
                        }
                        catch (Exception ex)
                        {
                            _log.Warn(ex);
                            await _cs.AddAsync(Context.User.Id, $"Shop error refund", entry.Price);
                            await ReplyErrorLocalized("shop_role_purchase_error").ConfigureAwait(false);

                            return;
                        }
                        await _cs.AddAsync(entry.AuthorId, $"Shop sell item - {entry.Type}", GetProfitAmount(entry.Price));
                        await ReplyConfirmLocalized("shop_role_purchase", Format.Bold(role.Name)).ConfigureAwait(false);

                        return;
                    }
                    else
                    {
                        await ReplyErrorLocalized("not_enough", _bc.BotConfig.CurrencySign).ConfigureAwait(false);

                        return;
                    }
                }
                else if (entry.Type == ShopEntryType.List)
                {
                    if (entry.Items.Count == 0)
                    {
                        await ReplyErrorLocalized("out_of_stock").ConfigureAwait(false);

                        return;
                    }

                    var item = entry.Items.ToArray()[new NadekoRandom().Next(0, entry.Items.Count)];

                    if (_cs.Remove(Context.User.Id, $"Shop purchase - {entry.Type}", entry.Price))
                    {
                        int removed;
                        using (var uow = _db.UnitOfWork)
                        {
                            var x = uow._context.Set <ShopEntryItem>().Remove(item);

                            removed = uow.Complete();
                        }
                        try
                        {
                            await(await Context.User.GetOrCreateDMChannelAsync())
                            .EmbedAsync(new EmbedBuilder().WithOkColor()
                                        .WithTitle(GetText("shop_purchase", Context.Guild.Name))
                                        .AddField(efb => efb.WithName(GetText("item")).WithValue(item.Text).WithIsInline(false))
                                        .AddField(efb => efb.WithName(GetText("price")).WithValue(entry.Price.ToString()).WithIsInline(true))
                                        .AddField(efb => efb.WithName(GetText("name")).WithValue(entry.Name).WithIsInline(true)))
                            .ConfigureAwait(false);

                            await _cs.AddAsync(entry.AuthorId,
                                               $"Shop sell item - {entry.Name}",
                                               GetProfitAmount(entry.Price)).ConfigureAwait(false);
                        }
                        catch
                        {
                            using (var uow = _db.UnitOfWork)
                            {
                                uow._context.Set <ShopEntryItem>().Add(item);
                                uow.Complete();

                                await _cs.AddAsync(Context.User.Id,
                                                   $"Shop error refund - {entry.Name}",
                                                   entry.Price,
                                                   uow).ConfigureAwait(false);
                            }
                            await ReplyErrorLocalized("shop_buy_error").ConfigureAwait(false);

                            return;
                        }
                        await ReplyConfirmLocalized("shop_item_purchase").ConfigureAwait(false);
                    }
                    else
                    {
                        await ReplyErrorLocalized("not_enough", _bc.BotConfig.CurrencySign).ConfigureAwait(false);

                        return;
                    }
                }
            }