public async Task EventStart(CurrencyEvent.Type ev, params string[] options)
            {
                var(opts, _) = OptionsParser.ParseFrom(new EventOptions(), options);
                if (!await _service.TryCreateEventAsync(ctx.Guild.Id,
                                                        ctx.Channel.Id,
                                                        ev,
                                                        opts,
                                                        GetEmbed
                                                        ).ConfigureAwait(false))
                {
                    await ReplyErrorLocalizedAsync("start_event_fail").ConfigureAwait(false);

                    return;
                }
            }
Example #2
0
            public async Task Slowmode(params string[] args)
            {
                var(opts, succ) = OptionsParser.ParseFrom(new SlowmodeService.Options(), args);
                if (!succ)
                {
                    await ReplyErrorLocalized("invalid_params").ConfigureAwait(false);

                    return;
                }
                if (_service.StartSlowmode(Context.Channel.Id, opts.MessageCount, opts.PerSec))
                {
                    await Context.Channel.SendConfirmAsync(GetText("slowmode_init"),
                                                           GetText("slowmode_desc", Format.Bold(opts.MessageCount.ToString()), Format.Bold(opts.PerSec.ToString())))
                    .ConfigureAwait(false);
                }
            }
Example #3
0
            public async Task TypeStart(params string[] args)
            {
                var(options, _) = OptionsParser.ParseFrom(new TypingGame.Options(), args);
                var channel = (ITextChannel)Context.Channel;

                var game = _service.RunningContests.GetOrAdd(channel.Guild.Id, id => new TypingGame(_games, _client, channel, Prefix, options));

                if (game.IsActive)
                {
                    await channel.SendErrorAsync(
                        $"Contest already running in " +
                        $"{game.Channel.Mention} channel.")
                    .ConfigureAwait(false);
                }
                else
                {
                    await game.Start().ConfigureAwait(false);
                }
            }
Example #4
0
        public async Task Commands(string module = null, params string[] args)
        {
            var channel = Context.Channel;

            var(opts, _) = OptionsParser.ParseFrom(new CommandsOptions(), args);

            module = module?.Trim().ToUpperInvariant();
            if (string.IsNullOrWhiteSpace(module))
            {
                return;
            }

            // Find commands for that module
            // don't show commands which are blocked
            // order by name
            var cmds = _cmds.Commands.Where(c => c.Module.GetTopLevelModule().Name.ToUpperInvariant().StartsWith(module, StringComparison.InvariantCulture))
                       .Where(c => !_perms.BlockedCommands.Contains(c.Aliases[0].ToLowerInvariant()))
                       .OrderBy(c => c.Aliases[0])
                       .Distinct(new CommandTextEqualityComparer());


            // check preconditions for all commands, but only if it's not 'all'
            // because all will show all commands anyway, no need to check
            HashSet <CommandInfo> succ = new HashSet <CommandInfo>();

            if (opts.View != CommandsOptions.ViewType.All)
            {
                succ = new HashSet <CommandInfo>((await Task.WhenAll(cmds.Select(async x =>
                {
                    var pre = (await x.CheckPreconditionsAsync(Context, _services).ConfigureAwait(false));
                    return(Cmd: x, Succ: pre.IsSuccess);
                })).ConfigureAwait(false))
                                                 .Where(x => x.Succ)
                                                 .Select(x => x.Cmd));

                if (opts.View == CommandsOptions.ViewType.Hide)
                {
                    // if hidden is specified, completely remove these commands from the list
                    cmds = cmds.Where(x => succ.Contains(x));
                }
            }

            var cmdsWithGroup = cmds.GroupBy(c => c.Module.Name.Replace("Commands", "", StringComparison.InvariantCulture))
                                .OrderBy(x => x.Key == x.First().Module.Name ? int.MaxValue : x.Count());

            if (!cmds.Any())
            {
                if (opts.View != CommandsOptions.ViewType.Hide)
                {
                    await ReplyErrorLocalizedAsync("module_not_found").ConfigureAwait(false);
                }
                else
                {
                    await ReplyErrorLocalizedAsync("module_not_found_or_cant_exec").ConfigureAwait(false);
                }
                return;
            }
            var i      = 0;
            var groups = cmdsWithGroup.GroupBy(x => i++ / 48).ToArray();
            var embed  = new EmbedBuilder().WithOkColor();

            foreach (var g in groups)
            {
                var last = g.Count();
                for (i = 0; i < last; i++)
                {
                    var transformed = g.ElementAt(i).Select(x =>
                    {
                        //if cross is specified, and the command doesn't satisfy the requirements, cross it out
                        if (opts.View == CommandsOptions.ViewType.Cross)
                        {
                            return($"{(succ.Contains(x) ? "✅" : "❌")}{Prefix + x.Aliases.First(),-15} {"[" + x.Aliases.Skip(1).FirstOrDefault() + "]",-8}");
                        }
                        return($"{Prefix + x.Aliases.First(),-15} {"[" + x.Aliases.Skip(1).FirstOrDefault() + "]",-8}");
                    });

                    if (i == last - 1 && (i + 1) % 2 != 0)
                    {
                        var grp   = 0;
                        var count = transformed.Count();
                        transformed = transformed
                                      .GroupBy(x => grp++ % count / 2)
                                      .Select(x =>
                        {
                            if (x.Count() == 1)
                            {
                                return($"{x.First()}");
                            }
                            else
                            {
                                return(String.Concat(x));
                            }
                        });
                    }
                    embed.AddField(g.ElementAt(i).Key, "```css\n" + string.Join("\n", transformed) + "\n```", true);
                }
            }
            embed.WithFooter(GetText("commands_instr", Prefix));
            await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
        }
