private async Task SendThreadReply(ITextChannel channel, guid msgId, string message = null, Embed embed = null, AllowedMentions allowedMentions = null) { //await this.Client.LogMessage(LogType.Response, this.Channel, this.Client.GlobalConfig.UserId, message); if (message == null && embed == null) { return; } if (this.ReplyMsgIds.ContainsKey(msgId)) { if (await channel.GetMessageAsync(this.ReplyMsgIds[msgId]) is SocketUserMessage msg) { await msg.ModifyAsync(m => { m.Content = message; m.Embed = embed; }); return; } } IUserMessage reply = await channel.SendMessageAsync(message, embed : embed, allowedMentions : allowedMentions); this.ReplyMsgIds.TryAdd(msgId, reply.Id); }
private async Task SendFameMessageAsync(IMessage msg) { ITextChannel chan = await this.GetOrCreateFameChannelAsync(msg); if (chan == null) { return; } IGuildUser guildUser = await chan.Guild.GetCurrentUserAsync(); if (guildUser.GetPermissions(chan).Has(ChannelPermission.ManageWebhooks | ChannelPermission.SendMessages | ChannelPermission.AddReactions)) { IWebhookSenderService webhook = this.ServiceManager.GetService <IWebhookSenderService>("Webhook"); ulong msgId = await webhook.RepostMessageAsync(chan, msg); IUserMessage postedMsg; if (msgId == 0) { postedMsg = await this.MessageSender.RepostMessageAsync(chan, msg); } else { postedMsg = (IUserMessage)await chan.GetMessageAsync(msgId); } if (postedMsg != null) { await postedMsg.AddReactionAsync(Star2Emote); } } }
public async Task RemoveServerAsync(IPEndPoint endPoint, ulong guildID) { GameServer serverToRemove = (await dbContext.GameServers.AsQueryable().ToListAsync().ConfigureAwait(false)).FirstOrDefault(x => x.ServerIP.Address.ToString() == endPoint.Address.ToString() && x.ServerIP.Port == endPoint.Port && x.GuildID == guildID); if (serverToRemove == null) { throw new ArgumentException("The specified server does not exist"); } if (serverToRemove.MessageID != null) { try { SocketGuild guild = discordClient.GetGuild(serverToRemove.GuildID); ITextChannel channel = guild?.GetTextChannel(serverToRemove.ChannelID); if (await(channel?.GetMessageAsync(serverToRemove.MessageID.Value)).ConfigureAwait(false) is Discord.Rest.RestUserMessage msg) { await msg.DeleteAsync().ConfigureAwait(false); } } catch (Exception e) { logger.LogError(e, $"Error trying to remove message for game server {endPoint.Address}"); } } _ = dbContext.GameServers.Remove(serverToRemove); _ = await dbContext.SaveChangesAsync().ConfigureAwait(false); }
public async Task ExecuteGiveaway(GiveawayEntry entry, ulong serverId) { IGuild guild = await m_client.GetGuildAsync(serverId); ServerEntry server = m_db.GetServerEntry(serverId); ITextChannel channel = await guild.GetTextChannelAsync(entry.ChannelId); IUserMessage message = await channel.GetMessageAsync(entry.ReactionMessageId) as IUserMessage; var asyncparticipants = message.GetReactionUsersAsync(new Emoji(server.GiveawayReactionEmote), int.MaxValue); IEnumerable <IUser> users = await asyncparticipants.FlattenAsync(); List <IUser> participants = users.Where(user => user.Id != m_client.CurrentUser.Id).ToList(); List <IUser> winners = new List <IUser>(); if (participants.Count <= 0) { await channel.SendMessageAsync($"No one participated for {entry.Content}"); } else { for (int i = 0; i < entry.Count; i++) { IUser winner; do { winner = participants[m_random.Next(0, participants.Count)]; } while(winners.Contains(winner) && entry.Count < participants.Count); winners.Add(winner); } await channel.SendMessageAsync($"{string.Join(' ', winners.Select(winner => winner.Mention))} won **{entry.Content}**!"); } }
public async Task <IUserMessage> TryGetMessage(Cacheable <IUserMessage, ulong> messageCacheable, ITextChannel channel, SocketReaction reaction) { IUserMessage message; if (messageCacheable.HasValue) { message = messageCacheable.Value; } //This should work however there is a bug in d.net that is not fixed in the current d.net 2.1.1 implementation /*else if (reaction.Message.IsSpecified) * { * message = reaction.Message.Value; * }*/ else { var iMessage = await channel.GetMessageAsync(messageCacheable.Id); if (iMessage is IUserMessage uMessage) { message = uMessage; } else { return(null); } } return(message); }
public async Task EditMessage(ICommandContext context, ITextChannel chanl, ulong messageId, string text) { var msg = await chanl.GetMessageAsync(messageId); if (!(msg is IUserMessage umsg) || msg.Author.Id != context.Client.CurrentUser.Id) { return; } var rep = new ReplacementBuilder() .WithDefault(context) .Build(); if (CREmbed.TryParse(text, out var crembed)) { rep.Replace(crembed); await umsg.ModifyAsync(x => { x.Embed = crembed.ToEmbed().Build(); x.Content = crembed.PlainText?.SanitizeMentions() ?? ""; }).ConfigureAwait(false); } else { await umsg.ModifyAsync(x => { x.Content = text.SanitizeMentions(); x.Embed = null; }).ConfigureAwait(false); } }
// gallery -> chat reaction transfert private async void UpdateBotMessage(ulong messageId) { // get message by id and channel id ITextChannel galleryChannel = (ITextChannel)_client.GetChannel(galleryId); ITextChannel galleryTalkChannel = (ITextChannel)_client.GetChannel(galleryTalkId); if (galleryTalkChannel is null) { return; } if (!(galleryTalkChannel is ITextChannel)) { return; } IMessage message = await galleryChannel.GetMessageAsync(messageId); // get emote list if (message == null) { return; } var emoteList = message.Reactions; var messageLinkUrl = $"https://discord.com/channels/{serverId}/{galleryId}/{messageId}"; // get 10 message around the timeperiod of the original message from the other channel var messageList = await galleryTalkChannel.GetMessagesAsync(messageId, Direction.After, 10).LastOrDefaultAsync(); IMessage messageToEdit = null; foreach (var item in messageList.Reverse()) { // only tests message with the bot if (item.Author.IsBot == false) { continue; } // if no embed return if (item.Embeds.Count == 0) { continue; } //test if the embed contains if (item.Embeds.First().Description.Contains(messageLinkUrl)) { messageToEdit = item; break; } } // if no message fits returns if (messageToEdit == null) { return; } // edit the message IUserMessage userMessageToEdit = messageToEdit as IUserMessage; await userMessageToEdit.ModifyAsync(messageItem => { messageItem.Content = ""; messageItem.Embed = ModifyFooter(userMessageToEdit.Embeds, emoteList, message.Content, message.Id, message.Author.Id); }); }
private async Task <Option <IUserMessage> > GetStarboardMessage(ulong messageId, ITextChannel starboardChannel) { return(await _cache.TryGetOrSetAndGetAsync( CacheId.GetMessageId(messageId), async() => await starboardChannel.GetMessageAsync(messageId, CacheMode.AllowDownload) .ConfigureAwait(false) as IUserMessage, _postedMsgTtl).ConfigureAwait(false)); }
private static async Task DeleteMessage(DeleteMessageTimerArgs deleteArgs, ITextChannel textChannel) { IMessage message = await textChannel.GetMessageAsync(deleteArgs.MessageId); if (message != null) { await textChannel.DeleteMessagesAsync(new[] { message }); } }
public async Task Delete(ITextChannel channel, int n) { for (int i = 0; i < n; i++) { var msg = await channel.GetMessageAsync(channel.Id); await msg.DeleteAsync(); } }
public async Task CopyMessasge(ITextChannel channel, ulong messageId) { var loadWebhook = webhookLoader.Value; var msg = await channel.GetMessageAsync(messageId) as IUserMessage; var user = msg.Author as IGuildUser; var webHook = await loadWebhook; _ = webHook.SendMessageAsync(msg.Content.Replace("@", "`@`") + "\n" + msg.Attachments.Select(x => x.Url).JoinLines(), false, msg.Embeds.Select(x => x as Embed), user.GetDisplayName(), user.GetAvatarUrl()); }
public static async Task <IUserMessage> SetDiscordUserMessage(ITextChannel channel, ulong msgId, TimeSpan timeout) { var msg = await channel.GetMessageAsync(msgId) as IUserMessage; if (msg == null) { return(null); } Set(DISCORD_USER_MESSAGE + msgId, new Item(msg, DateTime.UtcNow.Add(timeout))); return(msg); }
private async Task InternalMessageAction(ITextChannel channel, ulong messageId, StoopidTime time, Func <IMessage, Task> func) { var userPerms = ((SocketGuildUser)ctx.User).GetPermissions(channel); var botPerms = ((SocketGuild)ctx.Guild).CurrentUser.GetPermissions(channel); if (!userPerms.Has(ChannelPermission.ManageMessages)) { await ReplyErrorLocalizedAsync("insuf_perms_u").ConfigureAwait(false); return; } if (!botPerms.Has(ChannelPermission.ManageMessages)) { await ReplyErrorLocalizedAsync("insuf_perms_i").ConfigureAwait(false); return; } var msg = await channel.GetMessageAsync(messageId).ConfigureAwait(false); if (msg == null) { await ReplyErrorLocalizedAsync("msg_not_found").ConfigureAwait(false); return; } if (time == null) { await msg.DeleteAsync().ConfigureAwait(false); } else if (time.Time <= TimeSpan.FromDays(7)) { var _ = Task.Run(async() => { await Task.Delay(time.Time).ConfigureAwait(false); await msg.DeleteAsync().ConfigureAwait(false); }); } else { await ReplyErrorLocalizedAsync("time_too_long").ConfigureAwait(false); return; } var conf = await ReplyAsync("👌").ConfigureAwait(false); conf.DeleteAfter(3); }
static private async Task <IUserMessage> LocateVoteReply(BotDatabaseContext dbContext, ITextChannel channel, VoteReplyRecord voteReplyRecord) { var voteReply = await channel.GetMessageAsync(voteReplyRecord.ReplyId) as IUserMessage; if (voteReply is null) { dbContext.VoteReplyRecords.Remove(voteReplyRecord); await dbContext.SaveChangesAsync(); } return(voteReply); }
internal async Task Delete(ITextChannel channel, ulong messageId) { var message = await channel.GetMessageAsync(messageId); if (message == null) { Debug.Log("message not found"); return; } await message.DeleteAsync(); await Program.NotificationChannel.SendMessageAsync($"けしたよ:{channel.Id}:{messageId}:{message.ToString()}"); Debug.Log($"delete:{channel.Id}:{messageId}:{message.ToString()}"); }
/// <summary> /// Deletes message in <paramref name="textChannel"/> /// </summary> /// <param name="textChannel"><see cref="ITextChannel"/> where message will be deleted</param> /// <param name="messageID">ID of the message that will be deleted</param> /// <exception cref="NullReferenceException">Thrown when <paramref name="textChannel"/> is <see cref="null"/></exception> public static async Task DeleteMessageAsync(ITextChannel textChannel, ulong messageID) { if (textChannel is null) { throw new NullReferenceException(); } var message = await textChannel.GetMessageAsync(messageID); if (message is null) { return; } await message.DeleteAsync(); }
public async Task Ama(ulong msgId) { ulong channelId = Data.Configuration.AmaChannelID; ITextChannel amaChannel = await Context.Guild.GetTextChannelAsync(channelId); IMessage amaMsg = await amaChannel.GetMessageAsync(msgId); await Context.Message.DeleteAsync(); await new EmbedBuilder() .WithAuthor(amaMsg.Author) .WithUrl(amaMsg.GetJumpUrl()) .WithColor(Color.Purple) .WithDescription(amaMsg.Content) .Build() .SendToChannel(Context.Channel); }
public async Task <IUserMessage> GetStarboardMessageAsync(IUserMessage msg, GuildData guildData = null) { IGuild guild = (msg.Channel as ITextChannel).Guild; if (guildData == null) { guildData = Data.BotData.guildDictionary[guild.Id]; } if (starboardMessageStatus != StarboardMessageStatus.CREATED || starboardMessageId == null) { return(null); } bool isNsfw = (msg.Channel as ITextChannel).IsNsfw; ITextChannel starboardChannel = isNsfw ? await guild.GetTextChannelAsync(guildData.starboardChannelNSFW) : await guild.GetTextChannelAsync(guildData.starboardChannel); return(await starboardChannel.GetMessageAsync(starboardMessageId.Value) as IUserMessage); }
protected async override Task Init() { if (!File.Exists("Files/KeepStar.json")) { string json = JsonConvert.SerializeObject(new KeepStarProgress(), Formatting.Indented); using (StreamWriter writer = File.CreateText("Files/KeepStar.json")) await writer.WriteAsync(json); } ITextChannel channel = await Guild.GetTextChannelAsync(Config.UpdateChannel); if (channel != null && await ExistsAsync("UpdateMessage")) { ulong msgID = await LoadAsync <ulong>("UpdateMessage"); KSMessage = await channel.GetMessageAsync(msgID) as IUserMessage; } else if (channel != null) { KSMessage = await SendToChannel(channel) as IUserMessage; await SaveAsync("UpdateMessage", KSMessage.Id); } }
public async Task <Result> Execute(CommandMetadata data, ulong channelId, ulong messageId) { ITextChannel channel = ParentPlugin.GuildHandler.FindTextChannel(channelId); IMessage message = await channel?.GetMessageAsync(messageId); if (channel == null) { throw new ArgumentException("The channel could not be found."); } if (message == null) { throw new ArgumentException("The message could not be found."); } var karma = ParentPlugin.GetKarma(message.Author.Id); var karmaMessage = karma.GetMessages().FirstOrDefault(x => x.Id == message.Id); if (karmaMessage == null) { throw new ArgumentException("The message given has neither upvotes or downvotes."); } var upvoters = karmaMessage.GetUpvotes().Select(x => ParentPlugin.GuildHandler.FindUser(x)); var downvoters = karmaMessage.GetDownvotes().Select(x => ParentPlugin.GuildHandler.FindUser(x)); string ups = string.Join(", ", upvoters.Select(x => UserToString(x))); string downs = string.Join(", ", downvoters.Select(x => UserToString(x))); string UserToString(IUser user) => user == null ? "*Missing User*" : user.GetShownName(); return(new Result(new EmbedBuilder().WithTitle("Voters of Message") .WithDescription($"> [{message.Content.Replace('\n', ' ')}]({message.GetJumpUrl ()}) - {karmaMessage.ToString()}") .AddField("The following people upvoted the message..", upvoters.Count() == 0 ? "```No one :(```" : $"```{ups}```") .AddField("The following people downvoted the message..", downvoters.Count() == 0 ? "```No one! :)```" : $"```{downs}```") .Build(), string.Empty)); }
public async Task <IUserMessage> TryGetMessage(Cacheable <IUserMessage, ulong> messageCacheable, ITextChannel channel, SocketReaction reaction) { IUserMessage message; if (messageCacheable.HasValue) { message = messageCacheable.Value; } else { var iMessage = await channel.GetMessageAsync(messageCacheable.Id); if (iMessage is IUserMessage uMessage) { message = uMessage; } else { return(null); } } return(message); }
// chat -> gallery reaction transfert private async void AddreactionToGallery(ulong messageId) { ITextChannel galleryChannel = (ITextChannel)_client.GetChannel(galleryId); ITextChannel galleryTalkChannel = (ITextChannel)_client.GetChannel(galleryTalkId); // verify neither of the channel aren't null if (galleryChannel is null || galleryTalkChannel is null) { return; } if (!(galleryChannel is ITextChannel) || !(galleryTalkChannel is ITextChannel)) { return; } // get original message IMessage message; message = await galleryTalkChannel.GetMessageAsync(messageId); // get message ID var reactionList = message.Reactions; if (message.Embeds.Count == 0) { return; } string oldDescription = message.Embeds.First().Description; oldDescription = GetAllUrlFromString(oldDescription).First(); oldDescription = oldDescription.Remove(0, 29); oldDescription = oldDescription.Remove(0, GetUntilOrEmpty(oldDescription, '/').Length + 1); oldDescription = oldDescription.Remove(0, GetUntilOrEmpty(oldDescription, '/').Length + 1); ulong newMessageId = Convert.ToUInt64(oldDescription); // get original message IMessage originalMessage = await galleryChannel.GetMessageAsync(newMessageId); // edit the message IUserMessage userMessageToEdit = originalMessage as IUserMessage; // react with the emote if it's not on the message already foreach (var reaction in reactionList) { Console.WriteLine($"Emote to add: {reaction.Key}"); try { await userMessageToEdit.AddReactionAsync(reaction.Key); } catch (Exception error) { Console.WriteLine("error: " + error.Source); } } // remove the react if it's on the message and not in the reaction list foreach (var reaction in userMessageToEdit.Reactions) { // skip the sent message if it's already on the message if (reactionList.ContainsKey(reaction.Key)) { continue; } // remove the emote if it's on the message but not on the list Console.WriteLine($"Emote to remove: {reaction.Key}"); await userMessageToEdit.RemoveReactionAsync(reaction.Key, botId); } }
public async Task Quote(params string[] id) { Utilities.CheckAvailability(Context.Guild.Id, Program.Module.Communication); await p.DoAction(Context.User, Context.Guild.Id, Program.Module.Communication); IUser author = (id.Length == 0) ? (null) : (await Utilities.GetUser(string.Join("", id), Context.Guild)); if (id.Length == 0 || author != null) { if (author == null) { author = Context.User; } IMessage msg = (await Context.Channel.GetMessagesAsync().FlattenAsync()).Skip(1).ToList().Find(x => x.Author.Id == author.Id); if (msg == null) { await ReplyAsync(Sentences.QuoteNoMessage(Context.Guild.Id)); } else { await ReplyAsync("", false, new EmbedBuilder() { Description = msg.Content }.WithAuthor(msg.Author.ToString(), msg.Author.GetAvatarUrl()).WithFooter("The " + msg.CreatedAt.ToString(Base.Sentences.DateHourFormat(Context.Guild.Id)) + " in " + msg.Channel.Name).Build()); } } else { IMessage msg = null; Match url = Regex.Match(id[0], "https:\\/\\/discordapp.com\\/channels\\/" + Context.Guild.Id + "\\/([0-9]{18})\\/([0-9]{18})"); if (url.Success) { ulong idChan, idMsg; if (ulong.TryParse(url.Groups[1].Value, out idChan) && ulong.TryParse(url.Groups[2].Value, out idMsg)) { msg = await(await Context.Guild.GetTextChannelAsync(idChan))?.GetMessageAsync(idMsg); } } else { ulong uId; try { uId = Convert.ToUInt64(id[0]); } catch (FormatException) { await ReplyAsync(Sentences.QuoteInvalidId(Context.Guild.Id)); return; } catch (OverflowException) { await ReplyAsync(Sentences.QuoteInvalidId(Context.Guild.Id)); return; } msg = await Context.Channel.GetMessageAsync(uId); if (msg == null) { foreach (IGuildChannel chan in await Context.Guild.GetChannelsAsync()) { try { ITextChannel textChan = chan as ITextChannel; if (textChan == null) { continue; } msg = await textChan.GetMessageAsync(uId); if (msg != null) { break; } } catch (HttpException) { } } } } if (msg == null) { await ReplyAsync(Sentences.QuoteInvalidId(Context.Guild.Id)); } else { await ReplyAsync("", false, new EmbedBuilder() { Description = msg.Content }.WithAuthor(msg.Author.ToString(), msg.Author.GetAvatarUrl()).WithFooter("The " + msg.CreatedAt.ToString(Base.Sentences.DateHourFormat(Context.Guild.Id)) + " in " + msg.Channel.Name).Build()); } } }
public async Task RawMessage(ITextChannel channel, ulong messageId) { var msg = await channel.GetMessageAsync(messageId); await ReplyAsync(Format.Sanitize(msg.Content.SliceBack(2000 - 7)).MarkdownCodeBlock()); }
private static Task <IMessage> GetMessageInChannel(ulong messageId, ITextChannel channel) => channel.GetMessageAsync(messageId);
public async Task ManageMultiRoleAsync(int Id = 0, string Option = null, string Value = null) { List <MultiRoleEntry> entries = Global.MultiRoleHandler.Entries.Where(t => t.GuildId == Context.Guild.Id).ToList(); MultiRoleEntry entry = null; EmbedBuilder b = new EmbedBuilder() { Title = GetEntry("Title"), Color = Color.Green, Description = "" }; bool paginate = false; if (entries.Count == 0) { b.Description = GetEntry("NoMultiRole"); } else if (Id < 1 || Id > entries.Count) { int limit = Math.Min(entries.Count, 10); int pages = entries.Count / 10 + 1; for (int i = 0; i < limit; i++) { entry = entries[i]; b.Description += GetEntry("Row", "ID", (i + 1).ToString(), "CM", $"<#{ entry.ChannelId }>", "MID", entry.MessageId.ToString()); } b.Footer = new EmbedFooterBuilder() { Text = GetEntry("Page", "C", "1", "M", pages.ToString()) }; if (pages > 1) { paginate = true; } } else if (Option == null) { entry = entries[Id - 1]; string content, roles, options; ITextChannel ch = await Context.Guild.GetTextChannelAsync(entry.ChannelId); if (ch != null) { IMessage message = await ch.GetMessageAsync(entry.MessageId); if (message != null) { content = message.Content; roles = string.Join("\n", entry.EmoteRolePairs.Select(t => $"{ t.Key } - <@{ t.Value }>")); options = $"OnlyOne: { entry.OnlyOne }"; } else { content = GetEntry("ChannelRemoved"); roles = content; options = content; } } else { content = GetEntry("ChannelRemoved"); roles = content; options = content; } b.AddField(GetEntry("ContentFieldTitle"), content); b.AddField(GetEntry("RoleFieldTitle"), roles); b.AddField(GetEntry("OptionsFieldTitle"), options); } else { entry = entries[Id - 1]; string exclude = "GuildId;ChannelId;MessageId;EmoteRolePairs"; PropertyInfo[] infos = typeof(MultiRoleEntry).GetProperties(BindingFlags.Public | BindingFlags.Instance); PropertyInfo info = infos.First(t => t.Name.ToLower() == Option.ToLower() && !exclude.Contains(t.Name)); if (info == null) { b.Description = GetEntry("OptionNotFound"); } else if (Value == null) { b.Description = GetEntry("OptionValue", "O", info.Name, "V", info.GetValue(entry).ToString()); } else { Type pType = info.PropertyType; switch (pType.Name) { case "Boolean": bool?boolVal = null; switch (Value.ToLower()) { case "true": case "1": boolVal = true; break; case "false": case "0": boolVal = false; break; } if (boolVal == null) { b.Description = GetEntry("IncorrectValue"); } else { info.SetValue(entries[Id - 1], boolVal.Value); b.Description = GetEntry("OptionChanged"); Global.MultiRoleHandler.Save(); } break; } } } IUserMessage msg = await ReplyAsync("", false, b.Build()); if (paginate) { //await msg.AddReactionsAsync(new Emoji[2] { new Emoji("◀️"), new Emoji("▶️") }); } }
public async Task Command(ulong messageId, ITextChannel channel, string emote, IRole role, params string[] args) { IMessage message = await channel.GetMessageAsync(messageId); IEmote emoteRes; if (Emote.TryParse(emote, out Emote result)) { emoteRes = result; } else { emoteRes = new Emoji(emote); } var emoteRolePair = new Dictionary <IEmote, IRole> { { emoteRes, role } }; if (args.Any()) { // If there aren't an even amount of args, we know the user messed up. if ((args.Length % 2) != 0) { throw new KaguyaSupportException("There were an invalid amount of additional arguments provided. " + "Note that for each additional entry, there must be an " + "emote followed by a role."); } var emoteRolePairs = new string[args.Length / 2][]; int count = 0; for (int i = 0; i < args.Length; i += 2) { var rolePair = new string[2]; rolePair[0] = args[i]; rolePair[1] = args[i + 1]; emoteRolePairs[count] = rolePair; count++; } foreach (string[] pair in emoteRolePairs) { string emoteText = pair[0]; string roleText = pair[1]; bool validEmote = false; bool validRole = false; if (Emote.TryParse(emoteText, out Emote emoteResult) || pair[1].GetType() == typeof(Emoji)) { validEmote = true; } IRole roleResult = Context.Guild.Roles.FirstOrDefault(x => x.Name.ToLower() == roleText.ToLower()); if (roleResult != null) { validRole = true; } if (validEmote == false) { throw new KaguyaSupportException("Failed to parse a valid emote from the provided " + $"input: Emote: '{emoteText}'\n\n" + $"Note that the emote must be from this server only and " + $"cannot be a standard emoji."); } if (validRole == false) { throw new KaguyaSupportException("Failed to parse a valid role from the provided " + $"input: Role: '{roleText}'"); } emoteRolePair.Add(emoteResult, Context.Guild.GetRole(roleResult.Id)); } } if (message == null) { throw new KaguyaSupportException("The message with this ID could not be found in the specified channel. " + "You must specify the 'channel' argument for this command if you are " + "executing the command from another channel. \n\n" + $"Example: '{{prefix}}crr {messageId} {{#some-channel}} ...'"); } var cacheToSend = new List <ReactionRole>(emoteRolePair.Count); int cacheListIndex = 0; var respSb = new StringBuilder(); foreach (KeyValuePair <IEmote, IRole> pair in emoteRolePair) { bool isEmoji = false; IEmote pEmote = pair.Key; IRole pRole = pair.Value; ReactionRole rr; if (pEmote is Emote customEmote) { rr = new ReactionRole { EmoteNameorId = customEmote.Id.ToString(), MessageId = message.Id, RoleId = pRole.Id, ServerId = Context.Guild.Id }; } else if (pEmote is Emoji standardEmoji) { rr = new ReactionRole { EmoteNameorId = standardEmoji.Name, MessageId = message.Id, RoleId = pRole.Id, ServerId = Context.Guild.Id }; isEmoji = true; } else { throw new KaguyaSupportException("The reaction role isn't an Emoji or Emote!!"); } if (pRole.IsManaged) { throw new KaguyaSupportException($"Role '{pRole.Name}' is managed by an integration or a bot. It may not be " + "assigned to users. Therefore, they may not be assigned to " + "reaction roles either."); } ReactionRole possibleMatch; if (isEmoji) { possibleMatch = await DatabaseQueries.GetFirstMatchAsync <ReactionRole>(x => x.EmoteNameorId == pEmote.Name && x.RoleId == pRole.Id && x.MessageId == rr.MessageId); } else { possibleMatch = await DatabaseQueries.GetFirstMatchAsync <ReactionRole>(x => x.EmoteNameorId == (pEmote as Emote).Id.ToString() && x.RoleId == pRole.Id && x.MessageId == rr.MessageId); } IReadOnlyDictionary <IEmote, ReactionMetadata> messageReactions = message.Reactions; // If the reaction is in the database, and Kaguya has a emote-role pair for this emote, throw an error. if (possibleMatch != null && messageReactions.Keys.Contains(pEmote) && messageReactions.GetValueOrDefault(pEmote).IsMe) { throw new KaguyaSupportException($"The emote '{emote}' has already been assigned to role {role} " + "as a reaction role."); } try { await message.AddReactionAsync(pEmote); await DatabaseQueries.InsertAsync(rr); cacheToSend.Insert(cacheListIndex, rr); respSb.AppendLine($"Successfully linked {pEmote} to {pRole.Mention}"); } catch (Discord.Net.HttpException e) { if (e.HttpCode == HttpStatusCode.BadRequest) { throw new KaguyaSupportException($"An error occurred when attempting to make the reaction role " + $"for the '{pEmote.Name}' emote. This error occurs when Discord " + $"doesn't know how to process an emote. This can happen if you " + $"copy/paste the emote into the Discord text box instead of " + $"manually typing out the emote yourself. Discord is really " + $"finnicky when it comes to emotes."); } throw new KaguyaSupportException($"An unknown error occurred.\n\n" + $"Exception Message: {e.Message}\nInner Exception: {e.InnerException}"); } catch (Exception) { throw new KaguyaSupportException("An error occurred when inserting the reaction role " + "into the database.\n\n" + $"Emote: {pEmote}\n" + $"Role: {pRole}"); } } var embed = new KaguyaEmbedBuilder(EmbedColor.YELLOW) { Title = "Kaguya Reaction Roles", Description = respSb.ToString() }; UpdatedCache?.Invoke(cacheToSend); await SendEmbedAsync(embed); }
public async Task EndPollAsync(string idOrUrl, [Remainder] string message = "") { Match idMatch = Regex.Match(idOrUrl, @"^(?:https?://(?:www\.)?discord(?:app)?\.com(?:/channels)/\d+/\d+/)?(\d+)$"); if (idMatch.Success) { var id = Convert.ToUInt64(idMatch.Groups[1].Value); PollInfo info; try { info = await GetPollInfoForMessage(id); } catch { await ReplyAsync($"Die angegebene Nachricht ist kein Poll!"); return; } if (info.IsEnded) { var errmsg = await ReplyAsync("Der Poll wurde schon beendet!"); //await Task.Delay(3000); //await base.Context.Message.DeleteAsync(); //await errmsg.DeleteAsync(); return; } ITextChannel channel = (ITextChannel)await base.Context.Guild.GetChannelAsync(info.ChannelId); if (channel == null) { var errmsg = await ReplyAsync("Der Kanal des Polls wurde nicht gefunden! Vielleicht hast du ihn schon gelöscht!"); //await Task.Delay(3000); //await base.Context.Message.DeleteAsync(); //await errmsg.DeleteAsync(); return; } IUserMessage msg = (IUserMessage)await channel.GetMessageAsync(id); if (msg == null) { var errmsg = await ReplyAsync("Der Poll wurde nicht gefunden! Vielleicht hast du ihn schon gelöscht!"); //await Task.Delay(3000); //await base.Context.Message.DeleteAsync(); //await errmsg.DeleteAsync(); return; } StringBuilder votes = new StringBuilder(); var voteList = msg.Reactions; foreach (OptionEmojiPair option in info.Options) { Emoji emoji = new Emoji(option.Emoji); int voteCount = voteList[emoji].ReactionCount - 1; option.Result = voteCount; votes.AppendLine($"{option.Emoji} - {option.Option}: {voteCount} Stimme{(voteCount == 1 ? "" : "n")}\n"); } info.ResultText = message; info.IsEnded = true; await UpdateDb(info); EmbedBuilder emb = new EmbedBuilder() .WithColor(Color.DarkRed) .WithTitle($"Auswertung | {info.Title}") .WithFooter(footer => footer.Text = $"{_prefix}poll") .WithCurrentTimestamp() .AddField("Voteergebnis:", $"{votes}\n{message}"); //await base.Context.Message.DeleteAsync(); await msg.ModifyAsync(msg => msg.Embed = emb.Build()); } else { var err = await ReplyAsync("Bitte gib eine gültige ID oder Url an!"); //await Task.Delay(3000); //await base.Context.Message.DeleteAsync(); //await err.DeleteAsync(); } }
protected override async Task <bool> PostServerInfoAsync(GameServer discordGameServer) { if (discordGameServer == null) { return(false); } ServerQuery serverQuery = null; try { using var udpClient = new UdpWrapper(); serverQuery = new ServerQuery(udpClient, null); serverQuery.Connect(discordGameServer.ServerIP.ToString()); ServerInfo serverInfo = await serverQuery.GetServerInfoAsync().ConfigureAwait(false); List <Player> players = (await serverQuery.GetPlayersAsync().ConfigureAwait(false)).Where(p => !p.Name.IsEmptyOrWhiteSpace()).ToList(); if (serverInfo == null || players == null) { return(false); } SocketGuild guild = discordClient?.GetGuild(discordGameServer.GuildID); ITextChannel channel = guild?.GetTextChannel(discordGameServer.ChannelID); if (guild == null || channel == null) { return(false); } string onlinePlayers = players.Count > serverInfo.MaxPlayers ? $"{serverInfo.MaxPlayers}(+{players.Count - serverInfo.MaxPlayers})/{serverInfo.MaxPlayers}" : $"{players.Count}/{serverInfo.MaxPlayers}"; var builder = new EmbedBuilder() .WithColor(new Color(21, 26, 35)) .WithTitle($"{serverInfo.Game} Server ({discordGameServer.ServerIP.Address}:{serverInfo.Port})") .WithDescription(serverInfo.Name) .AddField("Online Players", onlinePlayers) .AddField("Current Map", serverInfo.Map); if (players != null && players.Count > 0) { _ = builder.AddField("Currently connected players:", string.Join(", ", players.Select(x => x.Name).Where(name => !name.IsEmpty()).OrderBy(x => x)).TruncateTo(1023)); } //Discord removed support for protocols other than http or https so this currently makes no sense. Leaving it here, in case they re-enable it //string connectLink = $"steam://connect/{discordGameServer.ServerIP.Address}:{serverInfo.Port}"; //_ = builder.AddField("Connect using this link", connectLink); if (discordGameServer.GameVersion.IsEmpty()) { discordGameServer.GameVersion = serverInfo.Version; _ = dbContext.GameServers.Update(discordGameServer); _ = await dbContext.SaveChangesAsync().ConfigureAwait(false); } else { if (serverInfo.Version != discordGameServer.GameVersion) { discordGameServer.GameVersion = serverInfo.Version; discordGameServer.LastVersionUpdate = DateTime.Now; _ = dbContext.GameServers.Update(discordGameServer); _ = await dbContext.SaveChangesAsync().ConfigureAwait(false); } } string lastServerUpdate = ""; if (discordGameServer.LastVersionUpdate.HasValue) { lastServerUpdate = $" (Last update: {discordGameServer.LastVersionUpdate.Value})"; } _ = builder.AddField("Server version", $"{serverInfo.Version}{lastServerUpdate}"); _ = builder.WithFooter($"Last check: {DateTime.Now}"); string chart = await GenerateHistoryChartAsync(discordGameServer, serverInfo.Players, serverInfo.MaxPlayers).ConfigureAwait(false); if (!chart.IsEmptyOrWhiteSpace()) { _ = builder.AddField("Player Count History", chart); } if (discordGameServer.MessageID.HasValue) { if (await channel.GetMessageAsync(discordGameServer.MessageID.Value).ConfigureAwait(false) is IUserMessage existingMessage && existingMessage != null) { await existingMessage.ModifyAsync(x => x.Embed = builder.Build()).ConfigureAwait(false); } else { logger.LogWarning($"Error getting updates for server {discordGameServer.ServerIP}. Original message was removed."); await RemoveServerAsync(discordGameServer.ServerIP, discordGameServer.GuildID).ConfigureAwait(false); _ = await channel.SendMessageAsync($"Error getting updates for server {discordGameServer.ServerIP}. Original message was removed. Please use the proper remove command to remove the gameserver").ConfigureAwait(false); return(false); } } else { discordGameServer.MessageID = (await(channel?.SendMessageAsync("", false, builder.Build())).ConfigureAwait(false)).Id; _ = dbContext.GameServers.Update(discordGameServer); _ = await dbContext.SaveChangesAsync().ConfigureAwait(false); } }
static Build() { // Check for a link update message Ditto.Connected += async() => { Link link = null; await Ditto.Database.DoAsync(uow => { link = uow.Links.Get(l => l.Type == Database.Data.LinkType.Update); }, false).ConfigureAwait(false); if (link != null) { if (!string.IsNullOrEmpty(link.Value)) { var values = link.Value.Split("|", StringSplitOptions.RemoveEmptyEntries); var commitHash = values.LastOrDefault(); if (!string.IsNullOrEmpty(commitHash) && ulong.TryParse(values.FirstOrDefault(), out ulong messageId)) { IMessage message = null; IGuild guild = null; ITextChannel channel = null; await Ditto.Client.DoAsync(async client => { guild = client.GetGuild(link.GuildId); channel = await guild.GetTextChannelAsync(link.ChannelId).ConfigureAwait(false); message = await channel.GetMessageAsync(messageId, options: new RequestOptions() { RetryMode = RetryMode.RetryRatelimit }).ConfigureAwait(false); if (message != null) { await message.SetResultAsync(CommandResult.Success).ConfigureAwait(false); } // Post build info in a secondary task try { var _ = new Build() { Context = new CommandContextEx(client, message as IUserMessage) { Channel = channel, Guild = guild } }.Info(); //commitHash } catch (Exception ex) { Log.Error(ex); } // Remove link await Ditto.Database.DoAsync(uow => { uow.Links.Remove(link); }, true).ConfigureAwait(false); }).ConfigureAwait(false); } } } }; }