2020-01-15 07:34:18 +00:00
|
|
|
package gateway
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
"golang.org/x/time/rate"
|
|
|
|
)
|
|
|
|
|
2020-02-22 07:35:11 +00:00
|
|
|
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"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type IdentifyData struct {
|
|
|
|
Token string `json:"token"`
|
|
|
|
Properties IdentifyProperties `json:"properties"`
|
|
|
|
|
|
|
|
Compress bool `json:"compress,omitempty"` // true
|
|
|
|
LargeThreshold uint `json:"large_threshold,omitempty"` // 50
|
|
|
|
GuildSubscriptions bool `json:"guild_subscriptions"` // true
|
|
|
|
|
|
|
|
Shard *Shard `json:"shard,omitempty"` // [ shard_id, num_shards ]
|
|
|
|
|
|
|
|
Presence *UpdateStatusData `json:"presence,omitempty"`
|
|
|
|
|
|
|
|
Intents Intents `json:"intents,omitempty"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// Intents is a new Discord API feature that's documented at
|
|
|
|
// https://discordapp.com/developers/docs/topics/gateway#gateway-intents.
|
|
|
|
type Intents uint16
|
|
|
|
|
|
|
|
const (
|
|
|
|
IntentGuilds Intents = 1 << iota
|
|
|
|
IntentGuildMembers
|
|
|
|
IntentGuildBans
|
|
|
|
IntentGuildEmojis
|
|
|
|
IntentGuildIntegrations
|
|
|
|
IntentGuildWebhooks
|
|
|
|
IntentGuildInvites
|
|
|
|
IntentGuildVoiceStates
|
|
|
|
IntentGuildPresences
|
|
|
|
IntentGuildMessages
|
|
|
|
IntentGuildMessageReactions
|
|
|
|
IntentGuildMessageTyping
|
|
|
|
IntentDirectMessages
|
|
|
|
IntentDirectMessageReactions
|
|
|
|
IntentDirectMessageTyping
|
|
|
|
)
|
|
|
|
|
2020-01-15 07:34:18 +00:00
|
|
|
type Identifier struct {
|
|
|
|
IdentifyData
|
|
|
|
|
|
|
|
IdentifyShortLimit *rate.Limiter `json:"-"`
|
|
|
|
IdentifyGlobalLimit *rate.Limiter `json:"-"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func DefaultIdentifier(token string) *Identifier {
|
|
|
|
return NewIdentifier(IdentifyData{
|
|
|
|
Token: token,
|
|
|
|
Properties: Identity,
|
|
|
|
Shard: DefaultShard(),
|
|
|
|
|
2020-02-22 07:35:11 +00:00
|
|
|
Compress: true,
|
|
|
|
LargeThreshold: 50,
|
|
|
|
GuildSubscriptions: true,
|
2020-01-15 07:34:18 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
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),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (i *Identifier) Wait(ctx context.Context) error {
|
|
|
|
if err := i.IdentifyShortLimit.Wait(ctx); err != nil {
|
|
|
|
return errors.Wrap(err, "Can't wait for short limit")
|
|
|
|
}
|
|
|
|
if err := i.IdentifyGlobalLimit.Wait(ctx); err != nil {
|
|
|
|
return errors.Wrap(err, "Can't wait for global limit")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|