diff options
| -rw-r--r-- | bot/cogs/alias.py | 8 | ||||
| -rw-r--r-- | bot/cogs/antispam.py | 8 | ||||
| -rw-r--r-- | bot/cogs/filtering.py | 52 | ||||
| -rw-r--r-- | bot/cogs/modlog.py | 4 | ||||
| -rw-r--r-- | bot/cogs/token_remover.py | 6 | ||||
| -rw-r--r-- | bot/constants.py | 9 | ||||
| -rw-r--r-- | bot/resources/stars.json | 82 | ||||
| -rw-r--r-- | bot/rules/newlines.py | 23 | ||||
| -rw-r--r-- | config-default.yml | 4 | 
9 files changed, 176 insertions, 20 deletions
| diff --git a/bot/cogs/alias.py b/bot/cogs/alias.py index a726e374f..8574927fc 100644 --- a/bot/cogs/alias.py +++ b/bot/cogs/alias.py @@ -131,6 +131,14 @@ class Alias:          await self.invoke(ctx, "defcon disable") +    @command(name="exception", hidden=True) +    async def tags_get_traceback_alias(self, ctx): +        """ +        Alias for invoking <prefix>tags get traceback. +        """ + +        await self.invoke(ctx, "tags get traceback") +      @group(name="get",             aliases=("show", "g"),             hidden=True, diff --git a/bot/cogs/antispam.py b/bot/cogs/antispam.py index 800700a50..0d1c7c1e9 100644 --- a/bot/cogs/antispam.py +++ b/bot/cogs/antispam.py @@ -97,13 +97,13 @@ class AntiSpam:                      # Fire it off as a background task to ensure                      # that the sleep doesn't block further tasks                      self.bot.loop.create_task( -                        self.punish(message, member, full_reason, relevant_messages) +                        self.punish(message, member, full_reason, relevant_messages, rule_name)                      )                  await self.maybe_delete_messages(message.channel, relevant_messages)                  break -    async def punish(self, msg: Message, member: Member, reason: str, messages: List[Message]): +    async def punish(self, msg: Message, member: Member, reason: str, messages: List[Message], rule_name: str):          # Sanity check to ensure we're not lagging behind          if self.muted_role not in member.roles:              remove_role_after = AntiSpamConfig.punishment['remove_after'] @@ -114,8 +114,8 @@ class AntiSpam:                  f"**Reason:** {reason}\n"              ) -            # For multiple messages, use the logs API -            if len(messages) > 1: +            # For multiple messages or those with excessive newlines, use the logs API +            if len(messages) > 1 or rule_name == 'newlines':                  url = await self.mod_log.upload_log(messages)                  mod_alert_message += f"A complete log of the offending messages can be found [here]({url})"              else: diff --git a/bot/cogs/filtering.py b/bot/cogs/filtering.py index 6b4469ceb..25aaf8420 100644 --- a/bot/cogs/filtering.py +++ b/bot/cogs/filtering.py @@ -1,6 +1,6 @@  import logging  import re -from typing import Optional +from typing import Optional, Union  import discord.errors  from dateutil.relativedelta import relativedelta @@ -189,7 +189,25 @@ class Filtering:                          log.debug(message) -                        additional_embeds = msg.embeds if filter_name == "watch_rich_embeds" else None +                        additional_embeds = None +                        additional_embeds_msg = None + +                        if filter_name == "filter_invites": +                            additional_embeds = [] +                            for invite, data in triggered.items(): +                                embed = discord.Embed(description=( +                                    f"**Members:**\n{data['members']}\n" +                                    f"**Active:**\n{data['active']}" +                                )) +                                embed.set_author(name=data["name"]) +                                embed.set_thumbnail(url=data["icon"]) +                                embed.set_footer(text=f"Guild Invite Code: {invite}") +                                additional_embeds.append(embed) +                            additional_embeds_msg = "For the following guild(s):" + +                        elif filter_name == "watch_rich_embeds": +                            additional_embeds = msg.embeds +                            additional_embeds_msg = "With the following embed(s):"                          # Send pretty mod log embed to mod-alerts                          await self.mod_log.send_log_message( @@ -201,6 +219,7 @@ class Filtering:                              channel_id=Channels.mod_alerts,                              ping_everyone=Filter.ping_everyone,                              additional_embeds=additional_embeds, +                            additional_embeds_msg=additional_embeds_msg                          )                          break  # We don't want multiple filters to trigger @@ -282,10 +301,12 @@ class Filtering:          return bool(re.search(ZALGO_RE, text)) -    async def _has_invites(self, text: str) -> bool: +    async def _has_invites(self, text: str) -> Union[dict, bool]:          """ -        Returns True if the text contains an invite which is not on the guild_invite_whitelist in -        config.yml +        Checks if there's any invites in the text content that aren't in the guild whitelist. + +        If any are detected, a dictionary of invite data is returned, with a key per invite. +        If none are detected, False is returned.          Attempts to catch some of common ways to try to cheat the system.          """ @@ -295,10 +316,13 @@ class Filtering:          text = text.replace("\\", "")          invites = re.findall(INVITE_RE, text, re.IGNORECASE) +        invite_data = dict()          for invite in invites: +            if invite in invite_data: +                continue              response = await self.bot.http_session.get( -                f"{URLs.discord_invite_api}/{invite}" +                f"{URLs.discord_invite_api}/{invite}", params={"with_counts": "true"}              )              response = await response.json()              guild = response.get("guild") @@ -311,8 +335,20 @@ class Filtering:              guild_id = int(guild.get("id"))              if guild_id not in Filter.guild_invite_whitelist: -                return True -        return False +                guild_icon_hash = guild["icon"] +                guild_icon = ( +                    "https://cdn.discordapp.com/icons/" +                    f"{guild_id}/{guild_icon_hash}.png?size=512" +                ) + +                invite_data[invite] = { +                    "name": guild["name"], +                    "icon": guild_icon, +                    "members": response["approximate_member_count"], +                    "active": response["approximate_presence_count"] +                } + +        return invite_data if invite_data else False      @staticmethod      async def _has_rich_embed(msg: Message): diff --git a/bot/cogs/modlog.py b/bot/cogs/modlog.py index 495795b6d..65efda5ed 100644 --- a/bot/cogs/modlog.py +++ b/bot/cogs/modlog.py @@ -115,6 +115,7 @@ class ModLog:              files: Optional[List[File]] = None,              content: Optional[str] = None,              additional_embeds: Optional[List[Embed]] = None, +            additional_embeds_msg: Optional[str] = None,              timestamp_override: Optional[datetime.datetime] = None,              footer: Optional[str] = None,      ): @@ -143,7 +144,8 @@ class ModLog:          log_message = await channel.send(content=content, embed=embed, files=files)          if additional_embeds: -            await channel.send("With the following embed(s):") +            if additional_embeds_msg: +                await channel.send(additional_embeds_msg)              for additional_embed in additional_embeds:                  await channel.send(embed=additional_embed) diff --git a/bot/cogs/token_remover.py b/bot/cogs/token_remover.py index c1a0e18ba..05298a2ff 100644 --- a/bot/cogs/token_remover.py +++ b/bot/cogs/token_remover.py @@ -17,9 +17,9 @@ log = logging.getLogger(__name__)  DELETION_MESSAGE_TEMPLATE = (      "Hey {mention}! I noticed you posted a seemingly valid Discord API "      "token in your message and have removed your message. " -    "We **strongly recommend** regenerating your token as it's probably " -    "been compromised. You can do that here: " -    "<https://discordapp.com/developers/applications/me>\n" +    "This means that your token has been **compromised**. " +    "Please change your token **immediately** at: " +    "<https://discordapp.com/developers/applications/me>\n\n"      "Feel free to re-post it with the token removed. "      "If you believe this was a mistake, please let us know!"  ) diff --git a/bot/constants.py b/bot/constants.py index b4c9b6f11..ab62cd79d 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -515,7 +515,9 @@ NEGATIVE_REPLIES = [      "Not in a million years.",      "Fat chance.",      "Certainly not.", -    "NEGATORY." +    "NEGATORY.", +    "Nuh-uh.", +    "Not in my house!",  ]  POSITIVE_REPLIES = [ @@ -535,7 +537,7 @@ POSITIVE_REPLIES = [      "ROGER THAT",      "Of course!",      "Aye aye, cap'n!", -    "I'll allow it." +    "I'll allow it.",  ]  ERROR_REPLIES = [ @@ -547,7 +549,8 @@ ERROR_REPLIES = [      "You blew it.",      "You're bad at computers.",      "Are you trying to kill me?", -    "Noooooo!!" +    "Noooooo!!", +    "I can't believe you've done this",  ] diff --git a/bot/resources/stars.json b/bot/resources/stars.json new file mode 100644 index 000000000..8071b9626 --- /dev/null +++ b/bot/resources/stars.json @@ -0,0 +1,82 @@ +{ +  "Adele": "https://upload.wikimedia.org/wikipedia/commons/thumb/7/7c/Adele_2016.jpg/220px-Adele_2016.jpg", +  "Steven Tyler": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a8/Steven_Tyler_by_Gage_Skidmore_3.jpg/220px-Steven_Tyler_by_Gage_Skidmore_3.jpg", +  "Alex Van Halen": "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b3/Alex_Van_Halen_-_Van_Halen_Live.jpg/220px-Alex_Van_Halen_-_Van_Halen_Live.jpg", +  "Aretha Franklin": "https://upload.wikimedia.org/wikipedia/commons/thumb/c/c6/Aretha_Franklin_1968.jpg/220px-Aretha_Franklin_1968.jpg", +  "Ayumi Hamasaki": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/50/Ayumi_Hamasaki_2007.jpg/220px-Ayumi_Hamasaki_2007.jpg", +  "Koshi Inaba": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/af/B%27Z_at_Best_Buy_Theater_NYC_-_9-30-12_-_18.jpg/220px-B%27Z_at_Best_Buy_Theater_NYC_-_9-30-12_-_18.jpg", +  "Barbra Streisand": "https://upload.wikimedia.org/wikipedia/en/thumb/a/a3/Barbra_Streisand_-_1966.jpg/220px-Barbra_Streisand_-_1966.jpg", +  "Barry Manilow": "https://upload.wikimedia.org/wikipedia/commons/thumb/2/2b/BarryManilow.jpg/220px-BarryManilow.jpg", +  "Barry White": "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b7/Barry_White%2C_Bestanddeelnr_927-0099.jpg/220px-Barry_White%2C_Bestanddeelnr_927-0099.jpg", +  "Beyonce": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f2/Beyonce_-_The_Formation_World_Tour%2C_at_Wembley_Stadium_in_London%2C_England.jpg/220px-Beyonce_-_The_Formation_World_Tour%2C_at_Wembley_Stadium_in_London%2C_England.jpg", +  "Billy Joel": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/19/Billy_Joel_Shankbone_NYC_2009.jpg/220px-Billy_Joel_Shankbone_NYC_2009.jpg", +  "Bob Dylan": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/02/Bob_Dylan_-_Azkena_Rock_Festival_2010_2.jpg/220px-Bob_Dylan_-_Azkena_Rock_Festival_2010_2.jpg", +  "Bob Marley": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/5e/Bob-Marley.jpg/220px-Bob-Marley.jpg", +  "Bob Seger": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/16/Bob_Seger_2013.jpg/220px-Bob_Seger_2013.jpg", +  "Jon Bon Jovi": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/49/Jon_Bon_Jovi_at_the_2009_Tribeca_Film_Festival_3.jpg/220px-Jon_Bon_Jovi_at_the_2009_Tribeca_Film_Festival_3.jpg", +  "Britney Spears": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/da/Britney_Spears_2013_%28Straighten_Crop%29.jpg/200px-Britney_Spears_2013_%28Straighten_Crop%29.jpg", +  "Bruce Springsteen": "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3b/Bruce_Springsteen_-_Roskilde_Festival_2012.jpg/210px-Bruce_Springsteen_-_Roskilde_Festival_2012.jpg", +  "Bruno Mars": "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b0/BrunoMars24KMagicWorldTourLive_%28cropped%29.jpg/220px-BrunoMars24KMagicWorldTourLive_%28cropped%29.jpg", +  "Bryan Adams": "https://upload.wikimedia.org/wikipedia/commons/thumb/7/7e/Bryan_Adams_Hamburg_MG_0631_flickr.jpg/300px-Bryan_Adams_Hamburg_MG_0631_flickr.jpg", +  "Celine Dion": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/42/Celine_Dion_Concert_Singing_Taking_Chances_2008.jpg/220px-Celine_Dion_Concert_Singing_Taking_Chances_2008.jpg", +  "Cher": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Cher_-_Casablanca.jpg/220px-Cher_-_Casablanca.jpg", +  "Christina Aguilera": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e7/Christina_Aguilera_in_2016.jpg/220px-Christina_Aguilera_in_2016.jpg", +  "David Bowie": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e8/David-Bowie_Chicago_2002-08-08_photoby_Adam-Bielawski-cropped.jpg/220px-David-Bowie_Chicago_2002-08-08_photoby_Adam-Bielawski-cropped.jpg", +  "David Lee Roth": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fb/David_Lee_Roth_-_Van_Halen.jpg/220px-David_Lee_Roth_-_Van_Halen.jpg", +  "Donna Summer": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Nobel_Peace_Price_Concert_2009_Donna_Summer3.jpg/220px-Nobel_Peace_Price_Concert_2009_Donna_Summer3.jpg", +  "Drake": "https://upload.wikimedia.org/wikipedia/commons/thumb/8/81/Drake_at_the_Velvet_Underground_-_2017_%2835986086223%29_%28cropped%29.jpg/220px-Drake_at_the_Velvet_Underground_-_2017_%2835986086223%29_%28cropped%29.jpg", +  "Ed Sheeran": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/55/Ed_Sheeran_2013.jpg/220px-Ed_Sheeran_2013.jpg", +  "Eddie Van Halen": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a7/Eddie_Van_Halen.jpg/300px-Eddie_Van_Halen.jpg", +  "Elton John": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/d1/Elton_John_2011_Shankbone_2.JPG/220px-Elton_John_2011_Shankbone_2.JPG", +  "Elvis Presley": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/99/Elvis_Presley_promoting_Jailhouse_Rock.jpg/220px-Elvis_Presley_promoting_Jailhouse_Rock.jpg", +  "Eminem": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/4a/Eminem_-_Concert_for_Valor_in_Washington%2C_D.C._Nov._11%2C_2014_%282%29_%28Cropped%29.jpg/220px-Eminem_-_Concert_for_Valor_in_Washington%2C_D.C._Nov._11%2C_2014_%282%29_%28Cropped%29.jpg", +  "Enya": "https://enya.com/wp-content/themes/enya%20full%20site/images/enya-about.jpg", +  "Flo Rida": "https://upload.wikimedia.org/wikipedia/commons/thumb/8/8b/Flo_Rida_%286924266548%29.jpg/220px-Flo_Rida_%286924266548%29.jpg", +  "Frank Sinatra": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/af/Frank_Sinatra_%2757.jpg/220px-Frank_Sinatra_%2757.jpg", +  "Garth Brooks": "https://upload.wikimedia.org/wikipedia/commons/thumb/b/bc/Garth_Brooks_on_World_Tour_%28crop%29.png/220px-Garth_Brooks_on_World_Tour_%28crop%29.png", +  "George Michael": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f2/George_Michael.jpeg/220px-George_Michael.jpeg", +  "George Strait": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/0c/George_Strait_2014_1.jpg/220px-George_Strait_2014_1.jpg", +  "James Taylor": "https://upload.wikimedia.org/wikipedia/commons/thumb/c/cf/James_Taylor_-_Columbia.jpg/220px-James_Taylor_-_Columbia.jpg", +  "Janet Jackson": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/02/JanetJacksonUnbreakableTourSanFran2015.jpg/220px-JanetJacksonUnbreakableTourSanFran2015.jpg", +  "Jay-Z": "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Jay-Z.png/220px-Jay-Z.png", +  "Johnny Cash": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f2/JohnnyCash1969.jpg/220px-JohnnyCash1969.jpg", +  "Johnny Hallyday": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a1/Johnny_Hallyday_Cannes.jpg/220px-Johnny_Hallyday_Cannes.jpg", +  "Julio Iglesias": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/ef/Julio_Iglesias09.jpg/220px-Julio_Iglesias09.jpg", +  "Justin Bieber": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/da/Justin_Bieber_in_2015.jpg/220px-Justin_Bieber_in_2015.jpg", +  "Justin Timberlake": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/ed/Justin_Timberlake_by_Gage_Skidmore_2.jpg/220px-Justin_Timberlake_by_Gage_Skidmore_2.jpg", +  "Kanye West": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Kanye_West_at_the_2009_Tribeca_Film_Festival.jpg/220px-Kanye_West_at_the_2009_Tribeca_Film_Festival.jpg", +  "Katy Perry": "https://upload.wikimedia.org/wikipedia/commons/thumb/8/8a/Katy_Perry_at_Madison_Square_Garden_%2837436531092%29_%28cropped%29.jpg/220px-Katy_Perry_at_Madison_Square_Garden_%2837436531092%29_%28cropped%29.jpg", +  "Kenny G": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f4/KennyGHWOFMay2013.jpg/220px-KennyGHWOFMay2013.jpg", +  "Kenny Rogers": "https://upload.wikimedia.org/wikipedia/commons/thumb/8/8c/KennyRogers.jpg/220px-KennyRogers.jpg", +  "Lady Gaga": "https://upload.wikimedia.org/wikipedia/commons/thumb/2/2c/Lady_Gaga_interview_2016.jpg/220px-Lady_Gaga_interview_2016.jpg", +  "Lil Wayne": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a6/Lil_Wayne_%2823513397583%29.jpg/220px-Lil_Wayne_%2823513397583%29.jpg", +  "Linda Ronstadt": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/50/LindaRonstadtPerforming.jpg/220px-LindaRonstadtPerforming.jpg", +  "Lionel Richie": "https://upload.wikimedia.org/wikipedia/commons/thumb/c/cd/Lionel_Richie_2017.jpg/220px-Lionel_Richie_2017.jpg", +  "Madonna": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/d1/Madonna_Rebel_Heart_Tour_2015_-_Stockholm_%2823051472299%29_%28cropped_2%29.jpg/220px-Madonna_Rebel_Heart_Tour_2015_-_Stockholm_%2823051472299%29_%28cropped_2%29.jpg", +  "Mariah Carey": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f2/Mariah_Carey_WBLS_2018_Interview_4.jpg/220px-Mariah_Carey_WBLS_2018_Interview_4.jpg", +  "Meat Loaf": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e7/Meat_Loaf.jpg/220px-Meat_Loaf.jpg", +  "Michael Jackson": "https://upload.wikimedia.org/wikipedia/commons/thumb/3/31/Michael_Jackson_in_1988.jpg/220px-Michael_Jackson_in_1988.jpg", +  "Neil Diamond": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f4/Neil_Diamond_HWOF_Aug_2012_other_%28levels_adjusted_and_cropped%29.jpg/220px-Neil_Diamond_HWOF_Aug_2012_other_%28levels_adjusted_and_cropped%29.jpg", +  "Nicki Minaj": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/54/Nicki_Minaj_MTV_VMAs_4.jpg/250px-Nicki_Minaj_MTV_VMAs_4.jpg", +  "Olivia Newton-John": "https://upload.wikimedia.org/wikipedia/commons/thumb/c/c7/Olivia_Newton-John_2.jpg/220px-Olivia_Newton-John_2.jpg", +  "Paul McCartney": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/5d/Paul_McCartney_-_Out_There_Concert_-_140420-5941-jikatu_%2813950091384%29.jpg/220px-Paul_McCartney_-_Out_There_Concert_-_140420-5941-jikatu_%2813950091384%29.jpg", +  "Phil Collins": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f3/1_collins.jpg/220px-1_collins.jpg", +  "Pink": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/1a/P%21nk_Live_2013.jpg/220px-P%21nk_Live_2013.jpg", +  "Prince": "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b2/Prince_1983_1st_Avenue.jpg/220px-Prince_1983_1st_Avenue.jpg", +  "Reba McEntire": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e0/Reba_McEntire_by_Gage_Skidmore.jpg/220px-Reba_McEntire_by_Gage_Skidmore.jpg", +  "Rihanna": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/47/Rihanna_concert_in_Washington_DC_%282%29.jpg/250px-Rihanna_concert_in_Washington_DC_%282%29.jpg", +  "Robbie Williams": "https://upload.wikimedia.org/wikipedia/commons/thumb/2/21/Robbie_Williams.jpg/220px-Robbie_Williams.jpg", +  "Rod Stewart": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/57/Rod_stewart_05111976_12_400.jpg/220px-Rod_stewart_05111976_12_400.jpg", +  "Carlos Santana": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/54/Santana_2010.jpg/220px-Santana_2010.jpg", +  "Shania Twain": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/ee/ShaniaTwainJunoAwardsMar2011.jpg/220px-ShaniaTwainJunoAwardsMar2011.jpg", +  "Stevie Wonder": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/54/Stevie_Wonder_1973.JPG/220px-Stevie_Wonder_1973.JPG", +  "Tak Matsumoto": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/da/B%27Z_at_Best_Buy_Theater_NYC_-_9-30-12_-_22.jpg/220px-B%27Z_at_Best_Buy_Theater_NYC_-_9-30-12_-_22.jpg", +  "Taylor Swift": "https://upload.wikimedia.org/wikipedia/commons/thumb/2/25/Taylor_Swift_112_%2818119055110%29_%28cropped%29.jpg/220px-Taylor_Swift_112_%2818119055110%29_%28cropped%29.jpg", +  "Tim McGraw": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/5f/Tim_McGraw_October_24_2015.jpg/220px-Tim_McGraw_October_24_2015.jpg", +  "Tina Turner": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/10/Tina_turner_21021985_01_350.jpg/250px-Tina_turner_21021985_01_350.jpg", +  "Tom Petty": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/5a/Tom_Petty_Live_in_Horsens_%28cropped2%29.jpg/220px-Tom_Petty_Live_in_Horsens_%28cropped2%29.jpg", +  "Tupac Shakur": "https://upload.wikimedia.org/wikipedia/en/thumb/b/b5/Tupac_Amaru_Shakur2.jpg/220px-Tupac_Amaru_Shakur2.jpg", +  "Usher": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fa/Usher_Cannes_2016_retusche.jpg/220px-Usher_Cannes_2016_retusche.jpg", +  "Whitney Houston": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a7/Whitney_Houston_Welcome_Home_Heroes_1_cropped.jpg/220px-Whitney_Houston_Welcome_Home_Heroes_1_cropped.jpg", +  "Wolfgang Van Halen": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/0c/Wolfgang_Van_Halen_Different_Kind_of_Truth_2012.jpg/220px-Wolfgang_Van_Halen_Different_Kind_of_Truth_2012.jpg" +} diff --git a/bot/rules/newlines.py b/bot/rules/newlines.py index a6a1a52d0..fdad6ffd3 100644 --- a/bot/rules/newlines.py +++ b/bot/rules/newlines.py @@ -1,5 +1,6 @@  """Detects total newlines exceeding the set limit sent by a single user.""" +import re  from typing import Dict, Iterable, List, Optional, Tuple  from discord import Member, Message @@ -17,12 +18,32 @@ async def apply(          if msg.author == last_message.author      ) -    total_recent_newlines = sum(msg.content.count('\n') for msg in relevant_messages) +    # Identify groups of newline characters and get group & total counts +    exp = r"(\n+)" +    newline_counts = [] +    for msg in relevant_messages: +        newline_counts += [len(group) for group in re.findall(exp, msg.content)] +    total_recent_newlines = sum(newline_counts) +    # Get maximum newline group size +    if newline_counts: +        max_newline_group = max(newline_counts) +    else: +        # If no newlines are found, newline_counts will be an empty list, which will error out max() +        max_newline_group = 0 + +    # Check first for total newlines, if this passes then check for large groupings      if total_recent_newlines > config['max']:          return (              f"sent {total_recent_newlines} newlines in {config['interval']}s",              (last_message.author,),              relevant_messages          ) +    elif max_newline_group > config['max_consecutive']: +        return ( +            f"sent {max_newline_group} consecutive newlines in {config['interval']}s", +            (last_message.author,), +            relevant_messages +        ) +      return None diff --git a/config-default.yml b/config-default.yml index d0df50605..747fa7fab 100644 --- a/config-default.yml +++ b/config-default.yml @@ -162,6 +162,9 @@ filter:          - 273944235143593984  # STEM          - 348658686962696195  # RLBot          - 531221516914917387  # Pallets +        - 249111029668249601  # Gentoo +        - 327254708534116352  # Adafruit +        - 544525886180032552  # kennethreitz.org      domain_blacklist:          - pornhub.com @@ -318,6 +321,7 @@ anti_spam:          newlines:              interval: 10              max: 100 +            max_consecutive: 10          role_mentions:              interval: 10 | 
