Beispiel #1
0
        public override async Task BuildEmbedsAsync(List <Embed> embeds, IUserMessage msg, SocketReaction reaction)
        {
            foreach (Match match in this.Matches(msg.Content))
            {
                ulong guildId   = ulong.Parse(match.Groups[1].Value);
                ulong channelId = ulong.Parse(match.Groups[2].Value);
                ulong msgId     = ulong.Parse(match.Groups[3].Value);

                SocketGuild       guild    = this.DiscordClient.GetGuild(guildId);
                SocketTextChannel textChan = guild?.GetTextChannel(channelId);
                if (textChan == null)
                {
                    continue;
                }

                IMessage quotedMsg = await textChan.GetMessageAsync(msgId);

                if (quotedMsg == null)
                {
                    continue;
                }

                EmbedBuilder builder = new EmbedBuilder();
                builder
                .WithAuthorNickname(quotedMsg)
                .WithLimitedDescription(string.IsNullOrWhiteSpace(quotedMsg.Content) ? "Empty message." : quotedMsg.Content)
                .WithTimestamp(quotedMsg.Timestamp)
                .WithField("Quoted by", $"{reaction.User.Value.Mention} from [**#{quotedMsg.Channel.Name}**]({match.Value})", false);
                embeds.Add(builder.Build());
            }
        }
        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);
        }
Beispiel #3
0
        private static async Task CheckRuns(SocketGuild guild, ulong channelId, int minutesBefore, Func <SocketGuildUser, IMessage, IEmbed, Task> onMatch, CancellationToken token)
        {
            var channel = guild?.GetTextChannel(channelId);

            if (channel == null)
            {
                await Task.Delay(3000, token);

                return;
            }

            await foreach (var page in channel.GetMessagesAsync().WithCancellation(token))
            {
                foreach (var message in page)
                {
                    var embed = message.Embeds.FirstOrDefault(e => e.Type == EmbedType.Rich);

                    var nullableTimestamp = embed?.Timestamp;
                    if (!nullableTimestamp.HasValue)
                    {
                        continue;
                    }

                    var timestamp = nullableTimestamp.Value;

                    // ReSharper disable once InvertIf
                    if (timestamp.AddMinutes(-minutesBefore) <= DateTimeOffset.Now && timestamp.AddMinutes(-minutesBefore + 4.95) > DateTimeOffset.Now && embed.Author.HasValue)
                    {
                        Log.Information("Run matched!");

                        var host = guild.Users.FirstOrDefault(u => u.ToString() == embed.Author.Value.Name);
                        if (host == null)
                        {
                            host = guild.Users.FirstOrDefault(u => u.ToString() == embed.Author.Value.Name);
                        }

                        var messageReferenceCopy = message;
                        try
                        {
                            await onMatch(host, messageReferenceCopy, embed);
                        }
                        catch (Exception e)
                        {
                            Log.Error(e, "error: uncaught exception in onMatch");
                        }
                    }
                }
            }
        }
Beispiel #4
0
        private async Task CheckRuns(SocketGuild guild, ulong channelId, double queueTimeSeconds, Func <SocketGuildUser, IMessage, IEmbed, Task> onMatch, CancellationToken token)
        {
            var channel = guild?.GetTextChannel(channelId);

            if (channel == null)
            {
                await Task.Delay(3000, token);

                return;
            }

            await foreach (var page in channel.GetMessagesAsync().WithCancellation(token))
            {
                foreach (var message in page)
                {
                    var embed = message.Embeds.FirstOrDefault(e => e.Type == EmbedType.Rich);

                    var nullableTimestamp = embed?.Timestamp;
                    if (!nullableTimestamp.HasValue)
                    {
                        continue;
                    }

                    var timestamp = nullableTimestamp.Value;

                    // Remove expired posts
                    if (timestamp.AddMinutes(60) < DateTimeOffset.Now)
                    {
                        await message.DeleteAsync();

                        continue;
                    }

#if DEBUG
                    if (queueTimeSeconds > 0 && timestamp.AddSeconds(queueTimeSeconds) <= DateTimeOffset.Now && embed.Author.HasValue)
                    {
                        var eventId  = ulong.Parse(embed.Footer?.Text ?? "0");
                        var toNotify = _db.EventReactions
                                       .Where(er => er.EventId == eventId)
                                       .Where(er => !er.QueueOpenNotified);
                        await foreach (var er in toNotify.WithCancellation(token))
                        {
                            var member = guild.GetUser(er.UserId);
                            _ = member.SendMessageAsync($"The event you signed up for notifications on `(ID: {eventId})` is now open for queuing.\n" +
                                                        "If the run host has declared that they are pulling from the queue, you can join the queue by " +
                                                        "clicking on the appropriate role reaction on the event post.");
                            er.QueueOpenNotified = true;
                            await _db.UpdateEventReaction(er);
                        }
                    }
#endif

                    // ReSharper disable once InvertIf
                    if (timestamp.AddMinutes(-30) <= DateTimeOffset.Now && embed.Author.HasValue)
                    {
                        Log.Information("Run matched!");

                        var host = guild.Users.FirstOrDefault(u => u.ToString() == embed.Author.Value.Name);
                        if (host == null)
                        {
                            await guild.DownloadUsersAsync();

                            host = guild.Users.FirstOrDefault(u => u.ToString() == embed.Author.Value.Name);
                        }

                        var messageReferenceCopy = message;
                        try
                        {
                            await onMatch(host, messageReferenceCopy, embed);
                        }
                        catch (Exception e)
                        {
                            Log.Error(e, "error: uncaught exception in onMatch");
                        }
                    }
                }
            }
        }
