Пример #1
0
def instant_death(user_id,
                  role,
                  deathType,
                  answer=Mailbox().log(''),
                  recursive=''):
    """Eliminate the given user."""

    # If the user was reporter or mayor, get rid of that.
    if dy.get_mayor() == user_id:
        dy.kill_mayor()
        answer.remove_proms(user_id)
    if dy.get_reporter() == user_id:
        dy.kill_reporter()
        answer.remove_proms(user_id)

    for channel_id in db.get_secret_channels("Graveyard"):
        answer.edit_cc(channel_id, user_id, 1)

    # Change all channel settings
    for channel_id in db.channel_change_all(user_id, 1, 4):
        answer.edit_cc(channel_id, user_id, 4)
    for channel_id in db.channel_change_all(user_id, 2, 4):
        answer.edit_cc(channel_id, user_id, 4)
    for channel_id in db.channel_change_all(user_id, 5, 4):
        answer.edit_cc(channel_id, user_id, 4)

    # Change abducted settings
    for channel_id in db.channel_change_all(user_id, 3, 7):
        answer.edit_cc(channel_id, user_id, 7)
    for channel_id in db.channel_change_all(user_id, 6, 7):
        answer.edit_cc(channel_id, user_id, 7)

    for channel_id in db.get_secret_channels("Market"):
        answer.edit_cc(channel_id, user_id, 4)

    for channel_id in db.get_secret_channels("Reporter"):
        if int(db_get(user_id, 'undead')) == 1:
            answer.msg(
                "{} - <@{}> had the role of the `Undead`!".format(
                    db_get(user_id, 'emoji'), user_id), channel_id)
        else:
            answer.msg(
                "{} - <@{}> had the role of the `{}`!".format(
                    db_get(user_id, 'emoji'), user_id,
                    db_get(user_id, 'role')), channel_id)

    # Kill that user already!
    db_set(user_id, 'role', 'Dead')
    db_set(user_id, 'fakerole', 'Dead')

    answer.spam(unip + 'kill <@{}>'.format(user_id))

    if int(db_get(user_id, 'abducted')) != 1 and role not in ["Barber"]:
        db.insert_deadie(user_id, deathType)

    # Kill all standoffs
    for taker in db.get_standoff(user_id):
        answer = attack(taker[1], taker[2], taker[3], answer, recursive)

    return answer
Пример #2
0
def night():
    """Start the second part of the day.  
    The function assumes all polls have been evaluated, and that looking after attacks can begin.  
    The function returns a Mailbox."""
    threat = db.get_kill()
    answer = Mailbox().log("**Results from daily deaths:**")

    if dy.get_stage() == "Night":
        return Mailbox().respond("Sure, man. Whatever.")

    while threat != None:

        answer = roles.attack(threat[1],threat[2],threat[3],answer)
        threat = db.get_kill()

    for player in db.player_list(True):
        # Give potential night uses
        user_role = db_get(player,'role')
        for i in range(len(roles.night_users)):
            if user_role in roles.night_users[i]:
                # Give one-time users their one-time power
                if i == 0:
                    if dy.day_number() == 0:
                        db_set(player,'uses',1)
                    break

                if user_role in ['White Werewolf'] and dy.day_number() % 2 == 0:
                    i = 1

                db_set(player,'uses',i)
                answer.msg(power.power(user_role),db_get(player,'channel'))
                break

    answer.story(evening.evening(db.get_deadies()))
    db.delete_deadies()

    # Add polls
    for player in db.player_list():
        if db_get(player,'role') in pos.wolf_pack:
            for channel_id in db.get_secret_channels('Werewolf'):
                answer.new_poll(channel_id,'wolf',db.random_wolf(),story_text('wolf'))
            break
    for player in db.player_list():
        if db_get(player,'role') == 'Cult Leader':
            for channel_id in db.get_secret_channels('Cult_Leader'):
                answer.new_poll(channel_id,'cult',db.random_cult(),story_text('cult'))
            break
    for channel_id in db.get_secret_channels('Swamp'):
        answer.new_poll(channel_id,'thing','',story_text('thing'))

    answer.log("```Night {}```".format(dy.day_number()))
    dy.set_stage("Night")

    return answer
Пример #3
0
def test_secrets():
  reset.reset(True)
  assert db.get_secret_channels('Assassin') == []
  db.add_secret_channel(1,'Assassin')
  db.add_secret_channel(2,'Assassin')
  assert db.get_secret_channels('Assassin') == [1,2]
  db.add_secret_channel(3,'Werewolf')
  assert db.get_secret_channels('Assassin') == [1,2]
  db.add_secret_channel(4,'Assassin')
  assert db.get_secret_channels('Assassin') == [1,2,4]
  reset.reset(True)
Пример #4
0
def test_amulets():
  reset.reset(True)
  db.signup(1,'Alice',':hugging:')
  db.signup(2,'Bob',':smirk:')
  db.signup(3,'Charlie',':orange_book:')

  db.add_category(100,True)
  db.add_channel(10,1,True)
  db.add_channel(11,2,True)
  db.add_channel(12,1,True)

  db.add_secret_channel(10,'Amulet_Holder')
  db.add_secret_channel(11,'Amulet_Holder')

  db.set_user_in_channel(10,1,1)
  db.set_user_in_channel(10,2,3)
  db.set_user_in_channel(11,2,1)
  db.set_user_in_channel(12,1,1)
  db.set_user_in_channel(12,3,1)

  assert db.get_secret_channels('Amulet_Holder') == [10,11]

  assert db.amulets(1) == [10]
  assert db.amulets(2) == [10,11]
  assert db.amulets(3) == []
  assert db.has_amulet(1) == True
  assert db.has_amulet(3) == False
  reset.reset(True)
Пример #5
0
    def freeze(self, user_id):
        """Freeze a user.  
        This function alters the Mailbox, so 'add' and react commands may not work as intended."""
        db_set(user_id, 'frozen', 1)
        self.spam("<@{}> was frozen.".format(user_id))
        to_freeze = channel_change_all(user_id, 1, 2)

        for channel_id in get_secret_channels('Frozen_Realm'):
            self.edit_cc(channel_id, user_id, 1)
        for channel_id in to_freeze:
            self.edit_cc(channel_id, user_id, 2)
        return self
