jarvis-bot/jarvis/cogs/ctc2.py

151 lines
5.3 KiB
Python

"""JARVIS Complete the Code 2 Cog."""
import logging
import re
import aiohttp
from dis_snek import InteractionContext, Scale, Snake
from dis_snek.ext.paginators import Paginator
from dis_snek.models.discord.components import ActionRow, Button, ButtonStyles
from dis_snek.models.discord.embed import EmbedField
from dis_snek.models.discord.user import Member, User
from dis_snek.models.snek.application_commands import (
OptionTypes,
SlashCommand,
slash_option,
)
from dis_snek.models.snek.command import cooldown
from dis_snek.models.snek.cooldowns import Buckets
from jarvis_core.db import q
from jarvis_core.db.models import Guess
from jarvis.utils import build_embed
guild_ids = [862402786116763668] # [578757004059738142, 520021794380447745, 862402786116763668]
valid = re.compile(r"[\w\s\-\\/.!@#$%^*()+=<>,\u0080-\U000E0FFF]*")
invites = re.compile(
r"(?:https?://)?(?:www.)?(?:discord.(?:gg|io|me|li)|discord(?:app)?.com/invite)/([^\s/]+?)(?=\b)", # noqa: E501
flags=re.IGNORECASE,
)
class CTCCog(Scale):
"""JARVIS Complete the Code 2 Cog."""
def __init__(self, bot: Snake):
self.bot = bot
self.logger = logging.getLogger(__name__)
self._session = aiohttp.ClientSession()
self.url = "https://completethecodetwo.cards/pw"
def __del__(self):
self._session.close()
ctc2 = SlashCommand(name="ctc2", description="CTC2 related commands", scopes=guild_ids)
@ctc2.subcommand(sub_cmd_name="about")
@cooldown(bucket=Buckets.USER, rate=1, interval=30)
async def _about(self, ctx: InteractionContext) -> None:
components = [
ActionRow(
Button(style=ButtonStyles.URL, url="https://completethecode.com", label="More Info")
)
]
await ctx.send(
"See https://completethecode.com for more information", components=components
)
@ctc2.subcommand(
sub_cmd_name="pw",
sub_cmd_description="Guess a password for https://completethecodetwo.cards",
)
@slash_option(
name="guess", description="Guess a password", opt_type=OptionTypes.STRING, required=True
)
@cooldown(bucket=Buckets.USER, rate=1, interval=2)
async def _pw(self, ctx: InteractionContext, guess: str) -> None:
if len(guess) > 800:
await ctx.send(
(
"Listen here, dipshit. Don't be like <@256110768724901889>. "
"Make your guesses < 800 characters."
),
ephemeral=True,
)
return
elif not valid.fullmatch(guess):
await ctx.send(
(
"Listen here, dipshit. Don't be like <@256110768724901889>. "
"Make your guesses *readable*."
),
ephemeral=True,
)
return
elif invites.search(guess):
await ctx.send(
"Listen here, dipshit. No using this to bypass sending invite links.",
ephemeral=True,
)
return
guessed = await Guess.find_one(q(guess=guess))
if guessed:
await ctx.send("Already guessed, dipshit.", ephemeral=True)
return
result = await self._session.post(self.url, data=guess)
correct = False
if 200 <= result.status < 400:
await ctx.send(f"{ctx.author.mention} got it! Password is {guess}!")
correct = True
else:
await ctx.send("Nope.", ephemeral=True)
await Guess(guess=guess, user=ctx.author.id, correct=correct).commit()
@ctc2.subcommand(
sub_cmd_name="guesses",
sub_cmd_description="Show guesses made for https://completethecodetwo.cards",
)
@cooldown(bucket=Buckets.USER, rate=1, interval=2)
async def _guesses(self, ctx: InteractionContext) -> None:
await ctx.defer()
guesses = Guess.find().sort("correct", -1).sort("id", -1)
fields = []
async for guess in guesses:
user = await self.bot.fetch_user(guess["user"])
if not user:
user = "[redacted]"
if isinstance(user, (Member, User)):
user = user.username + "#" + user.discriminator
name = "Correctly" if guess["correct"] else "Incorrectly"
name += " guessed by: " + user
fields.append(
EmbedField(
name=name,
value=guess["guess"] + "\n\u200b",
inline=False,
)
)
pages = []
for i in range(0, len(fields), 5):
embed = build_embed(
title="completethecodetwo.cards guesses",
description=f"{len(fields)} guesses so far",
fields=fields[i : i + 5],
url="https://completethecodetwo.cards",
)
embed.set_thumbnail(url="https://dev.zevaryx.com/db_logo.png")
embed.set_footer(
text="dbrand.com",
icon_url="https://dev.zevaryx.com/db_logo.png",
)
pages.append(embed)
paginator = Paginator.create_from_embeds(self.bot, *pages, timeout=300)
await paginator.send(ctx)
def setup(bot: Snake) -> None:
"""Add CTCCog to JARVIS"""
CTCCog(bot)