fix(core): Improve client ready state and user parsing
The `_ready_event` is now set in `GatewayClient` immediately after receiving the `READY` payload, before dispatching `on_ready` to user code. This ensures `Client.wait_until_ready()` and `Client.is_ready()` accurately reflect the client's state before dependent user logic executes. This change allows simplifying `Client.sync_commands` by removing redundant `wait_until_ready()` calls and `application_id` checks, as the application ID is guaranteed to be available upon READY. Additionally, `User` model initialization is improved to correctly handle nested user data found in certain API payloads (e.g., within `member` objects in events like `PresenceUpdate`). Add `SOUNDBOARD` and `VIDEO_QUALITY_720_60FPS` to `GuildFeature` enum.
This commit is contained in:
parent
bd16b1c026
commit
a41a301927
@ -12,7 +12,7 @@ __title__ = "disagreement"
|
|||||||
__author__ = "Slipstream"
|
__author__ = "Slipstream"
|
||||||
__license__ = "BSD 3-Clause License"
|
__license__ = "BSD 3-Clause License"
|
||||||
__copyright__ = "Copyright 2025 Slipstream"
|
__copyright__ = "Copyright 2025 Slipstream"
|
||||||
__version__ = "0.8.0"
|
__version__ = "0.8.1"
|
||||||
|
|
||||||
from .client import Client, AutoShardedClient
|
from .client import Client, AutoShardedClient
|
||||||
from .models import (
|
from .models import (
|
||||||
|
@ -1665,16 +1665,6 @@ class Client:
|
|||||||
"Ensure the client is connected and READY."
|
"Ensure the client is connected and READY."
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
if not self.is_ready():
|
|
||||||
print(
|
|
||||||
"Warning: Client is not ready. Waiting for client to be ready before syncing commands."
|
|
||||||
)
|
|
||||||
await self.wait_until_ready()
|
|
||||||
if not self.application_id:
|
|
||||||
print(
|
|
||||||
"Error: application_id still not set after client is ready. Cannot sync commands."
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
await self.app_command_handler.sync_commands(
|
await self.app_command_handler.sync_commands(
|
||||||
application_id=self.application_id, guild_id=guild_id
|
application_id=self.application_id, guild_id=guild_id
|
||||||
|
@ -268,6 +268,8 @@ class GuildFeature(str, Enum): # Changed from IntEnum to Enum
|
|||||||
VERIFIED = "VERIFIED"
|
VERIFIED = "VERIFIED"
|
||||||
VIP_REGIONS = "VIP_REGIONS"
|
VIP_REGIONS = "VIP_REGIONS"
|
||||||
WELCOME_SCREEN_ENABLED = "WELCOME_SCREEN_ENABLED"
|
WELCOME_SCREEN_ENABLED = "WELCOME_SCREEN_ENABLED"
|
||||||
|
SOUNDBOARD = "SOUNDBOARD"
|
||||||
|
VIDEO_QUALITY_720_60FPS = "VIDEO_QUALITY_720_60FPS"
|
||||||
# Add more as they become known or needed
|
# Add more as they become known or needed
|
||||||
|
|
||||||
# This allows GuildFeature("UNKNOWN_FEATURE_STRING") to work
|
# This allows GuildFeature("UNKNOWN_FEATURE_STRING") to work
|
||||||
|
@ -334,6 +334,10 @@ class GatewayClient:
|
|||||||
self._resume_gateway_url,
|
self._resume_gateway_url,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# The client is now ready for operations. Set the event before dispatching to user code.
|
||||||
|
self._client_instance._ready_event.set()
|
||||||
|
logger.info("Client is now marked as ready.")
|
||||||
|
|
||||||
await self._dispatcher.dispatch(event_name, raw_event_d_payload)
|
await self._dispatcher.dispatch(event_name, raw_event_d_payload)
|
||||||
elif event_name == "GUILD_MEMBERS_CHUNK":
|
elif event_name == "GUILD_MEMBERS_CHUNK":
|
||||||
if isinstance(raw_event_d_payload, dict):
|
if isinstance(raw_event_d_payload, dict):
|
||||||
|
@ -51,6 +51,8 @@ class User:
|
|||||||
|
|
||||||
def __init__(self, data: dict, client_instance: Optional["Client"] = None) -> None:
|
def __init__(self, data: dict, client_instance: Optional["Client"] = None) -> None:
|
||||||
self._client = client_instance
|
self._client = client_instance
|
||||||
|
if "id" not in data and "user" in data:
|
||||||
|
data = data["user"]
|
||||||
self.id: str = data["id"]
|
self.id: str = data["id"]
|
||||||
self.username: Optional[str] = data.get("username")
|
self.username: Optional[str] = data.get("username")
|
||||||
self.discriminator: Optional[str] = data.get("discriminator")
|
self.discriminator: Optional[str] = data.get("discriminator")
|
||||||
@ -752,12 +754,10 @@ class Member(User): # Member inherits from User
|
|||||||
) # Pass user_data or data if user_data is empty
|
) # Pass user_data or data if user_data is empty
|
||||||
|
|
||||||
self.nick: Optional[str] = data.get("nick")
|
self.nick: Optional[str] = data.get("nick")
|
||||||
self.avatar: Optional[str] = data.get("avatar") # Guild-specific avatar hash
|
self.avatar: Optional[str] = data.get("avatar")
|
||||||
self.roles: List[str] = data.get("roles", []) # List of role IDs
|
self.roles: List[str] = data.get("roles", [])
|
||||||
self.joined_at: str = data["joined_at"] # ISO8601 timestamp
|
self.joined_at: str = data["joined_at"]
|
||||||
self.premium_since: Optional[str] = data.get(
|
self.premium_since: Optional[str] = data.get("premium_since")
|
||||||
"premium_since"
|
|
||||||
) # ISO8601 timestamp
|
|
||||||
self.deaf: bool = data.get("deaf", False)
|
self.deaf: bool = data.get("deaf", False)
|
||||||
self.mute: bool = data.get("mute", False)
|
self.mute: bool = data.get("mute", False)
|
||||||
self.pending: bool = data.get("pending", False)
|
self.pending: bool = data.get("pending", False)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "disagreement"
|
name = "disagreement"
|
||||||
version = "0.8.0"
|
version = "0.8.1"
|
||||||
description = "A Python library for the Discord API."
|
description = "A Python library for the Discord API."
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.10"
|
requires-python = ">=3.10"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user