Пример #6
0
    def abduct(self, user_id):
        """Abduct a user.  
        This function alters the Mailbox, so 'add' and react commands may not work as intended."""
        db_set(user_id, 'abducted', 1)
        self.spam("<@{}> has been abducted.".format(user_id))

        for channel_id in channel_change_all(user_id, 1, 3):
            self.edit_cc(channel_id, user_id, 3)
        for channel_id in channel_change_all(user_id, 5, 6):
            self.edit_cc(channel_id, user_id, 6)
        for channel_id in get_secret_channels('Swamp'):
            self.edit_cc(channel_id, user_id, 1)
        return self
Пример #7
0
def dog_follow(user_id, role):
    """This function allows the dog to choose a role to become.
    The function assumes the player is a cupid and has provided a role, so make sure to have filtered this out already.
    The role does not need to be Innocent, Cursed Civilian or Werewolf yet.
    The function returns a Mailbox.

    user_id -> the dog who chooses a role
    role -> the role they'd like to be"""

    uses = int(db_get(user_id, 'uses'))
    if uses < 1:
        return Mailbox().respond(
            "I am sorry! You currently cannot choose a role to become!", True)

    user_channel = int(db_get(user_id, 'channel'))

    if role not in ['Innocent', 'Cursed Civilian', 'Werewolf']:
        return Mailbox().msg(
            "I'm sorry, <{}>. Being a dog lets you choose a role, but it doesn't mean you can become ANYTHING."
            .format(user_id), user_channel, True)

    db_set(user_id, 'uses', uses - 1)

    answer = Mailbox().msg(
        "You have chosen to become the **{}**!".format(role), user_channel)
    answer.log("The **Dog** <@{}> has chosen to become a".format(user_id))

    if role == 'Innocent':
        answer.log_add('n **Innocent**!').dm(
            "You have chosen to become an **Innocent**. Protect the town, kill all those wolves!",
            user_id)
    if role == 'Cursed Civilian':
        answer.log_add(' **Cursed Civilian**!').dm(
            "You have chosen to become a **Cursed Civilian**! You will be part of the town... for now.",
            user_id)
    if role == 'Werewolf':
        answer.log_add(' **Werewolf**!').dm(
            "You have chosen to become a **Werewolf**! You will now join the wolf pack!",
            user_id)
        for channel_id in db.get_secret_channels("Werewolf"):
            answer.edit_cc(channel_id, user_id, 1)
            if int(db_get(user_id, 'frozen')) == 1:
                answer.edit_cc(channel_id, user_id, 2)
            answer.msg(
                "**ARRROOOO!\nWelcome, <@{0}>, to the wolf pack!** <@{0}>, a **Dog**, has chosen to turn themselves into a Werewolf! Give them a warm welcome."
                .format(user_id), channel_id)

    db_set(user_id, 'role', role)
    return answer
Пример #8
0
def enchant(user_id,victim_id):
    """This function allows the flute player to enchant targets.
    The function assumes both players are participants, of which the casting user is a flute player. Make sure to have filtered this out already.
    The function returns a Mailbox.

    Keyword arguments:
    user_id -> the flute player who enchants the player
    victim_id -> the player who's enchanted"""

    uses = int(db_get(user_id,'uses'))
    if uses < 1:
        return Mailbox().respond("I am sorry! You currently don't have the ability to enchant anyone!",True)

    user_channel = int(db_get(user_id,'channel'))
    user_undead = int(db_get(user_id,'undead'))

    victim_frozen = int(db_get(victim_id,'frozen'))
    victim_abducted = int(db_get(victim_id,'abducted'))
    victim_enchanted = int(db_get(victim_id,'enchanted'))

    if db_get(victim_id,'role') == 'Flute Player':
        return Mailbox().msg("You cannot enchant a flute player, sorry.",user_channel,True)
    if victim_abducted == 1:
        return Mailbox().msg("You wanted to warm up <@{}>... but you weren't able to find them! That is strange...",user_channel,True)
    if victim_frozen == 1:
        return Mailbox().msg("You failed to enchant your target, as they were frozen to the bone!.",user_channel,True)
    if victim_enchanted == 1:
        return Mailbox().msg("I am terribly sorry, but you cannot enchant a player who already *IS* enchanted!",user_channel,True)

    answer = Mailbox().msg("You have successfully enchanted <@{}>!".format(victim_id),user_channel)
    db_set(user_id,'uses',uses - 1)

    if user_undead == 1:
        answer.dm("You're an Undead, so you can't actually enchant anyone... but this will help you keep up your cover!",user_id)
        answer.log("The **Undead** <@{}> has pretended to enchant <@{}>.".format(user_id,victim_id))
    else:
        for channel_id in db.get_secret_channels('Flute_Victims'):
            answer.edit_cc(channel_id,victim_id,1)
            answer.msg("<@{}> has been enchanted! Please welcome them to the circle of the enchanted ones.".format(victim_id),channel_id)
        answer.log("The **Flute Player** <@{}> has enchanted <@{}>.".format(user_id,victim_id))
        db_set(victim_id,'enchanted',1)

    return answer
