예제 #1
0
    async def cmd_list(self, ctx, full=""):
        cmds = []
        suffix = Lang.lang(self, 'list_suffix') if full else ""

        for k in self.commands.keys():
            if full:
                arg_lens = []
                for t in self.commands[k].texts:
                    arg_list = arg_list_re.findall(t)
                    arg_lens.append(len(arg_list))
                cmds.append(
                    Lang.lang(self, 'list_full_data', k,
                              len(self.commands[k].texts), max(arg_lens)))

            else:
                cmds.append(k)

        if not cmds:
            await ctx.send(Lang.lang(self, 'list_no_cmds'))
            return

        cmds.sort(key=str.lower)
        cmd_msgs = utils.paginate(cmds, delimiter=", ", suffix=suffix)
        for msg in cmd_msgs:
            await ctx.send(msg)
예제 #2
0
    async def bugscore_increment(self, ctx, user, increment):
        if discord.utils.get(ctx.author.roles,
                             id=Config().BOTMASTER_ROLE_ID) is None:
            await ctx.message.add_reaction(Lang.CMDNOPERMISSIONS)
            return

        # find user
        try:
            user = await commands.MemberConverter().convert(ctx, user)
        except (commands.CommandError, IndexError):
            await ctx.send(Lang.lang(self, "bugscore_user_not_found", user))
            await ctx.message.add_reaction(Lang.CMDERROR)
            return

        try:
            increment = int(increment)
        except (ValueError, TypeError):
            await ctx.send(Lang.lang(self, "bugscore_nan", increment))
            await ctx.message.add_reaction(Lang.CMDERROR)
            return

        if user.id in self.storage["bugscore"]:
            self.storage["bugscore"][user.id] += increment
        else:
            self.storage["bugscore"][user.id] = increment
        if self.storage["bugscore"][user.id] <= 0:
            del self.storage["bugscore"][user.id]
        Storage.save(self)
        await ctx.message.add_reaction(Lang.CMDSUCCESS)
예제 #3
0
파일: mod.py 프로젝트: KDanny41/Geckarbot
    async def disable(self, ctx, command, *args):
        user = ctx.author
        date_args_start_index = 0
        if len(args) > 0:
            try:
                user = await commands.MemberConverter().convert(ctx, args[0])
                date_args_start_index = 1
            except (commands.CommandError, IndexError):
                date_args_start_index = 0

        if user != ctx.author and not permChecks.check_full_access(ctx.author):
            raise commands.MissingAnyRole(Config().FULL_ACCESS_ROLES)

        until = utils.analyze_time_input(*args[date_args_start_index:])

        result = self.bot.ignoring.add_user_command(user, command, until)
        if result == IgnoreEditResult.Success:
            await ctx.message.add_reaction(Lang.CMDSUCCESS)
        elif result == IgnoreEditResult.Already_in_list:
            await ctx.message.add_reaction(Lang.CMDERROR)
            await ctx.send(Lang.lang(self, 'user_cmd_already_blocked', command, utils.get_best_username(user)))
        elif result == IgnoreEditResult.Until_in_past:
            await ctx.message.add_reaction(Lang.CMDERROR)
            await ctx.send(Lang.lang(self, 'no_time_machine'))
        await utils.log_to_admin_channel(ctx)
예제 #4
0
파일: roles.py 프로젝트: KDanny41/Geckarbot
    async def create_message_text(self, server_roles, ctx):
        """
        Returns the message text for the role manage init message
        including the reactions and mod roles for the roles
        :param server_roles: the roles on the server
        :param ctx: The context of the used command to create the new message
        """
        msg = "{}\n".format(Storage().get(self)['message']['content'])

        for rid in self.rc():
            role = discord.utils.get(server_roles, id=rid)
            emote_msg = ""
            modrole_msg = ""

            if self.rc()[rid]['emoji']:
                emote_msg = Lang.lang(
                    self, 'init_reaction', await
                    utils.emojize(self.rc()[rid]['emoji'], ctx))
            if self.rc()[rid]['modrole'] != 0:
                modrole = discord.utils.get(server_roles,
                                            id=self.rc()[rid]['modrole'])
                modrole_msg = Lang.lang(self, 'init_modrole', modrole.name)

            if emote_msg and modrole_msg:
                todo_part = "{}, {}".format(emote_msg, modrole_msg)
            elif emote_msg:
                todo_part = emote_msg
            elif modrole_msg:
                todo_part = modrole_msg
            else:
                todo_part = Lang.lang(self, 'init_admin')

            msg += "\n{} - {}".format(role.name, todo_part)

        return msg
