private static async Task ReactionAdded(Cacheable <IUserMessage, ulong> message, ISocketMessageChannel channel, SocketReaction reaction) { // BongBot //try { // if (reaction.User.IsSpecified && reaction.User.Value.Id == 735232851431260290 && message.HasValue) { // _ = message.Value.AddReactionAsync(reaction.Emote); // LoggingManager.Log.Debug($"Reacted to BongBot {reaction.Emote}"); // } //} catch (Exception ex) { // LoggingManager.Log.Error(ex); //} // Bong trap try { if (BongTrapMessageId.HasValue && message.Id == BongTrapMessageId && reaction.User.IsSpecified && reaction.User.Value is SocketGuildUser socketUser) { Random rand = new Random(); if (!string.IsNullOrEmpty(socketUser.Nickname)) { string scrambledNick = new string(socketUser.Nickname.ToCharArray().OrderBy(s => (rand.Next(2) % 2) == 0).ToArray()); _ = socketUser.ModifyAsync(x => x.Nickname = scrambledNick); } else { string scrambledUsername = new string(socketUser.Username.ToCharArray().OrderBy(s => (rand.Next(2) % 2) == 0).ToArray()); _ = socketUser.ModifyAsync(x => x.Nickname = scrambledUsername); } } } catch (Exception ex) { LoggingManager.Log.Error(ex); } // Emote mode (EmoteModeTracker.Mode mode, object _) = EmoteModeTracker.GetMode(channel.Id); if (mode == EmoteModeTracker.Mode.TextOnly) { if (message.HasValue & reaction.User.IsSpecified) { if (WubbysFunHouse.IsDiscordOrTwitchStaff(reaction.User.Value)) { return; } await message.Value.RemoveReactionAsync(reaction.Emote, reaction.User.Value); } } }
private static async Task MessageUpdated(Cacheable <IMessage, ulong> originalMessage, SocketMessage updatedMessage, ISocketMessageChannel channel) { if (originalMessage.HasValue && !string.IsNullOrWhiteSpace(originalMessage.Value.Content) && !string.IsNullOrWhiteSpace(updatedMessage.Content) && !originalMessage.Value.Author.IsBot) { if (originalMessage.Value.Content != updatedMessage.Content) { string logMessage; if (originalMessage.HasValue) { logMessage = $"`[{originalMessage.Value.CreatedAt.DateTime.ToUniversalTime().ToString(Constants.DateTimeFormatMedium)}]` :pencil: {originalMessage.Value.Author} (`{originalMessage.Value.Author.Id}`) message edited in **#{channel.Name}**:{Environment.NewLine}**B:** {originalMessage.Value.ResolveTags()}{Environment.NewLine}**A:** {updatedMessage.ResolveTags()}"; } else { logMessage = $":warning: An unknown message was edited in **#{channel.Name}**: {Environment.NewLine}Old id was: {originalMessage.Id}{Environment.NewLine}New id is: {updatedMessage.Id}"; } if (!string.IsNullOrEmpty(logMessage)) { if (_DiscordClient.GetChannel(WubbysFunHouse.UserLogsChannelId) is IMessageChannel logChannel) { await logChannel.SendMessageAsync(logMessage); } } } } // ======== if (!(updatedMessage is SocketUserMessage message)) { return; } if (updatedMessage.Source != MessageSource.User) { return; } if (!WubbysFunHouse.IsDiscordOrTwitchStaff(updatedMessage.Author)) { await ProcessMessageEmotesAsync(message); } }
/// <summary> /// Process additional actions for a message. /// </summary> /// <param name="channel">Text channel message was sent in.</param> /// <param name="message">Message to process.</param> /// <param name="user">User who sent the message.</param> private static async Task ProcessMessageAsync(SocketTextChannel channel, SocketUserMessage message, SocketGuildUser user) { if (WubbysFunHouse.IsDiscordOrTwitchStaff(user)) { return; } try { // chadwick (226992558839037952) #server-suggestions (502630201948373003) 50% chance //if (user.Id == 226992558839037952 && channel.Id == 502630201948373003 && new Random().Next(1, 100) > 50) { // await channel.SendMessageAsync($"<@226992558839037952> No"); //} // Emote mode if (await ProcessMessageEmotesAsync(message)) { return; } // Jingle bells //if (message.Content.Replace(" ", "").Contains("jingle", StringComparison.OrdinalIgnoreCase)) { // Task runner = Task.Run(async () => { // await JingleBells(message.Channel.Id).ConfigureAwait(false); // }); //} string contentLowercase = message.Content.ToLowerInvariant(); // Discord invites if (contentLowercase.Contains("https://discord.gg/")) { await message.DeleteAsync(); await channel.SendMessageAsync($"{user.Mention} No invites allowed."); return; } // Discord gifts if (contentLowercase.Contains("https://discord.gift/") && WubbysFunHouse.IsSubscriber(user)) { return; } // Main channel if (channel.Id == WubbysFunHouse.MainChannelId) { // If tier 3 skip filters if (user.Roles.Any(x => x.Id == WubbysFunHouse.TwitchSubscriberTier3RoleId)) { return; } // If not rank 10 or higher if (!user.Roles.Any(x => x.Id == WubbysFunHouse.ForkliftDriversRoleId)) { string betterUserFormat = $"{(string.IsNullOrWhiteSpace(user.Nickname) ? user.Username : user.Nickname)} `{user}`"; // Move links if (message.Content.ContainsUrls()) { if (_DiscordClient.GetChannel(WubbysFunHouse.LinksChannelId) is IMessageChannel linksChannel) { LoggingManager.Log.Info($"Link in #{channel.Name} by {user} ({user.Id})"); await linksChannel.SendMessageAsync($"● Posted by {betterUserFormat} in <#{WubbysFunHouse.MainChannelId}>{Environment.NewLine}{message.ResolveTags()}"); await message.DeleteAsync(); await channel.SendMessageAsync($"{user.Mention} You need the `Forklift Drivers` role or higher to post links here. Link was moved to <#{WubbysFunHouse.LinksChannelId}>."); } // Move attachments } else if (message.Attachments.Count > 0) { if (_DiscordClient.GetChannel(WubbysFunHouse.ActualFuckingSpamChannelId) is IMessageChannel actualFuckingSpamChannel) { foreach (Attachment attachment in message.Attachments) { using HttpResponseMessage response = await Http.Client.GetAsync(attachment.Url); if (response.IsSuccessStatusCode) { using HttpContent content = response.Content; Stream stream = await content.ReadAsStreamAsync(); LoggingManager.Log.Info($"Attachment in #{channel.Name} by {user} ({user.Id}); {attachment.Filename}; api: {attachment.Size.Bytes().Humanize("#.##")}; downloaded: {stream.Length.Bytes().Humanize("#.##")}"); if (stream.Length > Constants.DiscordMaximumFileSize) { await actualFuckingSpamChannel.SendMessageAsync($"An attachment was uploaded by {betterUserFormat} in <#{WubbysFunHouse.MainChannelId}> and can not be re-uploaded, the attachment is too large for a bot to upload (`{attachment.Size.Bytes().Humanize("#.##")} / {stream.Length.Bytes().Humanize("#.##")}`). They probably have Nitro."); } else { stream.Seek(0, SeekOrigin.Begin); await actualFuckingSpamChannel.SendFileAsync(stream, attachment.Filename, $"● Uploaded by {betterUserFormat} in <#{WubbysFunHouse.MainChannelId}>{Environment.NewLine}{message.Content}"); } } else { throw new HttpRequestException($"There was an error; ({(int)response.StatusCode}) {response.ReasonPhrase}"); } } await message.DeleteAsync(); await channel.SendMessageAsync($"{user.Mention} You need to be `Forklift Drivers` or higher to upload files here. Attachment was moved to <#{WubbysFunHouse.ActualFuckingSpamChannelId}>."); } } } } // Too many animated emotes in actual f*****g spam if (channel.Id == WubbysFunHouse.ActualFuckingSpamChannelId) { int count = message.Content.CountStringOccurrences("<a:"); if (count > 10) { await message.DeleteAsync(); await channel.SendMessageAsync($"{user.Mention} Only 10 or less animated emotes/emoji per-message. Having many of them breaks the channel for some people."); } } } catch (Exception ex) { LoggingManager.Log.Error(ex); } }
private static async Task UserJoined(SocketGuildUser user) { // Log join if (_DiscordClient.GetChannel(WubbysFunHouse.UserLogsChannelId) is IMessageChannel logChannel) { await logChannel.SendMessageAsync($"`[{DateTime.UtcNow.ToString(Constants.DateTimeFormatMedium)}]` :inbox_tray: {user} (`{user.Id}`) has joined."); } // Username check if (!user.Username.All(x => x <= sbyte.MaxValue)) { _ = Task.Run(async() => { await Task.Delay(1000); try { await WubbysFunHouse.AddRoleAsync(user, WubbysFunHouse.MutedRoleId, "Auto-muted on join due to weird username."); await SendMessageAsync(WubbysFunHouse.ModLogsChannelId, $":exclamation: {user.Mention} was auto-muted on join due to due to weird username."); await Task.Run(async() => { await Task.Delay(8000); if (!user.Roles.Any(x => x.Id == WubbysFunHouse.MutedRoleId)) { await WubbysFunHouse.AddRoleAsync(user, WubbysFunHouse.MutedRoleId, "Auto-muted on join due to weird username (second attempt)."); await SendMessageAsync(WubbysFunHouse.ModLogsChannelId, $":bangbang: {user.Mention} was auto-muted on join due to due to weird username (second attempt, first one either failed or was overridden <@{Constants.XathzUserId}>)."); } }); } catch (Exception ex) { LoggingManager.Log.Error(ex); } }); } // Auto-mute accounts that have been created recently if (user.CreatedAt.AddDays(7) > DateTimeOffset.Now) { _ = Task.Run(async() => { await Task.Delay(2000); try { await WubbysFunHouse.AddRoleAsync(user, WubbysFunHouse.MutedRoleId, "Auto-muted on join due to account being younger than a week."); await SendMessageAsync(WubbysFunHouse.ModLogsChannelId, $":anger: {user.Mention} was auto-muted on join due to account being younger than a week."); } catch (Exception ex) { LoggingManager.Log.Error(ex); } }); } if (user == null) { LoggingManager.Log.Error("User joined, user is null"); return; } if (string.IsNullOrEmpty(user.Guild.Id.ToString())) { LoggingManager.Log.Error("User joined, guild id is null"); return; } await _DiscordClient.GetGuild(user.Guild.Id).DownloadUsersAsync(); user = _DiscordClient.GetGuild(user.Guild.Id).GetUser(user.Id); if (string.IsNullOrEmpty(user.AvatarId)) { LoggingManager.Log.Error("User joined, avatar id is null!"); return; } // ======== Task runner = Task.Run(async() => { try { StatisticsManager.NameChangeType changeType = StatisticsManager.NameChangeType.Username | StatisticsManager.NameChangeType.Discriminator | StatisticsManager.NameChangeType.Display; string backblazeAvatarBucket = null, backblazeAvatarFilename = null, backblazeAvatarUrl = null; try { ImageFormat imageFormat = user.AvatarId.StartsWith("a_") ? ImageFormat.Gif : ImageFormat.Png; Task <MemoryStream> download = Http.GetStreamAsync(user.GetAvatarUrl(imageFormat, 1024)); using MemoryStream data = await download; if (download.IsCompletedSuccessfully) { Backblaze.File avatarUpload = await Backblaze.UploadAvatarAsync(data, $"{user.Id}/{Backblaze.ISOFileNameDate(imageFormat.ToString().ToLower())}"); backblazeAvatarBucket = avatarUpload.BucketName; backblazeAvatarFilename = avatarUpload.FileName; backblazeAvatarUrl = avatarUpload.ShortUrl; changeType |= StatisticsManager.NameChangeType.Avatar; } else { LoggingManager.Log.Error(download.Exception); backblazeAvatarBucket = null; backblazeAvatarFilename = null; backblazeAvatarUrl = null; } } catch { } StatisticsManager.InsertUserChange(DateTime.UtcNow, user.Guild.Id, user.Id, changeType, null, user.Username, null, user.Discriminator, null, user.Nickname, backblazeAvatarBucket, backblazeAvatarFilename, backblazeAvatarUrl); } catch (Exception ex) { LoggingManager.Log.Error(ex); } }); }