public async Task Marry(DiscordGuildUser user) { await ReplyEmbed( $"{Formatter.UsernameDiscrim(user.GuildUser)}, do you want to marry {Formatter.UsernameDiscrim(Context.User)}?", Purple, "💍"); var criteria = InteractiveServiceExtensions.CreateEnsureFromUserInChannelCriteria(user.GuildUser.Id, Context.Channel.Id); var resp = await _interactiveService.NextMessageAsync(Context, criteria, TimeSpan.FromSeconds(45)).ConfigureAwait(false); if (resp == null) { await ReplyFailureEmbed($"{Formatter.UsernameDiscrim(user.GuildUser)} didn't answer in time >.<"); return; } if (!InteractiveServiceExtensions.StringContainsYes(resp.Content)) { await ReplyFailureEmbed($"{Formatter.UsernameDiscrim(user.GuildUser)} didn't answer with a yes ˚‧º·(˚ ˃̣̣̥᷄⌓˂̣̣̥᷅ )‧º·˚"); return; } var res = await _marriageRepo.TryAddMarriage(Context.User.Id, user.GuildUser.Id); if (!res) { await ReplyFailureEmbed(res.Err().Message); return; } var eb = new EmbedBuilder() { Color = Purple, Title = "💑 You are now married", ImageUrl = "https://media.giphy.com/media/iQ5rGja9wWB9K/giphy.gif" }; await ReplyEmbed(eb); }
public async Task RemoveReminder() { var remsOption = await _remindRepo.GetUserReminders(Context.User.Id).ConfigureAwait(false); if (!remsOption) { await ReplyFailureEmbed("You don't have any reminders."); return; } var eb = new EmbedBuilder() { Color = Purple, ThumbnailUrl = Context.User.GetAvatarUrl() ?? Context.User.GetDefaultAvatarUrl(), Title = "⏰ Remove a Reminder", Description = "Answer with a number indicating the ID of the reminder you'd like to remove.", Footer = RequestedByMe() }; var rems = ~remsOption; rems.Sort((r1, r2) => r1.DueDateUtc.CompareTo(r2.DueDateUtc)); for (int i = 0; i < rems.Count; i++) { var rem = rems[i]; var remindIn = rem.DueDateUtc.Subtract(DateTime.UtcNow); int num = i + 1; eb.AddField(x => { x.IsInline = false; x.Name = $"**{num.ToString()}#** Due in {remindIn.Humanize(minUnit: TimeUnit.Second, maxUnit: TimeUnit.Year, precision: 4)}"; x.Value = $"{rem.Message}\n_On {rem.DueDateUtc.Date.ToString("dd/MM/yyyy")}_"; }); } await ReplyEmbed(eb); var criteria = InteractiveServiceExtensions.CreateEnsureFromUserInChannelCriteria(Context.User.Id, Context.Channel.Id); var resp = await _interactiveService.NextMessageAsync(Context, criteria, TimeSpan.FromSeconds(45)); if (resp == null) { await ReplyFailureEmbed("Failed to answer in time >.<"); return; } if (!int.TryParse(resp.Content, out var removeId)) { await ReplyFailureEmbed("Please respond with the ID of the reminder to remove e.g. `1` or `7`."); return; } removeId--; if (removeId < 0 || removeId >= rems.Count) { await ReplyFailureEmbed($"Not a valid ID! Please choose a reminder between 1 and {rems.Count.ToString()}"); return; } await _remindRepo.RemoveReminder(rems[removeId].Id); await ReplySuccessEmbed("Successfully removed reminder."); }
private async Task WaifuTradeComp(IUser tradeUser, int wantId, int offerId) { // First we gotta make sure that the users have the respective waifus var wantUserWaifu = await _waifuService.GetUserWaifu(tradeUser.Id, wantId).ConfigureAwait(false); if (wantUserWaifu == null) { await ReplyFailureEmbed("The user does not have the Waifu you want."); return; } var offerUserWaifu = await _waifuService.GetUserWaifu(Context.User.Id, offerId).ConfigureAwait(false); if (offerUserWaifu == null) { await ReplyFailureEmbed("You do not have the Waifu that you offer!"); return; } // They both have both. So we can actually ask for the trade. // No further preparations or queries until the user actually accepts the trade var wantWaifu = await _waifuService.GetWaifuById(wantId).ConfigureAwait(false); var offerWaifu = await _waifuService.GetWaifuById(offerId).ConfigureAwait(false); if (wantWaifu == null || offerWaifu == null) { await ReplyFailureEmbed( "Could not find one of the Waifus. They might have been removed from the DB..."); return; } var eb = new EmbedBuilder() { Title = "Waifu Trade Request", Footer = RequestedByFooter(Context.User), Description = $"{Formatter.UsernameDiscrim(Context.User)} wishes to trade with you.", Color = Purple, ImageUrl = offerWaifu.ImageUrl, }; eb.AddField(x => { x.IsInline = true; x.Name = "User offers"; x.Value = $"{offerWaifu.Name}\n{WaifuFormatter.GetRarityString(offerWaifu.Rarity)}\n_ID: {offerWaifu.Id}_"; }); eb.AddField(x => { x.IsInline = true; x.Name = "User wants"; x.Value = $"{wantWaifu.Name}\n{WaifuFormatter.GetRarityString(wantWaifu.Rarity)}\n_ID: {wantWaifu.Id}_"; }); eb.AddField(x => { x.IsInline = false; x.Name = "Accept?"; x.Value = "You can accept this trade request by writing `y` or `yes` (nothing else). " + "If you write anything else Sora will count that as declining the offer."; }); await ReplyAsync("", embed : eb.Build()); // Now wait for response. var criteria = InteractiveServiceExtensions.CreateEnsureFromUserInChannelCriteria(tradeUser.Id, Context.Channel.Id); var resp = await _interactiveService.NextMessageAsync(Context, criteria, TimeSpan.FromSeconds(45)) .ConfigureAwait(false); if (resp == null) { await ReplyFailureEmbed($"{Formatter.UsernameDiscrim(tradeUser)} didn't answer in time >.<"); return; } if (!InteractiveServiceExtensions.StringIsYOrYes(resp.Content)) { await ReplyFailureEmbed($"{Formatter.UsernameDiscrim(tradeUser)} declined the trade offer."); return; } // User accepted offer. if (!await _waifuService.TryTradeWaifus(Context.User.Id, tradeUser.Id, offerId, wantId) .ConfigureAwait(false)) { await ReplyFailureEmbed("Failed to make trade. Please try again"); return; } await ReplySuccessEmbedExtended("Successfully traded Waifus!", $"{Formatter.UsernameDiscrim(Context.User)} got {wantWaifu.Name}\n" + $"{Formatter.UsernameDiscrim(tradeUser)} got {offerWaifu.Name}"); }
private async Task SearchAndChoose(string query, bool yt) { if (!_node.TryGetPlayer(Context.Guild, out var player)) { await ReplyFailureEmbed("I have not joined any Voice Channel yet."); return; } if (!await CheckIfSameVc(player.VoiceChannel)) { return; } var search = yt ? await _node.SearchYouTubeAsync(query) : await _node.SearchSoundCloudAsync(query); if (search.LoadStatus == LoadStatus.LoadFailed || search.LoadStatus == LoadStatus.NoMatches) { await ReplyFailureEmbed("Couldn't find anything with the specified query."); return; } // Create selection var eb = new EmbedBuilder() { Color = Blue, Title = $"{MUSICAL_NOTE} Top Search Results", Description = "Answer with the index of the song you'd like to add. Anything else to choose nothing", Footer = RequestedByMe() }; var tracks = search.Tracks.Take(Math.Min(10, search.Tracks.Count)).ToList(); for (var i = 0; i < tracks.Count; i++) { var track = tracks[i]; eb.AddField(x => { x.IsInline = false; // ReSharper disable once AccessToModifiedClosure x.Name = $"#{(i + 1).ToString()} by {track.Author}"; x.Value = $"[{Formatter.FormatTime(track.Duration)}] - **[{track.Title}]({track.Url})**"; }); } var msg = await ReplyEmbed(eb); var criteria = InteractiveServiceExtensions.CreateEnsureFromUserInChannelCriteria(Context.User.Id, Context.Channel.Id); var resp = await _interactiveService.NextMessageAsync(Context, criteria, TimeSpan.FromSeconds(45)); await msg.DeleteAsync(); // To reduce clutter if (resp == null) { await ReplyFailureEmbed("Failed to answer in time >.<"); return; } if (!int.TryParse(resp.Content, out var trackNr)) { await ReplyFailureEmbed("Please respond with the ID of the song to add e.g. `1` or `7`."); return; } trackNr--; if (trackNr < 0 || trackNr >= tracks.Count) { await ReplyFailureEmbed( $"Not a valid ID! Please choose a song between 1 and {tracks.Count.ToString()}"); return; } var t = tracks[trackNr]; try { // We got a track to add or play if (player.Track == null) { await player.PlayAsync(t); await ReplyMusicExtended(t, false); return; } // Otherwise we add it to the queue player.Queue.Enqueue(t); await ReplyMusicExtended(t); } catch (Exception) { await ReplyFailureEmbed("Something broke :/"); } }