예제 #5
0
    async def end(self):

        embed = self.score.embed()
        winners = [get_best_username(Storage().get(self.plugin), x) for x in self.score.winners()]

        # Übergangslösung
        points = self.score.points()
        for user in points:
            self.plugin.update_ladder(user, points[user])

        msgkey = "quiz_end"
        if len(winners) > 1:
            msgkey = "quiz_end_pl"
        elif len(winners) == 0:
            msgkey = "quiz_end_no_winner"
        winners = utils.format_andlist(winners, ands=Lang.lang(self.plugin, "and"),
                                       emptylist=Lang.lang(self.plugin, "nobody"))
        msg = Lang.lang(self.plugin, msgkey, winners)

        if msg is None:
            await self.channel.send(embed=embed)
        elif embed is None:
            await self.channel.send(msg)
        else:
            await self.channel.send(msg, embed=embed)

        self.plugin.end_quiz(self.channel)
예제 #6
0
    async def on_message(self, msg):
        self.plugin.logger.debug("Caught message: {}".format(msg.content))
        # ignore DM and msg when the quiz is not in question phase
        if not isinstance(msg.channel, discord.TextChannel):
            return
        if self.state != Phases.QUESTION:
            self.plugin.logger.debug("Ignoring message, quiz is not in question phase")
            return

        # Valid answer
        try:
            check = self.quizapi.current_question().check_answer(msg.content)
            if check:
                reaction = "reaction_correct"
            else:
                reaction = "reaction_incorrect"
            self.plugin.logger.debug("Valid answer from {}: {} ({})".format(msg.author.name, msg.content, reaction))
        except InvalidAnswer:
            return

        if not self.debug and self.last_author == msg.author:
            await msg.channel.send(Lang.lang(self.plugin, "answering_order", msg.author))
            return

        self.last_author = msg.author
        if check:
            self.state = Phases.EVAL
        await msg.add_reaction(Lang.lang(self.plugin, reaction))
예제 #7
0
    async def search(self, ctx, *args):
        if len(args) == 0:
            await ctx.message.add_reaction(Lang.CMDERROR)
            await ctx.send(Lang.lang(self, "redact_search_args"))
            return

        r = []
        for i in self.complaints:
            complaint = self.complaints[i]
            found = True
            for searchterm in args:
                # Search check
                if searchterm.lower() not in complaint.to_message().lower():
                    found = False
                    break
            if not found:
                continue

            # Search result
            r.append(complaint)

        if not r:
            await ctx.send(Lang.lang(self, "redact_search_not_found"))
            return

        msgs = utils.paginate(r,
                              prefix=Lang.lang(self, "redact_search_title"),
                              delimiter="\n\n",
                              f=to_msg)
        for el in msgs:
            await ctx.send(el)
예제 #8
0
    async def register_command(self, msg, *args):
        """
        This is the callback for !kwiss register.
        :param msg: Message object
        :param args: Passed arguments, including "register"
        """
        assert self.cmdstring_register in args
        if "skip" in args:
            self.state = Phases.ABOUTTOSTART
            return

        if len(args) > 1:
            await self.channel.send(Lang.lang(self.plugin, "too_many_arguments"))
            return

        if self.state == Phases.INIT:
            await self.channel.send("No idea how you did that, but you registered too early.")
            return

        if self.state != Phases.REGISTERING:
            await self.channel.send(Lang.lang(self.plugin, "registering_too_late", msg.author))
            return

        if msg.author in self.registered_participants:
            return

        self.registered_participants[msg.author] = []
        self.score.add_participant(msg.author)
        self.plugin.logger.debug("{} registered".format(msg.author.name))
        await msg.add_reaction(Lang.CMDSUCCESS)
