diff --git a/structs.go b/structs.go index 762c27d..27b16e3 100644 --- a/structs.go +++ b/structs.go @@ -72,28 +72,24 @@ type Session struct { VoiceReady bool // Set to true when Voice Websocket is ready UDPReady bool // Set to true when UDP Connection is ready - // Other.. + // The websocket connection. wsConn *websocket.Conn - //TODO, add bools for like. - // are we connnected to websocket? - // have we authenticated to login? - // lets put all the general session - // tracking and infos here.. clearly - // Everything below here is used for Voice testing. - // This stuff is almost guarenteed to change a lot - // and is even a bit hackish right now. - Voice *Voice // Stores all details related to voice connections + // Stores all details related to voice connections + Voice *Voice // Managed state object, updated with events. - State *State - StateEnabled bool - StateMaxMessageCount int + State *State + StateEnabled bool // When nil, the session is not listening. listening chan interface{} + // Should the session reconnect the websocket on errors. ShouldReconnectOnError bool + + // Should the session request compressed websocket data. + Compress bool } // A VoiceRegion stores data for a specific voice region server. diff --git a/util.go b/util.go index 00ccb9d..20ab084 100644 --- a/util.go +++ b/util.go @@ -17,6 +17,12 @@ import ( "fmt" ) +// printEvent prints out a WSAPI event. +func printEvent(e *Event) { + fmt.Println(fmt.Sprintf("Event. Type: %s, State: %d Operation: %d Direction: %d", e.Type, e.State, e.Operation, e.Direction)) + printJSON(e.RawData) +} + // printJSON is a helper function to display JSON data in a easy to read format. func printJSON(body []byte) { var prettyJSON bytes.Buffer diff --git a/wsapi.go b/wsapi.go index ff9cfc1..03d987a 100644 --- a/wsapi.go +++ b/wsapi.go @@ -11,8 +11,13 @@ package discordgo import ( + "bytes" + "compress/zlib" + "encoding/json" "errors" "fmt" + "io" + "net/http" "runtime" "time" @@ -31,6 +36,7 @@ type handshakeData struct { Version int `json:"v"` Token string `json:"token"` Properties handshakeProperties `json:"properties"` + Compress bool `json:"compress"` } type handshakeOp struct { @@ -58,14 +64,17 @@ func (s *Session) Open() (err error) { return } + header := http.Header{} + header.Add("accept-encoding", "zlib") + // TODO: See if there's a use for the http response. // conn, response, err := websocket.DefaultDialer.Dial(session.Gateway, nil) - s.wsConn, _, err = websocket.DefaultDialer.Dial(g, nil) + s.wsConn, _, err = websocket.DefaultDialer.Dial(g, header) if err != nil { return } - err = s.wsConn.WriteJSON(handshakeOp{2, handshakeData{3, s.Token, handshakeProperties{runtime.GOOS, "Discordgo v" + VERSION, "", "", ""}}}) + err = s.wsConn.WriteJSON(handshakeOp{2, handshakeData{3, s.Token, handshakeProperties{runtime.GOOS, "Discordgo v" + VERSION, "", "", ""}, s.Compress}}) if err != nil { return } @@ -242,8 +251,8 @@ func (s *Session) UpdateStatus(idle int, game string) (err error) { func unmarshalEvent(event *Event, i interface{}) (err error) { if err = unmarshal(event.RawData, i); err != nil { - fmt.Println(event.Type, err) - printJSON(event.RawData) // TODO: Better error loggingEvent. + fmt.Println("Unable to unmarshal event data.") + printEvent(event) } return } @@ -256,17 +265,30 @@ func unmarshalEvent(event *Event, i interface{}) (err error) { // Events will be handled by any implemented handler in Session. // All unhandled events will then be handled by OnEvent. func (s *Session) event(messageType int, message []byte) (err error) { + var reader io.Reader + reader = bytes.NewBuffer(message) - if s.Debug { - printJSON(message) + if messageType == 2 { + z, err1 := zlib.NewReader(reader) + if err1 != nil { + fmt.Println(err1) + return err1 + } + defer z.Close() + reader = z } var e *Event - if err = unmarshal(message, &e); err != nil { + decoder := json.NewDecoder(reader) + if err = decoder.Decode(&e); err != nil { fmt.Println(err) return } + if s.Debug { + printEvent(e) + } + switch e.Type { case "READY": var st *Ready @@ -603,8 +625,8 @@ func (s *Session) event(messageType int, message []byte) (err error) { return } default: - fmt.Println("UNKNOWN EVENT: ", e.Type) - printJSON(message) + fmt.Println("Unknown Event.") + printEvent(e) } // if still here, send to generic OnEvent