Example #5
0
            public async Task ChessChallenge(IGuildUser opponent, params string[] args)
            {
                if (opponent == Context.User)
                {
                    await Context.Channel.SendErrorAsync("You cannot challenge yourself!").ConfigureAwait(false);

                    return;
                }

                if (opponent.IsBot)
                {
                    await Context.Channel.SendErrorAsync("You cannot challenge a bot (yet)!").ConfigureAwait(false);

                    return;
                }
                var opts = OptionsParser.ParseFrom(new ChessOptions(), args);

                opts.ChallengeTo = opponent;

                var response = await Service.CreateChessChallenge(opts).ConfigureAwait(false);

                using var json = JsonDocument.Parse(response);
                var challenge    = json.RootElement.GetProperty("challenge");
                var challengeUrl = challenge.GetProperty("url").GetString();
                var speed        = $"{challenge.GetProperty("timeControl").GetProperty("show").GetString()} {challenge.GetProperty("speed").GetString().ToTitleCase()}";

                if (string.IsNullOrWhiteSpace(challengeUrl))
                {
                    await Context.Channel.SendErrorAsync("Something went wrong when creating the challenge.\nPlease try again later");

                    return;
                }

                var userDm = await Context.User.GetOrCreateDMChannelAsync().ConfigureAwait(false);

                var oppDm = await opponent.GetOrCreateDMChannelAsync().ConfigureAwait(false);

                await Context.Channel.EmbedAsync(new EmbedBuilder().WithDynamicColor(Context)
                                                 .WithTitle("Chess Challenge")
                                                 .WithAuthor(speed)
                                                 .WithDescription($"{Context.User.Mention} vs {opponent.Mention}\nCheck DMs for challenge link."))
                .ConfigureAwait(false);

                try
                {
                    if (opts.Color == ChessColor.Random)
                    {
                        await userDm.EmbedAsync(new EmbedBuilder().WithDynamicColor(Context)
                                                .WithTitle($"Chess Challenge vs {opponent}")
                                                .WithAuthor(speed)
                                                .WithDescription($"[Click here for Challenge Link]({challengeUrl})"))
                        .ConfigureAwait(false);

                        await oppDm.EmbedAsync(new EmbedBuilder().WithDynamicColor(Context)
                                               .WithTitle($"Chess Challenge vs {Context.User}")
                                               .WithAuthor(speed)
                                               .WithDescription($"[Click here for Challenge Link]({challengeUrl})"))
                        .ConfigureAwait(false);
                    }
                    else
                    {
                        await userDm.EmbedAsync(new EmbedBuilder().WithColor(opts.Color == ChessColor.White ? new Color(255, 255, 255) : new Color(0, 0, 0))
                                                .WithTitle($"Chess Challenge vs {opponent}")
                                                .WithAuthor($"{speed} as {opts.Color}")
                                                .WithDescription($"[Click here for Challenge Link]({challengeUrl}{(opts.Color == ChessColor.White ? "?color=white" : "?color=black")})"))
                        .ConfigureAwait(false);

                        await oppDm.EmbedAsync(new EmbedBuilder().WithColor(opts.Color == ChessColor.Black ? new Color(255, 255, 255) : new Color(0, 0, 0))
                                               .WithTitle($"Chess Challenge vs {Context.User}")
                                               .WithAuthor($"{speed} as {opts.Color}")
                                               .WithDescription($"[Click here for Challenge Link]({challengeUrl}{(opts.Color == ChessColor.Black ? "?color=white" : "?color=black")})"))
                        .ConfigureAwait(false);
                    }
                }
                catch (Exception)
                {
                    if (opts.Color == ChessColor.Random)
                    {
                        await userDm.EmbedAsync(new EmbedBuilder().WithDynamicColor(Context)
                                                .WithTitle("Chess Challenge")
                                                .WithAuthor(speed)
                                                .WithDescription($"{Context.User.Mention} vs {opponent.Mention}\n[Click here for Challenge Link]({challengeUrl})"))
                        .ConfigureAwait(false);
                    }
                    else
                    {
                        await Context.Channel.EmbedAsync(new EmbedBuilder().WithDynamicColor(Context)
                                                         .WithTitle("Chess Challenge")
                                                         .WithAuthor($"{speed} as {opts.Color}")
                                                         .WithDescription($"{Context.User.Mention} vs {opponent.Mention}\n[Click here for Challenge Link]({challengeUrl}{(opts.Color == ChessColor.White ? "?color=white" : "?color=black")})"))
                        .ConfigureAwait(false);
                    }
                }

                Service.PollGame(Context, opts, challengeUrl, speed);
            }
