1
0
Fork 0
mirror of https://github.com/diamondburned/arikawa.git synced 2024-11-05 06:26:08 +00:00
arikawa/gateway/identify.go
diamondburned 6ef093eb98 Gateway: Refactor, v8 user struct updates
This commit refactored several structures from package discord to be in
package gateway. Those structures are mostly presence ones, which per
official documentation has a lot more to do with the Gateway API than
the REST API or anything else.

This commit also renamed several global variables to have a more
consistent and obvious name.

As of v8, the user API has had a lot of minor and some major changes,
especially regarding its Ready event API. The most significant change is
the addition of the ReadySupplemental event as well as several changes
to the Ready field itself.

All of these changes above are breaking, and they have already broken
the state package. These breaking changes will be addressed in other
packages by the next commit.
2020-11-28 17:22:03 -08:00

145 lines
3.9 KiB
Go

package gateway
import (
"context"
"runtime"
"time"
"github.com/pkg/errors"
"golang.org/x/time/rate"
)
// DefaultPresence is used as the default presence when initializing a new
// Gateway.
var DefaultPresence *UpdateStatusData
// Identifier is a wrapper around IdentifyData to add in appropriate rate
// limiters.
type Identifier struct {
IdentifyData
IdentifyShortLimit *rate.Limiter // optional
IdentifyGlobalLimit *rate.Limiter // optional
}
// DefaultIdentifier creates a new default Identifier
func DefaultIdentifier(token string) *Identifier {
return NewIdentifier(IdentifyData{
Token: token,
Properties: DefaultIdentity,
Shard: DefaultShard,
Presence: DefaultPresence,
Compress: true,
LargeThreshold: 50,
})
}
// NewIdentifier creates a new identifier with the given IdentifyData and
// default rate limiters.
func NewIdentifier(data IdentifyData) *Identifier {
return &Identifier{
IdentifyData: data,
IdentifyShortLimit: rate.NewLimiter(rate.Every(5*time.Second), 1),
IdentifyGlobalLimit: rate.NewLimiter(rate.Every(24*time.Hour), 1000),
}
}
// Wait waits for the rate limiters to pass. If a limiter is nil, then it will
// not be used to wait. This is useful
func (i *Identifier) Wait(ctx context.Context) error {
if i.IdentifyShortLimit != nil {
if err := i.IdentifyShortLimit.Wait(ctx); err != nil {
return errors.Wrap(err, "can't wait for short limit")
}
}
if i.IdentifyGlobalLimit != nil {
if err := i.IdentifyGlobalLimit.Wait(ctx); err != nil {
return errors.Wrap(err, "can't wait for global limit")
}
}
return nil
}
// DefaultIdentity is used as the default identity when initializing a new
// Gateway.
var DefaultIdentity = IdentifyProperties{
OS: runtime.GOOS,
Browser: "Arikawa",
Device: "Arikawa",
}
// IdentifyData is the struct for a data that's sent over in an Identify
// command.
type IdentifyData struct {
Token string `json:"token"`
Properties IdentifyProperties `json:"properties"`
Compress bool `json:"compress,omitempty"` // true
LargeThreshold uint `json:"large_threshold,omitempty"` // 50
Shard *Shard `json:"shard,omitempty"` // [ shard_id, num_shards ]
Presence *UpdateStatusData `json:"presence,omitempty"`
Intents Intents `json:"intents,omitempty"`
}
// DefaultIdentifyData creates a default IdentifyData with the given token.
func DefaultIdentifyData(token string) IdentifyData {
return IdentifyData{
Token: token,
Properties: DefaultIdentity,
Shard: DefaultShard,
Presence: DefaultPresence,
Compress: true,
LargeThreshold: 50,
}
}
// SetShard is a helper function to set the shard configuration inside
// IdentifyData.
func (i *IdentifyData) SetShard(id, num int) {
if i.Shard == nil {
i.Shard = new(Shard)
}
i.Shard[0], i.Shard[1] = id, num
}
type IdentifyProperties struct {
// Required
OS string `json:"os"` // GOOS
Browser string `json:"browser"` // Arikawa
Device string `json:"device"` // Arikawa
// Optional
BrowserUserAgent string `json:"browser_user_agent,omitempty"`
BrowserVersion string `json:"browser_version,omitempty"`
OsVersion string `json:"os_version,omitempty"`
Referrer string `json:"referrer,omitempty"`
ReferringDomain string `json:"referring_domain,omitempty"`
}
// Shard is a type for two numbers that represent the Bot's shard configuration.
// The first number is the shard's ID, which could be obtained through the
// ShardID method. The second number is the total number of shards, which could
// be obtained through the NumShards method.
type Shard [2]int
// DefaultShard returns the default shard configuration of 1 shard total, in
// which the current shard ID is 0.
var DefaultShard = &Shard{0, 1}
// ShardID returns the current shard's ID. It uses the first number.
func (s Shard) ShardID() int {
return s[0]
}
// NumShards returns the total number of shards. It uses the second number.
func (s Shard) NumShards() int {
return s[1]
}