From 92c27c7712f3b3dd9cf8d9c408997a37ee2c8a3b Mon Sep 17 00:00:00 2001 From: Bruce Marriner Date: Fri, 8 Apr 2016 11:51:58 -0500 Subject: [PATCH 1/4] Because binzy was too lazy. No seriously, this allows us see if a guild is actually being created or just being lazy-loaded. --- state.go | 2 +- structs.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/state.go b/state.go index 68267d3..6180150 100644 --- a/state.go +++ b/state.go @@ -66,7 +66,7 @@ func (s *State) GuildAdd(guild *Guild) error { for i, g := range s.Guilds { if g.ID == guild.ID { // If this guild already exists with data, don't stomp on props - if !g.Unavailable { + if g.Unavailable != nil && !*g.Unavailable { guild.Members = g.Members guild.Presences = g.Presences guild.Channels = g.Channels diff --git a/structs.go b/structs.go index 3f6cd35..a7a4ef2 100644 --- a/structs.go +++ b/structs.go @@ -178,7 +178,7 @@ type Guild struct { Presences []*Presence `json:"presences"` Channels []*Channel `json:"channels"` VoiceStates []*VoiceState `json:"voice_states"` - Unavailable bool `json:"unavailable"` + Unavailable *bool `json:"unavailable"` } // A GuildParams stores all the data needed to update discord guild settings From 836e78d3d99723730facbb5be2b4611082d5ca46 Mon Sep 17 00:00:00 2001 From: Bruce Marriner Date: Mon, 11 Apr 2016 16:56:43 -0500 Subject: [PATCH 2/4] Pass struct along with OnEvent event. --- structs.go | 1 + wsapi.go | 2 ++ 2 files changed, 3 insertions(+) diff --git a/structs.go b/structs.go index a7a4ef2..a51c0ac 100644 --- a/structs.go +++ b/structs.go @@ -265,6 +265,7 @@ type Event struct { Operation int `json:"op"` Direction int `json:"dir"` RawData json.RawMessage `json:"d"` + Struct interface{} `json:"-"` } // A Ready stores all data for the websocket READY event. diff --git a/wsapi.go b/wsapi.go index d5a6169..765b705 100644 --- a/wsapi.go +++ b/wsapi.go @@ -301,6 +301,8 @@ func (s *Session) event(messageType int, message []byte) { if i != nil { s.handle(i) } + + e.Struct = i s.handle(e) return From 1a672823a28f33e5b6ad9701eff2a7aeba74565e Mon Sep 17 00:00:00 2001 From: Bruce Marriner Date: Mon, 11 Apr 2016 18:54:19 -0500 Subject: [PATCH 3/4] Lint and Cleanup --- discord.go | 8 ++++++-- message.go | 2 +- oauth2.go | 40 +--------------------------------------- oauth2_test.go | 2 +- restapi.go | 2 +- structs.go | 12 ++++++------ voice.go | 8 ++++---- 7 files changed, 20 insertions(+), 54 deletions(-) diff --git a/discord.go b/discord.go index 57e2052..a143f05 100644 --- a/discord.go +++ b/discord.go @@ -43,7 +43,6 @@ func New(args ...interface{}) (s *Session, err error) { } // If no arguments are passed return the empty Session interface. - // Later I will add default values, if appropriate. if args == nil { return } @@ -94,7 +93,7 @@ func New(args ...interface{}) (s *Session, err error) { } // case Config: - // TODO: Parse configuration + // TODO: Parse configuration struct default: err = fmt.Errorf("Unsupported parameter type provided.") @@ -127,6 +126,7 @@ func New(args ...interface{}) (s *Session, err error) { // Session.validateHandler(func (s *discordgo.Session, m *discordgo.MessageCreate)) // will return the reflect.Type of *discordgo.MessageCreate func (s *Session) validateHandler(handler interface{}) reflect.Type { + handlerType := reflect.TypeOf(handler) if handlerType.NumIn() != 2 { @@ -161,6 +161,7 @@ func (s *Session) validateHandler(handler interface{}) reflect.Type { // The return value of this method is a function, that when called will remove the // event handler. func (s *Session) AddHandler(handler interface{}) func() { + s.initialize() eventType := s.validateHandler(handler) @@ -192,6 +193,7 @@ func (s *Session) AddHandler(handler interface{}) func() { // handle calls any handlers that match the event type and any handlers of // interface{}. func (s *Session) handle(event interface{}) { + s.handlersMu.RLock() defer s.handlersMu.RUnlock() @@ -216,6 +218,7 @@ func (s *Session) handle(event interface{}) { // initialize adds all internal handlers and state tracking handlers. func (s *Session) initialize() { + s.handlersMu.Lock() if s.handlers != nil { s.handlersMu.Unlock() @@ -233,5 +236,6 @@ func (s *Session) initialize() { // onReady handles the ready event. func (s *Session) onReady(se *Session, r *Ready) { + go s.heartbeat(s.wsConn, s.listening, r.HeartbeatInterval) } diff --git a/message.go b/message.go index b2b5d00..60773bb 100644 --- a/message.go +++ b/message.go @@ -34,9 +34,9 @@ type Attachment struct { ID string `json:"id"` URL string `json:"url"` ProxyURL string `json:"proxy_url"` + Filename string `json:"filename"` Width int `json:"width"` Height int `json:"height"` - Filename string `json:"filename"` Size int `json:"size"` } diff --git a/oauth2.go b/oauth2.go index 526767a..962d409 100644 --- a/oauth2.go +++ b/oauth2.go @@ -9,10 +9,6 @@ package discordgo -import ( - "fmt" -) - // ------------------------------------------------------------------------------------------------ // Code specific to Discord OAuth2 Applications // ------------------------------------------------------------------------------------------------ @@ -25,10 +21,6 @@ type Application struct { Icon string `json:"icon,omitempty"` Secret string `json:"secret,omitempty"` RedirectURIs *[]string `json:"redirect_uris,omitempty"` - - // Concept.. almost guarenteed to be removed. - // Imagine that it's just not even here at all. - ses *Session } // Application returns an Application structure of a specific Application @@ -41,7 +33,6 @@ func (s *Session) Application(appID string) (st *Application, err error) { } err = unmarshal(body, &st) - st.ses = s return } @@ -54,11 +45,7 @@ func (s *Session) Applications() (st []*Application, err error) { } err = unmarshal(body, &st) - for k, _ := range st { - st[k].ses = s - } return - // TODO .. } // ApplicationCreate creates a new Application @@ -78,11 +65,10 @@ func (s *Session) ApplicationCreate(ap *Application) (st *Application, err error } err = unmarshal(body, &st) - st.ses = s return } -// ApplicationEdit edits an existing Application +// ApplicationUpdate updates an existing Application // var : desc func (s *Session) ApplicationUpdate(appID string, ap *Application) (st *Application, err error) { @@ -98,7 +84,6 @@ func (s *Session) ApplicationUpdate(appID string, ap *Application) (st *Applicat } err = unmarshal(body, &st) - st.ses = s return } @@ -114,29 +99,6 @@ func (s *Session) ApplicationDelete(appID string) (err error) { return } -////////////////////////////////////////////////////////////////////////////// -// Below two functions are experimental ideas, they will absolutely change -// one way or another and may be deleted entirely. - -// Delete is a concept helper function, may be removed. -// this func depends on the Application.ses pointer -// pointing to the Discord session that the application -// came from. This "magic" makes some very very nice helper -// functions possible. -func (a *Application) Delete() (err error) { - if a.ses == nil { - return fmt.Errorf("ses is nil.") - } - return a.ses.ApplicationDelete(a.ID) -} - -// Delete is a concept helper function, may be removed. -// this one doesn't depend on the "magic" of adding the ses -// pointer to each Application -func (a *Application) DeleteB(s *Session) (err error) { - return s.ApplicationDelete(a.ID) -} - // ------------------------------------------------------------------------------------------------ // Code specific to Discord OAuth2 Application Bots // ------------------------------------------------------------------------------------------------ diff --git a/oauth2_test.go b/oauth2_test.go index ed252f7..96ad736 100644 --- a/oauth2_test.go +++ b/oauth2_test.go @@ -50,7 +50,7 @@ func ExampleApplication() { } // Delete the application we created. - err = ap.Delete() + err = dg.ApplicationDelete(ap.ID) log.Printf("Delete: err: %+v\n", err) return diff --git a/restapi.go b/restapi.go index f1674c9..3209cdd 100644 --- a/restapi.go +++ b/restapi.go @@ -462,7 +462,7 @@ func (s *Session) GuildEdit(guildID string, g GuildParams) (st *Guild, err error for _, r := range regions { valid = append(valid, r.ID) } - err = errors.New(fmt.Sprintf("Region not a valid region (%q)", valid)) + err = fmt.Errorf("Region not a valid region (%q)", valid) return } } diff --git a/structs.go b/structs.go index a51c0ac..6c0a1fb 100644 --- a/structs.go +++ b/structs.go @@ -118,14 +118,14 @@ type Channel struct { GuildID string `json:"guild_id"` Name string `json:"name"` Topic string `json:"topic"` + Type string `json:"type"` + LastMessageID string `json:"last_message_id"` Position int `json:"position"` Bitrate int `json:"bitrate"` - Type string `json:"type"` - PermissionOverwrites []*PermissionOverwrite `json:"permission_overwrites"` IsPrivate bool `json:"is_private"` - LastMessageID string `json:"last_message_id"` Recipient *User `json:"recipient"` Messages []*Message `json:"-"` + PermissionOverwrites []*PermissionOverwrite `json:"permission_overwrites"` } // A PermissionOverwrite holds permission overwrite data for a Channel @@ -145,7 +145,7 @@ type Emoji struct { RequireColons bool `json:"require_colons"` } -// Custom VerificationLevel typedef for int +// VerificationLevel type defination type VerificationLevel int // Constants for VerificationLevel levels from 0 to 3 inclusive @@ -302,10 +302,10 @@ type TypingStart struct { // A PresenceUpdate stores data for the presence update websocket event. type PresenceUpdate struct { - User *User `json:"user"` Status string `json:"status"` - Roles []string `json:"roles"` GuildID string `json:"guild_id"` + Roles []string `json:"roles"` + User *User `json:"user"` Game *Game `json:"game"` } diff --git a/voice.go b/voice.go index 926a90e..eec18f6 100644 --- a/voice.go +++ b/voice.go @@ -28,7 +28,7 @@ import ( // Code related to both VoiceConnection Websocket and UDP connections. // ------------------------------------------------------------------------------------------------ -// A VoiceConnectionConnection struct holds all the data and functions related to a Discord Voice Connection. +// A VoiceConnection struct holds all the data and functions related to a Discord Voice Connection. type VoiceConnection struct { sync.Mutex @@ -64,6 +64,8 @@ type VoiceConnection struct { voiceSpeakingUpdateHandlers []VoiceSpeakingUpdateHandler } +// VoiceSpeakingUpdateHandler type provides a function defination for the +// VoiceSpeakingUpdate event type VoiceSpeakingUpdateHandler func(vc *VoiceConnection, vs *VoiceSpeakingUpdate) // Speaking sends a speaking notification to Discord over the voice websocket. @@ -156,7 +158,7 @@ func (v *VoiceConnection) Close() { } } -// Adds a Handler for VoiceSpeakingUpdate events. +// AddHandler adds a Handler for VoiceSpeakingUpdate events. func (v *VoiceConnection) AddHandler(h VoiceSpeakingUpdateHandler) { v.Lock() defer v.Unlock() @@ -208,8 +210,6 @@ func (v *VoiceConnection) waitUntilConnected() error { time.Sleep(1 * time.Second) i++ } - - return nil } // Open opens a voice connection. This should be called From da732804b15d0faf7ff4aa1deb6d3a437acf685b Mon Sep 17 00:00:00 2001 From: Bruce Marriner Date: Mon, 11 Apr 2016 20:25:55 -0500 Subject: [PATCH 4/4] Added section for troubleshooting --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 7d0a678..bed8cf3 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,12 @@ an issue if you would like your project added or removed from this list - [GoGerard](https://github.com/GoGerard/GoGerard) A modern bot for Discord - [Digo](https://github.com/sethdmoore/digo) A pluggable bot for your Discord server +## Troubleshooting +For help with common problems please reference the +[Troubleshooting](https://github.com/bwmarrin/discordgo/wiki/Troubleshooting) +section of the project wiki. + + ## Contributing Contributions are very welcomed, however please follow the below guidelines.