From 00629255679804bfde6ea70b844210962d9a10a7 Mon Sep 17 00:00:00 2001 From: Xevion Date: Sat, 23 Jan 2021 20:34:47 -0600 Subject: [PATCH] basic task automation client, logging and response processing --- bot/client.py | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 bot/client.py diff --git a/bot/client.py b/bot/client.py new file mode 100644 index 0000000..074a232 --- /dev/null +++ b/bot/client.py @@ -0,0 +1,126 @@ +import argparse +import asyncio +import logging +import re +import time +from datetime import datetime +from pprint import pprint +from typing import Optional, Tuple + +import discord +from discord.ext.tasks import loop + +logger = logging.getLogger(__file__) +logger.setLevel(logging.DEBUG) + + +class UnbelievaClient(discord.Client): + def __init__(self, bot_id: int, channel_id: int, *args, **kwargs) -> None: + super().__init__(*args, **kwargs) + self.last_message = -1 + + self.bot_id, self.channel_id = bot_id, channel_id + + self.channel: Optional[discord.TextChannel] = None + self.bot: Optional[discord.User] = None + self.tasks = [ + ('$work', 5 * 60 + 5), + ('$slut', 13 * 60 + 5), + ('$crime', 20 * 60 + 5) + ] + self.task_times = {} + self.durations = { + 'hour': 3600, + 'minute': 60, + 'second': 1 + } + self.task_parsings = { + 'work': '$work', + 'be a slut': '$slut', + 'commit a crime': '$crime' + } + + self.money = 0 + self.last_deposit = -1 + self.last_user_deposit = -1 + + async def on_ready(self): + await self.wait_until_ready() + self.channel: discord.TextChannel = self.get_channel(self.channel_id) + self.bot = self.bot_id + self.check_task_available.start() + logger.info(f'Connected to #{self.channel.name} in {self.channel.guild.name}') + + + async def on_message(self, message: discord.Message): + if message.channel == self.channel: + if message.author.id == self.bot and len(message.embeds) > 0: + embed = message.embeds[0] + + if embed.author.name == f'{self.user.name}#{self.user.discriminator}': + # Handling for task wait times + task_match = re.search(r'You cannot (work|be a slut|commit a crime) for ([\w\s]+)\.', + embed.description) + if task_match: + self.handle_task_wait(task_match) + + # Handling earnings + money_match = re.search(r'\$([0-9,]+)', embed.description) + if money_match and 'deposited' not in embed.description.lower(): + change = int(money_match.group(1).replace(',', '')) + if embed.colour.value == 15684432: + self.money -= change + logger.info(f'Lost ${change}') + elif embed.colour.value == 6732650: + self.money += change + logger.info(f'Gained ${change}') + + def handle_task_wait(self, match: re.Match): + task_command = self.task_parsings[match.group(1)] + duration_match = re.match( + r'(\d+) (hour|minute|second)s?(?: and (\d+) (hour|minute|second)s?)?', + match.group(2)) + + groups = len(list(filter(lambda s: s is not None, duration_match.groups()))) + duration = 0 + for i in range(0, groups // 2): + x, y = (i * 2) + 1, (i * 2) + 2 + duration += int(duration_match.group(x)) * self.durations[duration_match.group(y)] + epoch = time.time() + duration + 2 + logger.debug(f'"{match.group(2)}" => {duration}s') + logger.debug(f'Changed {task_command} to wait {duration + 2}s instead.') + self.task_times[task_command] = epoch + + @loop(seconds=1) + async def check_task_available(self): + await self.wait_until_ready() + + # Check for available tasks + now = time.time() + task_completed = False + for task, duration in self.tasks: + if self.task_times.get(task, 0) <= now: + logger.debug(f'Planning to execute {task} {duration}s from now.') + self.task_times[task] = now + duration + await self.command_sleep() + logger.debug(f'Executing {task} task.') + await self.channel.send(task) + self.last_message = time.time() + task_completed = True + + if not task_completed: + if self.last_deposit + (30 * 60) <= now: + await self.command_sleep() + await self.channel.send('$dep all') + self.last_message = time.time() + self.last_deposit = time.time() + + async def command_sleep(self): + """Sleep right before sending a command.""" + now = time.time() + time_between = now - self.last_message + wait_time = 6 - time_between + + if wait_time > 0: + logger.debug(f'Sleeping for {round(wait_time, 2)}s before sending a command...') + await asyncio.sleep(wait_time)