1
0
Fork 0
mirror of https://github.com/diamondburned/arikawa.git synced 2024-11-30 18:53:30 +00:00

Gateway: Added undocumented GuildMemberListUpdate event

This commit is contained in:
diamondburned (Forefront) 2020-03-15 22:55:45 -07:00
parent 1b785b1c38
commit 8899462ff0
5 changed files with 75 additions and 21 deletions

View file

@ -101,9 +101,12 @@ func (g *Gateway) UpdateStatus(data UpdateStatusData) error {
// Undocumented
type GuildSubscribeData struct {
GuildID discord.Snowflake `json:"guild_id"`
Typing bool `json:"typing"`
Activities bool `json:"activities"`
GuildID discord.Snowflake `json:"guild_id"`
// Channels is not documented. It's used to fetch the right members sidebar.
Channels map[discord.Snowflake][][2]int `json:"channels"`
}
func (g *Gateway) GuildSubscribe(data GuildSubscribeData) error {

View file

@ -106,6 +106,51 @@ type (
Presences []discord.Presence `json:"presences,omitempty"`
}
// GuildMemberListUpdate is an undocumented event. It's received when the
// client sends over GuildSubscriptions with the Channels field used.
// The State package does not handle this event.
GuildMemberListUpdate struct {
ID string `json:"id"`
GuildID discord.Snowflake `json:"guild_id"`
MemberCount uint64 `json:"member_count"`
OnlineCount uint64 `json:"online_count"`
// Groups is all the visible role sections.
Groups []GuildMemberListGroup `json:"groups"`
Ops []GuildMemberListOp `json:"ops"`
}
GuildMemberListGroup struct {
ID string `json:"id"` // either discord.Snowflake Role IDs or "online"
Count uint64 `json:"count"`
}
GuildMemberListOp struct {
// Mysterious string, so far spotted to be [SYNC, INSERT, UPDATE, DELETE].
Op string `json:"op"`
// NON-SYNC ONLY
// Only available for Ops that aren't "SYNC".
Index int `json:"index,omitempty"`
Item GuildMemberListOpItem `json:"item,omitempty"`
// SYNC ONLY
// Range requested in GuildSubscribeData.
Range [2]int `json:"range,omitempty"`
// Items is basically a linear list of roles and members, similarly to
// how the client renders it. No, it's not nested.
Items []GuildMemberListOpItem `json:"items,omitempty"`
}
// GuildMemberListOpItem is an enum. Either of the fields are provided, but
// never both. Refer to (*GuildMemberListUpdate).Ops for more.
GuildMemberListOpItem struct {
Group *GuildMemberListGroup `json:"group,omitempty"`
Member *struct {
discord.Member
HoistedRole string `json:"hoisted_role"`
Presence discord.Presence `json:"presence"`
} `json:"member,omitempty"`
}
GuildRoleCreateEvent struct {
GuildID discord.Snowflake `json:"guild_id"`
Role discord.Role `json:"role"`

View file

@ -34,6 +34,10 @@ var EventCreator = map[string]func() Event{
"GUILD_MEMBER_UPDATE": func() Event { return new(GuildMemberUpdateEvent) },
"GUILD_MEMBERS_CHUNK": func() Event { return new(GuildMembersChunkEvent) },
"GUILD_MEMBER_LIST_UPDATE": func() Event {
return new(GuildMemberListUpdate)
},
"GUILD_ROLE_CREATE": func() Event { return new(GuildRoleCreateEvent) },
"GUILD_ROLE_UPDATE": func() Event { return new(GuildRoleUpdateEvent) },
"GUILD_ROLE_DELETE": func() Event { return new(GuildRoleDeleteEvent) },

View file

@ -27,6 +27,7 @@ const (
Version = "6"
Encoding = "json"
// Compress = "zlib-stream"
)
var (
@ -135,6 +136,7 @@ func NewGatewayWithDriver(token string, driver json.Driver) (*Gateway, error) {
param := url.Values{}
param.Set("v", Version)
param.Set("encoding", Encoding)
// param.Set("compress", Compress)
// Append the form to the URL
URL += "?" + param.Encode()
@ -249,15 +251,15 @@ func (g *Gateway) start() error {
// This is where we'll get our events
ch := g.WS.Listen()
// Make a new WaitGroup for use in background loops:
g.waitGroup = new(sync.WaitGroup)
// Wait for an OP 10 Hello
var hello HelloEvent
if _, err := AssertEvent(g, <-ch, HelloOP, &hello); err != nil {
return errors.Wrap(err, "Error at Hello")
}
// Make a new WaitGroup for use in background loops:
g.waitGroup = new(sync.WaitGroup)
// Send Discord either the Identify packet (if it's a fresh connection), or
// a Resume packet (if it's a dead connection).
if g.SessionID == "" {
@ -375,8 +377,9 @@ func (g *Gateway) send(lock bool, code OPCode, v interface{}) error {
return errors.Wrap(err, "Failed to encode payload")
}
ctx, cancel := context.WithTimeout(context.Background(), g.WSTimeout)
defer cancel()
// ctx, cancel := context.WithTimeout(context.Background(), g.WSTimeout)
// defer cancel()
ctx := context.Background()
if lock {
g.available.RLock()

View file

@ -13,21 +13,20 @@ import (
type OPCode uint8
const (
DispatchOP OPCode = iota // recv
HeartbeatOP // send/recv
IdentifyOP // send...
StatusUpdateOP //
VoiceStateUpdateOP //
VoiceServerPingOP //
ResumeOP //
ReconnectOP // recv
RequestGuildMembersOP // send
InvalidSessionOP // recv...
HelloOP
HeartbeatAckOP
_
CallConnectOP
GuildSubscriptionsOP
DispatchOP OPCode = 0 // recv
HeartbeatOP OPCode = 1 // send/recv
IdentifyOP OPCode = 2 // send...
StatusUpdateOP OPCode = 3 //
VoiceStateUpdateOP OPCode = 4 //
VoiceServerPingOP OPCode = 5 //
ResumeOP OPCode = 6 //
ReconnectOP OPCode = 7 // recv
RequestGuildMembersOP OPCode = 8 // send
InvalidSessionOP OPCode = 9 // recv...
HelloOP OPCode = 10
HeartbeatAckOP OPCode = 11
CallConnectOP OPCode = 13
GuildSubscriptionsOP OPCode = 14
)
type OP struct {