about summary refs log tree commit diff
path: root/pkg/discord/gateway.go
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2022-04-08 12:54:09 +0200
committerMel <einebeere@gmail.com>2022-04-08 12:54:09 +0200
commit24f175df385466e04ef21d153713d2ecf3a9733b (patch)
tree1c5c6253a22804697462d3fb9e9f3189af15c286 /pkg/discord/gateway.go
parent18389cf659c40cebc4572924929abfcec3c6b875 (diff)
downloadjinx-24f175df385466e04ef21d153713d2ecf3a9733b.tar.zst
jinx-24f175df385466e04ef21d153713d2ecf3a9733b.zip
Subdivide discord into packages
Diffstat (limited to 'pkg/discord/gateway.go')
-rw-r--r--pkg/discord/gateway.go201
1 files changed, 0 insertions, 201 deletions
diff --git a/pkg/discord/gateway.go b/pkg/discord/gateway.go
deleted file mode 100644
index 32a1e99..0000000
--- a/pkg/discord/gateway.go
+++ /dev/null
@@ -1,201 +0,0 @@
-package discord
-
-import (
-	"context"
-	"encoding/json"
-	"fmt"
-	"jinx/pkg/libs/cancellablewebsocket"
-	"net/http"
-
-	"github.com/gorilla/websocket"
-	"github.com/rs/zerolog"
-)
-
-type Gateway interface {
-	Start(ctx context.Context, url string, token string) error
-	Close() error
-
-	Heartbeat() error
-}
-
-var _ Gateway = &GatewayImpl{}
-
-type GatewayImpl struct {
-	ctx          context.Context
-	logger       *zerolog.Logger
-	conn         *cancellablewebsocket.CancellableWebSocket
-	heartbeat    Heartbeat
-	eventHandler EventHandler
-	lastSeq      uint64
-}
-
-func NewGateway(logger *zerolog.Logger, eventHandler EventHandler) *GatewayImpl {
-	gateway := &GatewayImpl{
-		ctx:          nil,
-		logger:       logger,
-		conn:         nil,
-		eventHandler: eventHandler,
-		heartbeat:    nil,
-		lastSeq:      0,
-	}
-
-	// Cycle dependency, is this the best way to do this?
-	heartbeat := NewHeartbeat(logger, gateway)
-	gateway.heartbeat = heartbeat
-
-	return gateway
-}
-
-func (g *GatewayImpl) Start(ctx context.Context, url string, token string) error {
-	connectHeader := http.Header{}
-	conn, err := cancellablewebsocket.Dial(websocket.DefaultDialer, ctx, url, connectHeader)
-	if err != nil {
-		return err
-	}
-
-	g.conn = conn
-	g.ctx = ctx
-
-	hello, err := g.hello()
-	if err != nil {
-		return err
-	}
-
-	g.heartbeat.Start(ctx, hello.HeartbeatInterval)
-
-	if err = g.identify(token); err != nil {
-		return err
-	}
-
-	go g.listen()
-
-	return nil
-}
-
-func (g *GatewayImpl) Close() error {
-	return g.conn.Close()
-}
-
-func (g *GatewayImpl) Heartbeat() error {
-	msg := GatewayPayload[uint64]{
-		Op:   GATEWAY_OP_HEARTBEAT,
-		Data: g.lastSeq,
-	}
-
-	return g.send(msg)
-}
-
-func (g *GatewayImpl) hello() (GatewayHelloEvent, error) {
-	var msg GatewayPayload[GatewayHelloEvent]
-	if err := receive(g, &msg); err != nil {
-		return GatewayHelloEvent{}, err
-	}
-
-	if msg.Op != GATEWAY_OP_HELLO {
-		return GatewayHelloEvent{}, fmt.Errorf("expected opcode %d, got %d", GATEWAY_OP_HELLO, msg.Op)
-	}
-
-	return msg.Data, nil
-}
-
-func (g *GatewayImpl) identify(token string) error {
-	msg := GatewayPayload[GatewayIdentifyMsg]{
-		Op: GATEWAY_OP_IDENTIFY,
-		Data: GatewayIdentifyMsg{
-			Token:   token,
-			Intents: 13991,
-			Properties: GatewayIdentifyProperties{
-				OS:      "linux",
-				Browser: "jinx",
-				Device:  "jinx",
-			},
-		},
-		Sequence: 0,
-	}
-
-	if err := g.send(msg); err != nil {
-		return err
-	}
-
-	var res GatewayPayload[GatewayReadyEvent]
-	if err := receive(g, &res); err != nil {
-		return err
-	}
-
-	g.logger.Debug().Msgf("identify response payload: %+v", res)
-
-	if res.Op != GATEWAY_OP_DISPATCH {
-		return fmt.Errorf("expected opcode %d, got %d", GATEWAY_OP_DISPATCH, res.Op)
-	}
-
-	if res.EventName != "READY" {
-		return fmt.Errorf("expected event name %s, got %s", "READY", res.EventName)
-	}
-
-	return nil
-}
-
-func (g *GatewayImpl) listen() {
-	for {
-		var msg GatewayPayload[json.RawMessage]
-		if err := receive(g, &msg); err != nil {
-			g.logger.Error().Err(err).Msgf("error reading message")
-			continue
-		}
-
-		select {
-		case <-g.ctx.Done():
-			return
-		default:
-			g.onEvent(msg)
-		}
-	}
-}
-
-func (g *GatewayImpl) onEvent(msg GatewayPayload[json.RawMessage]) error {
-	switch msg.Op {
-	case GATEWAY_OP_HEARTBEAT_ACK:
-		g.heartbeat.Ack()
-	case GATEWAY_OP_HEARTBEAT:
-		g.heartbeat.ForceHeartbeat()
-	case GATEWAY_OP_DISPATCH:
-		return g.onDispatch(msg.EventName, msg.Data)
-	default:
-		g.logger.Warn().Msgf("received unknown opcode: %d", msg.Op)
-	}
-
-	return nil
-}
-
-func (g *GatewayImpl) onDispatch(eventName string, body json.RawMessage) error {
-	switch eventName {
-	case "MESSAGE_CREATE":
-		var payload GatewayMessageCreateEvent
-		if err := json.Unmarshal(body, &payload); err != nil {
-			return err
-		}
-
-		g.eventHandler.Fire(DISCORD_EVENT_MESSAGE, payload)
-	default:
-		g.logger.Warn().Msgf("received unknown event: %s", eventName)
-	}
-
-	return nil
-}
-
-func (g *GatewayImpl) send(payload any) error {
-	return g.conn.WriteJSON(payload)
-}
-
-func receive[D any](g *GatewayImpl, res *GatewayPayload[D]) error {
-	err := g.conn.ReadJSON(&res)
-	if err != nil {
-		return err
-	}
-
-	if res.Sequence != 0 {
-		g.lastSeq = res.Sequence
-	}
-
-	return nil
-}