jarvis-bot/jarvis/cogs/ctc2.py

171 lines
5.7 KiB
Python

import re
from datetime import datetime, timedelta
import aiohttp
import pymongo
from ButtonPaginator import Paginator
from discord import Member, User
from discord.ext import commands
from discord.ext.tasks import loop
from discord.utils import find
from discord_slash import SlashContext, cog_ext
from discord_slash.model import ButtonStyle
from jarvis.config import get_config
from jarvis.db import DBManager
from jarvis.utils import build_embed
from jarvis.utils.cachecog import CacheCog
from jarvis.utils.field import Field
guild_ids = [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)",
flags=re.IGNORECASE,
)
class CTCCog(CacheCog):
def __init__(self, bot):
super().__init__(bot)
mconf = get_config().mongo
self.db = DBManager(mconf["connect"]).mongo
self._session = aiohttp.ClientSession()
self.url = "https://completethecodetwo.cards/pw"
@cog_ext.cog_subcommand(
base="ctc2",
name="about",
description="CTC2 related commands",
guild_ids=guild_ids,
)
@commands.cooldown(1, 30, commands.BucketType.channel)
async def _about(self, ctx):
await ctx.send("See https://completethecode.com for more information")
@cog_ext.cog_subcommand(
base="ctc2",
name="pw",
description="Guess a password for https://completethecodetwo.cards",
guild_ids=guild_ids,
)
@commands.cooldown(1, 2, commands.BucketType.user)
async def _pw(self, ctx: SlashContext, guess: str):
if len(guess) > 800:
await ctx.send(
"Listen here, dipshit. Don't be like "
+ "<@256110768724901889>. Make your guesses < 800 characters.",
hidden=True,
)
return
elif not valid.fullmatch(guess):
await ctx.send(
"Listen here, dipshit. Don't be like "
+ "<@256110768724901889>. Make your guesses *readable*.",
hidden=True,
)
return
elif invites.search(guess):
await ctx.send(
"Listen here, dipshit. "
+ "No using this to bypass sending invite links.",
hidden=True,
)
return
guessed = self.db.ctc2.guesses.find_one({"guess": guess})
if guessed:
await ctx.send("Already guessed, dipshit.", hidden=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.", hidden=True)
self.db.ctc2.guesses.insert_one(
{"guess": guess, "user": ctx.author.id, "correct": correct}
)
@cog_ext.cog_subcommand(
base="ctc2",
name="guesses",
description="Show guesses made for https://completethecodetwo.cards",
guild_ids=guild_ids,
)
@commands.cooldown(1, 2, commands.BucketType.user)
async def _guesses(self, ctx: SlashContext):
exists = self.check_cache(ctx)
if exists:
await ctx.defer(hidden=True)
await ctx.send(
"Please use existing interaction: "
+ f"{exists['paginator']._message.jump_url}",
hidden=True,
)
return
guesses = self.db.ctc2.guesses.find().sort(
[("correct", pymongo.DESCENDING), ("_id", pymongo.DESCENDING)]
)
fields = []
for guess in guesses:
user = ctx.guild.get_member(guess["user"])
if not user:
user = self.bot.fetch_user(guess["user"])
if not user:
user = "[redacted]"
if isinstance(user, User) or isinstance(user, Member):
user = user.name + "#" + user.discriminator
name = "Correctly" if guess["correct"] else "Incorrectly"
name += " guessed by: " + user
fields.append(
Field(
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(
bot=self.bot,
ctx=ctx,
embeds=pages,
timeout=60 * 5, # 5 minute timeout
only=ctx.author,
disable_after_timeout=True,
use_extend=len(pages) > 2,
left_button_style=ButtonStyle.grey,
right_button_style=ButtonStyle.grey,
basic_buttons=["", ""],
)
self.cache[hash(paginator)] = {
"guild": ctx.guild.id,
"user": ctx.author.id,
"timeout": datetime.utcnow() + timedelta(minutes=5),
"command": ctx.subcommand_name,
"paginator": paginator,
}
await paginator.start()
def setup(bot):
bot.add_cog(CTCCog(bot))