Beispiel #5
0
        private async Task GetFeedUpdateAsync(Models.Feed guildFeed, bool getLatest = false)
        {
            SocketGuild       guild   = discordClient.GetGuild(guildFeed.GuildID);
            SocketTextChannel channel = guild?.GetTextChannel(guildFeed.ChannelID);

            if (guild == null || channel == null || guildFeed.URL.IsEmpty())
            {
                return;
            }
            Feed feed;

            try
            {
                feed = await FeedReader.ReadAsync(guildFeed.URL).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                logger.LogWarning(ex, $"Error getting feeds for {guildFeed.URL} in {guild.Name}:{channel.Name}");
                return;
            }
            if (feed == null || feed.Items == null || feed.Items.Count < 1)
            {
                return;
            }

            DateTime lastUpdateUTC              = guildFeed.LastUpdate ?? DateTime.UtcNow.Subtract(TimeSpan.FromMinutes(updateIntervallMinutes));
            IEnumerable <FeedItem> allFeeds     = feed?.Items?.Where(x => x.PublishingDate.HasValue);
            List <FeedItem>        updatedFeeds = allFeeds?.Where(x => x.PublishingDate.Value.ToUniversalTime() > lastUpdateUTC)
                                                  .OrderBy(x => x.PublishingDate)
                                                  .ToList();

            if (updatedFeeds != null && updatedFeeds.Count == 0 && getLatest)
            {
                updatedFeeds = allFeeds.Take(1).ToList();
            }
            if (updatedFeeds != null && updatedFeeds.Count > 0)
            {
                var builder = new EmbedBuilder();
                _ = builder.WithColor(new Color(21, 26, 35));
                if (!feed.ImageUrl.IsEmpty())
                {
                    _ = builder.WithImageUrl(feed.ImageUrl);
                }
                _ = builder.WithTitle($"New update{(updatedFeeds.Count > 1 ? "s" : "")} for \"{guildFeed.Name}".TruncateTo(255, "") + "\"");
                DateTime latestUpdateUTC = DateTime.MinValue;
                foreach (FeedItem feedItem in updatedFeeds)
                {
                    if (feedItem.PublishingDate.HasValue && feedItem.PublishingDate.Value.ToUniversalTime() > latestUpdateUTC)
                    {
                        latestUpdateUTC = feedItem.PublishingDate.Value.ToUniversalTime();
                    }
                    string fieldName = feedItem.PublishingDate.HasValue
                        ? feedItem.PublishingDate.Value.ToLocalTime().ToString()
                        : DateTime.Now.ToString();
                    string author = feedItem.Author;
                    if (author.IsEmpty())
                    {
                        if (feed.Type == FeedType.Rss_1_0)
                        {
                            author = (feedItem.SpecificItem as Rss10FeedItem)?.DC?.Creator;
                        }
                        else if (feed.Type == FeedType.Rss_2_0)
                        {
                            author = (feedItem.SpecificItem as Rss20FeedItem)?.DC?.Creator;
                        }
                    }
                    author = !author.IsEmptyOrWhiteSpace() ? $"{author.Trim()}: " : string.Empty;
                    string maskedLink = $"[{author}{ParseHtml(feedItem.Title).Trim()}]({feedItem.Link})";
                    string content    = ParseHtml(feedItem.Description).Trim();
                    if (content.IsEmptyOrWhiteSpace())
                    {
                        content = ParseHtml(feedItem.Content).Trim();
                    }
                    content = content.IsEmptyOrWhiteSpace() ? "[...]" : content.TruncateTo(250, "");
                    string fieldContent = $"{maskedLink}{Environment.NewLine}*{content}".TruncateTo(1023, "") + "*"; // Embed field value must be <= 1024 characters
                    _ = builder.AddField(fieldName, fieldContent, true);
                }
                _ = await(channel?.SendMessageAsync("", false, builder.Build())).ConfigureAwait(false);
                if (latestUpdateUTC > DateTime.MinValue)
                {
                    guildFeed.LastUpdate = latestUpdateUTC;
                    _ = dbContext.Feeds.Update(guildFeed);
                    _ = await dbContext.SaveChangesAsync().ConfigureAwait(false);
                }
            }
        }
        protected override async Task <bool> PostServerInfoAsync(GameServer discordGameServer)
        {
            if (discordGameServer == null)
            {
                return(false);
            }
            MineQuery query = null;

            try
            {
                query = new MineQuery(discordGameServer.ServerIP.Address, discordGameServer.ServerIP.Port, logger);
                MineQueryResult serverInfo = await query.GetServerInfoAsync().ConfigureAwait(false);

                if (serverInfo == null)
                {
                    return(false);
                }
                SocketGuild       guild   = discordClient?.GetGuild(discordGameServer.GuildID);
                SocketTextChannel channel = guild?.GetTextChannel(discordGameServer.ChannelID);
                if (guild == null || channel == null)
                {
                    return(false);
                }
                EmbedBuilder builder = new EmbedBuilder()
                                       .WithColor(new Color(21, 26, 35))
                                       .WithTitle($"Minecraft Server ({discordGameServer.ServerIP.Address}:{discordGameServer.ServerIP.Port})")
                                       .WithDescription($"Motd: {serverInfo.Description.Motd}");

                _ = serverInfo.Players.Sample != null && serverInfo.Players.Sample.Count > 0
                    ? builder.AddField($"Online Players ({serverInfo.Players.Online}/{serverInfo.Players.Max})", string.Join(", ", serverInfo.Players.Sample.Select(x => x.Name)))
                    : builder.AddField("Online Players", $"{serverInfo.Players.Online}/{serverInfo.Players.Max}");

                if (discordGameServer.GameVersion.IsEmpty())
                {
                    discordGameServer.GameVersion = serverInfo.Version.Name;
                    _ = dbContext.GameServers.Update(discordGameServer);
                    _ = await dbContext.SaveChangesAsync().ConfigureAwait(false);
                }
                else
                {
                    if (serverInfo.Version.Name != discordGameServer.GameVersion)
                    {
                        discordGameServer.GameVersion       = serverInfo.Version.Name;
                        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.WithFooter($"Server version: {serverInfo.Version.Name}{lastServerUpdate} || Last check: {DateTime.Now}");

                // Generate chart every full 10 minutes
                if (DateTime.Now.Minute % 10 == 0)
                {
                    string chart = await GenerateHistoryChartAsync(discordGameServer, serverInfo.Players.Online, serverInfo.Players.Max).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
                {
                    IUserMessage message = await(channel?.SendMessageAsync("", false, builder.Build())).ConfigureAwait(false);
                    discordGameServer.MessageID = message.Id;
                    _ = dbContext.GameServers.Update(discordGameServer);
                    _ = await dbContext.SaveChangesAsync().ConfigureAwait(false);
                }
            }
        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);
                }
            }
Beispiel #8
0
        public async Task SavelinksAsync([Summary("The message link to quote")] string link, [Summary("The qauntities of link to save")] int quantity)
        {
            // Initializes the control boolean
            bool success = false;

            // Remove the message base part and splits all the IDs into an array
            string[] stringIDs = link.Replace(MessageBaseLink, "").Split('/');

            // Creates a new array to hold the IDs
            ulong[] ids = new ulong[3];

            // Parses all the IDs from strings to unsigned longs and saves the result into the array, also it stores the successes or failures into the boolean
            for (int i = 0; i < 3; i++)
            {
                success = UInt64.TryParse(stringIDs[i], out ids[i]);
            }

            // If the parse fails, delete the original user command message
            if (!success)
            {
                await Context.Message.DeleteAsync();

                await Ageha.Log(LogSeverity.Error, "Could not parse some ID");

                return;
            }

            // Free up memory
            stringIDs = null;

            // Tries to get the guild from the ID
            SocketGuild sourceGuild = Context.Client.GetGuild(ids[0]);

            // If the guild is null, reply to the user
            if (sourceGuild == null)
            {
                await ReplyAsync("I'm not in the linked server");

                return;
            }

            // Tries to get the channel from the ID
            SocketTextChannel sourceChannel = sourceGuild?.GetTextChannel(ids[1]);

            // If the channel is null, reply to the user
            if (sourceChannel == null)
            {
                await ReplyAsync("I can't view the linked channel");

                return;
            }

            // Tries to get the message from the ID
            IMessage linkedMessage = sourceChannel?.GetMessageAsync(ids[2]).Result;

            // If the message is null, reply to the user
            if (linkedMessage == null)
            {
                await ReplyAsync("The linked message doesn't exist");

                return;
            }

            // Free up some memory
            ids = null;

            // Gets the cached messages
            var cachedMessages = await sourceChannel.GetMessagesAsync(linkedMessage, Direction.Before, quantity).FlattenAsync();

            // Puts the linked message in the list
            cachedMessages.Append(linkedMessage);

            // Reverses the list to be in chronological order
            cachedMessages.Reverse();

            // Sends the quantity of found messages in the channel
            await ReplyAsync($"Found {cachedMessages.Count()} links.");

            // Creates an empty dictionary and a counter
            Dictionary <int, string> links = new Dictionary <int, string>();
            int counter = 0;

            // Only proceeds if any messages are found
            if (cachedMessages != null || cachedMessages.Count() > 0)
            {
                // Creates a valid file name to save the links
                string fileName = $"{MakeValidFileName(sourceGuild.Name)}_{MakeValidFileName(sourceChannel.Name)}_{linkedMessage.Id}.json";

                // Iterates over all messages found
                foreach (IMessage message in cachedMessages)
                {
                    // Only tries to pick emotes if the message isn't empty
                    if (!String.IsNullOrWhiteSpace(message.Content))
                    {
                        // Iterates over all tags
                        foreach (ITag tag in message.Tags)
                        {
                            // Only procceeds on emote tags
                            if (tag.Type == TagType.Emoji)
                            {
                                // Adds the emote link and updates the counter
                                links.Add(counter++, Emote.Parse($"<:{(tag.Value as Emote).Name}:{tag.Key.ToString()}>").Url);
                            }
                        }
                    }

                    // Checks to seed if there are any embeds
                    if (message.Embeds.Count > 0)
                    {
                        GetEmbeds(message.Embeds, ref links, ref counter);
                    }

                    // Checks to seed if there are any attachments
                    if (message.Attachments.Count > 0)
                    {
                        GetAttachments(message.Attachments, ref links, ref counter);
                    }
                }

                // Writes the json on a file
                JsonWrapper.WriteJSON <int, string>(fileName, links);

                // Sends the json back in the channel
                await Context.Channel.SendFileAsync(fileName, $"Here is the json containing {cachedMessages.Count()} links from before the message : {linkedMessage.GetJumpUrl()}");

                // Deletes the original file
                File.Delete(fileName);
            }
        }
Beispiel #9
0
        private static async Task CheckRuns(SocketGuild guild, ulong channelId, int minutesBefore, Func <SocketGuildUser, IMessage, IEmbed, Task> onMatch, CancellationToken token)
        {
            var channel = guild?.GetTextChannel(channelId);

            if (channel == null)
            {
                await Task.Delay(3000, token);

                return;
            }

            Log.Information("Checking runs...");

            await foreach (var page in channel.GetMessagesAsync().WithCancellation(token))
            {
                foreach (var message in page)
                {
                    var embed = message.Embeds.FirstOrDefault(e => e.Type == EmbedType.Rich);

                    var nullableTimestamp = embed?.Timestamp;
                    if (!nullableTimestamp.HasValue)
                    {
                        continue;
                    }

                    var timestamp = nullableTimestamp.Value;

                    // Remove expired posts
                    if (timestamp.AddMinutes(60) < DateTimeOffset.Now)
                    {
                        await message.DeleteAsync();

                        continue;
                    }

                    // Hacky solution to avoid rare situations where people get spammed with notifications
                    if (timestamp.AddMinutes(-22) < DateTimeOffset.Now)
                    {
                        continue;
                    }

                    Log.Information("{Username} - ETA {TimeUntil} hrs.", embed.Author?.Name, (timestamp - DateTimeOffset.Now).TotalHours);

                    // ReSharper disable once InvertIf
                    if (timestamp.AddMinutes(-minutesBefore) <= DateTimeOffset.Now && embed.Author.HasValue)
                    {
                        Log.Information("Run matched!");

                        var host = guild.Users.FirstOrDefault(u => u.ToString() == embed.Author.Value.Name);
                        if (host == null)
                        {
                            host = guild.Users.FirstOrDefault(u => u.ToString() == embed.Author.Value.Name);
                        }

                        var messageReferenceCopy = message;
                        try
                        {
                            await onMatch(host, messageReferenceCopy, embed);
                        }
                        catch (Exception e)
                        {
                            Log.Error(e, "error: uncaught exception in onMatch");
                        }
                    }
                }
            }
        }
Beispiel #10
0
        /// <summary>
        /// Posts any moderation actions done with the bot into the assigned mod log channel if one is assigned.
        /// Post is an embed that shares the action, target'd user, user that used the command, and reason for the command.
        /// </summary>
        /// <param name="guild">The guild the command was used in.</param>
        /// <param name="action">The moderation action that was used.</param>
        /// <param name="user">The moderator who used the command.</param>
        /// <param name="target">The user targeted by the command.</param>
        /// <param name="reason">The reason for using the command.</param>
        /// <returns></returns>
        public static async Task PostInModLog(SocketGuild guild, string action, SocketUser user, IGuildUser target, [Remainder] string reason)
        {
            //Channel to send the chat logs in
            ulong channel = Data.Data.GetModLogChannel(guild.Id);

            if (channel != 0) //If a channel has been assigned as the mod log channel
            {
                Random            ran         = new Random();
                int               color1      = ran.Next(0, 256); //Gets a random color for the embed
                int               color2      = ran.Next(0, 256);
                int               color3      = ran.Next(0, 256);
                SocketTextChannel channelPost = guild.GetTextChannel(channel);
                if (target != null) //If action was targeted at a user
                {
                    //Embedbuilder object
                    EmbedBuilder Embed = new EmbedBuilder();
                    Embed.AddField("Action:", action);
                    Embed.AddField("Targeted User:"******"{target.Username} ({target.Mention})");
                    Embed.AddField("Moderator:", $"{user.Username} ({user.Mention})");
                    Embed.AddField("Reason:", reason);

                    //Assign the author's image
                    Embed.WithThumbnailUrl(user.GetAvatarUrl());

                    //Add the timestamp to the bottom
                    Embed.WithCurrentTimestamp();

                    //Assign the color on the left side
                    Embed.WithColor(color1, color2, color3);

                    try
                    {
                        await channelPost.SendMessageAsync("", false, Embed.Build());
                    }
                    catch (Exception)
                    {
                        await user.SendMessageAsync("I do not have permission to post in the mod log. Please inform the administrator of the server.");
                    }
                }
                else //If action was not targeted at a user
                {
                    //Embedbuilder object
                    EmbedBuilder Embed = new EmbedBuilder();
                    Embed.AddField("Action:", action);
                    Embed.AddField("Moderator:", $"{user.Username} ({user.Mention})");

                    if (reason != "")
                    {
                        Embed.AddField("Reason:", reason);
                    }

                    //Assign the author's image
                    Embed.WithThumbnailUrl(user.GetAvatarUrl());
                    Embed.WithCurrentTimestamp();

                    //Assign the color on the left side
                    Embed.WithColor(color1, color2, color3);
                    try
                    {
                        await channelPost.SendMessageAsync("", false, Embed.Build());
                    }
                    catch (Exception)
                    {
                        await user.SendMessageAsync("I do not have permission to post in the mod log. Please inform the administrator of the server.");
                    }
                }
            }
        }
Beispiel #11
0
        public override async Task ServerUpdate(SocketGuild server)
        {
            var triviaServerData = server.GetMemory().GetData <TriviaSystem, TriviaServerData>();

            if (!triviaServerData.IsReady)
            {
                return;                 //TODO: Let the admins know that this is misconfigured.
            }

            var now = DateTime.Now;

            if ((now - triviaServerData.lastTriviaPost).TotalSeconds <= triviaServerData.postIntervalInSeconds)
            {
                return;
            }

            triviaServerData.lastTriviaPost = now;
            triviaServerData.currentChannel = triviaServerData.triviaChannels[MopBot.Random.Next(triviaServerData.triviaChannels.Count)];

            var channel = server.GetTextChannel(triviaServerData.currentChannel);

            if (channel == null)
            {
                return;                 //TODO: Same as above
            }

            TriviaQuestion[] validQuestions;

            //Find questions we didn't pick yet, handle running out of them.
            while (true)
            {
                lock (triviaServerData.questions) {
                    validQuestions = triviaServerData.questions.Where(q => !q.wasPosted).ToArray();
                }

                if (validQuestions.Length == 0)
                {
                    if (triviaServerData.autoClearCache && triviaServerData.questions.Count > 0)
                    {
                        ClearCache(triviaServerData);

                        continue;
                    }
                    else
                    {
                        await channel.SendMessageAsync($"{server.Owner.Mention} We're out of trivia questions!\r\n\r\nAdd new questions, or..\r\n• Use `!trivia clearcache` to clear list of used questions;\r\n• Use `!trivia autoclearcache true` to automate this process, if you're fully okay with same questions being repeat;");

                        return;
                    }
                }

                break;
            }

            //Set new question
            triviaServerData.currentQuestion           = validQuestions[MopBot.Random.Next(validQuestions.Length)];
            triviaServerData.currentQuestion.wasPosted = true;
            currentQuestionRegex = null;             //This will cause a new one to be made, when needed.

            string     mention             = null;
            SocketRole role                = null;
            bool       disallowRoleMention = false;
            var        currentUser         = server.CurrentUser;

            if (triviaServerData.triviaRole > 0)
            {
                role = server.GetRole(triviaServerData.triviaRole);

                if (role != null)
                {
                    if (!role.IsMentionable && currentUser.HasDiscordPermission(gp => gp.ManageRoles))
                    {
                        await role.ModifyAsync(rp => rp.Mentionable = true);

                        disallowRoleMention = true;
                    }

                    mention = role.Mention;
                }
                else
                {
                    triviaServerData.triviaRole = 0;
                }
            }

            var embedBuilder = MopBot.GetEmbedBuilder(server)
                               .WithAuthor("The next question is...")  //.WithTitle("The next question is...")
                               .WithDescription($"**{triviaServerData.currentQuestion.question}**")
                               .WithFooter("Type your answer right in this channel!");

            if (triviaServerData.thumbnailUrls?.Length > 0 == true)
            {
                try {
                    embedBuilder.WithThumbnailUrl(triviaServerData.thumbnailUrls[MopBot.Random.Next(triviaServerData.thumbnailUrls.Length)]);
                }
                catch { }
            }

            await channel.SendMessageAsync(mention, embed : embedBuilder.Build());

            if (disallowRoleMention)
            {
                await role.ModifyAsync(rp => rp.Mentionable = false);
            }

            if (triviaServerData.lockTriviaChannel && currentUser.HasChannelPermission(channel, DiscordPermission.ManageChannel))
            {
                //Unlock the channel, since there's a question now.

                await channel.ModifyPermissions(server.EveryoneRole, op => op.SendMessages == PermValue.Deny?op.Modify(sendMessages : PermValue.Inherit) : op);
            }
        }
Beispiel #12
0
 /// <summary>
 /// Posts a message towards the 'UserNameQueue' post target containing the name before and after the change with the given title.
 /// The embed has as thumbnail the avatar of the user (none if default) and is posted towards the given guild.
 /// </summary>
 /// <param name="embedTitle">Title of the embed</param>
 /// <param name="beforeText">Text of the embed to be used for the 'Before' field</param>
 /// <param name="afterText">Text of the embed to be used for the 'After' field</param>
 /// <param name="user">User with the invalid username, used for the avatar in the embed.</param>
 /// <param name="guild">The <see cref"Discord.WebSocket.SocketGuild"/> guild where this is posted towards in the 'UserNameQueue' post target</param>
 /// <returns></returns>
 private async Task NotifyAboutIllegalUserName(string embedTitle, string beforeText, string afterText, IUser user, SocketGuild guild)
 {
     var embed   = GetUserNameNotificationEmbed(embedTitle, beforeText, afterText, user);
     var userlog = guild.GetTextChannel(Global.PostTargets[PostTarget.USERNAME_QUEUE]);
     await userlog.SendMessageAsync(embed : embed);
 }
Beispiel #13
0
        static Logging()
        {
            Program.Initialize += delegate(object?sender, DiscordSocketClient client)
            {
                client.ChannelDestroyed += delegate(SocketChannel channel)
                {
                    //Only currently needed for Logs at the moment
                    //Will try to remove the pair if it exists in the list
                    SaveHandler.LogSave.Remove(new KeyValuePair <ulong, ulong>(((SocketGuildChannel)channel).Guild.Id,
                                                                               channel.Id));
                    SaveHandler.LockdownSave[((SocketGuildChannel)channel).Guild.Id]
                    .Remove(((SocketGuildChannel)channel).Id);
                    return(Task.CompletedTask);
                };

                client.MessageUpdated += async delegate(Cacheable <IMessage, ulong> oldMessage, SocketMessage newMessage,
                                                        ISocketMessageChannel channel)
                {
                    if (!oldMessage.HasValue || newMessage.Author.IsBot)
                    {
                        return;
                    }

                    SocketGuild guild = ((SocketTextChannel)channel).Guild;
                    if (SaveHandler.LogSave.ContainsKey(guild.Id))
                    {
                        SocketTextChannel logChannel = guild.GetTextChannel(SaveHandler.LogSave[guild.Id]);
                        if (oldMessage.Value.Content != newMessage.Content)
                        {
                            EmbedBuilder builder = new EmbedBuilder
                            {
                                Color       = Color.Teal,
                                Title       = "Message Edited",
                                Url         = newMessage.GetJumpUrl(),
                                Description =
                                    $"From {newMessage.Author.Mention} in <#{channel.Id}>:\n**Before:**\n{oldMessage.Value.Content}\n**After:**\n{newMessage.Content}"
                            };

                            if (builder.Length > EmbedBuilder.MaxDescriptionLength)
                            {
                                string[] msgs = Misc.ConvertToDiscordSendable(builder.Description);
                                for (int i = 0; i < msgs.Length; i++)
                                {
                                    string msg = msgs[i];
                                    builder.Description = msg;
                                    if (msgs.Length - 1 == i)
                                    {
                                        builder.WithCurrentTimestamp();
                                    }

                                    await logChannel.SendMessageAsync(embed : builder.Build());

                                    if (i == 0)
                                    {
                                        builder.Title = null;
                                    }
                                }
                            }
                            else
                            {
                                builder.WithCurrentTimestamp();
                                await logChannel.SendMessageAsync(embed : builder.Build());
                            }
                        }
                    }
                };

                client.UserLeft += async delegate(SocketGuildUser user)
                {
                    if (SaveHandler.LogSave.ContainsKey(user.Guild.Id))
                    {
                        SocketTextChannel logChannel = user.Guild.GetTextChannel(SaveHandler.LogSave[user.Guild.Id]);
                        RestAuditLogEntry lastKick   = (await user.Guild.GetAuditLogsAsync(3, actionType: ActionType.Kick).FlattenAsync()).FirstOrDefault(l => (l.Data as KickAuditLogData).Target == user);
                        EmbedBuilder      builder    = new EmbedBuilder
                        {
                            Color = Color.Teal
                        };

                        if (lastKick != null)
                        {
                            string msg = $"You were kicked from {user.Guild.Name}";
                            if (lastKick.Reason != null)
                            {
                                msg += $"\nReason: {lastKick.Reason}";
                            }
                            try
                            {
                                await user.SendMessageAsync(msg);
                            }
                            catch { }
                            builder.WithCurrentTimestamp();
                            builder.Title       = "User Kicked";
                            builder.Description = $"{lastKick.User.Mention} kicked {user.Mention} | {user}";
                            if (lastKick.Reason != null)
                            {
                                builder.Description += $"\n__Reason__: \"{lastKick.Reason}\"";
                            }
                            await logChannel.SendMessageAsync(embed : builder.Build());
                        }

                        builder.WithCurrentTimestamp();
                        builder.Title       = "User Left";
                        builder.Description = $"{user.Mention} | {user}";
                        await logChannel.SendMessageAsync(embed : builder.Build());
                    }
                };

                client.UserBanned += async delegate(SocketUser user, SocketGuild guild)
                {
                    if (SaveHandler.LogSave.ContainsKey(guild.Id))
                    {
                        RestAuditLogEntry lastBan =
                            (await guild.GetAuditLogsAsync(3, actionType: ActionType.Ban).FlattenAsync()).FirstOrDefault(l => (l.Data as BanAuditLogData).Target == user);
                        if (lastBan != null)
                        {
                            string msg = $"You were banned from {guild.Name}";
                            if (lastBan.Reason != null)
                            {
                                msg += $"\nReason: {lastBan.Reason}";
                            }
                            try
                            {
                                await user.SendMessageAsync(msg);
                            }
                            catch { }

                            SocketTextChannel logChannel = guild.GetTextChannel(SaveHandler.LogSave[guild.Id]);
                            EmbedBuilder      builder    = new EmbedBuilder
                            {
                                Color       = Color.Teal,
                                Title       = "User Banned",
                                Description = $"{lastBan.User.Mention} banned {user.Mention} | {user}"
                            };
                            builder.WithCurrentTimestamp();
                            if (!string.IsNullOrWhiteSpace(lastBan.Reason))
                            {
                                builder.Description += $"\n__Reason__: \"{lastBan.Reason}\"";
                            }
                            await logChannel.SendMessageAsync(embed : builder.Build());
                        }
                    }
                };
                client.MessageDeleted +=
                    async delegate(Cacheable <IMessage, ulong> message, ISocketMessageChannel channel)
                {
                    if (!message.HasValue || message.Value.Author.IsBot)
                    {
                        return;
                    }

                    SocketGuild guild = ((SocketGuildChannel)channel).Guild;
                    if (SaveHandler.LogSave.ContainsKey(guild.Id))
                    {
                        SocketTextChannel logChannel = guild.GetTextChannel(SaveHandler.LogSave[guild.Id]);
                        if (logChannel.Id != channel.Id &&
                            (!string.IsNullOrWhiteSpace(message.Value.Content) || message.Value.Attachments.Any()))
                        {
                            EmbedBuilder builder = new EmbedBuilder
                            {
                                Description = "",
                                Color       = Color.Teal,
                                Title       = "Message Deleted",
                            };
                            RestAuditLogEntry messageDeleted = (await guild.GetAuditLogsAsync(3, actionType: ActionType.MessageDeleted).FlattenAsync()).FirstOrDefault(l => (l.Data as MessageDeleteAuditLogData).Target.Id == message.Value.Author.Id);

                            if (!string.IsNullOrWhiteSpace(message.Value.Content))
                            {
                                builder.Description += $"From {message.Value.Author.Mention}, in <#{channel.Id}>";
                            }

                            if (messageDeleted != null)
                            {
                                builder.Description += $", deleted by {messageDeleted.User.Mention}";
                            }

                            builder.Description += $":\n{message.Value.Content}";

                            if (message.Value.Attachments.Any())
                            {
                                builder.Description += "\n\nAttachments:\n";
                                foreach (IAttachment attachment in message.Value.Attachments)
                                {
                                    builder.Description += $"{attachment.Url}\n";
                                }
                            }

                            if (builder.Length > EmbedBuilder.MaxDescriptionLength)
                            {
                                string[] msgs = Misc.ConvertToDiscordSendable(builder.Description);
                                for (int i = 0; i < msgs.Length; i++)
                                {
                                    string msg = msgs[i];
                                    builder.Description = msg;
                                    if (msgs.Length - 1 == i)
                                    {
                                        builder.WithCurrentTimestamp();
                                    }

                                    await logChannel.SendMessageAsync(embed : builder.Build());

                                    if (i == 0)
                                    {
                                        builder.Title = null;
                                    }
                                }
                            }
                            else
                            {
                                builder.WithCurrentTimestamp();
                                await logChannel.SendMessageAsync(embed : builder.Build());
                            }
                        }
                    }
                };

                client.GuildMemberUpdated += async delegate(SocketGuildUser before, SocketGuildUser after)
                {
                    if (before.IsBot)
                    {
                        return;
                    }

                    if (SaveHandler.LogSave.ContainsKey(after.Guild.Id))
                    {
                        SocketTextChannel logChannel = after.Guild.GetTextChannel(SaveHandler.LogSave[after.Guild.Id]);
                        if (logChannel != null)
                        {
                            if (before.Nickname != after.Nickname)
                            {
                                EmbedBuilder builder = new EmbedBuilder
                                {
                                    Color = Color.Teal
                                };
                                builder.WithCurrentTimestamp();
                                if (string.IsNullOrWhiteSpace(after.Nickname))
                                {
                                    builder.Title       = "Nickname Removal";
                                    builder.Description = $"{after.Mention}:\n`{before.Nickname}` -> `None`";
                                }
                                else if (string.IsNullOrWhiteSpace(before.Nickname))
                                {
                                    builder.Title       = "Nickname Changed";
                                    builder.Description = $"{after.Mention}:\n`None` -> `{after.Nickname}`";
                                }
                                else
                                {
                                    builder.Title       = "Nickname Changed";
                                    builder.Description =
                                        $"{after.Mention}:\n`{before.Nickname}` -> `{after.Nickname}`";
                                }

                                await logChannel.SendMessageAsync(embed : builder.Build());
                            }
                        }
                    }
                };
            };
        }
Beispiel #14
0
 public static async Task GuildJoinedAlert(SocketGuild g)
 {
     destGuild = Program._client.GetGuild(701178110485463152);
     SocketTextChannel destChannel = destGuild.GetTextChannel(701178110933991466);
     await destChannel.SendMessageAsync("", false, Utilities.GetEmbedMessage("Guild Joined", $"Joined Guild: {g.Name}", $"Owner: {g.Owner.Username}\nGuild ID: {g.Id}\nUsers: {g.MemberCount}", null));
 }
        public static async Task ReceiveData(SerializedData.SerializedData data, TcpClient client)
        {
            try
            {
                if (data == null)
                {
                    Console.WriteLine("STT: Received data null");
                    return;
                }

                Program.Log($"Receiving data: {data.Data} Channel: {data.Channel} for {data.Port}", true);
                if (data.Data.Contains("REQUEST_DATA PLAYER_LIST SILENT"))
                {
                    return;
                }
                SocketGuild guild = Bot.Client.Guilds.FirstOrDefault();

                if (data.Data.StartsWith("checksync"))
                {
                    string[] args = data.Data.Split(' ');
                    Program.Log($"Checking rolesync for {args[1]}", true);
                    SyncedUser user = Program.Users.FirstOrDefault(u => u.UserId == args[1]);
                    if (user == null)
                    {
                        Program.Log($"Role sync for {args[1]} not found.", true);
                        return;
                    }

                    foreach (SocketRole role in guild.GetUser(user.DiscordId).Roles)
                    {
                        if (Program.SyncedGroups.ContainsKey(role.Id))
                        {
                            SendData($"setgroup {user.UserId} {Program.SyncedGroups[role.Id]}", Program.Config.Port, "RoleSync");
                        }
                    }
                }
                if (data.Data == "ping")
                {
                    if (!bag.ContainsKey(data.Port))
                    {
                        Console.WriteLine($"STT: Adding {data.Port}");
                        bag.TryAdd(data.Port, client);
                    }

                    if (!bag[data.Port].Connected || bag[data.Port] == null)
                    {
                        Console.WriteLine($"STT: Bag {data.Port} not connected or null, removing.");
                        if (bag.TryRemove(data.Port, out TcpClient cli))
                        {
                            cli?.Close();
                        }
                    }
                    Console.WriteLine($"STT: Received heartbeat for: {data.Port}");
                    if (!heartbeats.ContainsKey(data.Port))
                    {
                        Heartbeat(data.Port);
                        heartbeats.TryAdd(data.Port, 0);
                    }
                    else
                    {
                        heartbeats[data.Port]--;
                    }

                    Program.Log($"Updating channelID's for plugin..{data.Port}", true);
                    try
                    {
                        Program.Log($"GameChannelID: {GameChannelId}", true);
                        SendData("set gameid", data.Port, "bot", GameChannelId);
                        Program.Log($"CommandChannelID: {CmdChannelId}", true);
                        SendData("set cmdid", data.Port, "bot", CmdChannelId);
                    }
                    catch (Exception e)
                    {
                        Program.Log(e.ToString());
                    }

                    return;
                }

                if (data.Data.StartsWith("updateStatus"))
                {
                    Program.Log($"updating status for bot", true);
                    string status = data.Data.Replace("updateStatus ", "");
                    if (status.StartsWith("0"))
                    {
                        await Bot.Client.SetStatusAsync(UserStatus.Idle);
                    }
                    else
                    {
                        await Bot.Client.SetStatusAsync(UserStatus.Online);
                    }
                    await Bot.Client.SetActivityAsync(new Game(status));

                    return;
                }
                data.Data = data.Data.Substring(data.Data.IndexOf('#') + 1);



                Console.WriteLine("Getting guild.");
                Console.WriteLine("Getting channel");
                if (guild == null)
                {
                    Console.WriteLine("Guild not found.");
                    return;
                }

                SocketTextChannel chan = null;
                if (data.Channel == 1)
                {
                    chan = guild.GetTextChannel(GameChannelId);
                }
                else if (data.Channel == 2)
                {
                    chan = guild.GetTextChannel(CmdChannelId);
                }
                else
                {
                    chan = guild.GetTextChannel(data.Channel);
                }

                if (chan == null)
                {
                    await Program.Log(new LogMessage(LogSeverity.Critical, "recievedData", "Channel not found."));

                    return;
                }

                if (chan.Id == Program.Config.GameLogChannelId || chan.Id == Program.Config.CommandLogChannelId)
                {
                    Program.Log("Storing message.", true);
                    lock (_messages)
                    {
                        if (!_messages.ContainsKey(chan.Id))
                        {
                            _messages.Add(chan.Id, string.Empty);
                        }
                        _messages[chan.Id] += $"[{DateTime.Now.Hour}:{DateTime.Now.Minute}:{DateTime.Now.Second}] {data.Data} {Environment.NewLine}";
                    }
                    return;
                }
                Console.WriteLine("Sending message.");
                await chan.SendMessageAsync($"[{DateTime.Now.Hour}:{DateTime.Now.Minute}:{DateTime.Now.Second}] {data.Data}");
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }