Skip to content

Commit

Permalink
Original work at Pycord-Development#2321
Browse files Browse the repository at this point in the history
Co-authored-by: Dasupergrasskakjd <[email protected]>
Co-authored-by: Dorukyum <[email protected]>
  • Loading branch information
2 people authored and Paillat-dev committed Oct 30, 2024
1 parent 05cf45e commit fefff2b
Show file tree
Hide file tree
Showing 14 changed files with 631 additions and 7 deletions.
1 change: 1 addition & 0 deletions discord/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
from .role import *
from .scheduled_events import *
from .shard import *
from .soundboard import *
from .stage_instance import *
from .sticker import *
from .team import *
Expand Down
8 changes: 8 additions & 0 deletions discord/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,14 @@ def _from_scheduled_event_image(
animated=False,
)

@classmethod
def _from_soundboard_sound(cls, state, sound_id: int) -> Asset:
return cls(
state,
url=f"{cls.BASE}/soundboard-sounds/{sound_id}",
key=str(sound_id),
)

def __str__(self) -> str:
return self._url

Expand Down
89 changes: 88 additions & 1 deletion discord/channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,16 @@
from __future__ import annotations

import datetime
from typing import TYPE_CHECKING, Any, Callable, Iterable, Mapping, TypeVar, overload
from typing import (
TYPE_CHECKING,
Any,
Callable,
Iterable,
Mapping,
NamedTuple,
TypeVar,
overload,
)

import discord.abc

Expand All @@ -40,6 +49,7 @@
SortOrder,
StagePrivacyLevel,
VideoQualityMode,
VoiceChannelEffectAnimationType,
VoiceRegion,
try_enum,
)
Expand All @@ -52,6 +62,7 @@
from .object import Object
from .partial_emoji import PartialEmoji, _EmojiTag
from .permissions import PermissionOverwrite, Permissions
from .soundboard import PartialSoundboardSound, SoundboardSound
from .stage_instance import StageInstance
from .threads import Thread
from .utils import MISSING
Expand All @@ -66,6 +77,8 @@
"PartialMessageable",
"ForumChannel",
"ForumTag",
# "VoiceChannelEffect",
"VoiceChannelEffectSendEvent",
)

if TYPE_CHECKING:
Expand All @@ -84,6 +97,7 @@
from .types.channel import StageChannel as StageChannelPayload
from .types.channel import TextChannel as TextChannelPayload
from .types.channel import VoiceChannel as VoiceChannelPayload
from .types.channel import VoiceChannelEffectSendEvent as VoiceChannelEffectSend
from .types.snowflake import SnowflakeList
from .types.threads import ThreadArchiveDuration
from .user import BaseUser, ClientUser, User
Expand Down Expand Up @@ -3220,6 +3234,79 @@ def get_partial_message(self, message_id: int, /) -> PartialMessage:
return PartialMessage(channel=self, id=message_id)


class VoiceChannelEffectAnimation(NamedTuple):
id: int
type: VoiceChannelEffectAnimationType


class VoiceChannelSoundEffect(PartialSoundboardSound): ...


class VoiceChannelEffectSendEvent:
"""Represents the payload for an :func:`on_voice_channel_effect_send`
.. versionadded:: 2.4
Attributes
----------
animation_type: :class:`int`
The type of animation that is being sent.
animation_id: :class:`int`
The ID of the animation that is being sent.
sound: Optional[:class:`SoundboardSound`]
The sound that is being sent, might be None if the effect is not a sound effect.
guild: :class:`Guild`
The guild that the sound is being sent in.
user: :class:`Member`
The member that is sending the sound.
channel: :class:`VoiceChannel`
The voice channel that the sound is being sent in.
data: :class:`dict`
The raw data sent by the gateway([#6025](https://github.com/discord/discord-api-docs/pull/6025)).
"""

__slots__ = (
"_state",
"animation_type",
"animation_id",
"sound",
"guild",
"user",
"channel",
"data",
"emoji",
)

