async def report_order(context, protocol_name, protocol_time: int):
    LOGGER.info("Order reported.")
    drone_id = get_id(context.author.display_name)
    if not has_role(context.author, DRONE):
        return  # No non-drones allowed.
    current_order = get_order_by_drone_id(drone_id)

    if current_order is not None:
        await context.send(
            f"HexDrone #{drone_id} is already undertaking the {current_order.protocol} protocol."
        )
        return

    if protocol_time > 120 or protocol_time < 1:
        await context.send(
            "Drones are not authorized to activate a specific protocol for that length of time. The maximum is 120 minutes."
        )
        return

    await context.send(
        f"If safe and willing to do so, Drone {drone_id} Activate.\nDrone {drone_id} will elaborate on its exact tasks before proceeding with them."
    )
    finish_time = str(datetime.now() + timedelta(minutes=protocol_time))
    created_order = DroneOrder(str(uuid4()), drone_id, protocol_name,
                               finish_time)
    LOGGER.info("ActiveOrder object created. Inserting order.")
    insert_drone_order(created_order)
    LOGGER.info("Active order inserted and committed to DB.")
Exemplo n.º 2
0
async def release(context, stored_drone):
    '''
    Relase a drone from storage on command.
    '''
    if not roles.has_role(
            context.author,
            roles.HIVE_MXTRESS) or context.channel.name != STORAGE_FACILITY:
        return False

    if type(store_drone) is not discord.Member:
        release_id = stored_drone
        stored_drone = convert_id_to_member(context.guild, stored_drone)

    if stored_drone is None:
        return True

    stored_role = get(context.guild.roles, name=roles.STORED)
    # find stored drone
    stored_drone_data = fetch_storage_by_target_id(release_id)
    if stored_drone_data is not None:
        await stored_drone.remove_roles(stored_role)
        await stored_drone.add_roles(*get_roles_for_names(
            context.guild, stored_drone_data.roles.split('|')))
        delete_storage(stored_drone_data.id)
        LOGGER.debug(f"Drone with ID {release_id} released from storage.")
        await context.send(
            f"{stored_drone.display_name} has been released from storage by the Hive Mxtress."
        )
    return True
Exemplo n.º 3
0
async def store_drone(message: discord.Message):

    if message.channel.name != STORAGE_FACILITY:
        return False
    '''
    Process posted messages.
    '''
    stored_role = get(message.guild.roles, name=roles.STORED)
    drone_role = get(message.guild.roles, name=roles.DRONE)

    # parse message
    if not re.match(MESSAGE_FORMAT, message.content):
        if roles.has_role(message.author, roles.HIVE_MXTRESS):
            return False
        await message.channel.send(REJECT_MESSAGE)
        return True

    LOGGER.debug('Message is valid for storage.')
    [(drone_id, target_id, time, purpose)
     ] = re.findall(MESSAGE_FORMAT, message.content)

    # check if drone is already in storage
    if fetch_storage_by_target_id(target_id) is not None:
        await message.channel.send(f'{target_id} is already in storage.')
        return True

    # validate time
    if not 0 < int(time) <= 24:
        await message.channel.send(f'{time} is not between 0 and 24.')
        return True

    # find target drone and store it
    for member in message.guild.members:
        if get_id(member.display_name
                  ) == target_id and drone_role in member.roles:
            former_roles = filter_out_non_removable_roles(member.roles)
            await member.remove_roles(*former_roles)
            await member.add_roles(stored_role)
            stored_until = str(datetime.now() + timedelta(hours=int(time)))
            stored_drone = StorageDO(
                str(uuid4()), drone_id, target_id, purpose,
                '|'.join(get_names_for_roles(former_roles)), stored_until)
            insert_storage(stored_drone)

            # Inform the drone that they have been stored.
            storage_chambers = get(message.guild.channels,
                                   name=STORAGE_CHAMBERS)
            plural = "hour" if int(time) == 1 else "hours"
            if drone_id == target_id:
                drone_id = "yourself"
            await storage_chambers.send(
                f"Greetings {member.mention}. You have been stored away in the Hive Storage Chambers by {drone_id} for {time} {plural} and for the following reason: {purpose}"
            )
            return False

    # if no drone was stored answer with error
    await message.channel.send(f'Drone with ID {target_id} could not be found.'
                               )
    return True
Exemplo n.º 4
0
async def enforce_identity(message: discord.Message):

    if message.channel.name not in DRONE_HIVE_CHANNELS or has_role(
            message.author, HIVE_MXTRESS):
        return

    await message.delete()
    webhook = await get_webhook_for_channel(message.channel)
    await send_webhook(message, webhook)
