This commit refactors a lot of voice's internals to be more stable and
handle more edge cases from Discord's voice servers. It should result in
an overall more stable voice connection.
A few helper functions have been added into voice.Session. Some fields
will have been broken and changed to accomodate for the refactor, as
well.
Below are some commits that have been squashed in:
voice: Fix Speaking() panic on closed
voice: StopSpeaking should not error out
The rationale is added as a comment into the Speaking() method.
voice: Add TestKickedOut
voice: Fix region change disconnecting
This commit refactors the whole package gateway as well as utils/ws
(formerly utils/wsutil) and voice/voicegateway. The new refactor
utilizes a design pattern involving a concurrent loop and an arriving
event channel.
An additional change was made to the way gateway events are typed.
Before, pretty much any type will satisfy a gateway event type, since
the actual type was just interface{}. The new refactor defines a
concrete interface that events can implement:
type Event interface {
Op() OpCode
EventType() EventType
}
Using this interface, the user can easily add custom gateway events
independently of the library without relying on string maps. This adds a
lot of type safety into the library and makes type-switching on Event
types much more reasonable.
Gateway error callbacks are also almost entirely removed in favor of
custom gateway events. A catch-all can easily be added like this:
s.AddHandler(func(err error) {
log.Println("gateway error:, err")
})
This commit refactors a lot of packages.
It refactors the handler package, removing the Synchronous field and
replacing it the AddSyncHandler API, which allows each handler to
control whether or not it should be ran synchronously independent of
other handlers. This is useful for libraries that need to guarantee the
incoming order of events.
It also refactors the store interfaces to accept more interfaces. This
is to make the API more consistent as well as reducing potential useless
copies. The public-facing state API should still be the same, so this
change will mostly concern users with their own store implementations.
Several miscellaneous functions (such as a few in package gateway) were
modified to be more suitable to other packages, but those functions
should rarely ever be used, anyway.
Several tests are also fixed within this commit, namely fixing state's
intents bug.
This commit consists of these smaller commits:
Gateway: SessionID to be a method for thread safety
This commit breaks the SessionID field of the Gateway struct to
be thread-safe by wrapping its access with a read-write mutex.
As this is a bug fix, it is reasonable of a breaking change
Heart: Allow later binding of event channel
Voice: Use the new Heart API
Heart: Fixed data races
Heart: Allow changing pace, thread-safe Heartbeat
This commit gets rid of all the code that previously managed different
voice sessions in different guilds. This is because there is rarely ever
a need for this, and most bots that need this could do their own
keeping.
This change, although removes some features off of the package, adds a
lot of clarity on what to do exactly when it comes to connecting to a
voice channel.
In order to make the migration process a bit easier, an example has been
added which guides through using the voice.Session API.
* Resolve issue with copied v1 struct
* Speaking event patches, support Client Connect/Disconnect events
* Remove extra debug in heart.go
* Initial voice packet reading
* Resolve unallocated slices, use a static slice/array for decryption, split version/type
* Use separate slice for recvOpus, check return of secretbox.Open, and use constant for header size
* Update missing reference to packetHeaderSize
* Resolve decryption issues, add ReadPacket to session
* Update documentation for recvBuf/recvOpus
* Update comment for recvPacket's array
This comimt adds a method into the UDP connection to control the
internal frequency ticker which controls the speed of playback. For more
information, refer to (*voice/udp.Connection).ResetFrequency().
StopSpeaking is removed because it no longer works with variable
parameters. The functionality of that method was also arguably useless,
as it only sends silent frames.
This commit adds multiple thread safe guards to do better the
concurrency promises. However, it also omits completely those guarantees
in certain places that don't make sense to call concurrently. This is
mostly documented.
This commit also adds a small piece of code to concurrently run things
with the race detector.
This commit omits thread safe guarantees in the UDP voice connection.
This is done because the UDP connection should not be shared across
threads, so those guarantees are now omitted for performance.
Session will still guard a UDP connection around a read mutex, because
Session itself has thread safe guarantees. This may change in the
future.
This commit refactors both wsutil, the normal Gateway and the Voice
Gateway to have better closing behavior, which should assume less and
cover edge cases completely.
This commit fixes race conditions in both package voice, package
voicegateway and package gateway.
Originally, several race conditions exist when both the user's and the
pacemaker's goroutines both want to do several things to the websocket
connection. For example, the user's goroutine could be writing, and the
pacemaker's goroutine could trigger a reconnection. This is racey.
This issue is partially fixed by removing the pacer loop from package
heart and combining the ticker into the event (pacemaker) loop itself.
Technically, a race condition could still be triggered with care, but
the API itself never guaranteed any of those. As events are handled
using an internal loop into a channel, a race condition will not be
triggered just by handling events and writing to the websocket.