Ejemplo n.º 1
0
        public async Task <long> PickAsync(ulong gid, ITextChannel ch, ulong uid, string pass)
        {
            long amount;

            ulong[] ids;
            using (var uow = _db.UnitOfWork)
            {
                // this method will sum all plants with that password,
                // remove them, and get messageids of the removed plants
                (amount, ids) = uow.PlantedCurrency.RemoveSumAndGetMessageIdsFor(ch.Id, pass);
                if (amount > 0)
                {
                    // give the picked currency to the user
                    await _cs.AddAsync(uid, "Picked currency", amount, gamble : false);
                }
                uow.Complete();
            }

            try
            {
                // delete all of the plant messages which have just been picked
                var _ = ch.DeleteMessagesAsync(ids);
            }
            catch { }

            // return the amount of currency the user picked
            return(amount);
        }
Ejemplo n.º 2
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);

            var cur = _service.GetUserCurrency(Context.User);

            await ReplyConfirmLocalized("timely", val + Bc.BotConfig.CurrencySign, cur + Bc.BotConfig.CurrencySign, period).ConfigureAwait(false);
        }
        public async Task <(CurrencyRaffleGame, JoinErrorType?)> JoinOrCreateGame(ulong channelId, IUser user, long amount, bool mixed, Func <IUser, long, 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);
                }

                //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).ConfigureAwait(false))
                {
                    if (newGame)
                    {
                        Games.Remove(channelId);
                    }
                    return(null, JoinErrorType.NotEnoughCurrency);
                }

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

                    return(null, JoinErrorType.AlreadyJoinedOrInvalidAmount);
                }
                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);

                            await _cs.AddAsync(winner.DiscordUser.Id, "Currency Raffle Win",
                                               won).ConfigureAwait(false);
                            Games.Remove(channelId, out _);
                            var oe = onEnded(winner.DiscordUser, won);
                        }
                        catch { }
                        finally { _locker.Release(); }
                    });
                }
                return(crg, null);
            }
            finally
            {
                _locker.Release();
            }
        }
Ejemplo n.º 4
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);
                }

                var win_amount = 0;

                foreach (var u in FinishedUsers)
                {
                    win_amount += (int)u.Bet;
                }

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

                var _ended = OnEnded?.Invoke(this);
            });
        }
Ejemplo n.º 5
0
        public async Task <(WaifuInfo, DivorceResult, long, TimeSpan?)> DivorceWaifuAsync(IUser user, ulong targetId)
        {
            DivorceResult result;
            TimeSpan?     remaining = null;
            long          amount    = 0;
            WaifuInfo     w         = null;

            using (var uow = _db.GetDbContext())
            {
                w = uow.Waifus.ByWaifuUserId(targetId);
                var now = DateTime.UtcNow;
                if (w?.Claimer == null || w.Claimer.UserId != user.Id)
                {
                    result = DivorceResult.NotYourWife;
                }
                else if (!_cache.TryAddDivorceCooldown(user.Id, out remaining))
                {
                    result = DivorceResult.Cooldown;
                }
                else
                {
                    amount = w.Price / 2;

                    if (w.Affinity?.UserId == user.Id)
                    {
                        await _cs.AddAsync(w.Waifu.UserId, "Waifu Compensation", amount, gamble : true);

                        w.Price = (int)Math.Floor(w.Price * _gss.Data.Waifu.Multipliers.DivorceNewValue);
                        result  = DivorceResult.SucessWithPenalty;
                    }
                    else
                    {
                        await _cs.AddAsync(user.Id, "Waifu Refund", amount, gamble : true);

                        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.SaveChangesAsync();
            }

            return(w, result, amount, remaining);
        }
Ejemplo n.º 6
0
            public async Task Pick()
            {
                var guild   = (SocketGuild)Context.Guild;
                var channel = (ITextChannel)Context.Channel;

                if (!guild.CurrentUser.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);
            }
Ejemplo n.º 7
0
            public async Task WheelOfFortune(long amount)
            {
                if (!await CheckBetMandatory(amount))
                {
                    return;
                }

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

                    return;
                }

                var wof = new WheelOfFortune();

                amount = (long)(amount * 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 <IActionResult> AddCurrency([FromBody] CurrencyDTO currency)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest() as IActionResult);
            }
            var info = await service.AddAsync(currency);

            return(info ? Ok() : StatusCode(400));
        }