Example #6
0
            public async Task Repeat(GuildDateTime dt, params string[] options)
            {
                if (!_service.RepeaterReady)
                {
                    return;
                }

                var(opts, _) = OptionsParser.ParseFrom(new Repeater.Options(), options);

                if (string.IsNullOrWhiteSpace(opts.Message) || opts.Interval >= 50001)
                {
                    return;
                }

                var toAdd = new Repeater()
                {
                    ChannelId      = ctx.Channel.Id,
                    GuildId        = ctx.Guild.Id,
                    Interval       = TimeSpan.FromMinutes(opts.Interval),
                    Message        = opts.Message,
                    NoRedundant    = opts.NoRedundant,
                    StartTimeOfDay = dt?.InputTimeUtc.TimeOfDay,
                };

                using (var uow = _db.GetDbContext())
                {
                    var gc = uow.GuildConfigs.ForId(ctx.Guild.Id, set => set.Include(x => x.GuildRepeaters));

                    if (gc.GuildRepeaters.Count >= 5)
                    {
                        return;
                    }
                    gc.GuildRepeaters.Add(toAdd);

                    await uow.SaveChangesAsync();
                }

                var rep = new RepeatRunner((SocketGuild)ctx.Guild, toAdd, _service);

                _service.Repeaters.AddOrUpdate(ctx.Guild.Id,
                                               new ConcurrentDictionary <int, RepeatRunner>(new[] { new KeyValuePair <int, RepeatRunner>(toAdd.Id, rep) }), (key, old) =>
                {
                    old.TryAdd(rep.Repeater.Id, rep);
                    return(old);
                });

                string secondPart = "";

                if (dt != null)
                {
                    secondPart = GetText("repeater_initial",
                                         Format.Bold(rep.InitialInterval.Hours.ToString()),
                                         Format.Bold(rep.InitialInterval.Minutes.ToString()));
                }

                await ctx.Channel.SendConfirmAsync(
                    "🔁 " + GetText("repeater",
                                   Format.Bold(((IGuildUser)ctx.User).GuildPermissions.MentionEveryone ? rep.Repeater.Message : rep.Repeater.Message.SanitizeMentions()),
                                   Format.Bold(rep.Repeater.Interval.Days.ToString()),
                                   Format.Bold(rep.Repeater.Interval.Hours.ToString()),
                                   Format.Bold(rep.Repeater.Interval.Minutes.ToString())) + " " + secondPart).ConfigureAwait(false);
            }