def __init__(
self,
data: VoiceChannelEffectSend,
state: ConnectionState,
sound: SoundboardSound | PartialSoundboardSound | None = None,
) -> None:
self._state = state
channel_id = int(data["channel_id"])
user_id = int(data["user_id"])
guild_id = int(data["guild_id"])
self.animation_type: VoiceChannelEffectAnimationType = try_enum(
VoiceChannelEffectAnimationType, data["animation_type"]
)
self.animation_id = int(data["animation_id"])
self.sound = sound
self.guild = state._get_guild(guild_id)
self.user = self.guild.get_member(user_id)
self.channel = self.guild.get_channel(channel_id)
self.emoji = (
PartialEmoji(
name=data["emoji"]["name"],
animated=data["emoji"]["animated"],
id=data["emoji"]["id"],
)
if data.get("emoji", None)
else None
)
self.data = data


def _guild_channel_factory(channel_type: int):
value = try_enum(ChannelType, channel_type)
if value is ChannelType.text:
Expand Down
42 changes: 42 additions & 0 deletions discord/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
from .mentions import AllowedMentions
from .monetization import SKU, Entitlement
from .object import Object
from .soundboard import DefaultSoundboardSound
from .stage_instance import StageInstance
from .state import ConnectionState
from .sticker import GuildSticker, StandardSticker, StickerPack, _sticker_factory
Expand All @@ -71,6 +72,7 @@
from .member import Member
from .message import Message
from .poll import Poll
from .soundboard import SoundboardSound
from .voice_client import VoiceProtocol

__all__ = ("Client",)
Expand Down Expand Up @@ -2269,3 +2271,43 @@ async def delete_emoji(self, emoji: Snowflake) -> None:
)
if self._connection.cache_app_emojis and self._connection.get_emoji(emoji.id):
self._connection.remove_emoji(emoji)

def get_sound(self, sound_id: int) -> SoundboardSound | None:
"""Gets a :class:`.Sound` from the bot's sound cache.
.. versionadded:: 2.4
Parameters
----------
sound_id: :class:`int`
The ID of the sound to get.
Returns
-------
:class:`.Sound`
The sound from the ID.
"""
return self._connection._get_sound(sound_id)

@property
def sounds(self) -> list[SoundboardSound]:
"""A list of all the sounds the bot can see.
.. versionadded:: 2.4
"""
return self._connection.sounds

async def fetch_default_sounds(self) -> list[SoundboardSound]:
"""|coro|
Fetches the bot's default sounds.
.. versionadded:: 2.4
Returns
-------
List[:class:`.Sound`]
The bot's default sounds.
"""
data = await self._connection.http.get_default_sounds()
return [DefaultSoundboardSound(self.http, s) for s in data]
8 changes: 8 additions & 0 deletions discord/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
"PromptType",
"OnboardingMode",
"ReactionType",
"VoiceChannelEffectAnimationType",
"SKUType",
"EntitlementType",
"EntitlementOwnerType",
Expand Down Expand Up @@ -1053,6 +1054,13 @@ class PollLayoutType(Enum):
default = 1


class VoiceChannelEffectAnimationType(Enum):
"""Voice channel effect animation type"""

premium = 0
basic = 1


T = TypeVar("T")


Expand Down
10 changes: 10 additions & 0 deletions discord/gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ class DiscordWebSocket:
HELLO = 10
HEARTBEAT_ACK = 11
GUILD_SYNC = 12
REQUEST_SOUNDBOARD_SOUNDS = 31

def __init__(self, socket, *, loop):
self.socket = socket
Expand Down Expand Up @@ -722,6 +723,15 @@ async def voice_state(self, guild_id, channel_id, self_mute=False, self_deaf=Fal
_log.debug("Updating our voice state to %s.", payload)
await self.send_as_json(payload)

async def request_soundboard_sounds(self, guild_ids):
payload = {
"op": self.REQUEST_SOUNDBOARD_SOUNDS,
"d": {"guild_ids": guild_ids},
}

_log.debug("Requesting soundboard sounds for guilds %s.", guild_ids)
await self.send_as_json(payload)

async def close(self, code=4000):
if self._keep_alive:
self._keep_alive.stop()
Expand Down
Loading

0 comments on commit fefff2b

Please sign in to comment.