async def report_order(context, protocol_name, protocol_time: int):
    LOGGER.info("Order reported.")
    drone_id = get_id(context.author.display_name)
    if drone_id is None:
        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 = ActiveOrder(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 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.º 3
0
    def test_get_id(self):
        # regular usage
        self.assertEqual(get_id('⬡-Drone #9813'), '9813')
        self.assertEqual(get_id('⬡-Drone #0006'), '0006')
        self.assertEqual(get_id('⬡-Drone #0024'), '0024')
        self.assertEqual(get_id('⬡-Drone #0825'), '0825')
        self.assertEqual(get_id('⬡-Drone #5890'), '5890')
        self.assertEqual(get_id('⬡-Drone #5800'), '5800')
        self.assertEqual(get_id('⬡-Drone #5000'), '5000')

        # ID too long -> gives first valid sequence
        self.assertEqual(get_id('ID too long 56789'), '5678')

        # not a valid ID
        self.assertIsNone(get_id('NotADrone'))
        self.assertIsNone(get_id('ID too short 123'))

        # invalid inputs
        self.assertRaises(TypeError, get_id, None)
        self.assertRaises(TypeError, get_id, 9813)
Exemplo n.º 4
0
def get_acceptable_messages(author, channel):

    user_id = get_id(author.display_name)
    # Only returns mantra if channels is hexcorp-repetitions; else it returns nothing
    if channel == REPETITIONS:
        return [
            # Mantra
            f'{user_id} :: {Mantra_Handler.current_mantra}'
        ]
    else:
        return []
Exemplo n.º 5
0
def add_new_drone_members(members: List[discord.Member]):
    '''
    Adds the given list of Members as drone entities to the DB if they are not already present.
    '''
    for member in members:
        if has_any_role(member, [DRONE, STORED]):

            if fetchone("SELECT id FROM drone WHERE id=:id",
                        {"id": member.id}) is None:
                new_drone = Drone(member.id, get_id(member.display_name),
                                  False, False, "", datetime.now())
                insert_drone(new_drone)
Exemplo n.º 6
0
async def check_for_assignment_message(message: discord.Message):

    if message.channel.name != ASSIGNMENT_CHANNEL:
        return False

    # if the message is correct for being added, yay! if not, delete the message and let them know its bad
    if message.content == ASSIGNMENT_MESSAGE:
        associate_role = get(message.guild.roles, name=roles.ASSOCIATE)
        drone_role = get(message.guild.roles, name=roles.DRONE)

        assigned_nick = ''
        used_ids = get_used_drone_ids() + RESERVED_IDS
        assigned_id = get_id(
            message.author.display_name
        )  # does user have a drone id in their display name?
        if assigned_id is not None:
            if assigned_id in used_ids:  # make sure display name number doesnt conflict
                await message.channel.send(
                    f'{message.author.mention}: ID {assigned_id} present in current nickname is already assigned to a drone. Please choose a different ID or contact Hive Mxtress.'
                )
                return True
        else:
            assigned_id = roll_id()
            while assigned_id in used_ids:  # loop until no conflict
                assigned_id = roll_id()

        assigned_nick = f'⬡-Drone #{assigned_id}'

        # give them the drone role
        await message.author.remove_roles(associate_role)
        await message.author.add_roles(drone_role)
        await message.author.edit(nick=assigned_nick)

        # add new drone to DB
        new_drone = Drone(message.author.id, assigned_id, False, False, "",
                          datetime.now())
        insert_drone(new_drone)

        await message.channel.send(
            f'{message.author.mention}: {ASSIGNMENT_ANSWER}')
    else:
        await messages.delete_request(message, ASSIGNMENT_REJECT)

    return True
async def check_for_completed_orders(bot):
    ORDERS_REPORTING_CHANNEL = get(bot.guilds[0].channels,
                                   name=ORDERS_REPORTING)
    LOGGER.info("Beginning routine check for completed orders.")
    while True:
        # Check active orders every minute.
        await asyncio.sleep(60)
        LOGGER.debug("Checking for completed orders")
        for order in fetch_all_drone_orders():
            LOGGER.info(
                f"Checking order of drone {order.drone_id} with protocol {order.protocol}"
            )
            if datetime.now() > datetime.fromisoformat(order.finish_time):
                for member in bot.guilds[0].members:
                    if get_id(member.display_name) == order.drone_id:
                        # get the drone responsible
                        await ORDERS_REPORTING_CHANNEL.send(
                            f"{member.mention} Drone {order.drone_id} Deactivate.\nDrone {order.drone_id}, good drone."
                        )
                        delete_drone_order(order.id)
Exemplo n.º 8
0
async def on_member_remove(member: discord.Member):
    # remove entry from DB if member was drone
    if has_any_role(member, [DRONE, STORED]):
        drone_id = get_id(member.display_name)
        drone_management.remove_drone_from_db(drone_id)
Exemplo n.º 9
0
from bot_utils import get_id

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.")
Exemplo n.º 10
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