blob: 73d45badb7b8b16daaf95e2d4d0bc956569a3e00 (
plain)
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
|
_atrocity_prepare() {
ATROCITY_SESSION="$(mktemp -d)"
export ATROCITY_SESSION
atrocity_debug "Preparing session in $ATROCITY_SESSION"
# shellcheck disable=SC2064
trap "rm -fr '$ATROCITY_SESSION'" EXIT
mkdir "$ATROCITY_SESSION"/online
printf null >"$ATROCITY_SESSION"/sequence
mkdir "$ATROCITY_SESSION"/write-queue
mkdir "$ATROCITY_SESSION"/write-buffer
echo 10 >"$ATROCITY_SESSION"/heartbeat-interval
}
atrocity_connect() {
if [ -e "$ATROCITY_SESSION"/connection-started ]; then
atrocity_debug "Atrocity loop has already been set up"
exit 1
fi
touch "$ATROCITY_SESSION"/connection-started
mkfifo "$ATROCITY_SESSION"/raw-write-queue
mkfifo "$ATROCITY_SESSION"/raw-read-queue
(
atrocity_debug "Write queue started" "$ATROCITY_SESSION/raw-write-queue"
while atrocity_is_online; do
find "$ATROCITY_SESSION"/write-queue -type l |
while read -r message; do
cat "$message"
atrocity_debug "Sending message $message: $(cat -- "$message")"
rm -f "$(readlink -f "$message")"
rm -f "$message"
done
done >"$ATROCITY_SESSION/raw-write-queue"
atrocite_debug "Exiting write queue"
) &
(
atrocity_debug "Heartbeat queue started"
while atrocity_is_online; do
atrocity_heartbeat
sleep "$(cat "$ATROCITY_SESSION"/heartbeat-interval)"
done
) &
(
atrocity_debug "Websocket connected"
websocat wss://gateway.discord.gg/
atrocity_debug "Websocket disconnected"
) <"$ATROCITY_SESSION/raw-write-queue" >"$ATROCITY_SESSION/raw-read-queue" &
}
atrocity_heartbeat() {
atrocity_debug "Heartbeating"
atrocity_gateway_send_raw '{"op":1,"d":'"$(atrocity_sequence_get)"'}'
}
atrocity_gateway_send_raw() {
local file
file="$(mktemp -p "$ATROCITY_SESSION"/write-buffer)"
printf "%s\n" "${*}" >"$file"
ln -s "$file" "$ATROCITY_SESSION/write-queue"
}
atrocity_sequence_get() {
cat "$ATROCITY_SESSION"/sequence
}
atrocity_is_online() {
[[ -d "$ATROCITY_SESSION"/online ]]
return $?
}
atrocity_loop() {
if ! [ -e "$ATROCITY_SESSION"/connection-started ]; then
atrocity_debug "Atrocity loop started before connection has been set up"
exit 1
fi
atrocity_debug "Loop started"
while true; do
local line
local operator
atrocity_debug "Trying to read line"
if read -r line; then
atrocity_debug "Reading message from discord: $line"
printf %s "$line" | jq 'if .s then .s else '"$(atrocity_sequence_get)"' end' >"$ATROCITY_SESSION"/sequence
operator="$(printf %s "$line" | jq .op)"
case "$operator" in
9) # Invalid session
atrocity_debug "Received invalid session: $line"
exit 1
;;
10) # Hello
atrocity_debug "Sending hello"
echo "$(($(printf "%s" "$line" | jq -r .d.heartbeat_interval) / 1000))" >"$ATROCITY_SESSION"/heartbeat-interval
atrocity_gateway_send_raw '{"op":2,"d":{"token":"'$ATROCITY_TOKEN'", "properties":{"os":"linux","browser":"bash","device":"bash"},"presence":{"status":"online","afk":false, "activities":[{"type":0,"name":"Being coded in Bash"}]}, "intents":33287}}'
;;
0) # Dispatch
atrocity_dispatch "$line"
;;
1) # Heartbeat
atrocity_heartbeat
;;
11) # Heartbeat ACK
# TODO: Check for zombie connections
atrocity_debug "Heartbeat ACK"
;;
*)
atrocity_debug "Unhandled operator $operator"
;;
esac
fi
done <"$ATROCITY_SESSION"/raw-read-queue
}
|