Example #7
0
            public async Task Connect4(params string[] args)
            {
                var(options, _) = OptionsParser.ParseFrom(new Connect4Game.Options(), args);
                if (!await CheckBetOptional(options.Bet).ConfigureAwait(false))
                {
                    return;
                }

                var          newGame = new Connect4Game(Context.User.Id, Context.User.ToString(), options, _cs);
                Connect4Game game;

                if ((game = _service.Connect4Games.GetOrAdd(Context.Channel.Id, newGame)) != newGame)
                {
                    if (game.CurrentPhase != Connect4Game.Phase.Joining)
                    {
                        return;
                    }

                    newGame.Dispose();
                    //means game already exists, try to join
                    var joined = await game.Join(Context.User.Id, Context.User.ToString(), options.Bet).ConfigureAwait(false);

                    return;
                }

                if (options.Bet > 0)
                {
                    if (!await _cs.RemoveAsync(Context.User.Id, "Connect4-bet", options.Bet, true).ConfigureAwait(false))
                    {
                        await ReplyErrorLocalized("not_enough", Bc.BotConfig.CurrencySign).ConfigureAwait(false);

                        _service.Connect4Games.TryRemove(Context.Channel.Id, out _);
                        game.Dispose();
                        return;
                    }
                }

                game.OnGameStateUpdated  += Game_OnGameStateUpdated;
                game.OnGameFailedToStart += Game_OnGameFailedToStart;
                game.OnGameEnded         += Game_OnGameEnded;
                _client.MessageReceived  += _client_MessageReceived;

                game.Initialize();
                if (options.Bet == 0)
                {
                    await ReplyConfirmLocalized("connect4_created").ConfigureAwait(false);
                }
                else
                {
                    await ReplyConfirmLocalized("connect4_created_bet", options.Bet + Bc.BotConfig.CurrencySign).ConfigureAwait(false);
                }

                Task _client_MessageReceived(SocketMessage arg)
                {
                    if (Context.Channel.Id != arg.Channel.Id)
                    {
                        return(Task.CompletedTask);
                    }

                    var _ = Task.Run(async() =>
                    {
                        bool success = false;
                        if (int.TryParse(arg.Content, out var col))
                        {
                            success = await game.Input(arg.Author.Id, col).ConfigureAwait(false);
                        }

                        if (success)
                        {
                            try { await arg.DeleteAsync().ConfigureAwait(false); } catch { }
                        }
                        else
                        {
                            if (game.CurrentPhase == Connect4Game.Phase.Joining ||
                                game.CurrentPhase == Connect4Game.Phase.Ended)
                            {
                                return;
                            }
                            RepostCounter++;
                            if (RepostCounter == 0)
                            {
                                try { msg = await Context.Channel.SendMessageAsync("", embed: (Embed)msg.Embeds.First()).ConfigureAwait(false); } catch { }
                            }
                        }
                    });

                    return(Task.CompletedTask);
                }

                Task Game_OnGameFailedToStart(Connect4Game arg)
                {
                    if (_service.Connect4Games.TryRemove(Context.Channel.Id, out var toDispose))
                    {
                        _client.MessageReceived -= _client_MessageReceived;
                        toDispose.Dispose();
                    }
                    return(ErrorLocalized("connect4_failed_to_start"));
                }

                Task Game_OnGameEnded(Connect4Game arg, Connect4Game.Result result)
                {
                    if (_service.Connect4Games.TryRemove(Context.Channel.Id, out var toDispose))
                    {
                        _client.MessageReceived -= _client_MessageReceived;
                        toDispose.Dispose();
                    }

                    string title;

                    if (result == Connect4Game.Result.CurrentPlayerWon)
                    {
                        title = GetText("connect4_won", Format.Bold(arg.CurrentPlayer.Username), Format.Bold(arg.OtherPlayer.Username));
                    }
                    else if (result == Connect4Game.Result.OtherPlayerWon)
                    {
                        title = GetText("connect4_won", Format.Bold(arg.OtherPlayer.Username), Format.Bold(arg.CurrentPlayer.Username));
                    }
                    else
                    {
                        title = GetText("connect4_draw");
                    }

                    return(msg.ModifyAsync(x => x.Embed = new EmbedBuilder()
                                                          .WithTitle(title)
                                                          .WithDescription(GetGameStateText(game))
                                                          .WithOkColor()
                                                          .Build()));
                }
            }
