- Remove long json strings

- Correctly encode contents to avoid errors
- Fixed #93
This commit is contained in:
trigg 2020-10-20 11:28:25 +00:00
parent 1bb1986c11
commit 3dd4fdb4ee

View file

@ -10,7 +10,11 @@
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
"""The connector for discord. Connects in as if it was Streamkit for OBS or Xsplit and communicates to get voice & text info to display""" """
The connector for discord.
Connects in as if it was Streamkit for OBS or Xsplit and
communicates to get voice & text info to display
"""
import select import select
import time import time
import json import json
@ -22,14 +26,18 @@ import requests
class DiscordConnector: class DiscordConnector:
"""The connector for discord. Connects in as if it was Streamkit for OBS or Xsplit and communicates to get voice & text info to display""" """
The connector for discord.
Connects in as if it was Streamkit for OBS or Xsplit and
communicates to get voice & text info to display
"""
def __init__(self, text_settings, voice_settings, text_overlay, voice_overlay): def __init__(self, text_settings, voice_settings, text_overlay, voice_overlay):
self.text_settings = text_settings self.text_settings = text_settings
self.text_overlay = text_overlay self.text_overlay = text_overlay
self.voice_settings = voice_settings self.voice_settings = voice_settings
self.voice_overlay = voice_overlay self.voice_overlay = voice_overlay
self.ws = None self.websocket = None
self.access_token = "none" self.access_token = "none"
self.oauth_token = "207646673902501888" self.oauth_token = "207646673902501888"
self.access_delay = 0 self.access_delay = 0
@ -51,19 +59,28 @@ class DiscordConnector:
self.last_text_channel = None self.last_text_channel = None
def get_access_token_stage1(self): def get_access_token_stage1(self):
self.ws.send("{\"cmd\":\"AUTHORIZE\",\"args\":{\"client_id\":\"%s\",\"scopes\":[\"rpc\",\"messages.read\"],\"prompt\":\"none\"},\"nonce\":\"deadbeef\"}" % ( cmd = {
self.oauth_token)) "cmd": "AUTHORIZE",
"args":
{
"client_id": self.oauth_token,
"scopes": ["rpc", "messages.read"],
"prompt": "none",
},
"nonce": "deadbeef"
}
self.websocket.send(json.dumps(cmd))
def get_access_token_stage2(self, code1): def get_access_token_stage2(self, code1):
url = "https://streamkit.discord.com/overlay/token" url = "https://streamkit.discord.com/overlay/token"
myobj = {"code": code1} myobj = {"code": code1}
x = requests.post(url, json=myobj) response = requests.post(url, json=myobj)
try: try:
j = json.loads(x.text) jsonresponse = json.loads(response.text)
except json.JSONDecodeError: except json.JSONDecodeError:
j = {} jsonresponse = {}
if "access_token" in j: if "access_token" in jsonresponse:
self.access_token = j["access_token"] self.access_token = jsonresponse["access_token"]
self.req_auth() self.req_auth()
else: else:
sys.exit(1) sys.exit(1)
@ -73,9 +90,9 @@ class DiscordConnector:
self.current_voice = "0" self.current_voice = "0"
return return
if channel != self.current_voice: if channel != self.current_voice:
cn = self.channels[channel]['name'] channel_name = self.channels[channel]['name']
logging.info( logging.info(
"Joined room: %s", cn) "Joined room: %s", channel_name)
self.sub_voice_channel(channel) self.sub_voice_channel(channel)
self.current_voice = channel self.current_voice = channel
if need_req: if need_req:
@ -104,17 +121,17 @@ class DiscordConnector:
utc_time = time.strptime( utc_time = time.strptime(
message["timestamp"], "%Y-%m-%dT%H:%M:%S.%f%z") message["timestamp"], "%Y-%m-%dT%H:%M:%S.%f%z")
epoch_time = calendar.timegm(utc_time) epoch_time = calendar.timegm(utc_time)
un = message["author"]["username"] username = message["author"]["username"]
if "nick" in message and message['nick'] and len(message["nick"]) > 1: if "nick" in message and message['nick'] and len(message["nick"]) > 1:
un = message["nick"] username = message["nick"]
ac = "#ffffff" colour = "#ffffff"
if "author_color" in message: if "author_color" in message:
ac = message["author_color"] colour = message["author_color"]
self.text.append({'id': message["id"], self.text.append({'id': message["id"],
'content': self.get_message_from_message(message), 'content': self.get_message_from_message(message),
'nick': un, 'nick': username,
'nick_col': ac, 'nick_col': colour,
'time': epoch_time, 'time': epoch_time,
'attach': self.get_attachment_from_message(message), 'attach': self.get_attachment_from_message(message),
}) })
@ -195,7 +212,9 @@ class DiscordConnector:
thisuser = j["data"]["user"] thisuser = j["data"]["user"]
nick = j["data"]["nick"] nick = j["data"]["nick"]
thisuser["nick"] = nick thisuser["nick"] = nick
mute = j["data"]["voice_state"]["mute"] or j["data"]["voice_state"]["self_mute"] or j["data"]["voice_state"]["suppress"] mute = (j["data"]["voice_state"]["mute"] or
j["data"]["voice_state"]["self_mute"] or
j["data"]["voice_state"]["suppress"])
deaf = j["data"]["voice_state"]["deaf"] or j["data"]["voice_state"]["self_deaf"] deaf = j["data"]["voice_state"]["deaf"] or j["data"]["voice_state"]["self_deaf"]
thisuser["mute"] = mute thisuser["mute"] = mute
thisuser["deaf"] = deaf thisuser["deaf"] = deaf
@ -275,8 +294,6 @@ class DiscordConnector:
if channel["type"] == 2: if channel["type"] == 2:
self.req_channel_details(channel["id"]) self.req_channel_details(channel["id"])
self.check_guilds() self.check_guilds()
# self.sub_all_voice_guild(j["nonce"])
# self.sub_all_text_guild(j["nonce"])
return return
elif j["cmd"] == "SUBSCRIBE": elif j["cmd"] == "SUBSCRIBE":
return return
@ -329,22 +346,45 @@ class DiscordConnector:
def on_close(self): def on_close(self):
logging.info("Connection closed") logging.info("Connection closed")
self.ws = None self.websocket = None
def req_auth(self): def req_auth(self):
self.ws.send("{\"cmd\":\"AUTHENTICATE\",\"args\":{\"access_token\":\"%s\"},\"nonce\":\"deadbeef\"}" % ( cmd = {
self.access_token)) "cmd": "AUTHENTICATE",
"args": {
"access_token": self.access_token
},
"nonce": "deadbeef"
}
self.websocket.send(json.dumps(cmd))
def req_guilds(self): def req_guilds(self):
self.ws.send("{\"cmd\":\"GET_GUILDS\",\"args\":{},\"nonce\":\"3333\"}") cmd = {
"cmd": "GET_GUILDS",
"args": {},
"nonce": "deadbeef"
}
self.websocket.send(json.dumps(cmd))
def req_channels(self, guild): def req_channels(self, guild):
self.ws.send("{\"cmd\":\"GET_CHANNELS\",\"args\":{\"guild_id\":\"%s\"},\"nonce\":\"%s\"}" % ( cmd = {
guild, guild)) "cmd": "GET_CHANNELS",
"args": {
"guild_id": guild
},
"nonce": guild
}
self.websocket.send(json.dumps(cmd))
def req_channel_details(self, channel): def req_channel_details(self, channel):
self.ws.send("{\"cmd\":\"GET_CHANNEL\",\"args\":{\"channel_id\":\"%s\"},\"nonce\":\"%s\"}" % ( cmd = {
channel, channel)) "cmd": "GET_CHANNEL",
"args": {
"channel_id": channel
},
"nonce": channel
}
self.websocket.send(json.dumps(cmd))
def find_user(self): def find_user(self):
count = 0 count = 0
@ -354,25 +394,21 @@ class DiscordConnector:
count += 1 count += 1
logging.warning("Getting %s rooms", count) logging.warning("Getting %s rooms", count)
def sub_raw(self, cmd, channel, nonce): def sub_raw(self, event, args, nonce):
self.ws.send("{\"cmd\":\"SUBSCRIBE\",\"args\":{%s},\"evt\":\"%s\",\"nonce\":\"%s\"}" % ( cmd = {
channel, cmd, nonce)) "cmd": "SUBSCRIBE",
"args": args,
"evt": event,
"nonce": nonce
}
self.websocket.send(json.dumps(cmd))
def sub_server(self): def sub_server(self):
# Experimental self.sub_raw("VOICE_CHANNEL_SELECT", {}, "VOICE_CHANNEL_SELECT")
self.sub_raw("VOICE_CHANNEL_SELECT", "", "VOICE_CHANNEL_SELECT") self.sub_raw("VOICE_CONNECTION_STATUS", {}, "VOICE_CONNECTION_STATUS")
self.sub_raw("VOICE_CONNECTION_STATUS", "", "VOICE_CONNECTION_STATUS")
#sub_raw(ws,"ACTIVITY_JOIN", "","ACTIVITY_JOIN")
#sub_raw(ws,"ACTIVITY_JOIN_REQUEST", "","ACTIVITY_JOIN_REQUEST")
#sub_raw(ws,"ACTIVITY_SPECTATE", "", "ACTIVITY_SPECTATE")
# sub_raw(ws,"ACTIVITY_INVITE","","ACTIVITY_INVITE")
#sub_raw(ws,"GAME_JOIN", "", "GAME_JOIN")
#sub_raw(ws,"GAME_SPECTATE", "", "GAME_SPECTATE")
#sub_raw(ws,"VOICE_SETTINGS_UPDATE", "", "VOICE_SETTINGS_UPDATE")
#sub_raw(ws,"GUILD_STATUS", "\"guild_id\":\"147073008450666496\"", "GUILD_STATUS")
def sub_channel(self, cmd, channel): def sub_channel(self, event, channel):
self.sub_raw(cmd, "\"channel_id\":\"%s\"" % (channel), channel) self.sub_raw(event, {"channel_id": channel}, channel)
def sub_text_channel(self, channel): def sub_text_channel(self, channel):
self.sub_channel("MESSAGE_CREATE", channel) self.sub_channel("MESSAGE_CREATE", channel)
@ -386,27 +422,9 @@ class DiscordConnector:
self.sub_channel("SPEAKING_START", channel) self.sub_channel("SPEAKING_START", channel)
self.sub_channel("SPEAKING_STOP", channel) self.sub_channel("SPEAKING_STOP", channel)
def sub_all_voice_guild(self, gid):
for channel in self.guilds[gid]["channels"]:
if channel["type"] == 2:
self.sub_voice_channel(channel["id"])
def sub_all_text_guild(self, gid):
for channel in self.guilds[gid]["channels"]:
if channel["type"] == 0:
self.sub_text_channel(channel["id"])
def sub_all_voice(self):
for guild in self.guilds:
self.sub_all_voice_guild(guild)
def sub_all_text(self):
for guild in self.guilds:
self.sub_all_text_guild(guild)
def do_read(self): def do_read(self):
# Ensure connection # Ensure connection
if not self.ws: if not self.websocket:
self.connect() self.connect()
if self.warn_connection: if self.warn_connection:
logging.info( logging.info(
@ -435,31 +453,33 @@ class DiscordConnector:
self.set_text_channel(self.text_settings.get_channel()) self.set_text_channel(self.text_settings.get_channel())
# Poll socket for new information # Poll socket for new information
r, _w, _e = select.select((self.ws.sock,), (), (), 0) recv, _w, _e = select.select((self.websocket.sock,), (), (), 0)
while r: while recv:
try: try:
# Recieve & send to on_message # Recieve & send to on_message
msg = self.ws.recv() msg = self.websocket.recv()
self.on_message(msg) self.on_message(msg)
r, _w, _e = select.select((self.ws.sock,), (), (), 0) recv, _w, _e = select.select((self.websocket.sock,), (), (), 0)
except websocket.WebSocketConnectionClosedException: except websocket.WebSocketConnectionClosedException:
self.on_close() self.on_close()
return True return True
return True return True
def start_listening_text(self, ch): def start_listening_text(self, channel):
if self.ws: if self.websocket:
self.sub_text_channel(ch) self.sub_text_channel(channel)
else: else:
self.last_text_channel = ch self.last_text_channel = channel
def connect(self): def connect(self):
if self.ws: if self.websocket:
return return
try: try:
self.ws = websocket.create_connection("ws://127.0.0.1:6463/?v=1&client_id=%s" % (self.oauth_token), self.websocket = websocket.create_connection(
origin="https://streamkit.discord.com") "ws://127.0.0.1:6463/?v=1&client_id=%s" % (self.oauth_token),
except ConnectionError as e: origin="https://streamkit.discord.com"
)
except ConnectionError as error:
if self.error_connection: if self.error_connection:
logging.error(e) logging.error(error)
self.error_connection = False self.error_connection = False