This repository has been archived by the owner on Apr 13, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gateway.v
118 lines (99 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
116
117
118
module vcord
import net.websocket
import json
import os { user_os }
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]
intents Intent [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 bot &Bot) ? {
bot.ws = websocket.new_client(default_gateway) ?
bot.ws.on_message_ref(ws_on_message, bot)
bot.ws.on_close_ref(ws_on_close, bot)
}
fn ws_on_close(mut ws websocket.Client, reason int, message string, mut bot &Bot) ? {
lock bot.hb {
if bot.hb.is_open {
bot.hb.is_open = false
bot.hb_thread.wait() ?
}
}
}
fn ws_on_message(mut ws websocket.Client, msg &websocket.Message, mut bot &Bot) ? {
if msg.opcode != .text_frame {
return
}
payload_string := msg.payload.bytestr()
packet := json.decode(GatewayPacket, payload_string) ?
if packet.s != 0 {
bot.seq = packet.s
}
match Op(packet.op) {
.dispatch {
event_func_name := 'on_$packet.t.to_lower()'
// also dispatch as raw event
handle_events(mut bot, 'on_raw', payload_string) ?
handle_events(mut bot, event_func_name, packet.d) ?
}
.hello {
hello := json.decode(HelloPacket, packet.d) ?
if bot.resuming == true {
mut resume := Resume {
token: bot.token,
session_id: bot.sid,
seq: int(bot.seq)
}
gateway_respond(mut &ws, 6, json.encode(resume)) ?
}
identify_packet := Identify{
token: bot.token
properties: IdentifyProperties{
os: user_os()
browser: 'valkyria'
device: 'valkyria'
}
intents: bot.intents
}
gateway_respond(mut &ws, 2, json.encode(identify_packet)) ?
lock bot.hb {
bot.hb.is_open = true
}
bot.hb_thread = go bot.hb_proc(hello.heartbeat_interval * time.millisecond)
}
.heartbeat_ack {
if bot.hb_last != 0 {
bot.latency = u32(time.now().unix - bot.hb_last)
}
}
.reconnect {
bot.resuming = true
bot.ws.close(1000, 'Reconnect') ?
}
else {}
}
}