Example #8
0
        public async Task Leaderboard(int page = 1, params string[] args)
        {
            if (--page < 0)
            {
                return;
            }

            var(opts, _) = OptionsParser.ParseFrom(new LbOpts(), args);

            List <DiscordUser> cleanRichest = new List <DiscordUser>();

            // it's pointless to have clean on dm context
            if (Context.Guild is null)
            {
                opts.Clean = false;
            }

            if (opts.Clean)
            {
                var now = DateTime.UtcNow;

                using (var uow = _db.GetDbContext())
                {
                    cleanRichest = uow.DiscordUsers.GetTopRichest(_client.CurrentUser.Id, 10_000);
                }

                await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);

                await _tracker.EnsureUsersDownloadedAsync(ctx.Guild).ConfigureAwait(false);

                var sg = (SocketGuild)Context.Guild;
                cleanRichest = cleanRichest.Where(x => sg.GetUser(x.UserId) != null)
                               .ToList();
            }
            else
            {
                using (var uow = _db.GetDbContext())
                {
                    cleanRichest = uow.DiscordUsers.GetTopRichest(_client.CurrentUser.Id, 9, page).ToList();
                }
            }

            await Context.SendPaginatedConfirmAsync(page, curPage =>
            {
                var embed = new EmbedBuilder()
                            .WithOkColor()
                            .WithTitle(CurrencySign + " " + GetText("leaderboard"));

                List <DiscordUser> toSend;
                if (!opts.Clean)
                {
                    using (var uow = _db.GetDbContext())
                    {
                        toSend = uow.DiscordUsers.GetTopRichest(_client.CurrentUser.Id, 9, curPage);
                    }
                }
                else
                {
                    toSend = cleanRichest.Skip(curPage * 9).Take(9).ToList();
                }
                if (!toSend.Any())
                {
                    embed.WithDescription(GetText("no_user_on_this_page"));
                    return(embed);
                }

                for (var i = 0; i < toSend.Count; i++)
                {
                    var x      = toSend[i];
                    var usrStr = x.ToString().TrimTo(20, true);

                    var j = i;
                    embed.AddField(efb => efb.WithName("#" + (9 * curPage + j + 1) + " " + usrStr)
                                   .WithValue(n(x.CurrencyAmount) + " " + CurrencySign)
                                   .WithIsInline(true));
                }

                return(embed);
            }, opts.Clean?cleanRichest.Count() : 9000, 9, opts.Clean);
        }