Ejemplo n.º 9
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);
        }
Ejemplo n.º 10
0
        public async Task Timely()
        {
            var val    = _config.Timely.Amount;
            var period = _config.Timely.Cooldown;

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

                return;
            }

            TimeSpan?rem;

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

                return;
            }

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

            await ReplyConfirmLocalizedAsync("timely", n(val) + CurrencySign, period).ConfigureAwait(false);
        }
Ejemplo n.º 11
0
            public async Task Betflip(ShmartNumber amount, BetFlipGuess guess)
            {
                if (!await CheckBetMandatory(amount).ConfigureAwait(false) || amount == 1)
                {
                    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;
                Uri          imageToSend;
                var          coins = _images.ImageUrls.Coins;

                if (rng.Next(0, 1000) <= 499)
                {
                    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, title;

                if (guess == result)
                {
                    var toWin = (long)(amount * Bc.BotConfig.BetflipMultiplier);
                    title = GetText("flip_win");
                    str   = Context.User.Mention + ", " + GetText("flip_guess", toWin + Bc.BotConfig.CurrencySign) + "\n" + GetText("flip_dosame");
                    await _cs.AddAsync(Context.User, "Betflip Gamble", toWin, false, gamble : true).ConfigureAwait(false);
                }
                else
                {
                    title = GetText("flip_lose");
                    str   = Context.User.Mention + ", " + GetText("flip_positive") + "\n" + GetText("better_luck");
                }

                await Context.Channel.EmbedAsync(new EmbedBuilder()
                                                 .WithTitle(title)
                                                 .WithDescription(str)
                                                 .WithOkColor()
                                                 .WithThumbnailUrl(imageToSend.ToString())).ConfigureAwait(false);
            }
Ejemplo n.º 12
0
        public async Task <Result> SpinAsync()
        {
            var result = _rng.Next(0, Multipliers.Length);
            var amount = (long)(_bet * Multipliers[result]);

            if (amount > 0)
            {
                await _cs.AddAsync(_userId, "Wheel Of Fortune - won", amount, gamble : true).ConfigureAwait(false);
            }
            return(new Result
            {
                Index = result,
                Amount = amount,
            });
        }
Ejemplo n.º 13
0
            public async Task Betflip(ShmartNumber amount, BetFlipGuess guess)
            {
                if (!await CheckBetMandatory(amount).ConfigureAwait(false) || amount == 1)
                {
                    return;
                }

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

                if (!removed)
                {
                    await ReplyErrorLocalizedAsync("not_enough", CurrencySign).ConfigureAwait(false);

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

                if (rng.Next(0, 1000) <= 499)
                {
                    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 = (long)(amount * _config.BetFlip.Multiplier);
                    str = Format.Bold(ctx.User.ToString()) + " " + GetText("flip_guess", toWin + CurrencySign);
                    await _cs.AddAsync(ctx.User, "Betflip Gamble", toWin, false, gamble : true).ConfigureAwait(false);
                }
                else
                {
                    str = ctx.User.ToString() + " " + GetText("better_luck");
                }

                await ctx.Channel.EmbedAsync(new EmbedBuilder()
                                             .WithDescription(str)
                                             .WithOkColor()
                                             .WithImageUrl(imageToSend.ToString())).ConfigureAwait(false);
            }
Ejemplo n.º 14
0
            public async Task Betflip(ShmartNumber amount, BetFlipGuess guess)
            {
                if (!await CheckBetMandatory(amount) || amount == 1)
                {
                    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 = (long)(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));
            }
Ejemplo n.º 15
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", 100, false)
                    .ConfigureAwait(false);

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

            return(Task.CompletedTask);
        }
Ejemplo n.º 16
0
        public async Task <Result> SpinAsync()
        {
            var result = _rng.Next(0, Multipliers.Length);

            var amount = (long)(_bet * Multipliers[result]);

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

                await _lb.AddAsync(_userId, LeaderboardType.Wheel, LeaderboardTimeType.AllTime, amount);

                await _lb.AddAsync(_userId, LeaderboardType.Gambling, LeaderboardTimeType.AllTime, amount);

                await _lb.AddAsync(_userId, LeaderboardType.Gambling, LeaderboardTimeType.Monthly, amount);
            }


            return(new Result
            {
                Index = result,
                Amount = amount,
            });
        }
Ejemplo n.º 17
0
        public XpService(DiscordSocketClient client, CommandHandler cmd, IBotConfigProvider bc,
                         NadekoBot bot, DbService db, NadekoStrings strings, IDataCache cache,
                         FontProvider fonts, IBotCredentials creds, ICurrencyService cs, IHttpClientFactory http)
        {
            _db          = db;
            _cmd         = cmd;
            _bc          = bc;
            _images      = cache.LocalImages;
            _log         = LogManager.GetCurrentClassLogger();
            _strings     = strings;
            _cache       = cache;
            _fonts       = fonts;
            _creds       = creds;
            _cs          = cs;
            _httpFactory = http;
            InternalReloadXpTemplate();

            if (client.ShardId == 0)
            {
                var sub = _cache.Redis.GetSubscriber();
                sub.Subscribe(_creds.RedisKey() + "_reload_xp_template",
                              (ch, val) => InternalReloadXpTemplate());
            }
            //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;

            updateXpTask = Task.Run(async() =>
            {
                while (true)
                {
                    await Task.Delay(TimeSpan.FromSeconds(5));
                    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, x.User));
                        if (toAddTo.Count == 0)
                        {
                            continue;
                        }

                        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.Complete();
                        }

                        await Task.WhenAll(toNotify.Select(async x =>
                        {
                            if (x.NotifOf == NotifOf.Server)
                            {
                                if (x.NotifyType == XpNotificationType.Dm)
                                {
                                    var chan = await x.User.GetOrCreateDMChannelAsync();
                                    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() ?? "-")));
                                    }
                                }
                                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())));
                                }
                            }
                            else
                            {
                                IMessageChannel chan;
                                if (x.NotifyType == XpNotificationType.Dm)
                                {
                                    chan = await x.User.GetOrCreateDMChannelAsync();
                                }
                                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())));
                            }
                        }));
                    }
                    catch (Exception ex)
                    {
                        _log.Warn(ex);
                    }
                }
            });
        }
