Przeglądaj źródła

Merge pull request #97 from iopred/compress

Support for compressed data in wsapi. Closes #40.
Bruce 9 lat temu
rodzic
commit
8453404305
3 zmienionych plików z 46 dodań i 22 usunięć
  1. 9 13
      structs.go
  2. 6 0
      util.go
  3. 31 9
      wsapi.go

+ 9 - 13
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.

+ 6 - 0
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

+ 31 - 9
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