Example #9
0
            public async Task Repeat(GuildDateTime dt, params string[] options)
            {
                if (!_service.RepeaterReady)
                {
                    return;
                }

                var(opts, _) = OptionsParser.ParseFrom(new Repeater.Options(), options);

                if (string.IsNullOrWhiteSpace(opts.Message) || opts.Interval >= 50001)
                {
                    return;
                }

                var startTimeOfDay = dt?.InputTimeUtc.TimeOfDay;

                // if interval not null, that means user specified it (don't change it)

                // if interval is null set the default to:
                // if time of day is specified: 24 * 60 (24h)
                // else 5
                var realInterval = opts.Interval ?? (startTimeOfDay is null ? 5 : 24 * 60);

                var toAdd = new Repeater()
                {
                    ChannelId      = ctx.Channel.Id,
                    GuildId        = ctx.Guild.Id,
                    Interval       = TimeSpan.FromMinutes(realInterval),
                    Message        = opts.Message,
                    NoRedundant    = opts.NoRedundant,
                    StartTimeOfDay = startTimeOfDay,
                };

                using (var uow = _db.GetDbContext())
                {
                    var gc = uow.GuildConfigs.ForId(ctx.Guild.Id, set => set.Include(x => x.GuildRepeaters));

                    if (gc.GuildRepeaters.Count >= 5)
                    {
                        return;
                    }
                    gc.GuildRepeaters.Add(toAdd);

                    await uow.SaveChangesAsync();
                }

                var runner = new RepeatRunner(_client, (SocketGuild)ctx.Guild, toAdd, _service);

                _service.Repeaters.AddOrUpdate(ctx.Guild.Id,
                                               new ConcurrentDictionary <int, RepeatRunner>(new[] { new KeyValuePair <int, RepeatRunner>(toAdd.Id, runner) }), (key, old) =>
                {
                    old.TryAdd(runner.Repeater.Id, runner);
                    return(old);
                });

                var description = GetRepeaterInfoString(runner);
                await ctx.Channel.EmbedAsync(new EmbedBuilder()
                                             .WithOkColor()
                                             .WithTitle(GetText("repeater_created"))
                                             .WithDescription(description));
            }
            public Task Race(params string[] args)
            {
                var(options, success) = OptionsParser.ParseFrom(new RaceOptions(), args);

                var ar = new AnimalRace(options, _cs, Bc.BotConfig.RaceAnimals.Shuffle().ToArray());

                if (!_service.AnimalRaces.TryAdd(Context.Guild.Id, ar))
                {
                    return(Context.Channel.SendErrorAsync(GetText("animal_race"), GetText("animal_race_already_started")));
                }

                ar.Initialize();

                var count = 0;

                Task _client_MessageReceived(SocketMessage arg)
                {
                    var _ = Task.Run(() =>
                    {
                        try
                        {
                            if (arg.Channel.Id == Context.Channel.Id)
                            {
                                if (ar.CurrentPhase == AnimalRace.Phase.Running && ++count % 9 == 0)
                                {
                                    raceMessage = null;
                                }
                            }
                        }
                        catch { }
                    });

                    return(Task.CompletedTask);
                }

                Task Ar_OnEnded(AnimalRace race)
                {
                    _client.MessageReceived -= _client_MessageReceived;
                    _service.AnimalRaces.TryRemove(Context.Guild.Id, out _);
                    var winner = race.FinishedUsers[0];

                    if (race.FinishedUsers[0].Bet > 0)
                    {
                        return(Context.Channel.SendConfirmAsync(GetText("animal_race"),
                                                                GetText("animal_race_won_money", Format.Bold(winner.Username),
                                                                        winner.Animal.Icon, (race.FinishedUsers[0].Bet * (race.Users.Length - 1)) + Bc.BotConfig.CurrencySign)));
                    }
                    else
                    {
                        return(Context.Channel.SendConfirmAsync(GetText("animal_race"),
                                                                GetText("animal_race_won", Format.Bold(winner.Username), winner.Animal.Icon)));
                    }
                }

                ar.OnStartingFailed     += Ar_OnStartingFailed;
                ar.OnStateUpdate        += Ar_OnStateUpdate;
                ar.OnEnded              += Ar_OnEnded;
                ar.OnStarted            += Ar_OnStarted;
                _client.MessageReceived += _client_MessageReceived;

                return(Context.Channel.SendConfirmAsync(GetText("animal_race"), GetText("animal_race_starting", options.StartTime),
                                                        footer: GetText("animal_race_join_instr", Prefix)));
            }
            public async Task WIP(params string[] args)
            {
                var(opts, _) = OptionsParser.ParseFrom(new RandomWIPOptions(), args);  //parse options, to be used to check if the result should be unembedded

                var msg = await Context.Channel.SendMessageAsync(GetText("jl_randomfriend_searching")).ConfigureAwait(false);

                string wipPage;                                                                                //we need to declare this here to use it out of the do-while loop

                string redirPage = "https://japari-library.com/wiki/Special:RandomInCategory/Missing_Content"; //by default look in the Missing_Content category

                //if requested, look for a specific kind of WIP page (unfortunately only 1 of these is possible at a time)
                if (opts.isIrl)
                {
                    redirPage = "https://japari-library.com/wiki/Special:RandomInCategory/Needs_RL_Info";
                }
                if (opts.isAppearance)
                {
                    redirPage = "https://japari-library.com/wiki/Special:RandomInCategory/Needs_Appearance";
                }
                if (opts.isPriority)
                {
                    redirPage = "https://japari-library.com/wiki/Special:RandomInCategory/Priority_Articles";
                }

                using (var http = _httpFactory.CreateClient())
                {
                    do
                    {
                        try
                        {
                            var response = await http.GetAsync(redirPage).ConfigureAwait(false);

                            var location = response.Headers.Location; //the redirect isn't automatically followed, you have to dig in the response header to find out what the page actually is
                            wipPage = location.AbsoluteUri;
                        }
                        catch (System.Net.Http.HttpRequestException)
                        {
                            await msg.ModifyAsync(m => m.Content = GetText("jl_wikisearch_error")).ConfigureAwait(false);

                            return;
                        }
                        wipPage = Regex.Replace(wipPage, "http*", "https"); //the URI is http by default while japari-librari is https, the vanilla link works but this is more correct
                    } while (wipPage.Contains("Category:"));                //Category pages count as Friend pages but we don't want none of that

                    if (opts.IsUnembedded)
                    {
                        wipPage = "<" + wipPage + ">"; //Enclosing a link in these tells Discord not to make an embed for it

                        string successText = "jl_randomwip_success";
                        if (opts.isPriority)
                        {
                            successText = "jl_randomwip_priority_success";
                        }
                        await msg.ModifyAsync(m => m.Content = GetText(successText, wipPage)).ConfigureAwait(false);
                    }
                    else //make it embedded
                    {
                        var config = Configuration.Default.WithDefaultLoader();

                        using (var document = await BrowsingContext.New(config).OpenAsync(wipPage).ConfigureAwait(false))
                        {
                            var imageElem = document.QuerySelector("table.infobox > tbody > tr >td > p > a.image > img");
                            imageElem = ((IHtmlImageElement)imageElem)?.Source == null?document.QuerySelector("div.tabbertab > p > a > img") : imageElem;     //if a wip page has multiple pictures, this will get the correct image

                            var friendImageUrl = ((IHtmlImageElement)imageElem)?.Source ?? "http://icecream.me/uploads/870b03f36b59cc16ebfe314ef2dde781.png"; //get wip image or a default one if one cannot be loaded

                            var friendInfoElem = document.QuerySelector("#mw-content-text > p");
                            // check if we can get the description or not, if not, just say the description is unavailable
                            var friendInfo = friendInfoElem == null ? "Description unavailable" : friendInfoElem.InnerHtml;

                            var friendNameElem = document.QuerySelector("#firstHeading");
                            var friendName     = friendNameElem.InnerHtml; //get page name

                            friendName = Regex.Replace(friendName, "<[^>]*>", "");
                            friendInfo = Regex.Replace(friendInfo, "<[^>]*>", ""); //remove html tags

                            // footer
                            var footer = new EmbedFooterBuilder();
                            footer.Text    = "Japari Library";
                            footer.IconUrl = "https://japari-library.com/w/resources/assets/Jlibrarywglogo.png?d63ab";

                            await msg.DeleteAsync();

                            await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() //make a small embed
                                                             .WithTitle(friendName)
                                                             .WithDescription(friendInfo)
                                                             .WithThumbnailUrl(friendImageUrl)
                                                             .WithUrl(wipPage)
                                                             .WithFooter(footer)
                                                             ).ConfigureAwait(false);
                        }
                    }
                }
            }