Ejemplo n.º 18
0
        public async Task <int> ClaimReward(ulong userId)
        {
            await claimLockJustInCase.WaitAsync().ConfigureAwait(false);

            var now = DateTime.UtcNow;

            try
            {
                var datas = _pledges?.Where(x => x.User.attributes?.social_connections?.discord?.user_id == userId.ToString())
                            ?? Enumerable.Empty <PatreonUserAndReward>();

                foreach (var data in datas)
                {
                    var amount = (int)(data.Reward.attributes.amount_cents * _bc.BotConfig.PatreonCurrencyPerCent);

                    using (var uow = _db.GetDbContext())
                    {
                        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 uow.SaveChangesAsync();

                            await _currency.AddAsync(userId, "Patreon reward - new", amount, gamble : true);

                            return(amount);
                        }

                        if (usr.LastReward.Month != now.Month)
                        {
                            usr.LastReward = now;
                            usr.AmountRewardedThisMonth = amount;
                            usr.UserId = userId;

                            await uow.SaveChangesAsync();

                            await _currency.AddAsync(userId, "Patreon reward - recurring", amount, gamble : true);

                            return(amount);
                        }

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

                            usr.LastReward = now;
                            usr.AmountRewardedThisMonth = amount;
                            usr.UserId = userId;
                            await uow.SaveChangesAsync();

                            await _currency.AddAsync(usr.UserId, "Patreon reward - update", toAward, gamble : true);

                            return(toAward);
                        }
                    }
                    return(0);
                }

                return(0);
            }
            finally
            {
                claimLockJustInCase.Release();
            }
        }