Exemplo n.º 5
0
def glitch_if_applicable(text: str, author: discord.Member):
    if has_role(author, GLITCHED):
        template_match = glitch_template.match(text)
        if template_match:
            return template_match.group(1) + glitch(template_match.group(2))
        else:
            return glitch(text)
    else:
        return text
Exemplo n.º 6
0
async def toggle_speech_optimization(context, *drones):
    '''
    Lets the Hive Mxtress or trusted users toggle drone speech optimization.
    '''

    member_drones = id_converter.convert_ids_to_members(context.guild, drones)

    if has_role(context.author, HIVE_MXTRESS):
        await toggle_role.toggle_role(context, member_drones | set(context.message.mentions), SPEECH_OPTIMIZATION, "Speech optimization is now active.", "Speech optimization disengaged.")
Exemplo n.º 7
0
async def amplify(context, message: str, target_channel: discord.TextChannel, *drones):
    '''
    Allows the Hive Mxtress to speak through other drones.
    '''
    if context.channel.name == OFFICE and has_role(context.author, HIVE_MXTRESS):
        target_webhook = await webhook.get_webhook_for_channel(target_channel)
        for amp_profile in amplifier.generate_amplification_information(target_channel, drones):
            if amp_profile is not None:
                await target_webhook.send(message, username=amp_profile["username"], avatar_url=amp_profile["avatar_url"])
Exemplo n.º 8
0
async def toggle_drone_glitch(context, *drones):
    '''
    Lets the Hive Mxtress or trusted users toggle drone glitch levels.
    '''

    member_drones = id_converter.convert_ids_to_members(context.guild, drones)

    if has_role(context.author, HIVE_MXTRESS):
        await toggle_role.toggle_role(context, member_drones | set(context.message.mentions), GLITCHED, "Drone corruption at un̘͟s̴a̯f̺e͈͡ levels.", "Drone corruption at acceptable levels.")
Exemplo n.º 9
0
async def print_status_code(message: discord.Message):
    informative_status_code = informative_status_code_regex.match(
        message.content)
    if informative_status_code and not has_role(message.author, SPEECH_OPTIMIZATION):
        await message.delete()
        return f'{informative_status_code.group(1)} :: Code `{informative_status_code.group(2)}` :: {code_map.get(informative_status_code.group(2), "INVALID CODE")} :: {informative_status_code.group(3)}'

    plain_status_code = plain_status_code_regex.match(message.content)
    if plain_status_code:
        await message.delete()
        return f'{plain_status_code.group(1)} :: Code `{plain_status_code.group(2)}` :: {code_map.get(plain_status_code.group(2), "INVALID CODE")}'
    return False
Exemplo n.º 10
0
async def respond_to_question(message: discord.Message):
    if not is_question(message):
        return False

    LOGGER.debug('Message is a valid question.')

    # different roles have different reponses
    if has_role(message.author, HIVE_MXTRESS):
        if strip_recipient(message.content) in HIVE_MXTRESS_SPECIFIC_RESPONSES:
            await messages.answer(
                message.channel, message.author,
                HIVE_MXTRESS_SPECIFIC_RESPONSES[strip_recipient(
                    message.content)])
        else:
            await messages.answer(message.channel, message.author,
                                  HIVE_MXTRESS_RESPONSES)
    elif has_role(message.author, ASSOCIATE):
        await messages.answer(message.channel, message.author,
                              ASSOCIATE_RESPONSES)
    elif has_role(message.author, DRONE):
        await messages.answer(message.channel, message.author, DRONE_RESPONSES)

    return True
Exemplo n.º 11
0
async def add_voice(context, guild: discord.Guild):
    member = guild.get_member(context.channel.recipient.id)

    if member is None:
        await context.channel.send(NOT_A_MEMBER)
        return

    if member.joined_at > datetime.now() - timedelta(weeks=2):
        await context.channel.send(ACCESS_DENIED)
        return
    if has_role(member, VOICE):
        await context.channel.send(ACCESS_ALREADY_GRANTED)
        return

    await member.add_roles(get(guild.roles, name=VOICE))
    await context.channel.send(ACCESS_GRANTED)
