def reset_cooldown(channel_name: str) -> None:
    """
    Updates the cooldown for the given channel, setting the last accessed
    time to now.
    """
    if channel_name[0] == "#":
        channel_name = channel_name[1:]
        log.error("Someplace in the code is using channels with #.")
    cooldowns[channel_name] = datetime.datetime.utcnow()
Exemple #2
0
    async def on_message(self, message):
        full_cmd = message.content.split()
        if not full_cmd:
            return
        cmd = full_cmd[0]
        if not cmd:
            return
        if not cmd[0] == settings["prefix"]:
            return
        cmd = cmd[len(settings["prefix"]):]  # skip past "!"

        # check cooldown for this channel.
        guild = message.guild
        if not guild:
            return
        channel = str(
            guild.id)  # this is a unique int representing this discord server.
        author = message.author
        is_mod = (author.guild_permissions.administrator
                  if author.guild_permissions else False)
        context = CommandContext(
            author=AuthorInfo(name=message.author.display_name, is_mod=is_mod),
            channel=channel,
            platform="discord",
        )
        db = Database.get()
        content = " ".join(full_cmd[1:] or [])
        if check_cooldown(db, context.channel):
            # Enforce cooldown for this channel.
            return
        try:
            resp = self.logic.exec(context, cmd, content)
            if resp:
                embed = discord.Embed(
                    title="LogicEFTBot",
                    url="https://eft.bot",
                    description="The Free Tarkov Bot",
                    color=0x780A81,
                )
                # embed.set_thumbnail(url="") #Will be implimented soon
                embed.add_field(name=cmd.capitalize() + " check",
                                value=resp,
                                inline=True)
                await message.channel.send(embed=embed)
                reset_cooldown(context.channel)
        except CommandNotFoundException:
            # just be silent if we don't know the command.
            pass
        except Exception as e:
            # Log all other exceptions.
            log.error(
                f"Exception processing command ({cmd}) for channel '{guild.name}' (id={context.channel}) -"
            )
            log.error(e)
            traceback.print_exc()
def check_cooldown(db: Database, channel_name: str) -> bool:
    """
    Returns true if the given channel is under cooldown.
    (API requests should be blocked to avoid overloading backend.)
    """
    if channel_name[0] == "#":
        channel_name = channel_name[1:]
        log.error("Someplace in the code is using channels with #.")
    cooldown_time = cooldowns[channel_name] if channel_name in cooldowns else None
    if cooldown_time is None:
        return False  # no cooldown found.
    cooldown = db.get_cd(channel_name)
    if cooldown is None:
        cooldown = int(settings["default_cooldown"])
    return not datetime.datetime.utcnow() - cooldown_time > timedelta(seconds=cooldown)
Exemple #4
0
 def _connect(self):
     """
     Establish a connection to the server at the front of the server_list.
     """
     server = self.servers.peek()
     try:
         self.connect(
             server.host,
             server.port,
             self._nickname,
             server.password,
             ircname=self._realname,
         )
     except Exception as e:
         log.error("Error connecting to the server: %s", str(e))
         pass
Exemple #5
0
 def get_command_aliases(self, channel: str) -> Optional[Dict[str, str]]:
     """
     Returns all of the aliases set for this channel (or None.)
     """
     self.sql.execute("SELECT aliases FROM users WHERE username=%s",
                      (channel, ))
     aliases = self.sql.fetchone()
     if aliases: aliases = aliases[0]
     if not aliases:
         return None
     try:
         return cast(Dict[str, str], json.loads(aliases))
     except json.decoder.JSONDecodeError:
         log.error(
             "Got invalid JSON while deserializing commands for channel %s",
             channel)
         return None
Exemple #6
0
 def do_command(self, context: CommandContext, event: Any, command: str,
                content: Optional[str]):
     c = self.connection
     try:
         resp = self.logic.exec(context, command, content)
         if resp:
             self.do_send_msg(context.channel, resp)
     except CommandNotFoundException:
         # just be silent if we don't know the command.
         pass
     except Exception as e:
         # Log all other exceptions.
         log.error(
             f"Exception processing command ({command}) for channel ({context.channel}) -"
         )
         log.error(e)
         traceback.print_exc()