예제 #9
0
    async def end(self):

        embed = self.score.embed()
        winners = [get_best_username(Storage().get(self.plugin), x) for x in self.score.winners()]

        msgkey = "quiz_end"
        if len(winners) > 1:
            msgkey = "quiz_end_pl"
        elif len(winners) == 0:
            msgkey = "quiz_end_no_winner"
        winners = utils.format_andlist(winners, ands=Lang.lang(self.plugin, "and"),
                                       emptylist=Lang.lang(self.plugin, "nobody"))
        msg = Lang.lang(self.plugin, msgkey, winners)
        if msg is None:
            await self.channel.send(embed=embed)
        elif embed is None:
            await self.channel.send(msg)
        else:
            await self.channel.send(msg, embed=embed)

        if self.ranked:
            for player in self.registered_participants:
                self.plugin.update_ladder(player, self.score.calc_points(player))

        self.plugin.end_quiz(self.channel)
예제 #10
0
    async def dm_callback(self, cb, message):
        self.plugin.logger.debug("Incoming message from {}: {}".format(
            self.user, message.content))
        if message.content.strip() == "":
            # you never know
            return

        if self.plugin.statemachine.state != State.COLLECT:
            await self.send(Lang.lang(self.plugin, "entry_too_late"))
            return

        first = True
        if self.chosen:
            first = False

        self.chosen = message.content
        if first:
            await self.send(
                Lang.lang(self.plugin, "entry_done",
                          utils.get_best_username(self.assigned.user),
                          self.chosen))
        else:
            await self.send(Lang.lang(self.plugin, "entry_change",
                                      self.chosen))

        self.plugin.assigned()
예제 #11
0
파일: dsc.py 프로젝트: KDanny41/Geckarbot
    async def dsc_status(self, ctx):
        if Storage.get(self)['status']:
            status_msg = Lang.lang(self, 'status_base', Storage.get(self)['status'])
        else:
            status_msg = Lang.lang(self, 'status_base', Lang.lang(self, 'status_none'))

        await ctx.send(status_msg)
예제 #12
0
파일: dsc.py 프로젝트: KDanny41/Geckarbot
    async def dsc_winners(self, ctx):
        c = self.get_api_client()
        winners = c.get(Config.get(self)['winners_range'])

        w_msgs = []
        regex = re.compile(r"\d+")
        for w in winners[1:]:
            if w[0] is None or not w[0]:
                continue

            m0 = regex.findall(w[0])
            m2 = regex.findall(w[2])
            no = m0[0]
            dt = datetime(int(m0[2]), int(m0[1]), 1)
            participator_coutn = m0[3]
            winner_name = w[1]
            pts_winner = int(m2[0])
            pts_max = int(m2[1])
            pts_percentage = round(pts_winner / pts_max * 100)

            w_msgs.append(Lang.lang(self, 'winner_msg', no, winner_name, pts_winner, pts_max, pts_percentage,
                                    participator_coutn, dt.month, dt.year))

        for m in utils.paginate(w_msgs, Lang.lang(self, 'winner_prefix')):
            await ctx.send(m)
예제 #13
0
    async def cmd_add(self, ctx, cmd_name, *args):
        if not "".join(args):
            await ctx.message.add_reaction(Lang.CMDERROR)
            raise commands.MissingRequiredArgument(
                inspect.signature(self.cmd_add).parameters['args'])
        cmd_name = cmd_name.lower()

        # TODO Process multiple output texts
        cmd_texts = [" ".join(args)]

        # Process special discord /cmd
        for i in range(0, len(cmd_texts)):
            contains_me = cmd_texts[i].lower().startswith("/me")

            if contains_me:
                cmd_texts[i] = "_{}_".format(cmd_texts[i][3:])

        if cmd_name in self.commands:
            self.commands[cmd_name].texts.extend(cmd_texts)
            self.save()
            await ctx.message.add_reaction(Lang.CMDSUCCESS)
            await ctx.send(Lang.lang(self, "add_exists", cmd_name))
        else:
            self.commands[cmd_name] = Cmd(cmd_name, ctx.author.id, cmd_texts)
            self.save()
            # await utils.log_to_admin_channel(ctx)
            await ctx.message.add_reaction(Lang.CMDSUCCESS)
            await utils.write_debug_channel(
                self.bot,
                Lang.lang(self, 'cmd_added',
                          self.commands[cmd_name].get_raw_texts()))
예제 #14
0
 async def abortphase(self):
     self.plugin.end_quiz(self.channel)
     if self.current_question_timer is not None:
         try:
             self.current_question_timer.cancel()
         except utils.HasAlreadyRun:
             pass
     if self.ranked and len(self.registered_participants) < self.config["ranked_min_players"]:
         await self.channel.send(Lang.lang(self.plugin, "ranked_playercount", self.config["ranked_min_players"]))
     else:
         await self.channel.send(Lang.lang(self.plugin, "quiz_abort"))
