public async Task BanlistCommand(Banlist input) { var format = input switch { Banlist.Ocg => BanlistFormats.OCG, Banlist.TcgAdv => BanlistFormats.TCG, Banlist.TcgTrad => BanlistFormats.TRAD, _ => throw new ArgumentOutOfRangeException(nameof(input), input, null) }; var banlist = await YuGiOhDbService.GetBanlistAsync(format); if (banlist.Forbidden.Any()) { await DirectMessageAsync(FormatBanlist("Forbidden", banlist.Forbidden)); } if (banlist.Limited.Any()) { await DirectMessageAsync(FormatBanlist("Limited", banlist.Limited)); } if (banlist.SemiLimited.Any()) { await DirectMessageAsync(FormatBanlist("Semi-Limited", banlist.SemiLimited)); } await RespondAsync("The banlist has been directly messaged to you"); }
public async Task PriceCommand([Remainder] string input) { var card = await YuGiOhDbService.GetCardAsync(input); if (card is not null) { if (!card.TcgExists) { await ReplyAsync("Card does not exist in TCG therefore no price can be determined for this card currently!"); return; } using (Context.Channel.EnterTypingState()) { var response = await Web.GetPrices(card.Name) ?? await Web.GetPrices(card.RealName); if (response is null) { await ReplyAsync($"There was an error in retrieving the prices for \"{input}\". Please try again later."); return; } var data = response.Data.Where(d => string.IsNullOrEmpty(d.PriceData.Message)).ToList(); var author = new EmbedAuthorBuilder() .WithIconUrl("https://vignette1.wikia.nocookie.net/yugioh/images/8/82/PotofGreed-TF04-JP-VG.jpg/revision/latest?cb=20120829225457") .WithName("YuGiOh Prices") .WithUrl($"https://yugiohprices.com/card_price?name={Uri.EscapeDataString(input)}"); var body = new EmbedBuilder() .WithAuthor(author) .WithColor(new Color(33, 108, 42)) .WithCurrentTimestamp(); if (data.Count > 25) { body.WithDescription("**There are more than 25 results! Due to that, only the first 25 results are shown!**"); data = data.GetRange(0, 25); } body = data.Aggregate(body, (current, datum) => current.AddPrice(datum, true)); await SendEmbedAsync(body); } } else { await NoResultError(input); } }
public async Task ImageCommand([Remainder] string input) { var card = await YuGiOhDbService.GetCardAsync(input); if (card is not null) { await UploadImage(card.Name, card.Img); } else { await NoResultError(input); } }
public async Task ArtCommand([Autocomplete(typeof(CardAutocomplete)), Summary(description: "The card")] string input) { var card = await YuGiOhDbService.GetCardAsync(input); if (card is not null) { await UploadImage(card.Name, card.GetArtUrl()); } else { await NoResultError(input); } }
public async Task CardCommand([Autocomplete(typeof(CardAutocomplete)), Summary(description: "The card")] string input) { var card = await YuGiOhDbService.GetCardAsync(input); if (card is not null) { await SendCardEmbedAsync(card.GetEmbedBuilder(), GuildConfig.Minimal); } else { await NoResultError(input); } }
public async Task BuyCommand() { var attachments = Context.Message.Attachments; if (attachments.Count == 0) { return; } var file = attachments.FirstOrDefault(attachment => Path.GetExtension(attachment.Filename) == ".ydk"); if (file is null) { await ReplyAsync("Invalid file provided! Must be a ydk or text file!"); return; } var url = file.Url; string text; await using (var stream = await Web.GetStream(url)) { var buffer = new byte[stream.Length]; await stream.ReadAsync(buffer.AsMemory(0, (int)stream.Length)); text = Encoding.UTF8.GetString(buffer); } var cards = text.Replace("#main", "") .Replace("#extra", "") .Replace("#created by ...", "") .Replace("!side", "") .Split('\n') .Select(passcode => passcode.Trim()) .Where(passcode => !string.IsNullOrEmpty(passcode)) .Select(async passcode => await YuGiOhDbService.GetNameWithPasscodeAsync(passcode)) .Select(task => task.Result) .Where(name => !string.IsNullOrEmpty(name)) .GroupBy(name => name) .Aggregate(new StringBuilder(), (builder, group) => builder.Append("||").Append(Uri.EscapeDataString($"{group.Count()} {group.First()}"))) .ToString(); url = $"http://store.tcgplayer.com/massentry?productline=YuGiOh&c={cards}"; var response = await Web.Post("https://api-ssl.bitly.com/v4/shorten", $"{{\"long_url\": \"{url}\"}}", "Bearer", Config.Instance.Tokens.Bitly); url = JObject.Parse(await response.Content.ReadAsStringAsync())["link"].Value <string>(); await ReplyAsync(url); }
private async Task <(string name, int count, double price)> GetName(IGrouping <string, string> group) { var passcode = group.First(); var name = await YuGiOhDbService.GetNameWithPasscodeAsync(passcode); if (name is not null) { var response = await Web.GetResponseMessage(Constants.FandomWikiUrl + passcode); name = response.RequestMessage.RequestUri.Segments.Last().Replace('_', ' '); name = WebUtility.UrlDecode(name); } return(name, group.Count(), double.Epsilon); }
public async Task CardCommand([Remainder] string input) { var card = await YuGiOhDbService.GetCardAsync(input); if (card is not null) { await SendCardEmbedAsync(card.GetEmbedBuilder(), GuildConfig.Minimal, Web); } else { await NoResultError(input); } //if (Cache.NameToCard.TryGetValue(input, out var card)) // return SendCardEmbed(card.GetEmbedBuilder(), _minimal, Web); //else // return NoResultError(input); }
public async Task RandomCommand() { var card = await YuGiOhDbService.GetRandomCardAsync(); await SendCardEmbedAsync(card.GetEmbedBuilder(), GuildConfig.Minimal, Web); }
public async Task BanlistCommand([Remainder] string input) { BanlistFormats format; switch (input.ToLower()) { case "ocg": case "1": format = BanlistFormats.OCG; break; case "tcg": case "2": format = BanlistFormats.TCG; break; case "tcgtrad": case "trad": case "3": format = BanlistFormats.TRAD; break; default: format = BanlistFormats.TCG; break; } var banlist = await YuGiOhDbService.GetBanlistAsync(format); if (banlist.Forbidden.Any()) { await DirectMessageAsync(FormatBanlist("Forbidden", banlist.Forbidden)); } if (banlist.Limited.Any()) { await DirectMessageAsync(FormatBanlist("Limited", banlist.Limited)); } if (banlist.SemiLimited.Any()) { await DirectMessageAsync(FormatBanlist("Semi-Limited", banlist.SemiLimited)); } //BanlistFormat banlist; //switch (format.ToLower()) //{ // case "ocg": // case "1": // banlist = Cache.Banlist.OcgBanlist; // break; // case "tcgadv": // case "2": // banlist = Cache.Banlist.TcgAdvBanlist; // break; // case "tcgtrad": // case "3": // banlist = Cache.Banlist.TcgTradBanlist; // break; // default: // await ReplyAsync("The valid formats are OCG or 1, TCGADV or 2, TCGTRAD or 3!"); // return; //} //if (banlist.Forbidden.Any()) // await DirectMessageAsync("", FormatBanlist("Forbidden", banlist.Forbidden)); //await DirectMessageAsync("", FormatBanlist("Limited", banlist.Limited)); //await DirectMessageAsync("", FormatBanlist("Semi-Limited", banlist.SemiLimited)); }
public async Task RandomCardArtCommand() { var card = await YuGiOhDbService.GetRandomCardAsync(); await UploadImage(card.Name, GetArtUrl(card.Passcode)); }
public async Task GuessCommand() { if (Cache.GuessInProgress.ContainsKey(Context.Channel.Id)) { await RespondAsync(":game_die: There is a game in progress!"); return; } var logger = _loggerFactory.CreateLogger("Guess"); try { Cache.GuessInProgress.TryAdd(Context.Channel.Id, null); Card card = null !; Exception e; do { try { card = await YuGiOhDbService.GetRandomCardAsync(); if (string.IsNullOrEmpty(card.Passcode)) { throw new NullReferenceException(nameof(card.Passcode)); } //https://storage.googleapis.com/ygoprodeck.com/pics_artgame/{passcode}.jpg var url = $"{Constants.ArtBaseUrl}{card.Passcode}.{Constants.ArtFileType}"; var name = $"{card.Name}"; if (!string.IsNullOrEmpty(card.RealName)) { name += $" / {card.RealName}"; } logger.Info("{CardName} {Url}", name, url); await using (var stream = await Web.GetStream(url)) await UploadAsync(stream, $"{GetConfusingString()}.{Constants.ArtFileType}", $":stopwatch: You have **{GuildConfig.GuessTime}** seconds to guess what card this art belongs to! Case insensitive (used to be case sensitive)!"); e = null; } catch (NullReferenceException nullref) { e = nullref; } } while (e is not null); var criteria = new GuessCriteria(card.Name, card.RealName); var answer = await NextMessageAsync(BaseCriteria.AddCriterion(criteria), TimeSpan.FromSeconds(GuildConfig.GuessTime)); if (answer is not null) { await ReplyAsync($":trophy: The winner is **{(answer.Author as SocketGuildUser)?.Nickname ?? answer.Author.Username}**! The card was `{criteria.Answer}`!"); } else { var possibleAnswersOutput = criteria.PossibleAnswers .Skip(1) .Aggregate( new StringBuilder($"`{criteria.PossibleAnswers.First()}`"), (strBuilder, possibleAnswer) => strBuilder.Append(" or `").Append(possibleAnswer).Append('`') ); await ReplyAsync($":stop_button: Ran out of time! The card was {possibleAnswersOutput}!"); } } catch (Exception ex) { logger.Error("There was a problem with guess!", ex); } finally { Cache.GuessInProgress.TryRemove(Context.Channel.Id, out _); } }
public async Task HangmanCommand() { if (Cache.HangmanInProgress.ContainsKey(Context.Channel.Id)) { await RespondAsync(":game_die: There is a game in progress in this channel!"); return; } var logger = _loggerFactory.CreateLogger("Hangman"); Cache.HangmanInProgress[Context.Channel.Id] = null; try { var card = await YuGiOhDbService.GetRandomCardAsync(); logger.Info(card.Name); var cts = new CancellationTokenSource(); var hangmanService = new HangmanService(card.Name); var criteria = BaseCriteria .AddCriterion(new NotCommandCriteria(GuildConfig)) .AddCriterion(new NotInlineSearchCriteria()); if (!GuildConfig.HangmanAllowWords) { criteria.AddCriterion(new CharacterOnlyCriteria()); } var time = TimeSpan.FromSeconds(GuildConfig.HangmanTime); await RespondAsync("You can now type more than a letter for hangman!\n" + $"As well as change the hangman time ({GuildConfig.Prefix}hangmantime <seconds>)! Ask an admin about it!\n" + $"You may also disable the ability to input more than one letter! ({GuildConfig.Prefix}hangmanwords <true/false>)\n" + $"You have **{time.ToPrettyString()}**!\n" + hangmanService.GetCurrentDisplay()); var _ = new Timer((cancelTokenSrc) => (cancelTokenSrc as CancellationTokenSource) !.Cancel(), cts, TimeSpan.FromSeconds(GuildConfig.HangmanTime), Timeout.InfiniteTimeSpan); SocketUser user = null; do { var input = await NextMessageAsync(criteria, token : cts.Token); if (cts.IsCancellationRequested) { break; } user = input.Author; switch (hangmanService.AddGuess(input.Content)) { case GuessStatus.Duplicate: await ReplyAsync($"You already guessed `{input}`!\n" + hangmanService.GetCurrentDisplay()); break; case GuessStatus.Nonexistent: await ReplyAsync($"```fix\n{hangmanService.GetHangman()}```\n" + hangmanService.GetCurrentDisplay()); break; case GuessStatus.Accepted: await ReplyAsync(hangmanService.GetCurrentDisplay()); break; } } while (!cts.IsCancellationRequested && hangmanService.CompletionStatus == CompletionStatus.Incomplete); if (cts.IsCancellationRequested) { await ReplyAsync($"Time is up! No one won! The card is `{hangmanService.Word}`"); } else { switch (hangmanService.CompletionStatus) { case CompletionStatus.Complete: await ReplyAsync($":trophy: The winner is **{(user as SocketGuildUser)!.Nickname ?? user!.Username}**!"); break; case CompletionStatus.Hanged: await ReplyAsync($"You have been hanged! The card was `{hangmanService.Word}`."); break; } } } catch (Exception ex) { logger.Error(ex, "There was a problem with hangman"); } finally { Cache.HangmanInProgress.TryRemove(Context.Channel.Id, out _); } }
public async Task SearchCommand([Autocomplete(typeof(CardAutocomplete)), Summary(description: "The input")] string input) { var cards = (await YuGiOhDbService.SearchCardsAsync(input)).ToImmutableArray(); await DisplaySearch(cards, input); }
public async Task RandomImageCommand() { var card = await YuGiOhDbService.GetRandomCardAsync(); await UploadImage(card.Name, card.Img); }
public async Task AntisupportCommand([Autocomplete(typeof(AntisupportAutocomplete)), Summary(description: "The input")] string input) { var cards = (await YuGiOhDbService.GetCardsInAntisupportAsync(input)).ToImmutableArray(); await DisplaySearch(cards, input, "antisupports"); }
public async Task BoosterCommand([Autocomplete(typeof(BoosterPackAutocomplete)), Summary(description: "The boosterpack")] string input) { var boosterPack = await YuGiOhDbService.GetBoosterPackAsync(input); if (boosterPack is not null) { var descBuilder = new StringBuilder() .Append("**Amount:** ") .Append(boosterPack.Cards.Count) .AppendLine(" cards") .AppendLine() .AppendLine("**Release dates**"); descBuilder = boosterPack.Dates .Aggregate(descBuilder, (current, date) => current.Append("**") .Append(date.Name) .Append(":** ") .AppendFormat("{0: MM/dd/yyyy}", date.Date) .AppendLine() ); var options = PagedOptions; options.FieldsPerPage = 1; var paginator = new PaginatedMessage() { Title = boosterPack.Name, Color = _random.NextColor(), AlternateDescription = descBuilder.ToString(), Options = options }; var pages = new LinkedList <EmbedFieldBuilder>(); paginator.Pages = pages; var rarityToCards = new Dictionary <string, List <string> >(); foreach (var card in boosterPack.Cards) { foreach (var rarity in card.Rarities) { if (!rarityToCards.ContainsKey(rarity)) { rarityToCards[rarity] = new List <string>(); } rarityToCards[rarity].Add(card.Name); } } foreach (var(rarity, card) in rarityToCards) { var cards = card .Aggregate(new StringBuilder(), (current, next) => current.AppendLine(next)) .ToString(); while (cards.Length >= 1024) { const int maxLength = 1000; var substring = cards[..maxLength];