Пример #9
0
def attack(user_id, role, murderer, answer=Mailbox().log(''), recursive='\n'):
    """This functions attacks the given player with the given role.  
    The effects are immediate, but they can be used in all scenarios, as only\
    standoffs are executed during this attack."""

    if role == 'Inactive':
        answer.log_add(recursive + success + skull +
                       "<@{}> was killed due to inactivity.".format(user_id))
        return instant_death(user_id, role, 'Inactive', answer,
                             recursive + next)

    # Prevent Pyromancer from causing way too long lines
    # No, I didn't add this during debugging.
    # Yes, that means I planned to design it this terribly.
    if role == 'Pyromancer' and int(db_get(user_id, 'powdered')) != 1:
        return answer

    user_role = db_get(user_id, 'role')
    answer.log_add(recursive + failure)

    try:
        demonized = False
        if int(db_get(user_id, 'demonized')) == 1:
            demonized = True

        undead = False
        if int(db_get(user_id, 'undead')) == 1 or user_role == 'Undead':
            undead = True
            demonized = False
    except Exception:
        demonized = False
        undead = False

    # End function if player is dead (exit condition for recursion)
    if user_role in ['Dead', 'Spectator', 'Suspended', None, 'Unknown']:
        return answer.log_add(recursive + success +
                              '<@{}> was already dead!'.format(user_id))

    if role == 'Cupid':
        answer.log_add(recursive + success + skull +
                       '<@{}> committed suicide.'.format(user_id))
        answer = instant_death(user_id, role, 'Cupid', answer,
                               recursive + next)
        if int(db_get(user_id, 'abducted')) != int(db_get(
                murderer, 'abducted')):
            answer.dm("Abducted or not, you know your lover has deceased! ",
                      user_id)
            answer.dm_add(
                "You couldn't handle the pain, and that's why you decided to put an end to it.\n"
            )
            answer.dm_add("Your story ends here.")
        elif int(db_get(user_id, 'frozen')) == 1:
            answer.dm(
                "Even though your heart has become cold from the ice surrounding you, ",
                user_id)
            answer.dm_add(
                "but it got even colder when you saw the dead body of <@{}> being carried away.\n"
                .format(murderer))
            answer.dm_add(
                "It was at this moment where the ice got even colder...")
        else:
            answer.dm(
                "You couldn't bear the sight of your lover, <@{}>, ".format(
                    murderer), user_id)
            answer.dm_add(
                "lying dead in your arms. This is why you have decided to end it all!\n"
            )
            answer.dm_add(
                "Let\'s just hope this isn\'t like Romeo and Juliet...")
        answer.dm_add(
            "**Your lover, <@{}>, has died. In response, you have committed suicide.**"
            .format(murderer))
        return answer

    if role == 'Fortune Teller':
        if not undead:
            answer.dm(
                "Your idol, the fortune teller <@{}>, has deceased. ".format(
                    murderer), db_get(user_id, 'channel'))
            answer.dm_add(
                "They were a great inspiration to you, and that's why ")
            answer.dm_add("you've decided to get in their footsteps!\n")
            answer.dm_add("**You have turned into a Fortune Teller. Find and ")
            answer.dm_add(
                "eliminate all werewolves, solo players and other enemies!**")
            answer.log_add(recursive + success +
                           '<@{}> became a fortune teller.')
        else:
            answer.dm(
                "Your idol, the fortune teller <@{}>, has deceased. ".format(
                    murderer), user_id)
            answer.dm_add("They were a great inspiration to you... ")
            answer.dm_add(
                "back when you were alive, at least. Now, your undead heart is as cold as it has ever been, "
            )
            answer.dm_add("and nothing will happen to you.\n")
            answer.dm_add(
                "**The rules have changed. You will remain Undead.**")
            answer.log_add(recursive + success +
                           '<@{}> failed to become a fortune teller.')
            db_set(user_id, 'role', 'Fortune Teller')
        return answer

    if role == 'Horseman' and user_role == 'Horseman':
        horse_number = db_get(user_id, 'horseman')
        apocalypse_ready = True
        for player in db.player_list():
            if int(db_get(player, 'horseman')) != 0:
                apocalypse_ready = False
            if int(db_get(player, 'horseman')) == horse_number:
                db_set(player, 'horseman', 0)
        answer.log_add(recursive + success +
                       '<@{}> was united.'.format(user_id))

        if horse_number != 0:
            for channel_id in db.get_secret_channels('Horseman'):
                answer.msg(
                    '**Horseman #{} has been united!**'.format(horse_number),
                    channel_id)

        if apocalypse_ready:
            for player in db.player_list():
                if db_get(player, 'role') == 'Horseman':
                    answer.log_add(recursive + next + failure)
                    answer.log_add(recursive + next + success +
                                   '<@{}> has joined the **Apocalypse**!')
                    db_set(player, 'horseman', 5)

                    answer.secret_dm(
                        'All Horsemen are united! This means that the **APOCALYPSE** can be unleashed!',
                        'Horseman')
            answer.story('Oh no! The Apocalypse has been unleashed!')
        return answer

    # End if user is frozen.
    if int(db_get(user_id, 'frozen')) == 1:
        return answer.log_add(
            recursive + success +
            '<@{}> was frozen and thus protected.'.format(user_id))

    if role == "Devil":
        if user_role == 'Devil':
            answer.log_add(recursive + success +
                           '<@{}> did not die to their own wage.')
            return answer
        answer.log_add(recursive + success + skull +
                       '<@{}> was killed by the wager.')
        answer = instant_death(user_id, role, 'Wager', answer,
                               recursive + next)
        return answer

    # Let all zombies kill all other zombies.
    if role == "Zombie":
        answer.log_add(recursive + success + skull +
                       '<@{}> has decayed.'.format(user_id))
        answer = instant_death(user_id, role, 'Zombie', answer,
                               recursive + next)
        return answer

    # Kill abducted players (or The Thing himself)
    if role == "The Thing":
        answer.log_add(recursive + success + skull +
                       '<@{}> drowned in the swamp.'.format(user_id))
        # TODO: kill the player (BUT NOT THROUGH THE SUICIDE FUNCTION)
        return answer

    # End if user is immortal.
    if user_role == "Immortal":
        answer.log_add(recursive + success +
                       '<@{}> is immortal.'.format(user_id))
        return answer

    # End if user is abducted.
    if int(db_get(user_id, 'abducted')) == 1:
        return answer.log_add(
            recursive + success +
            '<@{}> was abucted and thus protected.'.format(user_id))

    # Kill lynch!
    if role == "Innocent":
        replacements = [
            standoff for standoff in db.get_standoff(user_id)
            if standoff[2] == 'Executioner'
        ]

        if replacements == []:
            answer.log_add(recursive + success + skull +
                           '<@{}> was killed by an angry mob.'.format(user_id))
            answer = instant_death(user_id, role, 'Lynch', answer,
                                   recursive + next)

        else:
            answer.log_add(recursive + success +
                           '<@{}> escaped death as the Executioner.')

            if user_role == 'Executioner':
                db_set(user_id, 'role', 'Innocent')

            for standoff in replacements:
                db.delete_standoff(standoff[0])
                answer = instant_death(standoff[1], standoff[2], 'Lynch',
                                       answer, recursive + next)

        return answer

    # Kill whoever stands in the barber's way!
    if role == "Barber":
        if user_role != 'Idiot':
            answer.log_add(recursive + success + skull +
                           '<@{}> was cut to death.'.format(user_id))
            answer = instant_death(user_id, role, 'Barber', answer,
                                   recursive + next)
            answer.story(barber_kill_story(murderer, user_id))

        else:
            msg = "*\"Tomorrow, at noon, right here. You got that?\"* Yup, it definitely seemed like <@{}> ".format(
                user_id)
            msg += "remembered the barber\'s appointment.\nIt was only today that it turned out - they had forgotten "
            msg += "about it! Good thing for them, for <@{}> had the intent to cut a little far below the hairline...\n".format(
                murderer)
            msg += "**<@{0}>, the Barber, has failed to execute <@{1}>, the Idiot! <@{0}> will now continue the game ".format(
                murderer, user_id)
            msg += "as a regular Innocent, and <@{}> as an even better Idiot, as they are no longer allowed to vote.**".format(
                user_id)
            answer.story(msg).log_add(
                recursive + success +
                '<@{}> failed to give <@{}> a \"haircut\".'.format(
                    murderer, user_id))
            db_set(user_id, 'role', 'Idiot ')

        return answer

    # Save users if they have souls to spare.
    souls = int(db_get(user_id, 'souls'))
    if souls > 0:
        db_set(user_id, 'souls', souls - 1)
        answer.log_add(recursive + success +
                       '<@{}> lost a soul.'.format(user_id))
        return answer

    # End if the user sleeps with another.
    if role == "Hooker" and not demonized:
        answer.log_add(recursive + success + skull +
                       '<@{}> was slept with <@{}>.'.format(user_id, murderer))
        answer = instant_death(user_id, role, 'Hooker', answer,
                               recursive + next)
        return answer

    # End if player dies in someone else's place.
    if role == "Executioner":
        answer.log_add(recursive + success + skull +
                       '<@{}> was executed.'.format(user_id))
        answer = instant_death(user_id, role, 'Executioner', answer,
                               recursive + next)
        return answer

    # End if player dies in someone else's place.
    if role == "Huntress" and not demonized:
        answer.log_add(recursive + success + skull +
                       '<@{}> was shot.'.format(user_id))
        answer = instant_death(user_id, role, 'Huntress', answer,
                               recursive + next)
        return answer

    # Check if user has an amulet.
    if db.has_amulet(user_id) and role not in ['Hooker']:
        return answer.log_add(
            recursive + success +
            "<@{}> was protected by their amulet.".format(user_id))

    # Protect apocalypse horsemen
    if int(db_get(user_id, 'horseman')) == 5:
        return answer.log_add(
            '<@{}> was protected by the Apocalypse.'.format(user_id))

    # Kill assassinations
    if role == 'Assassin' and not demonized:
        answer.log_add(recursive + success + skull +
                       '<@{}> was assassinated.'.format(user_id))
        answer = instant_death(user_id, role, 'Assassin', answer,
                               recursive + next)
        return answer
    if role == 'Cult Leader' and not demonized:
        answer.log_add(recursive + success + skull +
                       '<@{}> was killed by the cult.'.format(user_id))
        answer = instant_death(user_id, role, 'Cult', answer, recursive + next)
        return answer
    if role == 'Priest' and not demonized:
        if user_role in pos.wolf_team:
            answer.log_add(recursive + success + skull +
                           '<@{}> was holified.'.format(user_id))
            answer = instant_death(user_id, role, 'Priest', answer,
                                   recursive + next)
        else:
            answer.log_add(recursive + success + skull +
                           '<@{}> holified themselves.'.format(murderer))
            answer = instant_death(user_id, role, 'Priest', answer,
                                   recursive + next)
        return answer
    if role == 'Witch' and not demonized:
        answer.log_add(recursive + success + skull +
                       '<@{}> was poisoned.'.format(user_id))
        answer = instant_death(user_id, role, 'Witch', answer,
                               recursive + next)
        return answer

    # Kill wolf attacked
    if role in ['Werewolf', 'Lone Wolf', 'White Werewolf']:
        if user_role == 'Runner':
            answer.log_add(recursive + success +
                           '<@{}> outran a wolf attack.'.format(user_id))
            answer.dm('You. Are. EXHAUSTED.\n', user_id)
            answer.dm_add(
                'Last night may have been the worst night of your life! ')
            answer.dm_add(
                'You\'re still alive, however. And that\'s what counts. ')
            answer.dm_add(
                'Let\'s hope that, whatever those creatures were, won\'t attack again tomorrow night!\n'
            )
            answer.dm_add(
                '**Last night, you have been attacked by a wolf. You have become a regular Innocent.**'
            )
            db_set(user_id, 'role', 'Innocent')
            return answer
        if user_role == 'Cursed Civilian':
            answer.dm(
                "The curse that went around you, had been a little itchy lately... and it kept getting worse! ",
                user_id)
            answer.dm_add(
                "It got worse and worse, and you couldn't help but notice how hair started growing everywhere!\n"
            )
            answer.dm_add(
                "Last night, you were waking up by the grunts of a what sounded like a wolf! "
            )
            answer.dm_add(
                "You thought your days were over, but the wolf did not attack. Instead, "
            )
            answer.dm_add(
                "the wolf watched as your nails grew longer, your ears became spiky and your smell "
            )
            answer.dm_add(
                "slowly improved... and you looked just like one of the silhouettes in the shadow, "
            )
            answer.dm_add(
                "waiting for you to join them in the beautiful night's sky...\n"
            )
            answer.dm_add(
                "**You have been visited by wolves last night, and your curse made you turn "
            )
            answer.dm_add(
                "into a werewolf. Devour all villagers and win the game!**")

            db_set(user_id, 'role', 'Werewolf')
            answer.log_add(recursive + success +
                           '<@{}> has turned into a Werewolf!'.format(user_id))

            for channel_id in db.get_secret_channels('Werewolf'):
                answer.edit_cc(channel_id, user_id, 1)
                answer.msg("**ARRROOOO!\nWelcome, <@{}>!**".format(user_id),
                           channel_id)
                answer.msg_add(
                    "Last night, the **cursed civilian** <@{}> was attacked by wolves, "
                    .format(user_id))
                answer.msg_add(
                    "and has now become a **werewolf**! Please, welcome this new member "
                )
                answer.msg_add("of the wolf pack!")
            return answer
        if not demonized:
            answer.log_add(recursive + success + skull +
                           '<@{}> was eaten by a werewolf.'.format(user_id))
            answer = instant_death(user_id, role, 'Werewolf', answer,
                                   recursive + next)
            return answer

    # Kill solo attacked
    if role == 'Demon' and not demonized:
        answer.log_add(recursive + success + skull +
                       '<@{}> was sent to hell.'.format(user_id))
        answer = instant_death(user_id, role, 'Demon', answer,
                               recursive + next)
        return answer
    if role == 'Horseman' and not demonized:
        answer.log_add(recursive + success + skull +
                       '<@{}> was apocalypsed.'.format(user_id))
        answer = instant_death(user_id, role, 'Horseman', answer,
                               recursive + next)
        return answer
    if role == 'Pyromancer' and not demonized:
        answer.log_add(recursive + success + skull +
                       '<@{}> went up in flames.'.format(user_id))
        answer = instant_death(user_id, role, 'Pyromancer', answer,
                               recursive + next)
        return answer

    # Assume they were supposed to be killed, but that they are demonized. Let's turn them undead!
    answer.log_add(recursive + success + skull + '<@{}> has become undead.')

    db_set(user_id, 'undead', 1)
    answer.dm(
        "Last night, you didn't feel to well and decided to go out, to take a walk. ",
        user_id)
    answer.dm_add(
        "As soon as you stepped out the door, you felt like it was a bad idea - and it was!\n"
    )
    answer.dm_add(
        "The last thing you can remember is the sound of someone approaching you from behind, "
    )
    answer.dm_add(
        "the sound of a skull cracking open, and then - **NOTHING**.\n\n")
    answer.dm_add("Is this the end?\n\n")
    answer.dm_add(
        "It doesn't appear so. You wake up in a graveyard. A few cold and grim silhouettes "
    )
    answer.dm_add(
        "stand in front of you. You are surrounded, but it feels more... welcoming. "
    )
    answer.dm_add("And then the truth arrives.\n")
    answer.dm_add(
        "The **{}** you once were, is dead. Their soul could not rest, and that is you. "
    )
    answer.dm_add("The remainders of something that wasn't ready to die.\n")
    answer.dm_add(
        "**You have become Undead. Murder everyone that isn't an undead or a vampire."
    )

    for channel_id in db.get_secret_channels('Undead'):
        answer.edit_cc(channel_id, user_id, 1)
        answer.msg(
            "Last night, <@{}>, a **{}** has died! Please welcome them in the realm of the Undead!",
            channel_id)

    if user_role not in pos.pretenders:
        db_set(user_id, 'role', 'Undead')
        answer.dm_add("**")
    else:
        answer.dm_add(
            " Your former teammates do not know you are Undead, so make use of this advantage.**"
        )

    return answer