Example #12
0
            public async Task Jeopardy(params string[] args)
            {
                JeopardyOptions opts = OptionsParser.ParseFrom(new JeopardyOptions(), args);

                if (Service.ActiveGames.TryGetValue(Context.Channel.Id, out Jeopardy activeGame))
                {
                    await Context.Channel.SendErrorAsync("Jeopardy game is already in progress in current channel.").ConfigureAwait(false);

                    await Context.Channel.EmbedAsync(new EmbedBuilder().WithColor(activeGame.Color)
                                                     .WithAuthor("Jeopardy!")
                                                     .WithTitle($"{activeGame.CurrentClue.Category.Name} - ${activeGame.CurrentClue.Value}")
                                                     .WithDescription(activeGame.CurrentClue.Text)
                                                     .WithFooter($"#{activeGame.CurrentClue.Id} | answer with a question, e.g. what's x, who's x"))
                    .ConfigureAwait(false);

                    return;
                }

                await _semaphore.WaitAsync();

                Jeopardy jeopardy;

                try
                {
                    List <Category> categories = await Service.GenerateGame(opts.NumCategories).ConfigureAwait(false);

                    jeopardy = new Jeopardy(_client, await _config.GetGuildConfigAsync(Context.Guild.Id), categories, Context.Guild, Context.Channel as ITextChannel, _currency, await Service.GenerateFinalJeopardy());
                }
                catch (Exception e)
                {
                    Log.Error(e, "Could not start jeopardy game");
                    _semaphore.Release();
                    return;
                }


                if (Service.ActiveGames.TryAdd(Context.Channel.Id, jeopardy))
                {
                    _semaphore.Release();
                    try
                    {
                        await jeopardy.StartGame().ConfigureAwait(false);
                    }
                    finally
                    {
                        Service.ActiveGames.TryRemove(Context.Channel.Id, out jeopardy);
                        if (jeopardy != null)
                        {
                            await jeopardy.EnsureStopped().ConfigureAwait(false);

                            jeopardy.Dispose();
                        }
                    }
                }
                else
                {
                    _semaphore.Release();
                    Log.Error("Could not start jeopardy game");
                    jeopardy.Dispose();
                }
            }
