- Huge overhaul of connector
- Removed almost all uses of GET_CHANNEL - Rate limiting no longer in use - Probably don't need server limit any more - Unsubscribe from events when changing text/voice room - find_user now has a direct method call which is miles better than previous - hooked 'GUILD_CREATE" but currently not tested
This commit is contained in:
parent
014f176dc8
commit
94f1aa5cff
2 changed files with 132 additions and 102 deletions
|
|
@ -64,13 +64,6 @@ class DiscordConnector:
|
|||
self.last_connection = ""
|
||||
self.text = []
|
||||
self.authed = False
|
||||
self.last_text_channel = None
|
||||
|
||||
self.request_text_rooms = None
|
||||
self.request_text_rooms_response = None
|
||||
self.request_text_rooms_awaiting = 0
|
||||
self.last_requested_guild = 0
|
||||
self.needs_guild_rerequest = -1
|
||||
|
||||
self.rate_limited_channels = []
|
||||
self.reconnect_delay = 0
|
||||
|
|
@ -124,6 +117,8 @@ class DiscordConnector:
|
|||
"Joined room: %s", channel_name)
|
||||
else:
|
||||
log.info("Joining private room")
|
||||
if self.current_voice!="0":
|
||||
self.unsub_voice_channel(self.current_voice)
|
||||
self.sub_voice_channel(channel)
|
||||
self.current_voice = channel
|
||||
if need_req:
|
||||
|
|
@ -137,9 +132,7 @@ class DiscordConnector:
|
|||
self.current_text = "0"
|
||||
return
|
||||
if channel != self.current_text:
|
||||
self.current_text = channel
|
||||
log.info(
|
||||
"Changing text room: %s", channel)
|
||||
self.start_listening_text(channel)
|
||||
if need_req:
|
||||
self.req_channel_details(channel)
|
||||
|
||||
|
|
@ -293,8 +286,7 @@ class DiscordConnector:
|
|||
nick = j["data"]["nick"]
|
||||
thisuser["nick"] = nick
|
||||
self.update_user(thisuser)
|
||||
# If someone joins any voice room grab it fresh from server
|
||||
self.req_channel_details(self.current_voice)
|
||||
# We've joined a room... but where?
|
||||
if j["data"]["user"]["id"] == self.user["id"]:
|
||||
self.find_user()
|
||||
elif j["evt"] == "VOICE_STATE_DELETE":
|
||||
|
|
@ -302,7 +294,6 @@ class DiscordConnector:
|
|||
self.set_in_room(j["data"]["user"]["id"], False)
|
||||
if j["data"]["user"]["id"] == self.user["id"]:
|
||||
self.in_room = []
|
||||
# self.sub_all_voice()
|
||||
elif j["evt"] == "SPEAKING_START":
|
||||
self.list_altered = True
|
||||
# It's only possible to get alerts for the room you're in
|
||||
|
|
@ -332,8 +323,11 @@ class DiscordConnector:
|
|||
elif j["evt"] == "MESSAGE_DELETE":
|
||||
if self.current_text == j["data"]["channel_id"]:
|
||||
self.delete_text(j["data"]["message"])
|
||||
elif j["evt"] == "CHANNEL_CREATE":
|
||||
# We haven't been told what guild this is in
|
||||
self.req_channel_details(j["data"]["id"], 'new')
|
||||
else:
|
||||
log.info(j)
|
||||
log.warning(j)
|
||||
return
|
||||
elif j["cmd"] == "AUTHENTICATE":
|
||||
if j["evt"] == "ERROR":
|
||||
|
|
@ -354,6 +348,13 @@ class DiscordConnector:
|
|||
if len(self.voice_settings.guild_ids) == 0 or guild["id"] in self.voice_settings.guild_ids:
|
||||
self.req_channels(guild["id"])
|
||||
return
|
||||
elif j["cmd"] == "GET_GUILD":
|
||||
# We currently only get here because of a "CHANNEL_CREATE" event. Stupidly long winded way around
|
||||
if j["data"]:
|
||||
guild = j["data"]
|
||||
if len(self.voice_settings.guild_ids) == 0 or guild["id"] in self.voice_settings.guild_ids:
|
||||
self.req_channels(guild["id"])
|
||||
return
|
||||
elif j["cmd"] == "GET_CHANNELS":
|
||||
self.guilds[j['nonce']]["channels"] = j["data"]["channels"]
|
||||
for channel in j["data"]["channels"]:
|
||||
|
|
@ -362,47 +363,48 @@ class DiscordConnector:
|
|||
self.channels[channel["id"]] = channel
|
||||
if channel["type"] == 2:
|
||||
self.req_channel_details(channel["id"])
|
||||
if j["nonce"] == self.text_settings.get_guild():
|
||||
self.text_settings.set_channels(j["data"]["channels"])
|
||||
self.check_guilds()
|
||||
return
|
||||
elif j["cmd"] == "SUBSCRIBE":
|
||||
# Only log errors
|
||||
if j['evt']:
|
||||
log.warning(j)
|
||||
return
|
||||
elif j["cmd"] == "UNSUBSCRIBE":
|
||||
return
|
||||
elif j["cmd"] == "GET_SELECTED_VOICE_CHANNEL":
|
||||
if 'data' in j and j['data'] and 'id' in j['data']:
|
||||
self.set_channel(j['data']['id'])
|
||||
self.list_altered = True
|
||||
|
||||
for u in j['data']['voice_states']:
|
||||
thisuser = u["user"]
|
||||
nick = u["nick"]
|
||||
thisuser["nick"] = nick
|
||||
mute = (u["voice_state"]["mute"] or
|
||||
u["voice_state"]["self_mute"] or
|
||||
u["voice_state"]["suppress"])
|
||||
deaf = u["voice_state"]["deaf"] or u["voice_state"]["self_deaf"]
|
||||
thisuser["mute"] = mute
|
||||
thisuser["deaf"] = deaf
|
||||
self.update_user(thisuser)
|
||||
self.set_in_room(thisuser["id"], True)
|
||||
return
|
||||
elif j["cmd"] == "GET_CHANNEL":
|
||||
if j["evt"] == "ERROR":
|
||||
log.info(
|
||||
"Could not get room")
|
||||
return
|
||||
if j["data"]["type"] == 2: # Voice channel
|
||||
for voice in j["data"]["voice_states"]:
|
||||
if voice["user"]["id"] == self.user["id"]:
|
||||
self.set_channel(j["data"]["id"], False)
|
||||
if j["data"]["id"] == self.current_voice:
|
||||
self.list_altered = True
|
||||
self.in_room = []
|
||||
for voice in j["data"]["voice_states"]:
|
||||
thisuser = voice["user"]
|
||||
if "nick" in j["data"]:
|
||||
thisuser["nick"] = j["data"]["nick"]
|
||||
self.update_user(thisuser)
|
||||
self.set_in_room(thisuser["id"], True)
|
||||
elif j["data"]["type"] == 0: # Text channel
|
||||
if self.request_text_rooms_response is not None:
|
||||
count = len(self.request_text_rooms_response)
|
||||
if count < self.request_text_rooms_awaiting:
|
||||
self.request_text_rooms_response.append(j['data'])
|
||||
if count == self.request_text_rooms_awaiting-1: # Last one
|
||||
self.text_settings.set_channels(
|
||||
self.request_text_rooms_response)
|
||||
else:
|
||||
self.request_text_rooms_awaiting = 0
|
||||
self.request_text_rooms_response = None
|
||||
|
||||
if j["data"]["type"] == 0: # Text channel
|
||||
if self.current_text == j["data"]["id"]:
|
||||
self.text = []
|
||||
for message in j["data"]["messages"]:
|
||||
self.add_text(message)
|
||||
|
||||
return
|
||||
log.info(j)
|
||||
return
|
||||
log.warning(j)
|
||||
|
||||
def check_guilds(self):
|
||||
"""
|
||||
|
|
@ -424,8 +426,8 @@ class DiscordConnector:
|
|||
self.voice_overlay.set_enabled(True)
|
||||
if self.text_overlay:
|
||||
self.text_overlay.set_enabled(self.text_settings.enabled)
|
||||
if self.last_text_channel:
|
||||
self.sub_text_channel(self.last_text_channel)
|
||||
if self.current_text:
|
||||
self.start_listening_text(self.current_text)
|
||||
|
||||
def on_error(self, error):
|
||||
"""
|
||||
|
|
@ -437,7 +439,7 @@ class DiscordConnector:
|
|||
"""
|
||||
Called when connection is closed
|
||||
"""
|
||||
log.info("Connection closed")
|
||||
log.warning("Connection closed")
|
||||
self.voice_overlay.hide()
|
||||
if self.text_overlay:
|
||||
self.text_overlay.hide()
|
||||
|
|
@ -457,6 +459,17 @@ class DiscordConnector:
|
|||
}
|
||||
self.websocket.send(json.dumps(cmd))
|
||||
|
||||
def req_guild(self, guild_id,nonce):
|
||||
"""
|
||||
Request info on one guild
|
||||
"""
|
||||
cmd = {
|
||||
"cmd": "GET_GUILD",
|
||||
"args": {"guild_id": guild_id},
|
||||
"nonce": nonce
|
||||
}
|
||||
self.websocket.send(json.dumps(cmd))
|
||||
|
||||
def req_guilds(self):
|
||||
"""
|
||||
Request all guilds information for logged in user
|
||||
|
|
@ -477,20 +490,14 @@ class DiscordConnector:
|
|||
if guild in self.guilds:
|
||||
self.rate_limited_channels.append(guild)
|
||||
else:
|
||||
log.info(f"Didn't find guild with id {guild}")
|
||||
# cmd = {
|
||||
# "cmd": "GET_CHANNELS",
|
||||
# "args": {
|
||||
# "guild_id": guild
|
||||
# },
|
||||
# "nonce": guild
|
||||
# }
|
||||
# self.websocket.send(json.dumps(cmd))
|
||||
log.warning(f"Didn't find guild with id {guild}")
|
||||
|
||||
def req_channel_details(self, channel):
|
||||
"""message
|
||||
Request information about a specific channel
|
||||
"""
|
||||
if not self.websocket:
|
||||
return
|
||||
cmd = {
|
||||
"cmd": "GET_CHANNEL",
|
||||
"args": {
|
||||
|
|
@ -500,31 +507,19 @@ class DiscordConnector:
|
|||
}
|
||||
self.websocket.send(json.dumps(cmd))
|
||||
|
||||
def req_all_channel_details(self, guild):
|
||||
"""
|
||||
Ask for information on all channels in a guild
|
||||
"""
|
||||
for channel in self.guilds[guild]["channels"]:
|
||||
self.req_channel_details(channel["id"])
|
||||
|
||||
def find_user(self):
|
||||
"""
|
||||
***Potential overload issue***
|
||||
|
||||
Asks the server for information about every single voice channel (type==2)
|
||||
in the hope that one of them will say the user is present
|
||||
|
||||
because if asks about every single one without waiting for reply it is heavy even
|
||||
if the user is relatively simple to find
|
||||
|
||||
It might be worth limiting the usage of this
|
||||
Find the user
|
||||
"""
|
||||
count = 0
|
||||
for channel in self.channels:
|
||||
if self.channels[channel]["type"] == 2:
|
||||
self.req_channel_details(channel)
|
||||
count += 1
|
||||
log.warning("Getting %s rooms", count)
|
||||
|
||||
cmd = {
|
||||
"cmd": "GET_SELECTED_VOICE_CHANNEL",
|
||||
"args": {
|
||||
|
||||
},
|
||||
"nonce": "test"
|
||||
}
|
||||
self.websocket.send(json.dumps(cmd))
|
||||
|
||||
def sub_raw(self, event, args, nonce):
|
||||
"""
|
||||
|
|
@ -538,6 +533,18 @@ class DiscordConnector:
|
|||
}
|
||||
self.websocket.send(json.dumps(cmd))
|
||||
|
||||
def unsub_raw(self, event, args, nonce):
|
||||
"""
|
||||
Subscribe to event helper function
|
||||
"""
|
||||
cmd = {
|
||||
"cmd": "UNSUBSCRIBE",
|
||||
"args": args,
|
||||
"evt": event,
|
||||
"nonce": nonce
|
||||
}
|
||||
self.websocket.send(json.dumps(cmd))
|
||||
|
||||
def sub_server(self):
|
||||
"""
|
||||
Subscribe to helpful events that report connectivity issues &
|
||||
|
|
@ -548,6 +555,8 @@ class DiscordConnector:
|
|||
"""
|
||||
self.sub_raw("VOICE_CHANNEL_SELECT", {}, "VOICE_CHANNEL_SELECT")
|
||||
self.sub_raw("VOICE_CONNECTION_STATUS", {}, "VOICE_CONNECTION_STATUS")
|
||||
self.sub_raw("GUILD_CREATE", {}, "GUILD_CREATE")
|
||||
self.sub_raw("CHANNEL_CREATE", {}, "CHANNEL_CREATE")
|
||||
|
||||
def sub_channel(self, event, channel):
|
||||
"""
|
||||
|
|
@ -555,6 +564,12 @@ class DiscordConnector:
|
|||
"""
|
||||
self.sub_raw(event, {"channel_id": channel}, channel)
|
||||
|
||||
def unsub_channel(self, event, channel):
|
||||
"""
|
||||
Subscribe to event on channel
|
||||
"""
|
||||
self.unsub_raw(event, {"channel_id": channel}, channel)
|
||||
|
||||
def sub_text_channel(self, channel):
|
||||
"""
|
||||
Subscribe to text-based events.
|
||||
|
|
@ -563,6 +578,14 @@ class DiscordConnector:
|
|||
self.sub_channel("MESSAGE_UPDATE", channel)
|
||||
self.sub_channel("MESSAGE_DELETE", channel)
|
||||
|
||||
def unsub_text_channel(self, channel):
|
||||
"""
|
||||
Unsubscribe to text-based events.
|
||||
"""
|
||||
self.unsub_channel("MESSAGE_CREATE", channel)
|
||||
self.unsub_channel("MESSAGE_UPDATE", channel)
|
||||
self.unsub_channel("MESSAGE_DELETE", channel)
|
||||
|
||||
def sub_voice_channel(self, channel):
|
||||
"""
|
||||
Subscribe to voice-based events
|
||||
|
|
@ -573,6 +596,17 @@ class DiscordConnector:
|
|||
self.sub_channel("SPEAKING_START", channel)
|
||||
self.sub_channel("SPEAKING_STOP", channel)
|
||||
|
||||
def unsub_voice_channel(self, channel):
|
||||
"""
|
||||
Remove subscription to voice-based events
|
||||
"""
|
||||
self.unsub_channel("VOICE_STATE_CREATE", channel)
|
||||
self.unsub_channel("VOICE_STATE_UPDATE", channel)
|
||||
self.unsub_channel("VOICE_STATE_DELETE", channel)
|
||||
self.unsub_channel("SPEAKING_START", channel)
|
||||
self.unsub_channel("SPEAKING_STOP", channel)
|
||||
|
||||
|
||||
def do_read(self):
|
||||
"""
|
||||
Poorly named logic center.
|
||||
|
|
@ -592,7 +626,7 @@ class DiscordConnector:
|
|||
# No timeout left, connect to discord again
|
||||
self.connect()
|
||||
if self.warn_connection:
|
||||
log.info(
|
||||
log.warning(
|
||||
"Unable to connect to Discord client")
|
||||
self.warn_connection = False
|
||||
return True
|
||||
|
|
@ -600,11 +634,6 @@ class DiscordConnector:
|
|||
# Timeout requested, wait it out
|
||||
self.reconnect_delay -= 1
|
||||
return True
|
||||
if self.needs_guild_rerequest == 0:
|
||||
log.error("Re-requesting guild list")
|
||||
self.request_text_rooms_for_guild(self.last_requested_guild)
|
||||
if self.needs_guild_rerequest >= 0:
|
||||
self.needs_guild_rerequest -= 1
|
||||
# Recreate a list of users in current room
|
||||
newlist = []
|
||||
for userid in self.in_room:
|
||||
|
|
@ -658,9 +687,12 @@ class DiscordConnector:
|
|||
Helper function to avoid race conditions of reading config vs connecting to websocket
|
||||
"""
|
||||
if self.websocket:
|
||||
self.sub_text_channel(channel)
|
||||
else:
|
||||
self.last_text_channel = channel
|
||||
if self.current_text != "0":
|
||||
self.unsub_text_channel(self.current_text)
|
||||
if channel != "0":
|
||||
self.sub_text_channel(channel)
|
||||
self.req_channel_details(channel)
|
||||
self.current_text = channel
|
||||
|
||||
def request_text_rooms_for_guild(self, guild_id):
|
||||
"""
|
||||
|
|
@ -670,23 +702,8 @@ class DiscordConnector:
|
|||
"""
|
||||
if(guild_id == 0):
|
||||
return
|
||||
self.last_requested_guild = guild_id
|
||||
if guild_id in self.guilds:
|
||||
guild = self.guilds[guild_id]
|
||||
if "channels" in guild:
|
||||
self.request_text_rooms = guild_id
|
||||
self.request_text_rooms_response = []
|
||||
self.request_text_rooms_awaiting = 0
|
||||
for channel in guild["channels"]:
|
||||
if channel["type"] == 0:
|
||||
self.request_text_rooms_awaiting += 1
|
||||
self.req_all_channel_details(guild_id)
|
||||
else:
|
||||
log.warning(
|
||||
f"Trying to request channel details for guild without "
|
||||
f"cached channels. Retrying in 1 second"
|
||||
)
|
||||
self.needs_guild_rerequest = 60
|
||||
self.req_guild(guild_id, "refresh")
|
||||
|
||||
def connect(self):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ class TextSettingsWindow(SettingsWindow):
|
|||
"""
|
||||
self.connector = conn
|
||||
if self.channel:
|
||||
self.connector.start_listening_text(self.channel)
|
||||
self.connector.set_text_channel(self.channel)
|
||||
|
||||
def present_settings(self):
|
||||
"""
|
||||
|
|
@ -479,7 +479,7 @@ class TextSettingsWindow(SettingsWindow):
|
|||
return
|
||||
|
||||
channel = self.channel_lookup[button.get_active()]
|
||||
self.connector.start_listening_text(channel)
|
||||
self.connector.set_text_channel(channel)
|
||||
self.channel = channel
|
||||
self.save_config()
|
||||
|
||||
|
|
@ -536,6 +536,19 @@ class TextSettingsWindow(SettingsWindow):
|
|||
"""
|
||||
return self.channel
|
||||
|
||||
def set_channel(self, channel="0"):
|
||||
"""
|
||||
Change the stored channel
|
||||
"""
|
||||
self.channel = channel
|
||||
self.save_config()
|
||||
|
||||
def get_guild(self):
|
||||
"""
|
||||
Return selected guild
|
||||
"""
|
||||
return self.guild
|
||||
|
||||
def change_bg(self, button):
|
||||
"""
|
||||
Background colour changed
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue