98 lines
3.4 KiB
Python
98 lines
3.4 KiB
Python
import asyncio
|
|
import pymumble_py3
|
|
import discord
|
|
import shlex
|
|
import html
|
|
|
|
class Discord(discord.Client):
|
|
def __init__(self, mumblecord):
|
|
self.mumblecord = mumblecord
|
|
super().__init__()
|
|
|
|
async def on_ready(self):
|
|
print(f"Discord: logged in as {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):
|
|
self.mumble_host = conf_mumble["host"]
|
|
self.mumble_port = conf_mumble.getint("port", 64738)
|
|
self.mumble_user = conf_mumble.get("user", "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.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)
|
|
|
|
self.discord = None
|
|
|
|
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
|