Ejemplo n.º 19
0
        private async Task UpdateLoop()
        {
            while (true)
            {
                await Task.Delay(TimeSpan.FromSeconds(5));

                try
                {
                    var toNotify =
                        new List <(IGuild Guild, IMessageChannel MessageChannel, IUser User, int Level,
                                   XpNotificationLocation 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, x.User));
                    if (toAddTo.Count == 0)
                    {
                        continue;
                    }

                    using (var uow = _db.GetDbContext())
                    {
                        foreach (var item in group)
                        {
                            var xp = item.Sum(x => x.XpAmount);

                            //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 != XpNotificationLocation.None)
                                {
                                    toNotify.Add((first.Guild, 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 != XpNotificationLocation.None)
                                {
                                    toNotify.Add((first.Guild, 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.SaveChanges();
                    }

                    await Task.WhenAll(toNotify.Select(async x =>
                    {
                        if (x.NotifOf == NotifOf.Server)
                        {
                            if (x.NotifyType == XpNotificationLocation.Dm)
                            {
                                var chan = await x.User.GetOrCreateDMChannelAsync();
                                if (chan != null)
                                {
                                    await chan.SendConfirmAsync(_strings.GetText("level_up_dm",
                                                                                 x.Guild.Id,
                                                                                 "xp",
                                                                                 x.User.Mention, Format.Bold(x.Level.ToString()),
                                                                                 Format.Bold(x.Guild.ToString() ?? "-")));
                                }
                            }
                            else if (x.MessageChannel != null) // channel
                            {
                                await x.MessageChannel.SendConfirmAsync(_strings.GetText("level_up_channel",
                                                                                         x.Guild.Id,
                                                                                         "xp",
                                                                                         x.User.Mention, Format.Bold(x.Level.ToString())));
                            }
                        }
                        else
                        {
                            IMessageChannel chan;
                            if (x.NotifyType == XpNotificationLocation.Dm)
                            {
                                chan = await x.User.GetOrCreateDMChannelAsync();
                            }
                            else // channel
                            {
                                chan = x.MessageChannel;
                            }

                            await chan.SendConfirmAsync(_strings.GetText("level_up_global",
                                                                         x.Guild.Id,
                                                                         "xp",
                                                                         x.User.Mention, Format.Bold(x.Level.ToString())));
                        }
                    }));
                }
                catch (Exception ex)
                {
                    _log.Warn(ex);
                }
            }
        }
Ejemplo n.º 20
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 = (int)(data.Reward.attributes.amount_cents * _bc.BotConfig.PatreonCurrencyPerCent);

                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).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).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).ConfigureAwait(false);

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

                        return(toAward);
                    }
                }
                return(0);
            }
            finally
            {
                claimLockJustInCase.Release();
            }
        }
Ejemplo n.º 21
0
            public async Task Slot(ShmartNumber amount)
            {
                if (!_runningUsers.Add(Context.User.Id))
                {
                    return;
                }
                try
                {
                    if (!await CheckBetMandatory(amount).ConfigureAwait(false))
                    {
                        return;
                    }
                    const int maxAmount = 9999;
                    if (amount > maxAmount)
                    {
                        await ReplyErrorLocalized("max_bet_limit", maxAmount + Bc.BotConfig.CurrencySign).ConfigureAwait(false);

                        return;
                    }

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

                        return;
                    }
                    Interlocked.Add(ref _totalBet, amount.Value);
                    using (var bgImage = Image.Load(_images.SlotBackground))
                    {
                        var   result  = SlotMachine.Pull();
                        int[] numbers = result.Numbers;

                        for (int i = 0; i < 3; i++)
                        {
                            using (var randomImage = Image.Load(_images.SlotEmojis[numbers[i]]))
                            {
                                bgImage.Mutate(x => x.DrawImage(GraphicsOptions.Default, randomImage, new Point(95 + 142 * i, 330)));
                            }
                        }

                        var won      = amount * result.Multiplier;
                        var printWon = won;
                        var n        = 0;
                        do
                        {
                            var digit = (int)(printWon % 10);
                            using (var img = Image.Load(_images.SlotNumbers[digit]))
                            {
                                bgImage.Mutate(x => x.DrawImage(GraphicsOptions.Default, img, new Point(230 - n * 16, 462)));
                            }
                            n++;
                        } while ((printWon /= 10) != 0);

                        var printAmount = amount;
                        n = 0;
                        do
                        {
                            var digit = (int)(printAmount % 10);
                            using (var img = Image.Load(_images.SlotNumbers[digit]))
                            {
                                bgImage.Mutate(x => x.DrawImage(GraphicsOptions.Default, img, 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, gamble : true).ConfigureAwait(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);
                            }
                        }

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

                DivorceResult result;
                TimeSpan?     remaining = null;
                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 (!_cache.TryAddDivorceCooldown(Context.User.Id, out remaining))
                    {
                        result = DivorceResult.Cooldown;
                    }
                    else
                    {
                        amount = w.Price / 2;

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

                            w.Price = (int)Math.Floor(w.Price * 0.75f);
                            result  = DivorceResult.SucessWithPenalty;
                        }
                        else
                        {
                            await _cs.AddAsync(Context.User.Id, "Waifu Refund", amount, gamble : true).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
                {
                    await ReplyErrorLocalized("waifu_recent_divorce",
                                              Format.Bold(((int)remaining?.TotalHours).ToString()),
                                              Format.Bold(remaining?.Minutes.ToString())).ConfigureAwait(false);
                }
            }
Ejemplo n.º 23
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, gamble : true);
                    }
                }
                uow.Complete();
            }
        }
