mirror of
https://github.com/diamondburned/arikawa.git
synced 2025-03-24 19:09:19 +00:00
Added state handlers
This commit is contained in:
parent
958f592cb4
commit
b11b3e1a42
|
@ -36,16 +36,6 @@ type Guild struct {
|
|||
WidgetChannelID Snowflake `json:"widget_channel_id,string,omitempty"`
|
||||
SystemChannelID Snowflake `json:"system_channel_id,string,omitempty"`
|
||||
|
||||
// GUILD_CREATE only.
|
||||
Joined Timestamp `json:"timestamp,omitempty"`
|
||||
Large bool `json:"large,omitempty"`
|
||||
Unavailable bool `json:"unavailable,omitempty"`
|
||||
MemberCount uint64 `json:"member_count,omitempty"`
|
||||
VoiceStates []VoiceState `json:"voice_state,omitempty"`
|
||||
Members []Member `json:"members,omitempty"`
|
||||
Channels []Channel `json:"channel,omitempty"`
|
||||
Presences []Presence `json:"presences,omitempty"`
|
||||
|
||||
// It's DefaultMaxPresences when MaxPresences is 0.
|
||||
MaxPresences uint64 `json:"max_presences,omitempty"`
|
||||
MaxMembers uint64 `json:"max_members,omitempty"`
|
||||
|
@ -78,6 +68,24 @@ type Role struct {
|
|||
type Presence struct {
|
||||
User User `json:"user"`
|
||||
RoleIDs []Snowflake `json:"roles"`
|
||||
|
||||
// These fields are only filled in gateway events, according to the
|
||||
// documentation.
|
||||
|
||||
Nick string `json:"nick"`
|
||||
GuildID Snowflake `json:"guild_id"`
|
||||
|
||||
PremiumSince Timestamp `json:"premium_since,omitempty"`
|
||||
|
||||
Game *Activity `json:"game"`
|
||||
Activities []Activity `json:"activities"`
|
||||
|
||||
Status Status `json:"status"`
|
||||
ClientStatus struct {
|
||||
Desktop Status `json:"status,omitempty"`
|
||||
Mobile Status `json:"mobile,omitempty"`
|
||||
Web Status `json:"web,omitempty"`
|
||||
} `json:"client_status"`
|
||||
}
|
||||
|
||||
type Member struct {
|
||||
|
|
|
@ -68,3 +68,78 @@ const (
|
|||
ConnectionNotVisible ConnectionVisibility = iota
|
||||
ConnectionVisibleEveryone
|
||||
)
|
||||
|
||||
type Status string
|
||||
|
||||
const (
|
||||
UnknownStatus Status = ""
|
||||
OnlineStatus Status = "online"
|
||||
DoNotDisturbStatus Status = "dnd"
|
||||
IdleStatus Status = "idle"
|
||||
InvisibleStatus Status = "invisible"
|
||||
OfflineStatus Status = "offline"
|
||||
)
|
||||
|
||||
type Activity struct {
|
||||
Name string `json:"name"`
|
||||
Type ActivityType `json:"type"`
|
||||
URL URL `json:"url"`
|
||||
|
||||
// User only
|
||||
|
||||
CreatedAt UnixTimestamp `json:"created_at"`
|
||||
Timestamps struct {
|
||||
Start UnixMsTimestamp `json:"start,omitempty"`
|
||||
End UnixMsTimestamp `json:"end,omitempty"`
|
||||
} `json:"timestamps,omitempty"`
|
||||
|
||||
ApplicationID Snowflake `json:"application_id,omitempty"`
|
||||
Details string `json:"details,omitempty"`
|
||||
State string `json:"state,omitempty"` // party status
|
||||
Emoji Emoji `json:"emoji,omitempty"`
|
||||
|
||||
Party struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Size [2]int `json:"size,omitempty"` // [ current, max ]
|
||||
} `json:"party,omitempty"`
|
||||
|
||||
Assets struct {
|
||||
LargeImage string `json:"large_image,omitempty"` // id
|
||||
LargeText string `json:"large_text,omitempty"`
|
||||
SmallImage string `json:"small_image,omitempty"` // id
|
||||
SmallText string `json:"small_text,omitempty"`
|
||||
} `json:"assets,omitempty"`
|
||||
|
||||
Secrets struct {
|
||||
Join string `json:"join,omitempty"`
|
||||
Spectate string `json:"spectate,omitempty"`
|
||||
Match string `json:"match,omitempty"`
|
||||
} `json:"secrets,omitempty"`
|
||||
|
||||
Instance bool `json:"instance,omitempty"`
|
||||
Flags ActivityFlags `json:"flags,omitempty"`
|
||||
}
|
||||
|
||||
type ActivityType uint8
|
||||
|
||||
const (
|
||||
// Playing $name
|
||||
GameActivity ActivityType = iota
|
||||
// Streaming $details
|
||||
StreamingActivity
|
||||
// Listening to $name
|
||||
ListeningActivity
|
||||
// $emoji $name
|
||||
CustomActivity
|
||||
)
|
||||
|
||||
type ActivityFlags uint8
|
||||
|
||||
const (
|
||||
InstanceActivity ActivityFlags = 1 << iota
|
||||
JoinActivity
|
||||
SpectateActivity
|
||||
JoinRequestActivity
|
||||
SyncActivity
|
||||
PlayActivity
|
||||
)
|
||||
|
|
|
@ -1,78 +0,0 @@
|
|||
package gateway
|
||||
|
||||
import "github.com/diamondburned/arikawa/discord"
|
||||
|
||||
type Status string
|
||||
|
||||
const (
|
||||
UnknownStatus Status = ""
|
||||
OnlineStatus Status = "online"
|
||||
DoNotDisturbStatus Status = "dnd"
|
||||
IdleStatus Status = "idle"
|
||||
InvisibleStatus Status = "invisible"
|
||||
OfflineStatus Status = "offline"
|
||||
)
|
||||
|
||||
type Activity struct {
|
||||
Name string `json:"name"`
|
||||
Type ActivityType `json:"type"`
|
||||
URL discord.URL `json:"url"`
|
||||
|
||||
// User only
|
||||
|
||||
CreatedAt discord.UnixTimestamp `json:"created_at"`
|
||||
Timestamps struct {
|
||||
Start discord.UnixMsTimestamp `json:"start,omitempty"`
|
||||
End discord.UnixMsTimestamp `json:"end,omitempty"`
|
||||
} `json:"timestamps,omitempty"`
|
||||
|
||||
ApplicationID discord.Snowflake `json:"application_id,omitempty"`
|
||||
Details string `json:"details,omitempty"`
|
||||
State string `json:"state,omitempty"` // party status
|
||||
Emoji discord.Emoji `json:"emoji,omitempty"`
|
||||
|
||||
Party struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Size [2]int `json:"size,omitempty"` // [ current, max ]
|
||||
} `json:"party,omitempty"`
|
||||
|
||||
Assets struct {
|
||||
LargeImage string `json:"large_image,omitempty"` // id
|
||||
LargeText string `json:"large_text,omitempty"`
|
||||
SmallImage string `json:"small_image,omitempty"` // id
|
||||
SmallText string `json:"small_text,omitempty"`
|
||||
} `json:"assets,omitempty"`
|
||||
|
||||
Secrets struct {
|
||||
Join string `json:"join,omitempty"`
|
||||
Spectate string `json:"spectate,omitempty"`
|
||||
Match string `json:"match,omitempty"`
|
||||
} `json:"secrets,omitempty"`
|
||||
|
||||
Instance bool `json:"instance,omitempty"`
|
||||
Flags ActivityFlags `json:"flags,omitempty"`
|
||||
}
|
||||
|
||||
type ActivityType uint8
|
||||
|
||||
const (
|
||||
// Playing $name
|
||||
GameActivity ActivityType = iota
|
||||
// Streaming $details
|
||||
StreamingActivity
|
||||
// Listening to $name
|
||||
ListeningActivity
|
||||
// $emoji $name
|
||||
CustomActivity
|
||||
)
|
||||
|
||||
type ActivityFlags uint8
|
||||
|
||||
const (
|
||||
InstanceActivity ActivityFlags = 1 << iota
|
||||
JoinActivity
|
||||
SpectateActivity
|
||||
JoinRequestActivity
|
||||
SyncActivity
|
||||
PlayActivity
|
||||
)
|
|
@ -20,6 +20,10 @@ type (
|
|||
Guilds []discord.Guild `json:"guilds"`
|
||||
|
||||
Shard *Shard `json:"shard"`
|
||||
|
||||
// Undocumented fields
|
||||
Presences []discord.Presence `json:"presences,omitempty"`
|
||||
Notes map[discord.Snowflake]string `json:"notes,omitempty"`
|
||||
}
|
||||
|
||||
ResumedEvent struct{}
|
||||
|
@ -42,7 +46,19 @@ type (
|
|||
|
||||
// https://discordapp.com/developers/docs/topics/gateway#guilds
|
||||
type (
|
||||
GuildCreateEvent discord.Guild
|
||||
GuildCreateEvent struct {
|
||||
discord.Guild
|
||||
|
||||
Joined discord.Timestamp `json:"timestamp,omitempty"`
|
||||
Large bool `json:"large,omitempty"`
|
||||
Unavailable bool `json:"unavailable,omitempty"`
|
||||
MemberCount uint64 `json:"member_count,omitempty"`
|
||||
|
||||
VoiceStates []discord.VoiceState `json:"voice_state,omitempty"`
|
||||
Members []discord.Member `json:"members,omitempty"`
|
||||
Channels []discord.Channel `json:"channel,omitempty"`
|
||||
Presences []discord.Presence `json:"presences,omitempty"`
|
||||
}
|
||||
GuildUpdateEvent discord.Guild
|
||||
GuildDeleteEvent struct {
|
||||
ID discord.Snowflake `json:"id"`
|
||||
|
@ -78,7 +94,7 @@ type (
|
|||
}
|
||||
GuildMemberUpdateEvent struct {
|
||||
GuildID discord.Snowflake `json:"guild_id"`
|
||||
Roles []discord.Snowflake `json:"roles"`
|
||||
RoleIDs []discord.Snowflake `json:"roles"`
|
||||
User discord.User `json:"user"`
|
||||
Nick string `json:"nick"`
|
||||
}
|
||||
|
@ -109,6 +125,12 @@ type (
|
|||
}
|
||||
)
|
||||
|
||||
func (u GuildMemberUpdateEvent) Update(m *discord.Member) {
|
||||
m.RoleIDs = u.RoleIDs
|
||||
m.User = u.User
|
||||
m.Nick = u.Nick
|
||||
}
|
||||
|
||||
// https://discordapp.com/developers/docs/topics/gateway#messages
|
||||
type (
|
||||
MessageCreateEvent discord.Message
|
||||
|
@ -151,25 +173,8 @@ type (
|
|||
// https://discordapp.com/developers/docs/topics/gateway#presence
|
||||
type (
|
||||
// Clients may only update their game status 5 times per 20 seconds.
|
||||
PresenceUpdateEvent struct {
|
||||
User discord.User `json:"user"`
|
||||
Nick string `json:"nick"`
|
||||
Roles []discord.Snowflake `json:"roles"`
|
||||
GuildID discord.Snowflake `json:"guild_id"`
|
||||
|
||||
PremiumSince discord.Timestamp `json:"premium_since,omitempty"`
|
||||
|
||||
Game *Activity `json:"game"`
|
||||
Activities []Activity `json:"activities"`
|
||||
|
||||
Status Status `json:"status"`
|
||||
ClientStatus struct {
|
||||
Desktop Status `json:"status,omitempty"`
|
||||
Mobile Status `json:"mobile,omitempty"`
|
||||
Web Status `json:"web,omitempty"`
|
||||
} `json:"client_status"`
|
||||
}
|
||||
TypingStartEvent struct {
|
||||
PresenceUpdateEvent discord.Presence
|
||||
TypingStartEvent struct {
|
||||
ChannelID discord.Snowflake `json:"channel_id"`
|
||||
UserID discord.Snowflake `json:"user_id"`
|
||||
Timestamp discord.Timestamp `json:"timestamp"`
|
||||
|
@ -180,6 +185,10 @@ type (
|
|||
UserUpdateEvent discord.User
|
||||
)
|
||||
|
||||
func (u PresenceUpdateEvent) Update(p *discord.Presence) {
|
||||
|
||||
}
|
||||
|
||||
// https://discordapp.com/developers/docs/topics/gateway#voice
|
||||
type (
|
||||
VoiceStateUpdateEvent discord.VoiceState
|
||||
|
|
|
@ -3,7 +3,10 @@
|
|||
package state
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/gateway"
|
||||
"github.com/diamondburned/arikawa/handler"
|
||||
"github.com/diamondburned/arikawa/session"
|
||||
)
|
||||
|
@ -15,15 +18,22 @@ var (
|
|||
|
||||
type State struct {
|
||||
*session.Session
|
||||
Store
|
||||
|
||||
// Ready is not updated by the state.
|
||||
Ready gateway.ReadyEvent
|
||||
|
||||
// ErrorLog logs all errors that handler might have, including state fails.
|
||||
// This handler will also be used for Session, which would also be used for
|
||||
// Gateway. Defaults to log.Println.
|
||||
ErrorLog func(error)
|
||||
|
||||
// PreHandler is the manual hook that is executed before the State handler
|
||||
// is. This should only be used for low-level operations.
|
||||
// It's recommended to set Synchronous to true if you mutate the events.
|
||||
PreHandler *handler.Handler // default nil
|
||||
|
||||
MaxMessages uint // default 50
|
||||
|
||||
Store
|
||||
// *: State doesn't actually keep track of pinned messages.
|
||||
|
||||
unhooker func()
|
||||
}
|
||||
|
@ -32,6 +42,13 @@ func NewFromSession(s *session.Session, store Store) (*State, error) {
|
|||
state := &State{
|
||||
Session: s,
|
||||
Store: store,
|
||||
ErrorLog: func(err error) {
|
||||
log.Println("arikawa/state error:", err)
|
||||
},
|
||||
}
|
||||
|
||||
s.ErrorLog = func(err error) {
|
||||
state.ErrorLog(err)
|
||||
}
|
||||
|
||||
return state, state.hookSession()
|
||||
|
@ -49,12 +66,7 @@ func NewWithStore(token string, store Store) (*State, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
state := &State{
|
||||
Session: s,
|
||||
Store: store,
|
||||
}
|
||||
|
||||
return state, state.hookSession()
|
||||
return NewFromSession(s, store)
|
||||
}
|
||||
|
||||
// Unhook removes all state handlers from the session handlers.
|
||||
|
@ -335,32 +347,3 @@ func (s *State) Roles(guildID discord.Snowflake) ([]discord.Role, error) {
|
|||
|
||||
return rs, nil
|
||||
}
|
||||
|
||||
////
|
||||
|
||||
func (s *State) hookSession() error {
|
||||
/*
|
||||
s.unhooker = s.Session.AddHandler(func(iface interface{}) {
|
||||
if s.PreHandler != nil {
|
||||
s.PreHandler.Call(iface)
|
||||
}
|
||||
|
||||
s.mut.Lock()
|
||||
defer s.mut.Unlock()
|
||||
|
||||
switch ev := iface.(type) {
|
||||
case *gateway.ReadyEvent:
|
||||
// Override
|
||||
s.guilds = ev.Guilds
|
||||
s.privates = ev.PrivateChannels
|
||||
s.self = ev.User
|
||||
|
||||
case *gateway.MessageCreateEvent:
|
||||
_ = ev
|
||||
panic("IMPLEMENT ME")
|
||||
}
|
||||
})
|
||||
*/
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
178
state/state_events.go
Normal file
178
state/state_events.go
Normal file
|
@ -0,0 +1,178 @@
|
|||
package state
|
||||
|
||||
import (
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/gateway"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func (s *State) hookSession() error {
|
||||
s.unhooker = s.Session.AddHandler(func(iface interface{}) {
|
||||
if s.PreHandler != nil {
|
||||
s.PreHandler.Call(iface)
|
||||
}
|
||||
s.onEvent(iface)
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *State) onEvent(iface interface{}) {
|
||||
// TODO: voice states
|
||||
|
||||
switch ev := iface.(type) {
|
||||
case *gateway.ReadyEvent:
|
||||
// Handle guilds
|
||||
for _, g := range ev.Guilds {
|
||||
if err := s.Store.GuildSet(&g); err != nil {
|
||||
s.wrapErr(err, "Failed to set guild in state")
|
||||
}
|
||||
}
|
||||
|
||||
// Handle private channels
|
||||
for _, ch := range ev.PrivateChannels {
|
||||
if err := s.Store.ChannelSet(&ch); err != nil {
|
||||
s.wrapErr(err, "Failed to set channel in state")
|
||||
}
|
||||
}
|
||||
|
||||
// Handle user
|
||||
if err := s.Store.SelfSet(&ev.User); err != nil {
|
||||
s.wrapErr(err, "Failed to set self in state")
|
||||
}
|
||||
|
||||
// Set Ready to the state
|
||||
s.Ready = *ev
|
||||
|
||||
case *gateway.GuildCreateEvent:
|
||||
if err := s.Store.GuildSet(&ev.Guild); err != nil {
|
||||
s.wrapErr(err, "Failed to create guild in state")
|
||||
}
|
||||
|
||||
for _, m := range ev.Members {
|
||||
if err := s.Store.MemberSet(ev.Guild.ID, &m); err != nil {
|
||||
s.wrapErr(err, "Failed to add a member from guild in state")
|
||||
}
|
||||
}
|
||||
|
||||
for _, ch := range ev.Channels {
|
||||
ch.GuildID = ev.Guild.ID // just to make sure
|
||||
|
||||
if err := s.Store.ChannelSet(&ch); err != nil {
|
||||
s.wrapErr(err, "Failed to add a channel from guild in state")
|
||||
}
|
||||
}
|
||||
|
||||
for _, p := range ev.Presences {
|
||||
if err := s.Store.PresenceSet(ev.Guild.ID, &p); err != nil {
|
||||
s.wrapErr(err, "Failed to add a presence from guild in state")
|
||||
}
|
||||
}
|
||||
case *gateway.GuildUpdateEvent:
|
||||
if err := s.Store.GuildSet((*discord.Guild)(ev)); err != nil {
|
||||
s.wrapErr(err, "Failed to update guild in state")
|
||||
}
|
||||
case *gateway.GuildDeleteEvent:
|
||||
if err := s.Store.GuildRemove(ev.ID); err != nil {
|
||||
s.wrapErr(err, "Failed to delete guild in state")
|
||||
}
|
||||
|
||||
case *gateway.GuildMemberAddEvent:
|
||||
if err := s.Store.MemberSet(ev.GuildID, &ev.Member); err != nil {
|
||||
s.wrapErr(err, "Failed to add a member in state")
|
||||
}
|
||||
case *gateway.GuildMemberUpdateEvent:
|
||||
m, err := s.Store.Member(ev.GuildID, ev.User.ID)
|
||||
if err != nil {
|
||||
// We can't do much here.
|
||||
m = &discord.Member{}
|
||||
}
|
||||
|
||||
// Update available fields from ev into m
|
||||
ev.Update(m)
|
||||
|
||||
if err := s.Store.MemberSet(ev.GuildID, m); err != nil {
|
||||
s.wrapErr(err, "Failed to update a member in state")
|
||||
}
|
||||
case *gateway.GuildMemberRemoveEvent:
|
||||
if err := s.Store.MemberRemove(ev.GuildID, ev.User.ID); err != nil {
|
||||
s.wrapErr(err, "Failed to remove a member in state")
|
||||
}
|
||||
|
||||
case *gateway.GuildMembersChunkEvent:
|
||||
for _, m := range ev.Members {
|
||||
if err := s.Store.MemberSet(ev.GuildID, &m); err != nil {
|
||||
s.wrapErr(err, "Failed to add a member from chunk in state")
|
||||
}
|
||||
}
|
||||
|
||||
for _, p := range ev.Presences {
|
||||
if err := s.Store.PresenceSet(ev.GuildID, &p); err != nil {
|
||||
s.wrapErr(err, "Failed to add a presence from chunk in state")
|
||||
}
|
||||
}
|
||||
|
||||
case *gateway.GuildRoleCreateEvent:
|
||||
if err := s.Store.RoleSet(ev.GuildID, &ev.Role); err != nil {
|
||||
s.wrapErr(err, "Failed to add a role in state")
|
||||
}
|
||||
case *gateway.GuildRoleUpdateEvent:
|
||||
if err := s.Store.RoleSet(ev.GuildID, &ev.Role); err != nil {
|
||||
s.wrapErr(err, "Failed to update a role in state")
|
||||
}
|
||||
case *gateway.GuildRoleDeleteEvent:
|
||||
if err := s.Store.RoleRemove(ev.GuildID, ev.RoleID); err != nil {
|
||||
s.wrapErr(err, "Failed to remove a role in state")
|
||||
}
|
||||
|
||||
case *gateway.GuildEmojisUpdateEvent:
|
||||
if err := s.Store.EmojiSet(ev.GuildID, ev.Emojis); err != nil {
|
||||
s.wrapErr(err, "Failed to update emojis in state")
|
||||
}
|
||||
|
||||
case *gateway.ChannelCreateEvent:
|
||||
if err := s.Store.ChannelSet((*discord.Channel)(ev)); err != nil {
|
||||
s.wrapErr(err, "Failed to create a channel in state")
|
||||
}
|
||||
case *gateway.ChannelUpdateEvent:
|
||||
if err := s.Store.ChannelSet((*discord.Channel)(ev)); err != nil {
|
||||
s.wrapErr(err, "Failed to update a channel in state")
|
||||
}
|
||||
case *gateway.ChannelDeleteEvent:
|
||||
if err := s.Store.ChannelRemove((*discord.Channel)(ev)); err != nil {
|
||||
s.wrapErr(err, "Failed to remove a channel in state")
|
||||
}
|
||||
|
||||
// *gateway.ChannelPinsUpdateEvent is not tracked.
|
||||
|
||||
case *gateway.MessageCreateEvent:
|
||||
if err := s.Store.MessageSet((*discord.Message)(ev)); err != nil {
|
||||
s.wrapErr(err, "Failed to add a message in state")
|
||||
}
|
||||
case *gateway.MessageUpdateEvent:
|
||||
if err := s.Store.MessageSet((*discord.Message)(ev)); err != nil {
|
||||
s.wrapErr(err, "Failed to update a message in state")
|
||||
}
|
||||
case *gateway.MessageDeleteEvent:
|
||||
if err := s.Store.MessageRemove(ev.ChannelID, ev.ID); err != nil {
|
||||
s.wrapErr(err, "Failed to delete a message in state")
|
||||
}
|
||||
case *gateway.MessageDeleteBulkEvent:
|
||||
for _, id := range ev.IDs {
|
||||
if err := s.Store.MessageRemove(ev.ChannelID, id); err != nil {
|
||||
s.wrapErr(err, "Failed to delete bulk meessages in state")
|
||||
}
|
||||
}
|
||||
|
||||
case *gateway.PresenceUpdateEvent:
|
||||
if err := s.Store.PresenceSet(
|
||||
ev.GuildID, (*discord.Presence)(ev)); err != nil {
|
||||
|
||||
s.wrapErr(err, "Failed to update presence in state")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *State) wrapErr(err error, wrap string) {
|
||||
s.ErrorLog(errors.Wrap(err, wrap))
|
||||
}
|
|
@ -46,19 +46,21 @@ type StoreGetter interface {
|
|||
type StoreModifier interface {
|
||||
SelfSet(me *discord.User) error
|
||||
|
||||
// ChannelSet should switch on Type to know if it's a private channel or
|
||||
// not.
|
||||
ChannelSet(*discord.Channel) error
|
||||
ChannelRemove(*discord.Channel) error
|
||||
|
||||
EmojiSet(guildID discord.Snowflake, emojis []discord.Emoji) error
|
||||
|
||||
GuildSet(*discord.Guild) error
|
||||
GuildRemove(*discord.Guild) error
|
||||
GuildRemove(id discord.Snowflake) error
|
||||
|
||||
MemberSet(guildID discord.Snowflake, member *discord.Member) error
|
||||
MemberRemove(guildID, userID discord.Snowflake) error
|
||||
|
||||
MessageSet(*discord.Message) error
|
||||
MessageRemove(*discord.Message) error
|
||||
MessageRemove(channelID, messageID discord.Snowflake) error
|
||||
|
||||
PresenceSet(guildID discord.Snowflake, presence *discord.Presence) error
|
||||
PresenceRemove(guildID, userID discord.Snowflake) error
|
||||
|
|
|
@ -15,9 +15,13 @@ type DefaultStore struct {
|
|||
self discord.User
|
||||
|
||||
// includes normal and private
|
||||
privates map[discord.Snowflake]*discord.Channel // channelID:channel
|
||||
guilds map[discord.Snowflake]*discord.Guild // guildID:guild
|
||||
messages map[discord.Snowflake][]discord.Message // channelID:messages
|
||||
privates map[discord.Snowflake]*discord.Channel // channelID:channel
|
||||
guilds map[discord.Snowflake]*discord.Guild // guildID:guild
|
||||
|
||||
channels map[discord.Snowflake][]discord.Channel // guildID:channels
|
||||
members map[discord.Snowflake][]discord.Member // guildID:members
|
||||
presences map[discord.Snowflake][]discord.Presence // guildID:presences
|
||||
messages map[discord.Snowflake][]discord.Message // channelID:messages
|
||||
|
||||
mut sync.Mutex
|
||||
}
|
||||
|
@ -40,7 +44,10 @@ func NewDefaultStore(opts *DefaultStoreOptions) *DefaultStore {
|
|||
|
||||
privates: map[discord.Snowflake]*discord.Channel{},
|
||||
guilds: map[discord.Snowflake]*discord.Guild{},
|
||||
messages: map[discord.Snowflake][]discord.Message{},
|
||||
|
||||
channels: map[discord.Snowflake][]discord.Channel{},
|
||||
presences: map[discord.Snowflake][]discord.Presence{},
|
||||
messages: map[discord.Snowflake][]discord.Message{},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,8 +91,8 @@ func (s *DefaultStore) Channel(id discord.Snowflake) (*discord.Channel, error) {
|
|||
s.mut.Lock()
|
||||
defer s.mut.Unlock()
|
||||
|
||||
for _, g := range s.guilds {
|
||||
for _, ch := range g.Channels {
|
||||
for _, chs := range s.channels {
|
||||
for _, ch := range chs {
|
||||
if ch.ID == id {
|
||||
return &ch, nil
|
||||
}
|
||||
|
@ -101,12 +108,12 @@ func (s *DefaultStore) Channels(
|
|||
s.mut.Lock()
|
||||
defer s.mut.Unlock()
|
||||
|
||||
gd, ok := s.guilds[guildID]
|
||||
chs, ok := s.channels[guildID]
|
||||
if !ok {
|
||||
return nil, ErrStoreNotFound
|
||||
}
|
||||
|
||||
return gd.Channels, nil
|
||||
return chs, nil
|
||||
}
|
||||
|
||||
func (s *DefaultStore) PrivateChannels() ([]discord.Channel, error) {
|
||||
|
@ -136,20 +143,22 @@ func (s *DefaultStore) ChannelSet(channel *discord.Channel) error {
|
|||
s.privates[channel.ID] = channel
|
||||
|
||||
default:
|
||||
gd, ok := s.guilds[channel.GuildID]
|
||||
chs, ok := s.channels[channel.GuildID]
|
||||
if !ok {
|
||||
return ErrStoreNotFound
|
||||
}
|
||||
|
||||
for i, ch := range gd.Channels {
|
||||
for i, ch := range chs {
|
||||
if ch.ID == channel.ID {
|
||||
// Found, just edit
|
||||
gd.Channels[i] = *channel
|
||||
chs[i] = *channel
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
gd.Channels = append(gd.Channels, *channel)
|
||||
chs = append(chs, *channel)
|
||||
s.channels[channel.GuildID] = chs
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -159,14 +168,16 @@ func (s *DefaultStore) ChannelRemove(channel *discord.Channel) error {
|
|||
s.mut.Lock()
|
||||
defer s.mut.Unlock()
|
||||
|
||||
gd, ok := s.guilds[channel.GuildID]
|
||||
chs, ok := s.channels[channel.GuildID]
|
||||
if !ok {
|
||||
return ErrStoreNotFound
|
||||
}
|
||||
|
||||
for i, ch := range gd.Channels {
|
||||
for i, ch := range chs {
|
||||
if ch.ID == channel.ID {
|
||||
gd.Channels = append(gd.Channels[:i], gd.Channels[i+1:]...)
|
||||
chs = append(chs[:i], chs[i+1:]...)
|
||||
s.channels[channel.GuildID] = chs
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
@ -277,26 +288,15 @@ func (s *DefaultStore) Guilds() ([]discord.Guild, error) {
|
|||
|
||||
func (s *DefaultStore) GuildSet(g *discord.Guild) error {
|
||||
s.mut.Lock()
|
||||
defer s.mut.Unlock()
|
||||
|
||||
old := s.guilds[g.ID]
|
||||
|
||||
// Check the channels too
|
||||
if len(old.Channels) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(g.Channels) == 0 {
|
||||
g.Channels = old.Channels
|
||||
}
|
||||
|
||||
s.guilds[g.ID] = g
|
||||
s.mut.Unlock()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *DefaultStore) GuildRemove(g *discord.Guild) error {
|
||||
func (s *DefaultStore) GuildRemove(id discord.Snowflake) error {
|
||||
s.mut.Lock()
|
||||
delete(s.guilds, g.ID)
|
||||
delete(s.guilds, id)
|
||||
s.mut.Unlock()
|
||||
|
||||
return nil
|
||||
|
@ -310,14 +310,14 @@ func (s *DefaultStore) Member(
|
|||
s.mut.Lock()
|
||||
defer s.mut.Unlock()
|
||||
|
||||
gd, ok := s.guilds[guildID]
|
||||
ms, ok := s.members[guildID]
|
||||
if !ok {
|
||||
return nil, ErrStoreNotFound
|
||||
}
|
||||
|
||||
for _, member := range gd.Members {
|
||||
if member.User.ID == userID {
|
||||
return &member, nil
|
||||
for _, m := range ms {
|
||||
if m.User.ID == userID {
|
||||
return &m, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -330,12 +330,12 @@ func (s *DefaultStore) Members(
|
|||
s.mut.Lock()
|
||||
defer s.mut.Unlock()
|
||||
|
||||
gd, ok := s.guilds[guildID]
|
||||
ms, ok := s.members[guildID]
|
||||
if !ok {
|
||||
return nil, ErrStoreNotFound
|
||||
}
|
||||
|
||||
return gd.Members, nil
|
||||
return ms, nil
|
||||
}
|
||||
|
||||
func (s *DefaultStore) MemberSet(
|
||||
|
@ -344,22 +344,26 @@ func (s *DefaultStore) MemberSet(
|
|||
s.mut.Lock()
|
||||
defer s.mut.Unlock()
|
||||
|
||||
gd, ok := s.guilds[guildID]
|
||||
ms, ok := s.members[guildID]
|
||||
if !ok {
|
||||
return ErrStoreNotFound
|
||||
}
|
||||
|
||||
// Try and see if this member is already in the slice
|
||||
for i, m := range gd.Members {
|
||||
for i, m := range ms {
|
||||
if m.User.ID == member.User.ID {
|
||||
// If it is, we simply replace it
|
||||
gd.Members[i] = *member
|
||||
ms[i] = *member
|
||||
s.members[guildID] = ms
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Append the new member
|
||||
gd.Members = append(gd.Members, *member)
|
||||
ms = append(ms, *member)
|
||||
s.members[guildID] = ms
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -367,15 +371,17 @@ func (s *DefaultStore) MemberRemove(guildID, userID discord.Snowflake) error {
|
|||
s.mut.Lock()
|
||||
defer s.mut.Unlock()
|
||||
|
||||
gd, ok := s.guilds[guildID]
|
||||
ms, ok := s.members[guildID]
|
||||
if !ok {
|
||||
return ErrStoreNotFound
|
||||
}
|
||||
|
||||
// Try and see if this member is already in the slice
|
||||
for i, m := range gd.Members {
|
||||
for i, m := range ms {
|
||||
if m.User.ID == userID {
|
||||
gd.Members = append(gd.Members[:i], gd.Members[i+1:]...)
|
||||
ms = append(ms, ms[i+1:]...)
|
||||
s.members[guildID] = ms
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
@ -443,19 +449,21 @@ func (s *DefaultStore) MessageSet(message *discord.Message) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *DefaultStore) MessageRemove(message *discord.Message) error {
|
||||
func (s *DefaultStore) MessageRemove(
|
||||
channelID, messageID discord.Snowflake) error {
|
||||
|
||||
s.mut.Lock()
|
||||
defer s.mut.Unlock()
|
||||
|
||||
ms, ok := s.messages[message.ChannelID]
|
||||
ms, ok := s.messages[channelID]
|
||||
if !ok {
|
||||
return ErrStoreNotFound
|
||||
}
|
||||
|
||||
for i, m := range ms {
|
||||
if m.ID == message.ID {
|
||||
if m.ID == messageID {
|
||||
ms = append(ms[:i], ms[i+1:]...)
|
||||
s.messages[message.ChannelID] = ms
|
||||
s.messages[channelID] = ms
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
@ -471,12 +479,12 @@ func (s *DefaultStore) Presence(
|
|||
s.mut.Lock()
|
||||
defer s.mut.Unlock()
|
||||
|
||||
gd, ok := s.guilds[guildID]
|
||||
ps, ok := s.presences[guildID]
|
||||
if !ok {
|
||||
return nil, ErrStoreNotFound
|
||||
}
|
||||
|
||||
for _, p := range gd.Presences {
|
||||
for _, p := range ps {
|
||||
if p.User.ID == userID {
|
||||
return &p, nil
|
||||
}
|
||||
|
@ -491,12 +499,12 @@ func (s *DefaultStore) Presences(
|
|||
s.mut.Lock()
|
||||
defer s.mut.Unlock()
|
||||
|
||||
gd, ok := s.guilds[guildID]
|
||||
ps, ok := s.presences[guildID]
|
||||
if !ok {
|
||||
return nil, ErrStoreNotFound
|
||||
}
|
||||
|
||||
return gd.Presences, nil
|
||||
return ps, nil
|
||||
}
|
||||
|
||||
func (s *DefaultStore) PresenceSet(
|
||||
|
@ -505,19 +513,22 @@ func (s *DefaultStore) PresenceSet(
|
|||
s.mut.Lock()
|
||||
defer s.mut.Unlock()
|
||||
|
||||
gd, ok := s.guilds[guildID]
|
||||
ps, ok := s.presences[guildID]
|
||||
if !ok {
|
||||
return ErrStoreNotFound
|
||||
}
|
||||
|
||||
for i, p := range gd.Presences {
|
||||
for i, p := range ps {
|
||||
if p.User.ID == presence.User.ID {
|
||||
gd.Presences[i] = *presence
|
||||
ps[i] = *presence
|
||||
s.presences[guildID] = ps
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
gd.Presences = append(gd.Presences, *presence)
|
||||
ps = append(ps, *presence)
|
||||
s.presences[guildID] = ps
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -525,14 +536,16 @@ func (s *DefaultStore) PresenceRemove(guildID, userID discord.Snowflake) error {
|
|||
s.mut.Lock()
|
||||
defer s.mut.Unlock()
|
||||
|
||||
gd, ok := s.guilds[guildID]
|
||||
ps, ok := s.presences[guildID]
|
||||
if !ok {
|
||||
return ErrStoreNotFound
|
||||
}
|
||||
|
||||
for i, p := range gd.Presences {
|
||||
for i, p := range ps {
|
||||
if p.User.ID == userID {
|
||||
gd.Presences = append(gd.Presences[:i], gd.Presences[i+1:]...)
|
||||
ps = append(ps[:i], ps[i+1:]...)
|
||||
s.presences[guildID] = ps
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue