diff options
author | latex <latex@disroot.org> | 2023-03-31 02:05:25 +0200 |
---|---|---|
committer | latex <latex@disroot.org> | 2023-03-31 02:05:25 +0200 |
commit | 472b5b0e46dcadbc769b8b415aa6807297467e59 (patch) | |
tree | 37e5c0967ac7811867837ff6ffb829452b651184 | |
parent | 9ed06f53fd8db5bf920a315f480e923eb2c6620f (diff) | |
download | mumblecord-472b5b0e46dcadbc769b8b415aa6807297467e59.tar.gz |
add commands: guilds, vc, activevc
-rw-r--r-- | src/commands.py | 64 | ||||
-rw-r--r-- | src/main.py | 6 | ||||
-rw-r--r-- | src/mumblecord.py | 74 |
3 files changed, 136 insertions, 8 deletions
diff --git a/src/commands.py b/src/commands.py new file mode 100644 index 0000000..8a49e73 --- /dev/null +++ b/src/commands.py @@ -0,0 +1,64 @@ +import discord + +def register_all_commands(bot): + bot.register_command("guilds", cmd_guilds) + bot.register_command("vc", cmd_vc) + bot.register_command("activevc", cmd_activevc) + +def cmd_guilds(bot, text, user, arg, argv): + """ + Show all guilds + """ + response = "" + for guild in bot.discord.guilds: + response += f"{guild.id}: {guild.name}\n" + + user.send_text_message(response) + +def cmd_vc(bot, text, user, arg, argv): + """ + Show voice channels in all guilds, + or in a specific guild if the ID or name of guild has been given + """ + if not argv: + response = "" + for guild in bot.discord.guilds: + response += f"{guild.id}: {guild.name}\n" + for vc in guild.voice_channels: + response += f">{vc.id}: {vc.name}\n" + else: + guild = None + try: + guild = discord.utils.find(lambda g: g.id == int(argv[0]), bot.discord.guilds) + except ValueError: + pass + if not guild: + guild = discord.utils.find(lambda g: g.name == arg, bot.discord.guilds) + if not guild: + user.send_text_message("no guild found") + return + + response = f"{guild.name}: \n" + for vc in guild.voice_channels: + response += f">{vc.id}: {vc.name}\n" + + user.send_text_message(response) + +def cmd_activevc(bot, text, user, arg, argv): + """ + Show all voice channels with users inside + """ + if not argv: + response = "" + for guild in bot.discord.guilds: + vcs_with_active_members = [] + for vc in guild.voice_channels: + if len(vc.members) > 0: + vcs_with_active_members.append(vc) + if len(vcs_with_active_members) > 0: + response += f"{guild.id}: {guild.name}\n" + for vc in vcs_with_active_members: + response += f">{vc.id}: {vc.name} ({len(vc.members)})\n" + user.send_text_message(response) + else: + user.send_text_message("no active voice channels found") diff --git a/src/main.py b/src/main.py index 69f6a57..99ec97d 100644 --- a/src/main.py +++ b/src/main.py @@ -2,6 +2,7 @@ import asyncio import argparse import configparser import mumblecord +import commands parser = argparse.ArgumentParser( prog="mumblecord", @@ -17,6 +18,7 @@ conf_mumble = conf["mumble"] conf_discord = conf["discord"] bot = mumblecord.Mumblecord(conf_mumble, conf_discord) +commands.register_all_commands(bot) + +asyncio.run(bot.run()) -while True: - pass diff --git a/src/mumblecord.py b/src/mumblecord.py index 914265f..1972508 100644 --- a/src/mumblecord.py +++ b/src/mumblecord.py @@ -1,6 +1,8 @@ import asyncio import pymumble_py3 import discord +import shlex +import html class Discord(discord.Client): def __init__(self, mumblecord): @@ -9,7 +11,11 @@ class Discord(discord.Client): async def on_ready(self): print(f"Discord: logged in as {self.user}") - self.mumblecord.mumble.users.myself.comment(f"{self.user}") + self.mumblecord.update_mumble_comment() + +class ChannelLink: + def __init__(self, discord_voice_client): + self.discord_voice_client = discord_voice_client class Mumblecord: def __init__(self, conf_mumble, conf_discord): @@ -19,17 +25,73 @@ class Mumblecord: self.mumble_password = conf_mumble.get("password", "") self.mumble_cert = conf_mumble.get("cert", None) self.mumble_key = conf_mumble.get("key", None) - + self.mumble_prefix = conf_mumble.get("prefix", "$") + self.mumble_trusted_user = conf_mumble.get("trusted_user", None) + + self.commands = {} + self.voicelink = None + self.discord_token = conf_discord["token"] self.mumble = pymumble_py3.Mumble(self.mumble_host, self.mumble_user, password=self.mumble_password, certfile=self.mumble_cert, keyfile=self.mumble_key, stereo=True) - self.mumble.start() - self.mumble.is_ready() + self.mumble.callbacks.set_callback(pymumble_py3.constants.PYMUMBLE_CLBK_SOUNDRECEIVED, + self._mumble_sound_received) + self.mumble.callbacks.set_callback(pymumble_py3.constants.PYMUMBLE_CLBK_TEXTMESSAGERECEIVED, + self._mumble_text_message_received) + self.mumble.set_receive_sound(1) - asyncio.run(self._init_discord()) + self.discord = None - async def _init_discord(self): + async def run(self): self.discord = Discord(self) + await asyncio.gather( + asyncio.to_thread(self.mumble.start)) await self.discord.start(self.discord_token) + + def register_command(self, cmd, callback): + """ + Register a command. + When the command is ran, the callback will be called with the following arguments: + + bot: the Mumblecord class the callback is ran under + text: the text object from the pymumble TEXTMESSAGERECEIVED callback + user: the User who sent the message + arg: everything typed after the command. Useful if you just need one big argument + argv: an array of arguments, split for your convenience + """ + + self.commands[cmd] = {"callback": callback} + + def update_mumble_comment(self): + self.mumble.users.myself.comment(f"{self.discord.user}") + + def _mumble_text_message_received(self, text): + if not text.message.startswith(self.mumble_prefix): + return + if text.actor == 0: + # Some server will send a welcome message to the bot once connected. + # It doesn't have a valid "actor". Simply ignore it here. + return + + user = self.mumble.users[text.actor] + + message = html.unescape(text.message) + cmd = message[1:].split(" ", 1)[0] + + if not self.commands[cmd]: + return + + try: + arg = message[1:].split(" ", 1)[1] + argv = shlex.split(arg) + except IndexError: + arg = None + argv = None + + self.commands[cmd]["callback"](self, text, user, arg, argv) + + def _mumble_sound_received(self, user, soundchunk): + if self.voicelink is None: + return |