Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 29 additions & 12 deletions interactions/api/gateway/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from sys import platform, version_info
from time import perf_counter
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Type, Union
from zlib import decompressobj

from aiohttp import ClientWebSocketResponse, WSMessage, WSMsgType

Expand Down Expand Up @@ -98,6 +99,7 @@ class WebSocketClient:
"__heartbeater",
"__shard",
"__presence",
"_zlib",
"_task",
"__heartbeat_event",
"__started",
Expand Down Expand Up @@ -148,7 +150,7 @@ def __init__(

self.__closed: Event = Event(loop=self._loop) if version_info < (3, 10) else Event()
self._options: dict = {
"max_msg_size": 1024**2,
"max_msg_size": 0,
"timeout": 60,
"autoclose": False,
"compress": 0,
Expand Down Expand Up @@ -180,6 +182,8 @@ def __init__(

self.__stopping: Optional[Task] = None

self._zlib = decompressobj()

@property
def latency(self) -> float:
"""
Expand Down Expand Up @@ -827,6 +831,8 @@ async def _reconnect(self, to_resume: bool, code: Optional[int] = 1012) -> None:

self._client = None

self._zlib = decompressobj()

# We need to check about existing heartbeater tasks for edge cases.

if self._task:
Expand Down Expand Up @@ -863,6 +869,8 @@ async def __receive_packet(self, ignore_lock: bool = False) -> Optional[Dict[str
:rtype: Optional[Dict[str, Any]]
"""

buffer = bytearray()

while True:

if not ignore_lock:
Expand All @@ -874,12 +882,9 @@ async def __receive_packet(self, ignore_lock: bool = False) -> Optional[Dict[str
if packet.type == WSMsgType.CLOSE:
log.debug(f"Disconnecting from gateway = {packet.data}::{packet.extra}")

if packet.data >= 4000: # suppress 4001 because of weird presence errors
if packet.data >= 4000:
# This means that the error code is 4000+, which may signify Discord-provided error codes.

# However, we suppress 4001 because of weird presence errors with change_presence
# The payload is correct, and the presence object persists. /shrug

raise LibraryException(packet.data)

if ignore_lock:
Expand Down Expand Up @@ -919,8 +924,20 @@ async def __receive_packet(self, ignore_lock: bool = False) -> Optional[Dict[str
if packet.data is None:
continue # We just loop it over because it could just be processing something.

if isinstance(packet.data, bytes):
buffer.extend(packet.data)

if len(packet.data) < 4 or packet.data[-4:] != b"\x00\x00\xff\xff":
# buffer isn't done we need to wait
continue

msg = self._zlib.decompress(buffer)
msg = msg.decode("utf-8")
else:
msg = packet.data

try:
msg = loads(packet.data)
_msg = loads(msg)
except Exception as e:
import traceback

Expand All @@ -929,9 +946,9 @@ async def __receive_packet(self, ignore_lock: bool = False) -> Optional[Dict[str
)
# There's an edge case when the packet's None... or some other deserialisation error.
# Instead of raising an exception, we just log it to debug, so it doesn't annoy end user's console logs.
msg = None
_msg = None

return msg
return _msg

async def _send_packet(self, data: Dict[str, Any]) -> None:
"""
Expand Down Expand Up @@ -972,10 +989,11 @@ async def __identify(
"token": self._http.token,
"intents": self._intents.value,
"properties": {
"$os": platform,
"$browser": "interactions.py",
"$device": "interactions.py",
"os": platform,
"browser": "interactions.py",
"device": "interactions.py",
},
"compress": True,
},
}

Expand Down Expand Up @@ -1037,5 +1055,4 @@ async def close(self) -> None:
"""
if self._client:
await self._client.close()

self.__closed.set()