master
Raw Download raw file
  1package main
  2
  3import (
  4	"encoding/json"
  5	"github.com/gorilla/websocket"
  6	"go.uber.org/zap"
  7	"strconv"
  8	"time"
  9)
 10
 11type GeneralsIO struct {
 12	*websocket.Conn
 13	Updates chan<- Update
 14	Games   chan<- Game
 15}
 16
 17const (
 18	ENGINEIO_OPEN    = 0
 19	ENGINEIO_CLOSE   = 1
 20	ENGINEIO_PING    = 2
 21	ENGINEIO_PONG    = 3
 22	ENGINEIO_MESSAGE = 4
 23	SOCKETIO_CONNECT = 0
 24	SOCKETIO_EVENT   = 2
 25)
 26
 27// Packet > Message > Event
 28
 29type Packet struct {
 30	Type        int
 31	MessageType int
 32	Payload     []byte
 33}
 34
 35func (g *GeneralsIO) Connect() (err error) {
 36	dialer := &websocket.Dialer{}
 37	dialer.EnableCompression = false
 38	generals_url := "ws://botws.generals.io/socket.io/?EIO=3&transport=websocket"
 39	conn, _, err := dialer.Dial(generals_url, nil)
 40	if err != nil {
 41		return err
 42	}
 43	g.Conn = conn
 44	return err
 45}
 46
 47func (g *GeneralsIO) Emit(msg ...interface{}) error {
 48	w, err := g.NextWriter(websocket.TextMessage)
 49	if err != nil {
 50		return err
 51	}
 52	_, err = w.Write([]byte("42"))
 53	j := json.NewEncoder(w)
 54	return j.Encode(msg)
 55}
 56
 57func (g *GeneralsIO) Ping(t int) {
 58	for range time.Tick(time.Duration(t) * time.Second) {
 59		l.Debug("Ping")
 60		w, err := g.NextWriter(websocket.TextMessage)
 61		if err != nil {
 62			l.Fatal(err)
 63		}
 64		_, err = w.Write([]byte("2ping"))
 65		if err != nil {
 66			l.Fatal(err)
 67		}
 68	}
 69}
 70
 71func DecodePacket(b []byte) (p Packet, err error) {
 72	// TODO: b > 0
 73	t, err := strconv.Atoi(string(b[0]))
 74	if err != nil {
 75		return p, err
 76	}
 77
 78	switch t {
 79	case ENGINEIO_OPEN, ENGINEIO_CLOSE, ENGINEIO_PING, ENGINEIO_PONG:
 80		p.Type = t
 81		p.Payload = b[1:]
 82	case ENGINEIO_MESSAGE:
 83		p.Type = t
 84		mt, err := strconv.Atoi(string(b[1]))
 85		if err != nil {
 86			return p, err
 87		}
 88		p.MessageType = mt
 89		p.Payload = b[2:]
 90	}
 91	return
 92}
 93
 94func (g *GeneralsIO) RecievePackets() {
 95	for {
 96		_, packet, err := g.ReadMessage()
 97		if err != nil {
 98			l.Fatal(err)
 99		}
100		p, err := DecodePacket(packet)
101		if err != nil {
102			l.Fatal(err)
103		}
104		switch p.Type {
105		case ENGINEIO_PONG:
106			l.Debug("Pong")
107		case ENGINEIO_OPEN:
108			l.Info("Open", zap.String("packet", string(p.Payload)))
109		case ENGINEIO_MESSAGE:
110			switch p.MessageType {
111			case SOCKETIO_CONNECT:
112				l.Debug("Connected")
113			case SOCKETIO_EVENT:
114				// generals.go
115				err = DecodeEvent(p.Payload, g.Updates, g.Games)
116				if err != nil {
117					l.Error("Unhandled Event", zap.String("packet", string(packet)), zap.Error(err))
118				}
119			default:
120				l.Error("Unhandled Message", zap.String("packet", string(packet)))
121			}
122		default:
123			l.Error("Unhandled Packet", zap.String("packet", string(packet)))
124		}
125
126	}
127
128}