diff --git a/BotResources.py b/BotResources.py index 4052be6..b205b11 100644 --- a/BotResources.py +++ b/BotResources.py @@ -3,6 +3,7 @@ import configparser from os.path import exists PDB_ACCEPTABLE_HANDLERS = ['gqrx', 'op25'] +PDB_KNOWN_BOT_IDS = [756327271597473863, 915064996994633729, 943742040255115304] def check_if_config_exists(): diff --git a/bot.py b/bot.py index c20698a..bd8e063 100644 --- a/bot.py +++ b/bot.py @@ -1,6 +1,9 @@ +import asyncio import os import platform import discord + +import BotResources import sound import configparser from discord.ext import commands @@ -22,6 +25,7 @@ class Bot(commands.Bot): self.Default_Channel_ID = kwargs['Channel_ID'] self.Default_Mention_Group = kwargs['Mention_Group'] self.Handler = kwargs['Handler'] + self.Command_Prefix = kwargs['command_prefix'] # Init Variable for sound self.streamHandler = None @@ -51,20 +55,8 @@ class Bot(commands.Bot): # Add discord commands to the bot self.add_commands() - # Check the ./modules folder for any modules (cog.py) - self.check_for_modules() - - # Check the handler being used during init - def check_handler(self): - if self.Handler == "gqrx": - print("Starting GQRX handler") - from gqrxHandler import GQRXHandler - self.GQRXHandler = GQRXHandler() - - elif self.Handler == 'op25': - print("Starting OP25 handler") - from op25Handler import OP25Handler - self.OP25Handler = OP25Handler() + # Add discord events to the bot + self.add_events() # Start the bot def start_bot(self): @@ -75,7 +67,8 @@ class Bot(commands.Bot): # Test command to see if the bot is on (help command can also be used) @self.command(help="Use this to test if the bot is alive", brief="Sends a 'pong' in response") async def ping(ctx): - await ctx.send('pong') + if ctx.author.id != self.user.id: + await ctx.send('pong') # Command to join the bot the voice channel the user who called the command is in @self.command(help="Use this command to join the bot to your channel", @@ -224,7 +217,7 @@ class Bot(commands.Bot): await ctx.send(f"Ok {str(member).capitalize()}, I reloaded {module}") else: await ctx.send(f"{str(member).capitalize()}, something went wrong. Please check the console") - + @self.command(name='startsdr', hidden=True) async def _startsdr(ctx, member: discord.Member = None): self.start_sdr() @@ -233,6 +226,60 @@ class Bot(commands.Bot): async def _stopsdr(ctx, member: discord.Member = None): self.stop_sdr() + # Add discord events to the bot + def add_events(self): + # Run any functions that need to have the bot running to complete + @self.event + async def on_ready(): + # Check the ./modules folder for any modules (cog.py) + await self.check_for_modules() + + @self.event + async def on_message(message): + await self.check_and_reply_to_ping(message) + + # Check to see if other bots are online + async def check_other_bots_online(self): + print('Checking if other bots are online') + channel = self.get_channel(self.Default_Channel_ID) + print(f"Channel to be tested in: {channel}") + + bots_online = [] + + def verify_bot_msg(msg): + if msg.author.id in BotResources.PDB_KNOWN_BOT_IDS: + bots_online.append(msg.author.id) + + await self.wait_until_ready() + + await channel.send(f"{self.Command_Prefix}ping") + + seconds_waited = 0 + while seconds_waited < 2: + try: + await self.wait_for("message", check=verify_bot_msg, timeout=1) + except asyncio.exceptions.TimeoutError: + seconds_waited += 1 + + print(f"Bots Online: {bots_online}") + + if len(bots_online) == 0: + return False + elif len(bots_online) > 0: + return True + + # Check the handler being used during init + def check_handler(self): + if self.Handler == "gqrx": + print("Starting GQRX handler") + from gqrxHandler import GQRXHandler + self.GQRXHandler = GQRXHandler() + + elif self.Handler == 'op25': + print("Starting OP25 handler") + from op25Handler import OP25Handler + self.OP25Handler = OP25Handler() + # Load the proper OPUS library for the device being used def load_opus(self): # Check the system type and load the correct library @@ -258,14 +305,16 @@ class Bot(commands.Bot): return False # Search the ./modules folder for any modules to load - def check_for_modules(self): - # A valid module must be built as a 'cog', refer to the docs for more information - for folder_name in os.listdir("modules"): - if str(folder_name)[0] == '.': - continue - elif os.path.exists(os.path.join("modules", folder_name, "cog.py")): - print(f"Loaded extension: {folder_name}") - self.load_extension(f"modules.{folder_name}.cog") + async def check_for_modules(self): + # Check to see if other bots are online and don't load the modules if they are + if not await self.check_other_bots_online(): + # A valid module must be built as a 'cog', refer to the docs for more information + for folder_name in os.listdir("modules"): + if str(folder_name)[0] == '.': + continue + elif os.path.exists(os.path.join("modules", folder_name, "cog.py")): + print(f"Loaded extension: {folder_name}") + self.load_extension(f"modules.{folder_name}.cog") # Reload a selected module for changes def reload_modules(self, module): @@ -318,7 +367,7 @@ class Bot(commands.Bot): # Wait for the running processes to close if self.Handler == 'op25': self.OP25Handler.close_op25() - #self.OP25Handler.join() + # self.OP25Handler.join() # Need a way to 'close' GQRX self.sdr_started = False @@ -386,4 +435,12 @@ class Bot(commands.Bot): else: return False - + # Check if message is a ping request and respond even if it is a bot + async def check_and_reply_to_ping(self, message): + if "ping" in message.content: + ctx = await self.get_context(message) + await self.invoke(ctx) + return True + else: + await self.process_commands(message) + return False diff --git a/modules/LinkCop/cog.py b/modules/LinkCop/cog.py index b2ccdf9..9d70c13 100644 --- a/modules/LinkCop/cog.py +++ b/modules/LinkCop/cog.py @@ -2,6 +2,7 @@ import re import discord from discord.ext import commands import random +from BotResources import PDB_KNOWN_BOT_IDS regex_link = re.compile('(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+)') @@ -40,11 +41,12 @@ class LinkCop(commands.Cog): 758792783020163084 # Bots ] - self.whitelisted_ID = [ - 756327271597473863, # Greada ID - 915064996994633729, # Jorn ID + # Bring in the known bot IDs from PDB bots + self.whitelisted_ID = PDB_KNOWN_BOT_IDS + + self.whitelisted_ID.append([ 235148962103951360 # Carl Bot - ] + ]) self.add_events() @@ -71,7 +73,7 @@ class LinkCop(commands.Cog): print(f"Link Cop Error: '{err}'") print(f"Bot or other non-user that has not been whitelisted sent a message") - await self.bot.process_commands(ctx) + await self.bot.check_and_reply_to_ping(ctx) async def send_message(self, message): send_channel = self.bot.get_channel(id=self.reply_channel_id)