async def undone(self): cid = self.__id guild = self.__guild catg_working = load_category(guild, 'working') if not self.is_finished: raise TaskFailed('This ctf challenge has not been completed yet') # Update database chk_upd( self.name, self.__chals.update_one({'chan_id': cid}, {"$set": { 'finished': False }})) # Move channel to working await guild.get_channel(cid).edit(category=catg_working) self.refresh() return [(None, f'Reopened "{self.name}" as not done'), (self.ctf_id, trim_nl(f'''{self.team.mention} "{self.name}" is now undone. :weary:'''))]
async def create(guild, name): # Create role role = await guild.create_role(name=f'{name}_team', mentionable=True) # Create channel chan = await guild.create_text_channel( name=name, topic=f'General talk for {name} CTF event.') await (await chan.send( trim_nl(f'''Welcome to {name}. Here you can do general discussion about this event. Also use this this place to type `ctf` related commands. Here is a list of commands just for reference:\n\n'''))).pin() await (await embed_help(chan, 'CTF team help topic', ctf_help_text)).pin() await (await embed_help(chan, 'Challenge help topic', chal_help_text)).pin() # Update database teamdb[str(guild.id)].insert_one({ \ 'archived': False, 'name': name, 'chan_id': chan.id, 'role_id': role.id, 'chals': []}) CtfTeam.__teams__[chan.id] = CtfTeam(guild, chan.id) return [(None, f'{name} ctf has been created! :tada:')]
async def add_chal(self, name): cid = self.__chan_id guild = self.__guild teams = self.__teams catg_working = load_category(guild, 'working') if self.find_chal(name, False): raise TaskFailed(f'Challenge "{name}" already exists!') # Create a secret channel, initially only with us added. overwrites = { guild.default_role: basic_disallow, guild.me: basic_allow } fullname = f'{self.name}-{name}' chan = await catg_working.create_text_channel(name=fullname, overwrites=overwrites) Challenge.create(guild, cid, chan.id, name) chk_upd( fullname, teams.update_one({'chan_id': cid}, {'$push': { 'chals': chan.id }})) self.refresh() return [(None, trim_nl(f'''Challenge "{name}" has been added! Run `!ctf working {name}` join this challenge channel!'''))]
async def on_command_error(ctx, err): if isinstance(err, MissingPermissions): await ctx.send('You do not have permission to do that! ¯\_(ツ)_/¯') elif isinstance(err, BotMissingPermissions): await ctx.send( trim_nl(f''':cry: I can\'t do that. Please ask server ops to add all the permission for me! ```{str(err)}```''')) elif isinstance(err, DisabledCommand): await ctx.send(':skull: Command has been disabled!') elif isinstance(err, CommandNotFound): await ctx.send('Invalid command passed. Use !help.') elif isinstance(err, TaskFailed): await ctx.send(f':bangbang: {str(err)}') elif isinstance(err, NoPrivateMessage): await ctx.send(':bangbang: This command cannot be used in PMs.') else: await ctx.send('An error has occurred... :disappointed:') log.error(f'Ignoring exception in command {ctx.command}') log.error(''.join( traceback.format_exception(type(err), err, err.__traceback__)))
async def done(self, owner, users): cid = self.__id guild = self.__guild catg_done = load_category(guild, 'done') # Create list of solvers owner = Challenge._uid(owner) users = [Challenge._uid(u) for u in users] users.append(owner) users = list(set(users)) users.sort() mentions = [f'<@{uid}>' for uid in users] # Check if it is solved already if self.is_finished: old_solvers = self.solver_ids old_solvers.sort() if old_solvers == users: raise TaskFailed('This task is already solved with same users') # Update database chk_upd(self.name, self.__chals.update_one({'chan_id': cid}, {"$set": { \ 'finished': True, 'owner': owner, 'solvers': users }})) # Move channel to done await guild.get_channel(cid).edit(category=catg_done) mentions = ' '.join(mentions) self.refresh() return [ \ (self.ctf_id, trim_nl(f'''{self.team.mention} :tada: "{self.name}" has been completed by {mentions}!''')), (None, f'Challenge moved to done!')]