Files
songbird/src/events/context/mod.rs
Kyle Simpson c464fcc38d Events: Deprecate ClientConnect (#112)
Discord no longer send these websocket payloads, users should instead rely on the main part of their bot for determining actual connection events, or `SpeakingUpdate`s for SSRC mapping.

Closes #104.
2022-02-13 12:06:50 +00:00

171 lines
7.0 KiB
Rust

pub mod data;
pub(crate) mod internal_data;
use super::*;
use crate::{
model::payload::{ClientConnect, ClientDisconnect, Speaking},
tracks::{TrackHandle, TrackState},
};
pub use data as context_data;
use data::*;
use internal_data::*;
/// Information about which tracks or data fired an event.
///
/// [`Track`] events may be local or global, and have no tracks
/// if fired on the global context via [`Driver::add_global_event`].
///
/// [`Track`]: crate::tracks::Track
/// [`Driver::add_global_event`]: crate::driver::Driver::add_global_event
#[derive(Debug)]
#[non_exhaustive]
pub enum EventContext<'a> {
/// Track event context, passed to events created via [`TrackHandle::add_event`],
/// [`EventStore::add_event`], or relevant global events.
///
/// [`EventStore::add_event`]: EventStore::add_event
/// [`TrackHandle::add_event`]: TrackHandle::add_event
Track(&'a [(&'a TrackState, &'a TrackHandle)]),
/// Speaking state update, typically describing how another voice
/// user is transmitting audio data. Clients must send at least one such
/// packet to allow SSRC/UserID matching.
SpeakingStateUpdate(Speaking),
/// Speaking state transition, describing whether a given source has started/stopped
/// transmitting. This fires in response to a silent burst, or the first packet
/// breaking such a burst.
SpeakingUpdate(SpeakingUpdateData),
/// Opus audio packet, received from another stream.
VoicePacket(VoiceData<'a>),
/// Telemetry/statistics packet, received from another stream.
RtcpPacket(RtcpData<'a>),
#[deprecated(
since = "0.2.2",
note = "ClientConnect events are no longer sent by Discord. Please use SpeakingUpdate or Discord gateway events."
)]
/// Formerly fired whenever a client connects to a call for the first time, allowing SSRC/UserID
/// matching. This event no longer fires.
///
/// To detect when a user connects, you must correlate gateway (e.g., VoiceStateUpdate) events
/// from the main part of your bot.
///
/// To obtain a user's SSRC, you must use [`SpeakingUpdate`] events.
///
/// [`SpeakingUpdate`]: Self::SpeakingUpdate
ClientConnect(ClientConnect),
/// Fired whenever a client disconnects.
ClientDisconnect(ClientDisconnect),
/// Fires when this driver successfully connects to a voice channel.
DriverConnect(ConnectData<'a>),
/// Fires when this driver successfully reconnects after a network error.
DriverReconnect(ConnectData<'a>),
#[deprecated(
since = "0.2.0",
note = "Please use the DriverDisconnect event instead."
)]
/// Fires when this driver fails to connect to a voice channel.
///
/// Users will need to manually reconnect on receipt of this error.
/// **This event is deprecated in favour of [`DriverDisconnect`].**
///
/// [`DriverDisconnect`]: Self::DriverDisconnect
// TODO: remove in 0.3.x
DriverConnectFailed,
#[deprecated(
since = "0.2.0",
note = "Please use the DriverDisconnect event instead."
)]
/// Fires when this driver fails to reconnect to a voice channel after a network error.
///
/// Users will need to manually reconnect on receipt of this error.
/// **This event is deprecated in favour of [`DriverDisconnect`].**
///
/// [`DriverDisconnect`]: Self::DriverDisconnect
// TODO: remove in 0.3.x
DriverReconnectFailed,
/// Fires when this driver fails to connect to, or drops from, a voice channel.
DriverDisconnect(DisconnectData<'a>),
#[deprecated(
since = "0.2.0",
note = "Please use the DriverConnect/Reconnect events instead."
)]
/// Fires whenever the driver is assigned a new [RTP SSRC] by the voice server.
///
/// This typically fires alongside a [DriverConnect], or a full [DriverReconnect].
/// **This event is *deprecated* in favour of these alternatives**.
///
/// [RTP SSRC]: https://tools.ietf.org/html/rfc3550#section-3
/// [DriverConnect]: Self::DriverConnect
/// [DriverReconnect]: Self::DriverReconnect
// TODO: remove in 0.3.x
SsrcKnown(u32),
}
#[derive(Debug)]
pub enum CoreContext {
SpeakingStateUpdate(Speaking),
SpeakingUpdate(InternalSpeakingUpdate),
VoicePacket(InternalVoicePacket),
RtcpPacket(InternalRtcpPacket),
ClientConnect(ClientConnect),
ClientDisconnect(ClientDisconnect),
DriverConnect(InternalConnect),
DriverReconnect(InternalConnect),
DriverDisconnect(InternalDisconnect),
DriverConnectFailed,
DriverReconnectFailed,
SsrcKnown(u32),
}
impl<'a> CoreContext {
pub(crate) fn to_user_context(&'a self) -> EventContext<'a> {
use CoreContext::*;
match self {
SpeakingStateUpdate(evt) => EventContext::SpeakingStateUpdate(*evt),
SpeakingUpdate(evt) => EventContext::SpeakingUpdate(SpeakingUpdateData::from(evt)),
VoicePacket(evt) => EventContext::VoicePacket(VoiceData::from(evt)),
RtcpPacket(evt) => EventContext::RtcpPacket(RtcpData::from(evt)),
#[allow(deprecated)]
ClientConnect(evt) => EventContext::ClientConnect(*evt),
ClientDisconnect(evt) => EventContext::ClientDisconnect(*evt),
DriverConnect(evt) => EventContext::DriverConnect(ConnectData::from(evt)),
DriverReconnect(evt) => EventContext::DriverReconnect(ConnectData::from(evt)),
DriverDisconnect(evt) => EventContext::DriverDisconnect(DisconnectData::from(evt)),
#[allow(deprecated)]
DriverConnectFailed => EventContext::DriverConnectFailed,
#[allow(deprecated)]
DriverReconnectFailed => EventContext::DriverReconnectFailed,
#[allow(deprecated)]
SsrcKnown(s) => EventContext::SsrcKnown(*s),
}
}
}
impl EventContext<'_> {
/// Retreive the event class for an event (i.e., when matching)
/// an event against the registered listeners.
pub fn to_core_event(&self) -> Option<CoreEvent> {
use EventContext::*;
match self {
SpeakingStateUpdate(_) => Some(CoreEvent::SpeakingStateUpdate),
SpeakingUpdate(_) => Some(CoreEvent::SpeakingUpdate),
VoicePacket(_) => Some(CoreEvent::VoicePacket),
RtcpPacket(_) => Some(CoreEvent::RtcpPacket),
#[allow(deprecated)]
ClientConnect(_) => Some(CoreEvent::ClientConnect),
ClientDisconnect(_) => Some(CoreEvent::ClientDisconnect),
DriverConnect(_) => Some(CoreEvent::DriverConnect),
DriverReconnect(_) => Some(CoreEvent::DriverReconnect),
DriverDisconnect(_) => Some(CoreEvent::DriverDisconnect),
#[allow(deprecated)]
DriverConnectFailed => Some(CoreEvent::DriverConnectFailed),
#[allow(deprecated)]
DriverReconnectFailed => Some(CoreEvent::DriverReconnectFailed),
#[allow(deprecated)]
SsrcKnown(_) => Some(CoreEvent::SsrcKnown),
_ => None,
}
}
}