예제 #15
0
파일: misc.py 프로젝트: KDanny41/Geckarbot
    async def choose(self, ctx, *args):
        full_options_str = " ".join(args)
        if "sabaton" in full_options_str.lower():
            await ctx.send(Storage.lang(self, 'choose_sabaton'))

        options = [i for i in full_options_str.split("|") if i.strip() != ""]
        if len(options) < 1:
            await ctx.send(Lang.lang(self, 'choose_noarg'))
            return
        result = random.choice(options)
        await ctx.send(Lang.lang(self, 'choose_msg') + result.strip())
예제 #16
0
    async def eval(self):
        """
        Is called when the question is over. Evaluates scores and cancels the timer.
        :return:
        """
        self.plugin.logger.debug("Ending question")

        # End timeout timer
        if self.current_question_timer is not None:
            try:
                self.current_question_timer.cancel()
            except utils.HasAlreadyRun:
                self.plugin.logger.warning("This should really, really not happen.")
            self.current_question_timer = None
        else:
            # We ran into a timeout and need to give that function time to communicate this fact
            await asyncio.sleep(1)

        if self.current_reaction_listener is not None:
            self.current_reaction_listener.unregister()

        question = self.quizapi.current_question()

        # Normalize answers
        for el in self.registered_participants:
            if len(self.registered_participants[el]) != 1:
                self.registered_participants[el] = None
            else:
                self.registered_participants[el] = self.registered_participants[el][0]

        # Increment scores
        correctly_answered = []
        for user in self.registered_participants:
            if question.check_answer(self.registered_participants[user], emoji=True):
                correctly_answered.append(user)

        for user in correctly_answered:
            self.score.increase(user, self.current_question, totalcorr=len(correctly_answered))

        correct = [get_best_username(Storage().get(self.plugin), el) for el in correctly_answered]
        correct = utils.format_andlist(correct, Lang.lang(self.plugin, "and"), Lang.lang(self.plugin, "nobody"))
        if self.config["emoji_in_pose"]:
            ca = question.correct_answer_emoji
        else:
            ca = question.correct_answer_letter
        await self.channel.send(Lang.lang(self.plugin, "points_question_done", ca, correct))

        # Reset answers list
        for user in self.registered_participants:
            self.registered_participants[user] = []

        await asyncio.sleep(self.config["question_cooldown"])
        self.state = Phases.QUESTION
예제 #17
0
파일: misc.py 프로젝트: KDanny41/Geckarbot
 async def reminder_callback(self, job):
     channel = self.bot.get_channel(job.data['chan'])
     user = self.bot.get_user(job.data['user'])
     text = job.data['text']
     rid = job.data['id']
     remind_text = ""
     if text:
         remind_text = Lang.lang(self, 'remind_callback_msg', text)
     await channel.send(
         Lang.lang(self, 'remind_callback', user.mention, remind_text))
     logging.info("Executed reminder {}".format(rid))
     self.remove_reminder(rid)
예제 #18
0
파일: mod.py 프로젝트: KDanny41/Geckarbot
    async def disable_user(self, ctx, user: discord.Member, *args):
        until = utils.analyze_time_input(*args)

        result = self.bot.ignoring.add_user(user, until)
        if result == IgnoreEditResult.Success:
            await ctx.message.add_reaction(Lang.CMDSUCCESS)
        elif result == IgnoreEditResult.Already_in_list:
            await ctx.message.add_reaction(Lang.CMDERROR)
            await ctx.send(Lang.lang(self, 'user_already_blocked', utils.get_best_username(user)))
        elif result == IgnoreEditResult.Until_in_past:
            await ctx.message.add_reaction(Lang.CMDERROR)
            await ctx.send(Lang.lang(self, 'no_time_machine'))
        await utils.log_to_admin_channel(ctx)
예제 #19
0
    async def delivering_phase(self):
        for target in self.participants:
            todo = []
            for el in self.participants:
                if el.assigned != target:
                    todo.append(el.to_msg(show_assignees=self.show_assignees))

            for msg in utils.paginate(todo,
                                      prefix=Lang.lang(self, "list_title")):
                await target.send(msg)
        await self.channel.send(Lang.lang(self, "done"))
        self.cleanup()
        self.statemachine.state = State.IDLE