Ejemplo n.º 24
0
            public async Task WheelOfFortune(ShmartNumber amount)
            {
                if (!await CheckBetMandatory(amount).ConfigureAwait(false))
                {
                    return;
                }

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

                    return;
                }

                var    _rng          = new NadekoRandom();
                var    result        = _rng.Next(0, _results.Length);
                var    wonAmountTemp = _results[result].Item1 * amount;
                string commentary    = GetText(_results[result].Item2);
                var    rotation      = (result * 360) / _results.Length;
                var    mayhem        = _rng.Next(0, 100);

                if (mayhem == 0)
                {
                    wonAmountTemp = wonAmountTemp * _mayhemMultiplier;

                    await Context.Channel.SendConfirmAsync("Let's spin the "
                                                           + Format.Bold("Wheel of Mayhem")
                                                           + " for x"
                                                           + _mayhemMultiplier
                                                           + " multiplier, "
                                                           + Context.User.Mention
                                                           + "!")
                    .ConfigureAwait(false);

                    System.Threading.Thread.Sleep(2000);
                    await Context.Channel.SendConfirmAsync("Ratatata-ta-ta-ta ta ta...!").ConfigureAwait(false);

                    System.Threading.Thread.Sleep(2000);
                    await Context.Channel.SendConfirmAsync("Ta...!").ConfigureAwait(false);

                    System.Threading.Thread.Sleep(2000);
                    await Context.Channel.SendConfirmAsync("...").ConfigureAwait(false);

                    System.Threading.Thread.Sleep(2000);
                    await Context.Channel.SendConfirmAsync("Ta!").ConfigureAwait(false);

                    System.Threading.Thread.Sleep(200);
                }

                long wonAmount = (long)wonAmountTemp;  //remove the decimal part

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

                using (var bgImage = Image.Load(_images.Roulette))
                {
                    var originalWidth  = bgImage.Width;
                    var originalHeight = bgImage.Height;

                    bgImage.Mutate(x => x.Rotate(-rotation));

                    var widthCrop  = (bgImage.Width - originalWidth) / 2;
                    var heightCrop = (bgImage.Height - originalHeight) / 2;

                    bgImage.Mutate(x => x.Crop(new Rectangle(widthCrop,
                                                             heightCrop,
                                                             originalWidth,
                                                             originalHeight)));

                    using (var ptImage = Image.Load(_images.RoulettePointer)) {
                        var resizeOptions = new ResizeOptions();
                        resizeOptions.Mode     = ResizeMode.Pad;
                        resizeOptions.Position = AnchorPositionMode.TopLeft;
                        resizeOptions.Size     = new Size(originalWidth + (ptImage.Width / 2), originalHeight);
                        bgImage.Mutate(x => x.Resize(resizeOptions));

                        var pointerPosX = bgImage.Width - ptImage.Width;
                        var pointerPosY = (bgImage.Height / 2) - (ptImage.Height / 2);
                        bgImage.Mutate(x => x.DrawImage(GraphicsOptions.Default, ptImage, new Point(pointerPosX, pointerPosY)));
                    }

                    using (var imgStream = bgImage.ToStream())
                    {
                        string outText;
                        long   outAmount;
                        if (wonAmount >= 0)
                        {
                            outText   = GetText("won");
                            outAmount = wonAmount;
                        }
                        else
                        {
                            outText   = GetText("lost");
                            outAmount = -wonAmount;
                        }
                        await Context.Channel.SendFileAsync(imgStream,
                                                            "result.png",
                                                            $@"{Format.Bold(Context.User.ToString())} {outText}: `{outAmount}`{Bc.BotConfig.CurrencySign}{System.Environment.NewLine}{commentary}")
                        .ConfigureAwait(false);
                    }
                }
            }