Exemple #7
0
 def bot_alias(self, ctx: CommandContext, data: str) -> str:
     if not ctx.author.is_mod:
         return "You ain't a mod you dingus!"
     parts = data.split() if data else None
     if not parts or len(parts) != 2:
         return "Usage: !alias <alias> <existingCommand>"
     alias = parts[0].lower()
     existingCommand = parts[1].lower()
     if alias in self.commands:
         return f"Alias `{alias}` would overwrite an existing command. Please choose another alias."
     if not existingCommand in self.commands:
         return "Can't set an alias to a command which doesn't exist!"
     try:
         self.db.add_command_alias(ctx.channel, existingCommand, alias)
         return f"Set new alias ({alias}) for ({existingCommand})!"
     except Exception as e:
         log.error(str(e))
         return "Failed to add alias."
 def between_frames() -> None:
     # this is run when the twitch bot has free time, roughly every 5s.
     volume = bot.processed_commands
     bot.processed_commands = 0
     try:
         commands = []
         target_time = time.time() + 2
         while time.time() < target_time:
             # for 2 seconds, attempt to read all of the items out of the queue.
             # we don't want to spend too much time here, since this is called every 5 seconds,
             # and we have a responsibility to PONG the server.
             try:
                 command = queue.get(timeout=0.1)
                 if command:
                     commands.append(command)
             except Empty:
                 # no more items left to pull
                 break
         for command in commands:
             if command == END_OF_LIFE:
                 # exit command.
                 bot.disconnect()
                 # we need to be careful to empty the queue before exiting, so that
                 # there is not a deadlock.
                 # see: https://stackoverflow.com/questions/31665328/python-3-multiprocessing-queue-deadlock-when-calling-join-before-the-queue-is-em
                 while not queue.empty():
                     queue.get()
                 os._exit(0)
             else:
                 feedbackQueue.put(
                     ShardUpdate(
                         status=":smiley: Healthy",
                         message=f"Joining #{command}",
                         RPM=volume,
                     ))
                 # issue a join command to the twitch bot.
                 bot.do_join(str(command))
             feedbackQueue.put(
                 ShardUpdate(status=bot.status,
                             message=bot.message,
                             RPM=volume))
     except Exception as e:
         # nothing to do.
         log.error("Exception in shard: %s", str(e))
 def _connect(self):
     """
     Establish a connection to the server at the front of the server_list.
     """
     server = self.servers.peek()
     self.status = ":mobile_phone_with_arrow: Connecting"
     self.message = "Reaching twitch..."
     try:
         self.connect(
             server.host,
             server.port,
             self._nickname,
             server.password,
             ircname=self._realname,
         )
         self.status = ":white_heavy_check_mark: Healthy"
         self.message = "Connected"
     except Exception as e:
         log.error("Error connecting to the server: %s", str(e))
         pass
Exemple #10
0
    async def on_message(self, message):
        full_cmd = message.content.split()
        if not full_cmd:
            return
        cmd = full_cmd[0]
        if not cmd:
            return
        if not cmd[0] == settings["prefix"]:
            return
        cmd = cmd[len(settings["prefix"]):]  # skip past "!"

        # check cooldown for this channel.
        guild = message.guild
        if not guild:
            return
        channel = str(
            guild.id)  # this is a unique int representing this discord server.
        author = message.author
        is_mod = (author.guild_permissions.administrator
                  if author.guild_permissions else False)
        context = CommandContext(
            author=AuthorInfo(name=message.author.display_name, is_mod=is_mod),
            channel=channel,
            platform="discord",
        )
        db = Database.get()
        content = " ".join(full_cmd[1:] or [])
        if check_cooldown(db, context.channel):
            # Enforce cooldown for this channel.
            return
        try:
            resp = self.logic.exec(context, cmd, content)
            if isinstance(resp, str):
                await message.channel.send(resp)
            elif isinstance(resp, discord.Embed):
                await message.channel.send(embed=resp)
            else:
                log.error("Unknown response: {}".format(str(resp)))
            reset_cooldown(context.channel)
        except CommandNotFoundException:
            # just be silent if we don't know the command.
            pass
        except Exception as e:
            # Log all other exceptions.
            log.error(
                f"Exception processing command ({cmd}) for channel '{guild.name}' (id={context.channel}) -"
            )
            log.error(e)
            traceback.print_exc()