예제 #20
0
 async def cmd_raw(self, ctx, cmd_name):
     cmd_name = cmd_name.lower()
     if cmd_name in self.commands:
         creator = self.bot.get_user(self.commands[cmd_name].creator_id)
         for msg in utils.paginate(self.commands[cmd_name].get_raw_texts(),
                                   delimiter="\n",
                                   prefix=Lang.lang(
                                       self, 'raw_prefix', self.prefix,
                                       cmd_name,
                                       utils.get_best_username(creator))):
             await ctx.send(msg)
     else:
         await ctx.send(Lang.lang(self, "raw_doesnt_exists", cmd_name))
예제 #21
0
    async def redact(self, ctx):
        # Printing complaints
        if len(self.complaints) == 0:
            await ctx.send(Lang.lang(self, "redact_no_complaints"))
            return

        msgs = utils.paginate([el for el in self.complaints.values()],
                              prefix=Lang.lang(self, "redact_title"),
                              delimiter="\n\n",
                              msg_prefix="_ _\n",
                              f=to_msg)
        for el in msgs:
            await ctx.send(el)
예제 #22
0
파일: roles.py 프로젝트: KDanny41/Geckarbot
    async def role_add(self,
                       ctx,
                       role_name,
                       emoji_or_modrole="",
                       color: discord.Color = None):
        emoji_str = await utils.demojize(emoji_or_modrole, ctx)
        try:
            modrole = await commands.RoleConverter().convert(
                ctx, emoji_or_modrole)
            modrole_id = modrole.id
            emoji_str = ""
        except commands.CommandError:
            modrole_id = 0

        if not emoji_str and modrole_id == 0:
            try:
                color = await commands.ColourConverter().convert(
                    ctx, emoji_or_modrole)
            except (commands.CommandError, IndexError):
                color = discord.Color.default()

        try:
            existing_role = await commands.RoleConverter().convert(
                ctx, role_name)
        except commands.CommandError:
            existing_role = None
        if existing_role is not None:
            if existing_role.id in self.rc():
                # Update role data
                if emoji_str:
                    self.rc()[existing_role.id]['emoji'] = emoji_str
                if modrole_id != 0:
                    self.rc()[existing_role.id]['modrole'] = modrole_id
                await self.update_role_management(ctx)
                await ctx.send(Lang.lang(self, 'role_add_updated', role_name))
            else:
                # role exists on server, but not in config, add it there
                self.rc()[existing_role.id] = {
                    'emoji': emoji_str,
                    'modrole': modrole_id
                }
                await self.update_role_management(ctx)
                await ctx.send(Lang.lang(self, 'role_add_config', role_name))
            return

        # Execute role add
        new_role = await add_server_role(ctx.guild, role_name, color)
        self.rc()[new_role.id] = {'emoji': emoji_str, 'modrole': modrole_id}
        await self.update_role_management(ctx)
        await ctx.send(Lang.lang(self, 'role_add_created', role_name, color))
        await utils.log_to_admin_channel(ctx)
예제 #23
0
파일: dsc.py 프로젝트: KDanny41/Geckarbot
    async def dsc_set_config(self, ctx, key="", value=""):
        if not key and not value:
            await ctx.invoke(self.bot.get_command("configdump"), self.get_name())
            return

        if key and not value:
            key_value = Config.get(self).get(key, None)
            if key_value is None:
                await ctx.message.add_reaction(Lang.CMDERROR)
                await ctx.send(Lang.lang(self, 'key_not_exists', key))
            else:
                await ctx.message.add_reaction(Lang.CMDSUCCESS)
                await ctx.send(key_value)
            return

        if key == "channel_id":
            channel = None
            int_value = Config.get(self)['channel_id']
            try:
                int_value = int(value)
                channel = self.bot.guild.get_channel(int_value)
            except ValueError:
                pass
            if channel is None:
                Lang.lang(self, 'channel_id_int')
                await ctx.message.add_reaction(Lang.CMDERROR)
                return
            else:
                Config.get(self)[key] = int_value

        elif key == "songmaster_role_id":
            role = None
            int_value = Config.get(self)['songmaster_role_id']
            try:
                int_value = int(value)
                role = self.bot.guild.get_role(int_value)
            except ValueError:
                pass
            if role is None:
                Lang.lang(self, 'songmaster_id')
                await ctx.message.add_reaction(Lang.CMDERROR)
                return
            else:
                Config.get(self)[key] = int_value

        else:
            Config.get(self)[key] = value

        Config.save(self)
        await ctx.message.add_reaction(Lang.CMDSUCCESS)
