Merge pull request #97 from iopred/compress
Support for compressed data in wsapi. Closes #40.
This commit is contained in:
commit
8453404305
3 changed files with 46 additions and 22 deletions
18
structs.go
18
structs.go
|
@ -72,28 +72,24 @@ type Session struct {
|
||||||
VoiceReady bool // Set to true when Voice Websocket is ready
|
VoiceReady bool // Set to true when Voice Websocket is ready
|
||||||
UDPReady bool // Set to true when UDP Connection is ready
|
UDPReady bool // Set to true when UDP Connection is ready
|
||||||
|
|
||||||
// Other..
|
// The websocket connection.
|
||||||
wsConn *websocket.Conn
|
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.
|
// Stores all details related to voice connections
|
||||||
// This stuff is almost guarenteed to change a lot
|
Voice *Voice
|
||||||
// and is even a bit hackish right now.
|
|
||||||
Voice *Voice // Stores all details related to voice connections
|
|
||||||
|
|
||||||
// Managed state object, updated with events.
|
// Managed state object, updated with events.
|
||||||
State *State
|
State *State
|
||||||
StateEnabled bool
|
StateEnabled bool
|
||||||
StateMaxMessageCount int
|
|
||||||
|
|
||||||
// When nil, the session is not listening.
|
// When nil, the session is not listening.
|
||||||
listening chan interface{}
|
listening chan interface{}
|
||||||
|
|
||||||
|
// Should the session reconnect the websocket on errors.
|
||||||
ShouldReconnectOnError bool
|
ShouldReconnectOnError bool
|
||||||
|
|
||||||
|
// Should the session request compressed websocket data.
|
||||||
|
Compress bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// A VoiceRegion stores data for a specific voice region server.
|
// A VoiceRegion stores data for a specific voice region server.
|
||||||
|
|
6
util.go
6
util.go
|
@ -17,6 +17,12 @@ import (
|
||||||
"fmt"
|
"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.
|
// printJSON is a helper function to display JSON data in a easy to read format.
|
||||||
func printJSON(body []byte) {
|
func printJSON(body []byte) {
|
||||||
var prettyJSON bytes.Buffer
|
var prettyJSON bytes.Buffer
|
||||||
|
|
40
wsapi.go
40
wsapi.go
|
@ -11,8 +11,13 @@
|
||||||
package discordgo
|
package discordgo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"compress/zlib"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
"runtime"
|
"runtime"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -31,6 +36,7 @@ type handshakeData struct {
|
||||||
Version int `json:"v"`
|
Version int `json:"v"`
|
||||||
Token string `json:"token"`
|
Token string `json:"token"`
|
||||||
Properties handshakeProperties `json:"properties"`
|
Properties handshakeProperties `json:"properties"`
|
||||||
|
Compress bool `json:"compress"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type handshakeOp struct {
|
type handshakeOp struct {
|
||||||
|
@ -58,14 +64,17 @@ func (s *Session) Open() (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
header := http.Header{}
|
||||||
|
header.Add("accept-encoding", "zlib")
|
||||||
|
|
||||||
// TODO: See if there's a use for the http response.
|
// TODO: See if there's a use for the http response.
|
||||||
// conn, response, err := websocket.DefaultDialer.Dial(session.Gateway, nil)
|
// 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 {
|
if err != nil {
|
||||||
return
|
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 {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -242,8 +251,8 @@ func (s *Session) UpdateStatus(idle int, game string) (err error) {
|
||||||
|
|
||||||
func unmarshalEvent(event *Event, i interface{}) (err error) {
|
func unmarshalEvent(event *Event, i interface{}) (err error) {
|
||||||
if err = unmarshal(event.RawData, i); err != nil {
|
if err = unmarshal(event.RawData, i); err != nil {
|
||||||
fmt.Println(event.Type, err)
|
fmt.Println("Unable to unmarshal event data.")
|
||||||
printJSON(event.RawData) // TODO: Better error loggingEvent.
|
printEvent(event)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -256,17 +265,30 @@ func unmarshalEvent(event *Event, i interface{}) (err error) {
|
||||||
// Events will be handled by any implemented handler in Session.
|
// Events will be handled by any implemented handler in Session.
|
||||||
// All unhandled events will then be handled by OnEvent.
|
// All unhandled events will then be handled by OnEvent.
|
||||||
func (s *Session) event(messageType int, message []byte) (err error) {
|
func (s *Session) event(messageType int, message []byte) (err error) {
|
||||||
|
var reader io.Reader
|
||||||
|
reader = bytes.NewBuffer(message)
|
||||||
|
|
||||||
if s.Debug {
|
if messageType == 2 {
|
||||||
printJSON(message)
|
z, err1 := zlib.NewReader(reader)
|
||||||
|
if err1 != nil {
|
||||||
|
fmt.Println(err1)
|
||||||
|
return err1
|
||||||
|
}
|
||||||
|
defer z.Close()
|
||||||
|
reader = z
|
||||||
}
|
}
|
||||||
|
|
||||||
var e *Event
|
var e *Event
|
||||||
if err = unmarshal(message, &e); err != nil {
|
decoder := json.NewDecoder(reader)
|
||||||
|
if err = decoder.Decode(&e); err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if s.Debug {
|
||||||
|
printEvent(e)
|
||||||
|
}
|
||||||
|
|
||||||
switch e.Type {
|
switch e.Type {
|
||||||
case "READY":
|
case "READY":
|
||||||
var st *Ready
|
var st *Ready
|
||||||
|
@ -603,8 +625,8 @@ func (s *Session) event(messageType int, message []byte) (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
fmt.Println("UNKNOWN EVENT: ", e.Type)
|
fmt.Println("Unknown Event.")
|
||||||
printJSON(message)
|
printEvent(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if still here, send to generic OnEvent
|
// if still here, send to generic OnEvent
|
||||||
|
|
Loading…
Reference in a new issue