Пример #10
0
async def process_message(message,result):
    #if "<@&{}>".format(config.game_master) in message.content:
        #stats.increment_stat("game_master_pings", 1)
        #stats.increment_user_stat(message.author.id, "game_master_pings", 1)

    if db.isParticipant(message.author.id,True,True,True):
        db_set(message.author.id,'activity',0)

    gamelog_channel = client.get_channel(int(config.game_log))
    botspam_channel = client.get_channel(int(config.bot_spam))
    storytime_channel = client.get_channel(int(config.story_time))

    # The temp_msg list is for keeping track of temporary messages for deletion.
    temp_msg = []

    for mailbox in result:

        # If a Mailbox says so, all existing polls will be evaluated.
        if mailbox.evaluate_polls == True:
            for poll in db.get_all_polls():
                # poll.msg_table -> list of message ids
                # poll.blamed -> name of killer
                # poll.purpose -> the reason of the kill

                poll_channel = client.get_channel(int(poll.channel))
                if poll_channel == None:
                    await botspam_channel.send("We got a problem! Could you send these results to the appropriate channel, please?")
                    poll_channel = botspam_channel

                user_table = []
                for msg in poll.msg_table:
                    poll_msg = await poll_channel.get_message(msg)
                    for emoji in poll_msg.reactions:
                        users = await emoji.users().flatten()

                        for person in users:
                            if db.isParticipant(person.id):
                                user_table.append([person.id,emoji.emoji])

                log, result, chosen_emoji = count_votes(user_table,poll.purpose,dy.get_mayor())

                await botspam_channel.send(log)
                await poll_channel.send(result)
                for graveyard in db.get_secret_channels("Graveyard"):
                    await client.get_channel(graveyard).send(result)

                chosen_one = db.emoji_to_player(chosen_emoji)

                if chosen_emoji != '' and chosen_one != None:
                    chosen_one = int(chosen_one)
                    if poll.purpose == 'lynch':
                        db.add_kill(chosen_one,'Innocent')
                    elif poll.purpose == 'Mayor':
                        dy.set_mayor(chosen_one)
                        member = gamelog_channel.guild.get_member(int(chosen_one))
                        if member != None:
                            await member.add_roles(get_role(gamelog_channel.guild.roles, config.mayor), reason="Promoting {} to Mayor".format(member.display_name))
                    elif poll.purpose == 'Reporter':
                        dy.set_reporter(chosen_one)
                        for channel_id in db.get_secret_channels("Reporter"):
                            mailbox.edit_cc(channel_id,chosen_one,1)
                        member = gamelog_channel.guild.get_member(int(chosen_one))
                        if member != None:
                            await member.add_roles(get_role(gamelog_channel.guild.roles, config.reporter), reason="Promoting {} to Reporter".format(member.display_name))
                    elif poll.purpose == 'wolf':
                        db.add_kill(chosen_one,'Werewolf',db.random_wolf())
                    elif poll.purpose == 'cult':
                        db.add_kill(chosen_one,'Cult Leader',db.random_cult())
                    elif poll.purpose == 'thing':
                        db.add_kill(chosen_one,'The Thing','')

        for user_id in mailbox.demotions:
            if user_id == message.author.id and message.guild == gamelog_channel.guild:
                member = message.author
            else:
                member = gamelog_channel.guild.get_member(int(user_id))

            if member != None:
                for role in member.roles:
                    if role.id == config.mayor:
                        await member.remove_roles(role, reason="Demoting the Mayor")
                    if role.id == config.reporter:
                        await member.remove_roles(role, reason="Demoting the Reporter")

        # Create a new shop instance
        for element in mailbox.shops:
            shop_data = db_shop.get_shop_config(element.shop_config)
            i = 1
            j = 0
            emoji_table = []
            page_amount = int(len(shop_data["items"])-1/20)+1


            for item in shop_data["items"]:
                if j % 20 == 0:
                    embed = discord.Embed(title="Shop (Page {}/{})".format(i,page_amount), description=shop_data["shop_description"], color=0x00ff00)

                embed.add_field(name="[{}] {}".format(item["emoji"], item["name"]), value="{} {}\n*{}*\n".format(item["price"], shop_data["currency"], item["description"]), inline=False) # Add item to shop
                emoji_table.append(emojize(item["emoji"]))
                j += 1

                if j % 20 == 0:
                    i += 1
                    response = await client.get_channel(int(element.destination)).send(embed=embed)
                    db_shop.add_shop(response.id)

                    for item in emoji_table:
                        await response.add_reaction(item)
                    emoji_table = []

            if j % 20 != 0:
                response = await client.get_channel(int(element.destination)).send(embed=embed)
                db_shop.add_shop(response.id)

                for item in emoji_table:
                    await response.add_reaction(item)

        # If the Mailbox has a message for the gamelog, this is where it's sent.
        for element in mailbox.gamelog:
            msg = await gamelog_channel.send(element.content)
            for emoji in element.reactions:
                await msg.add_reaction(emoji)
            if element.temporary == True:
                temp_msg.append(msg)

        # If the Mailbox has a message for the botspam, this is where it's sent.
        for element in mailbox.botspam:
            msg = await botspam_channel.send(element.content)
            for emoji in element.reactions:
                await msg.add_reaction(emoji)
            if element.temporary == True:
                temp_msg.append(msg)

        # If the Mailbox has a message for the storytime (in-game announcements) channel, this is where it's sent.
        for element in mailbox.storytime:
            msg = await storytime_channel.send(element.content)
            for emoji in element.reactions:
                await msg.add_reaction(emoji)
            if element.temporary == True:
                temp_msg.append(msg)

        # The messages are sent here if they are a direct message to the one sending a command.
        for element in mailbox.answer:
            msg = await message.channel.send(element.content)
            for emoji in element.reactions:
                await msg.add_reaction(emoji)
            if element.temporary == True:
                temp_msg.append(msg)

        # The messages that are destined for a specific channel, are sent here.
        for element in mailbox.channel:

            # The following code is sent if the message is an embed.
            if element.embed:
                if element.destination == "spam":
                    msg = await botspam_channel.send(embed=element.content)
                    for emoji in element.reactions:
                        await msg.add_reaction(emoji)
                    if element.temporary == True:
                        temp_msg.append(msg)
                else:
                    msg = await client.get_channel(int(element.destination)).send(embed=element.content)
                    for emoji in element.reactions:
                        await msg.add_reaction(emoji)
                    if element.temporary == True:
                        temp_msg.append(msg)
            # The following code is sent if the message is a regular message.
            else:
                msg = await client.get_channel(int(element.destination)).send(element.content)
                for emoji in element.reactions:
                    await msg.add_reaction(emoji)
                if element.temporary == True:
                    temp_msg.append(msg)

        # DMs are sent here.
        for element in mailbox.player:
            member = client.get_user(int(element.destination))
            main_guild = botspam_channel.guild
            if member == None:
                member = main_guild.get_member(int(element.destination))
            if member == None:
                await message.channel.send("Couldn't send a DM to <@{}>!".format(element.destination))
                await botspam_channel.send(
                    "<@{}> has attempted to send a DM to <@{}>, but failed, because we couldn't find the specified user via `client.get_user`.".format(
                        message.author.id, element.destination))
            else:
                try:
                    msg = await member.send(element.content)
                    for emoji in element.reactions:
                        await msg.add_reaction(emoji)
                    if element.temporary == True:
                        temp_msg.append(msg)
                except discord.errors.Forbidden:
                    botspam_channel.send('I wasn\'t allowed to send a DM to <@{}>! Here\'s the content:'.format(member.id))
                    botspam_channel.send(element.content)
                except Exception:
                    botspam_channel.send('I failed to send a DM to <@{}>! Could somebody send this, please?'.format(member.id))
                    botspam_channel.send(element.content)

        # Settings of existing channels are altered here.
        for element in mailbox.oldchannels:
            # element.channel - channel to be edited;
            # element.victim - person's permission to be changed;
            # element.number - type of setting to set to: see issue #83 for more info.

            print('Editing permissions of {} for channel {}...'.format(element.victim,element.channel))
            channel = client.get_channel(element.channel)
            user = client.get_user(int(element.victim))
            main_guild = botspam_channel.guild
            member = main_guild.get_member(int(element.victim))
            if member == None:
                if user == None:
                    await botspam_channel.send("That\'s problematic! I couldn\'t edit the cc info of <@{0}> *(<#{0}> <@&{0}> ?)*".format(element.victim))
                    print('Unable to locate member {}.'.format(element.victim))
                member = user
            if channel == None:
                await botspam_channel.send('Unable to edit channel <#{0}> *(<@{0}> <@&{0}> ?)*'.format(int(element.victim)))
            elif member != None:
                await remove_all_game_roles(member)
                if element.number == 0:
                    await channel.set_permissions(user, read_messages=False, send_messages=False)
                    try:
                        if int(db_get(member.id,'frozen')) == 0:
                            raise NotImplementedError("This is a purposeful error raise!")
                    except Exception:
                        if db.isParticipant(member.id):
                            await member.add_roles(get_role(main_guild.roles, config.participant), reason="Updating CC Permissions")
                        elif db.isParticipant(member.id,True,True):
                            await member.add_roles(get_role(main_guild.roles, config.dead_participant), reason="Updating CC Permissions")
                        elif db.isParticipant(member.id,True,True,True):
                            await member.add_roles(get_role(main_guild.roles, config.suspended), reason="Updating CC Permissions")
                    else:
                        await member.add_roles(get_role(main_guild.roles, config.frozen_participant), reason="Updating CC Permissions")
                elif element.number == 1:
                    await channel.set_permissions(user, read_messages=True, send_messages=True)
                    await member.add_roles(get_role(main_guild.roles, config.participant), reason="Updating CC Permissions")
                elif element.number == 2:
                    await channel.set_permissions(user, read_messages=True, send_messages=False)
                    await member.add_roles(get_role(main_guild.roles, config.frozen_participant), reason="Updating CC Permissions")
                elif element.number == 3:
                    await channel.set_permissions(user, read_messages=False, send_messages=False)
                    await member.add_roles(get_role(main_guild.roles, config.participant), reason="Updating CC Permissions")
                elif element.number == 4:
                    await channel.set_permissions(user, read_messages=True, send_messages=False)
                    if db.isParticipant(member.id,False,True):
                        await member.add_roles(get_role(main_guild.roles, config.dead_participant), reason="Updating CC Permissions")
                elif element.number == 5:
                    await channel.set_permissions(user, read_messages=True, send_messages=False)
                    await member.add_roles(get_role(main_guild.roles, config.participant), reason="Updating CC Permissions")
                elif element.number == 6:
                    await channel.set_permissions(user, read_messages=False, send_messages=False)
                    await member.add_roles(get_role(main_guild.roles, config.participant), reason="Updating CC Permissions")
                elif element.number == 7:
                    await channel.set_permissions(user, read_messages=False, send_messages=False)
                    await member.add_roles(get_role(main_guild.roles, config.participant), reason="Updating CC Permissions")
                elif element.number == 8:
                    await channel.set_permissions(user, read_messages=False, send_messages=False)
                    await member.add_roles(get_role(main_guild.roles, config.suspended), reason="Updating CC Permissions")
                else:
                    await msg.channel.send('Something went wrong! Please contact a Game Master.')
                    return
                if db.isParticipant(element.victim,True,True):
                    db.set_user_in_channel(element.channel,element.victim,element.number)


        # New channels are created here.
        for element in mailbox.newchannels:
            # element.name - name of the channel;
            # element.owner - owner of the channel;
            # element.members - members of the channel
            # element.settlers - members for whom this shall become their home channel
            # element.secret - boolean if the channel is a secret channel

            if element.secret:
                element.owner = client.user.id

            if ' ' not in element.name:

                main_guild = botspam_channel.guild # Find the guild we're in

                if element.owner not in element.members:
                    element.members.append(element.owner)
                for buddy in element.settlers:
                    if buddy not in element.members:
                        msg = """**Warning:** I'm adding settlers to a channel!\nThis is should not be a problem, \
                        but it does at least indicate a flaw in the bot's code. Please, report this to the Game Masters!"""
                        await client.get_channel(message.channel).send(msg)
                        element.members.append(buddy)

                viewers = []
                frozones = []
                abductees = []
                deadies = []

                # Add dead people & spectators to cc
                if not element.secret:
                    for user in [dead_buddy for dead_buddy in db.player_list() if dead_buddy not in db.player_list(True)]:
                        element.members.append(user)

                # Categorize all players
                for user in element.members:
                    member = main_guild.get_member(user)

                    if member == None:
                        await botspam_channel.send("That\'s problematic! I couldn\'t add <@{0}> to a cc. *(<#{0}> <@&{0}> ?)*".format(element.victim))
                        await message.author.send("It doesn't seem like <@{}> is part of the server! I am sorry, I can't add them to your **conspiracy channel**.".format(user))
                    elif db.isParticipant(user,False,True) == True:
                        if int(db_get(user,'abducted')) == 1:
                            abductees.append(member)
                        elif int(db_get(user,'frozen')) == 1:
                            frozones.append(member)
                        elif db.isParticipant(user,False,False) == False:
                            deadies.append(member)
                        else:
                            viewers.append(member)
                    elif db_get(user,'role') == 'Suspended':
                        pass
                    else:
                        deadies.append(member)

                # Delete any potential duplicates
                viewers = list(set(viewers))
                frozones = list(set(frozones))
                abductees = list(set(abductees))
                deadies = list(set(deadies))

                # Role objects (based on ID)
                roles = main_guild.roles # Roles from the guild
                game_master_role = discord.utils.find(lambda r: r.id == game_master, roles)
                # TODO: Add read permissions for spectators if element.secret == False
                default_permissions = {
                    main_guild.default_role: discord.PermissionOverwrite(read_messages=False,send_messages=False),
                    game_master_role: discord.PermissionOverwrite(read_messages=True,send_messages=True),
                    client.user: discord.PermissionOverwrite(read_messages=True,send_messages=True),
                    **{
                        member: discord.PermissionOverwrite(read_messages=True,send_messages=True) for member in viewers
                    },
                    **{
                        member: discord.PermissionOverwrite(read_messages=True,send_messages=False) for member in frozones
                    },
                    **{
                        member: discord.PermissionOverwrite(read_messages=True,send_messages=False) for member in deadies
                    }
                }

                if not element.secret:
                    intro_msg = creation_messages.cc_intro([v.id for v in viewers])
                    reason_msg = 'CC requested by ' + message.author.name
                    title = "s{}_cc_{}".format(config.season,element.name)
                    category_name = 'S{} CCs PART {}'.format(config.season,db.count_categories(element.secret) + 1)
                else:
                    intro_msg = secret_messages.creation(element.name,[v.id for v in viewers])
                    reason_msg = 'Secret {} channel created.'.format(element.name)
                    title = "s{}_{}".format(config.season,element.name)
                    category_name = 'S{} Secret Channels Part {}'.format(config.season,db.count_categories(element.secret) + 1)

                # Create a new category if needed
                if db.get_category(element.secret) == None:
                    category = await main_guild.create_category(category_name, reason='It seems like we couldn\'t use our previous category! Don\'t worry, I just created a new one.')
                    db.add_category(category.id,element.secret)
                else:
                    category = main_guild.get_channel(db.get_category(element.secret))

                try:
                    # Create the text channel
                    channel = await main_guild.create_text_channel(
                        name=title,
                        category=category,
                        overwrites=default_permissions,
                        reason=reason_msg)
                    db.add_channel(channel.id,element.owner,element.secret)
                    if element.secret:
                        db.add_secret_channel(channel.id,element.name)

                        # If the channel is meant for an amulet holder, assign the amulet holder.
                        if element.name == 'Amulet_Holder':
                            for member in viewers:
                                if db_get(member.id,'role') == 'Amulet Holder':
                                    db_set(member.id,'amulet',channel.id)
                    if element.trashy:
                        db.add_trash_channel(channel.id)

                    await channel.send(intro_msg)

                    # Set all access rules in the database
                    for member in viewers:
                        db.set_user_in_channel(channel.id,member.id,1)
                    for member in frozones:
                        db.set_user_in_channel(channel.id,member.id,2)
                    for member in abductees:
                        db.set_user_in_channel(channel.id,member.id,3)
                    for member in deadies:
                        if db.isParticipant(member.id,True,True) == True:
                            db.set_user_in_channel(channel.id,member.id,4)


                except Exception as e: # Catch any thrown exceptions and send an error to the user.
                    await message.channel.send('It seems like I\'ve encountered an error! Please let the Game Masters know about this!')
                    await botspam_channel.send("Oi, Game Masters! I got a problem concerning channel creation for ya to fix.")
                    await botspam_channel.send(e)
                    raise e # Send the full log to Buddy1913 and his sketchy VM.

                # Give the settlers their own happy little residence
                for buddy in element.settlers:
                    db_set(buddy,"channel",channel.id)

            else:
                """This should not happen, but we'll use it, to prevent the bot from purposely causing an error
                everytime someone attempts to create a channel that contains spaces. 'cause believe me,
                that happens ALL the time."""
                msg = await message.channel.send("I\'m terribly sorry, but you can\'t use spaces in your channel name. Try again!")
                temp_msg.append(msg)


        # Polls are created here.
        for element in mailbox.polls:
            # element.channel
            # element.purpose
            # element.user_id
            # element.description

            msg = element.description + '\n'
            emoji_table = []
            msg_table = []
            i = 0

            for user in db.poll_list():
                if db.isParticipant(int(user[0])):
                    i += 1
                    msg += user[1] + " - <@" + str(user[0]) + "> "

                    if int(user[2]) + int(user[3]) > 0:
                        if int(user[2]) == 1:
                            msg += "**[FROZEN]** "
                        if int(user[3]) == 1:
                            msg += "**[ABDUCTED] **"
                    else:
                        emoji_table.append(user[1])

                    if i % 20 == 19:
                        if client.get_channel(int(element.channel)) == None:
                            await botspam_channel.send("Failed to send message in correct channel. ({})".format(element.channel))
                            msg = await botspam_channel.send(element.content)
                        else:
                            msg = await client.get_channel(int(element.channel)).send(msg)
                        for emoji in emoji_table:
                            await msg.add_reaction(emoji)
                        msg_table.append(msg)
                        emoji_table = []
                        msg = ''
                    else:
                        msg += '\n'

            if msg != '':
                msg = await client.get_channel(element.channel).send(msg)
                for emoji in emoji_table:
                    await msg.add_reaction(emoji)
                msg_table.append(msg)
            db.add_poll(msg_table,element.purpose,element.channel,element.user_id)
            await botspam_channel.send("A poll has been created in <#{}>!".format(element.channel))


        # Categories are deleted here.
        for element in mailbox.deletecategories:
            id = element.channel
            category = client.get_channel(id)
            if category != None:
                bot_message = await message.channel.send('Please react with 👍 to confirm deletion of category `' + category.name + '`.\n\nNote: This action will irreversibly delete all channels contained within the specified category. Please use with discretion.')
                await bot_message.add_reaction('👍')
                def check(reaction, user):
                    return user == message.author and str(reaction.emoji) == '👍'
                try:
                    reaction, user = await client.wait_for('reaction_add', timeout=30.0, check=check)
                except asyncio.TimeoutError:
                    await message.channel.send('Confirmation timed out.')
                    try:
                        await bot_message.delete()
                    except Exception:
                        pass
                else:
                    await message.channel.send('Ok, I\'ll get right on that.\n\n*This might take some time.*')
                    for channel in category.channels:
                        await channel.delete()
                    await category.delete()
                    await message.channel.send('\n:thumbsup: Channels and category deleted')
            else:
                await message.channel.send('Sorry, I couldn\'t find that category.')

        clean_time = len(mailbox.cleaners)
        if clean_time > 0:
            await botspam_channel.send("Cleaning up {} channels! This may take some time.".format(clean_time))

        for channel in mailbox.cleaners:

            trash_channel = client.get_channel(int(channel))

            if trash_channel != None:
                for message_id in db.empty_trash_channel(channel):
                    message = await trash_channel.get_message(int(message_id))
                    if message != None:
                        await message.delete()

    # Delete all temporary messages after about two minutes.
    await asyncio.sleep(120)
    for msg in temp_msg:
        try:
            await msg.delete()
        except Exception:
            # Unable to delete the message.
            # It was probaly already deleted or something.
            pass