Example #13
0
        public async Task XpLeaderboard(int page = 1, params string[] args)
        {
            if (--page < 0 || page > 100)
            {
                return;
            }

            var(opts, _) = OptionsParser.ParseFrom(new LbOpts(), args);

            await Context.Channel.TriggerTypingAsync();

            var socketGuild             = ((SocketGuild)ctx.Guild);
            List <UserXpStats> allUsers = new List <UserXpStats>();

            if (opts.Clean)
            {
                await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);

                await _tracker.EnsureUsersDownloadedAsync(ctx.Guild).ConfigureAwait(false);

                allUsers = _service.GetTopUserXps(ctx.Guild.Id, 1000)
                           .Where(user => !(socketGuild.GetUser(user.UserId) is null))
                           .ToList();
            }

            await ctx.SendPaginatedConfirmAsync(page, (curPage) =>
            {
                var embed = new EmbedBuilder()
                            .WithTitle(GetText("server_leaderboard"))
                            .WithOkColor();

                List <UserXpStats> users;
                if (opts.Clean)
                {
                    users = allUsers.Skip(curPage * 9).Take(9).ToList();
                }
                else
                {
                    users = _service.GetUserXps(ctx.Guild.Id, curPage);
                }

                if (!users.Any())
                {
                    return(embed.WithDescription("-"));
                }
                else
                {
                    for (int i = 0; i < users.Count; i++)
                    {
                        var levelStats = new LevelStats(users[i].Xp + users[i].AwardedXp);
                        var user       = ((SocketGuild)ctx.Guild).GetUser(users[i].UserId);

                        var userXpData = users[i];

                        var awardStr = "";
                        if (userXpData.AwardedXp > 0)
                        {
                            awardStr = $"(+{userXpData.AwardedXp})";
                        }
                        else if (userXpData.AwardedXp < 0)
                        {
                            awardStr = $"({userXpData.AwardedXp})";
                        }

                        embed.AddField(
                            $"#{(i + 1 + curPage * 9)} {(user?.ToString() ?? users[i].UserId.ToString())}",
                            $"{GetText("level_x", levelStats.Level)} - {levelStats.TotalXp}xp {awardStr}");
                    }
                    return(embed);
                }
            }, 900, 9, addPaginatedFooter : false);
        }