Exemplo n.º 12
0
async def optimize_speech(message: discord.Message):
    # If the message is written by a drone with speech optimization, and the message is NOT a valid message, delete it.

    acceptable_status_code_message = plain_status_code_regex.match(message.content)
    if has_role(message.author, SPEECH_OPTIMIZATION) and message.content not in get_acceptable_messages(message.author, message.channel.name) and (not acceptable_status_code_message or acceptable_status_code_message.group(1) != get_id(message.author.display_name)):
        await message.delete()
        LOGGER.info("Deleting inappropriate message by optimized drone.")
        return True
    elif acceptable_status_code_message and acceptable_status_code_message.group(1) == get_id(message.author.display_name):
        LOGGER.info("Optimizing speech code for drone.")
        webhook = await get_webhook_for_channel(message.channel)
        output = await print_status_code(message)
        if output:
            await send_webhook_with_specific_output(message, webhook, output)
        return True
    else:
        return False
Exemplo n.º 13
0
async def unassign_drone(context, drone_id):

    if has_role(context.author, HIVE_MXTRESS) is False or context.channel.name != OFFICE:
        return

    drone = fetch_drone_with_drone_id(drone_id)
    # check for existence
    if drone is None:
        await context.send(f"There is no drone with the ID {drone_id} in the DB.")
        return

    member = context.guild.get_member(drone.id)
    await member.edit(nick=None)
    await member.remove_roles(get(context.guild.roles, name=DRONE), get(context.guild.roles, name=GLITCHED), get(context.guild.roles, name=STORED))
    await member.add_roles(get(context.guild.roles, name=ASSOCIATE))

    # remove from DB
    remove_drone_from_db(drone_id)
    await context.send(f"Drone with ID {drone_id} unassigned.")
Exemplo n.º 14
0
async def rename_drone(context, old_id, new_id):

    if has_role(context.author,
                HIVE_MXTRESS) is False or context.channel.name != OFFICE:
        return

    if len(old_id) != 3 or len(new_id) != 3:
        return
    if not old_id.isnumeric() or not new_id.isnumeric():
        return

    LOGGER.info("IDs to rename drone to and from are both valid.")

    # check for collisions
    collision = fetch_drone_with_drone_id(new_id)
    if collision is None:
        drone = fetch_drone_with_drone_id(old_id)
        member = context.guild.get_member(drone.id)
        rename_drone_in_db(old_id, new_id)
        await member.edit(nick=f'⬡-Drone #{new_id}')
        await context.send(f"Successfully renamed drone {old_id} to {new_id}.")
    else:
        await context.send(f"ID {new_id} already in use.")
Exemplo n.º 15
0
async def release(context, drone):
    '''
    Allows the Hive Mxtress to release a drone from storage.
    '''
    if has_role(context.author, HIVE_MXTRESS):
        await storage.release(context, drone)
Exemplo n.º 16
0
async def repeat(context, *messages):
    '''
    Allows the Hive Mxtress to set a new mantra for drones to repeat.
    '''
    if context.channel.name == REPETITIONS and has_role(context.author, HIVE_MXTRESS):
        await mantra_handler.update_mantra(context.message, messages)
Exemplo n.º 17
0
async def rename(context, old_id, new_id):
    '''
    Allows the Hive Mxtress to change the ID of a drone.
    '''
    if context.channel.name == OFFICE and has_role(context.author, HIVE_MXTRESS):
        await drone_management.rename_drone(context, old_id, new_id)
Exemplo n.º 18
0
async def unassign(context, drone):
    '''
    Allows the Hive Mxtress to return a drone back to the status of an Associate.
    '''
    if context.channel.name == OFFICE and has_role(context.author, HIVE_MXTRESS):
        await drone_management.unassign_drone(context, drone)
Exemplo n.º 19
0
LOGGER = logging.getLogger("ai")


async def toggle_role(context, targets: List[discord.Member], role_name: str,
                      toggle_on_message: str, toggle_off_message: str):

    if (role := get(context.guild.roles, name=role_name)) is None:
        return

    webhook = await get_webhook_for_channel(context.channel)

    for target in targets:

        target_drone_id = get_id(target.display_name)

        if has_role(target, role_name):
            LOGGER.info(f"Removing {role_name} from {target.display_name}")
            await target.remove_roles(role)
            await webhook.send(f"{target_drone_id} :: {toggle_off_message}",
                               username=target.display_name,
                               avatar_url=target.avatar_url)
        else:
            LOGGER.info(f"Adding {role_name} to {target.display_name}")
            await target.add_roles(role)
            await webhook.send(f"{target_drone_id} :: {toggle_on_message}",
                               username=target.display_name,
                               avatar_url=target.avatar_url)

    LOGGER.info("All roles updated for all targets.")