Пример #11
0
def pay():
    """This function takes care of all properties that need to happen in the first wave of the end of the night.
    The function returns a Mailbox."""

    if dy.get_stage() == "Day":
        return [
            Mailbox().respond(
                "Whaddaya mean, `{}pay`? It already **is** day, bud.".format(
                    config.universal_prefix))
        ]

    # Add all listeners
    if int(dy.day_number()) == 0:
        for spy_channel in db.get_secret_channels("Flute_Player"):
            for innocent_channel in db.get_secret_channels("Flute_Victims"):
                db.add_listener(spy_channel, innocent_channel)

    answer = Mailbox()
    answer_table = [Mailbox(True)]

    for user_id in db.player_list():
        user_role = db_get(user_id, 'role')

        # Remove potential night uses
        for i in range(len(roles.night_users)):
            if user_role in [
                    "White Werewolf"
            ] and (dy.day_number() % 2 == 0) and dy.day_number() > 0:
                db_set(user_id, 'uses', 1)
                break
            elif user_role in roles.night_users[i]:
                if i > 0:
                    db_set(user_id, 'uses', 0)
                break

        # Force Cupid to fall in love
        if user_role == "Cupid" and db_get(user_id, 'uses') > 0:
            chosen = False
            attempts = 0

            while not chosen and attempts < 1000:
                forced_victim = random.choice(db.player_list(True, True))
                chosen = cupid_kiss(user_id, forced_victim, False)

            answer_table.append(chosen)

        # Force Dog to become Innocent
        if user_role == "Dog" and db_get(user_id, 'uses') > 0:
            db_set(user_id, 'role', "Innocent")
            answer.msg(
                "You haven't chosen a role! That's why you have now become and **Innocent**!",
                db_get(user_id, 'channel'))
            answer.log(
                "The **Dog** <@{}> didn't choose a role last night and turned into an **Innocent**!"
                .format(user_id))

        # Remove hooker effects
        db_set(user_id, 'sleepingover', 0)
        for standoff in db.get_standoff(user_id):
            if standoff[2] == 'Hooker':
                db.delete_standoff(standoff[0])

        # Force Look-Alike to become Innocent
        if user_role == "Look-Alike":
            db_set(user_id, 'role', "Innocent")
            answer.msg(
                "You haven't chosen a role! That's why you have now become an **Innocent**!",
                db_get(user_id, 'channel'))
            answer.log(
                "The **Dog** <@{}> didn't choose a role last night and turned into an **Innocent**!"
                .format(user_id))

        # Remove tanner disguises
        db_set(user_id, 'fakerole', user_role)

        # Remove zombie tag
        db_set(user_id, 'bitten', 0)

    answer_table.append(answer)
    answer_table.append(Mailbox().spam(config.universal_prefix + "day"))
    return answer_table