예제 #24
0
파일: misc.py 프로젝트: KDanny41/Geckarbot
 async def kicker_table(self, ctx):
     embed = discord.Embed(title=Lang.lang(self, 'kicker_title'))
     embed.add_field(name=Lang.lang(self, 'kicker_1BL'),
                     value=Lang.lang(self, 'kicker_1BL_link'))
     embed.add_field(name=Lang.lang(self, 'kicker_2BL'),
                     value=Lang.lang(self, 'kicker_2BL_link'))
     embed.add_field(name=Lang.lang(self, 'kicker_3FL'),
                     value=Lang.lang(self, 'kicker_3FL_link'))
     embed.add_field(name=Lang.lang(self, 'kicker_ATBL'),
                     value=Lang.lang(self, 'kicker_ATBL_link'))
     await ctx.send(embed=embed)
예제 #25
0
    async def collecting_phase(self):
        assert len(self.participants) > 1

        msg = [utils.get_best_username(el.user) for el in self.participants]
        msg = utils.format_andlist(msg, ands=Lang.lang(self, "and"))
        msg = Lang.lang(self, "list_participants", msg)
        await self.channel.send(msg)

        shuffled = self.participants.copy()
        utils.trueshuffle(shuffled)
        for i in range(len(self.participants)):
            self.participants[i].assign(shuffled[i])

        for el in self.participants:
            await el.init_dm()
예제 #26
0
파일: roles.py 프로젝트: KDanny41/Geckarbot
    async def role_request(self, ctx, role: discord.Role):
        modrole = None
        for configured_role in self.rc():
            if configured_role == role.id:
                modrole = discord.utils.get(
                    ctx.guild.roles, id=self.rc()[configured_role]['modrole'])
                break

        if modrole is None:
            await ctx.send(
                Lang.lang(self, 'role_request_no_modrole', role.name))
        else:
            await ctx.send(
                Lang.lang(self, 'role_request_ping', modrole.mention,
                          ctx.author.mention, role.name))
예제 #27
0
    async def timeout(self, question):
        """
        :param question: Question object of the question that was running at timer start time.
        """
        if self.current_question != question or self.state != Phases.QUESTION:
            # We are out of date
            self.plugin.logger.debug("Timeout warning out of date")
            return

        self.current_question_timer = None
        self.plugin.logger.debug("Question timeout")
        msg = Lang.lang(self.plugin, "points_timeout", self.quizapi.current_question_index(),
                        utils.format_andlist(self.havent_answered_hr(), ands=Lang.lang(self.plugin, "and")))
        self.state = Phases.EVAL
        await self.channel.send(msg)
예제 #28
0
파일: misc.py 프로젝트: KDanny41/Geckarbot
    async def who_mobbing(self, ctx):
        after_date = (datetime.now(timezone.utc) -
                      timedelta(minutes=30)).replace(tzinfo=None)
        users = [self.bot.user]
        messages = await ctx.channel.history(after=after_date).flatten()
        for message in messages:
            if message.author not in users:
                users.append(message.author)

        bully = random.choice(users)

        if bully is self.bot.user:
            text = Lang.lang(self, "bully_msg_self")
        else:
            text = Lang.lang(self, "bully_msg", utils.get_best_username(bully))
        await ctx.send(text)
예제 #29
0
 async def stopcmd(self, ctx):
     if self.statemachine.state == State.IDLE:
         await ctx.message.add_reaction(Lang.CMDERROR)
         await ctx.send(Lang.lang(self, "not_running"))
         return
     await ctx.message.add_reaction(Lang.CMDSUCCESS)
     self.cleanup()
예제 #30
0
파일: dsc.py 프로젝트: KDanny41/Geckarbot
 async def dsc_set_state(self, ctx, state):
     if state.lower() == "voting":
         await self._dsc_save_state(ctx, DscState.Voting)
     elif state.lower() == "signup":
         await self._dsc_save_state(ctx, DscState.Sign_up)
     else:
         await ctx.send(Lang.lang(self, 'invalid_phase'))