Ejemplo n.º 25
0
        public async Task <int> ClaimReward(ulong userId)
        {
            await claimLockJustInCase.WaitAsync().ConfigureAwait(false);

            var settings = _gamblingConfigService.Data;
            var now      = DateTime.UtcNow;

            try
            {
                var datas = _pledges?.Where(x => x.User.attributes?.social_connections?.discord?.user_id == userId.ToString())
                            ?? Enumerable.Empty <PatreonUserAndReward>();

                var totalAmount = 0;
                foreach (var data in datas)
                {
                    var amount = (int)(data.Reward.attributes.amount_cents * settings.PatreonCurrencyPerCent);

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

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

                            await uow.SaveChangesAsync();

                            await _currency.AddAsync(userId, "Patreon reward - new", amount, gamble : true);

                            totalAmount += amount;

                            Log.Information($"Sending new currency reward to {userId}");
                            await SendMessageToUser(userId, $"Thank you for your pledge! " +
                                                    $"You've been awarded **{amount}**{settings.Currency.Sign} !");

                            continue;
                        }

                        if (usr.LastReward.Month != now.Month)
                        {
                            usr.LastReward = now;
                            usr.AmountRewardedThisMonth = amount;

                            await uow.SaveChangesAsync();

                            await _currency.AddAsync(userId, "Patreon reward - recurring", amount, gamble : true);

                            totalAmount += amount;
                            Log.Information($"Sending recurring currency reward to {userId}");
                            await SendMessageToUser(userId, $"Thank you for your continued support! " +
                                                    $"You've been awarded **{amount}**{settings.Currency.Sign} for this month's support!");

                            continue;
                        }

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

                            usr.LastReward = now;
                            usr.AmountRewardedThisMonth = amount;
                            await uow.SaveChangesAsync();

                            await _currency.AddAsync(userId, "Patreon reward - update", toAward, gamble : true);

                            totalAmount += toAward;
                            Log.Information($"Sending updated currency reward to {userId}");
                            await SendMessageToUser(userId, $"Thank you for increasing your pledge! " +
                                                    $"You've been awarded an additional **{toAward}**{settings.Currency.Sign} !");

                            continue;
                        }
                    }
                }

                return(totalAmount);
            }
            finally
            {
                claimLockJustInCase.Release();
            }
        }
Ejemplo n.º 26
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 (await _cs.RemoveAsync(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;
                        }
                        var profit = GetProfitAmount(entry.Price);
                        await _cs.AddAsync(entry.AuthorId, $"Shop sell item - {entry.Type}", profit);

                        await _cs.AddAsync(Context.Client.CurrentUser.Id, $"Shop sell item - cut", entry.Price - profit);
                        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 (await _cs.RemoveAsync(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
                        {
                            await _cs.AddAsync(Context.User.Id,
                                               $"Shop error refund - {entry.Name}",
                                               entry.Price).ConfigureAwait(false);

                            using (var uow = _db.UnitOfWork)
                            {
                                uow._context.Set <ShopEntryItem>().Add(item);
                                uow.Complete();
                            }
                            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;
                    }
                }
            }
Ejemplo n.º 27
0
 private static async Task Award(IUser user, long amount, string reason = "NadekoConnector Award",
                                 bool sendMessage = false)
 {
     await _cs.AddAsync(user, reason, amount, sendMessage);
 }