-
Notifications
You must be signed in to change notification settings - Fork 0
/
gateway.v
115 lines (96 loc) · 2.48 KB
/
gateway.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
module vord
import net.websocket
import json
import time
const default_gateway = 'wss://gateway.discord.gg/?v=9&encoding=json'
struct GatewayPacket {
op byte [required]
d string [raw]
s u32 [required]
t string
}
struct HelloPacket {
heartbeat_interval u32 [required]
}
struct Resume {
token string [required]
session_id string [required]
seq int [required]
}
struct Identify {
token string [required]
properties IdentifyProperties [required]
}
struct IdentifyProperties {
os string [json: '\$os']
browser string [json: '\$browser']
device string [json: '\$device']
}
fn gateway_respond(mut ws websocket.Client, op byte, data string) ? {
ws.write_string('{"op":$op,"d":$data}') ?
}
pub fn create_ws(mut client &Client) ? {
client.ws = websocket.new_client(default_gateway) ?
client.ws.on_message_ref(ws_on_message, client)
client.ws.on_close_ref(ws_on_close, client)
}
fn ws_on_close(mut ws websocket.Client, reason int, message string, mut client &Client) ? {
lock client.hb {
if client.hb.is_open {
client.hb.is_open = false
client.hb_thread.wait() ?
}
}
}
fn ws_on_message(mut ws websocket.Client, msg &websocket.Message, mut client &Client) ? {
if msg.opcode != .text_frame {
return
}
payload_string := msg.payload.bytestr()
packet := json.decode(GatewayPacket, payload_string) ?
if packet.s != 0 {
client.seq = packet.s
}
match Op(packet.op) {
.dispatch {
event_func_name := 'on_$packet.t.to_lower()'
// also dispatch as raw event
handle_events(mut client, 'on_raw', payload_string) ?
handle_events(mut client, event_func_name, packet.d) ?
}
.hello {
hello := json.decode(HelloPacket, packet.d) ?
if client.resuming == true {
mut resume := Resume {
token: client.token,
session_id: client.sid,
seq: int(client.seq)
}
gateway_respond(mut &ws, 6, json.encode(resume)) ?
}
identify_packet := Identify{
token: client.token
properties: IdentifyProperties{
os: 'Linux'
browser: 'github/9xN'
device: 'vord'
}
}
gateway_respond(mut &ws, 2, json.encode(identify_packet)) ?
lock client.hb {
client.hb.is_open = true
}
client.hb_thread = go client.hb_proc(hello.heartbeat_interval * time.millisecond)
}
.heartbeat_ack {
if client.hb_last != 0 {
client.latency = u32(time.now().unix - client.hb_last)
}
}
.reconnect {
client.resuming = true
client.ws.close(1000, 'Reconnect') ?
}
else {}
}
}