Skip to content

Commit 137f04f

Browse files
committed
rewrite in typescript
1 parent a177ea9 commit 137f04f

File tree

6 files changed

+201
-2
lines changed

6 files changed

+201
-2
lines changed

src/dispatch/.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
dist
2+
node_modules
3+
package-lock.json
4+
*/.DS_Store

src/dispatch/package.json

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"name": "dispatch",
3+
"version": "1.0.0",
4+
"description": "A tool for creating Discord modifications at the server side.",
5+
"main": "dist/index.js",
6+
"scripts": {
7+
"test": "echo \"Error: no test specified\" && exit 1",
8+
"start": "node ./dist/index.js"
9+
},
10+
"repository": {
11+
"type": "git",
12+
"url": "git+https://github.com/RedDaedalus/dispatch.git"
13+
},
14+
"keywords": [
15+
"discord",
16+
"dispatch",
17+
"proxy"
18+
],
19+
"author": "Daedalus",
20+
"license": "MIT",
21+
"bugs": {
22+
"url": "https://github.com/RedDaedalus/dispatch/issues"
23+
},
24+
"homepage": "https://github.com/RedDaedalus/dispatch#readme",
25+
"dependencies": {
26+
"@types/flake-idgen": "^0.1.30",
27+
"@types/pako": "^1.0.1",
28+
"@types/ws": "^7.4.0",
29+
"discord-api-types": "^0.12.1",
30+
"erlpack": "^0.1.3",
31+
"flake-idgen": "^1.4.0",
32+
"pako": "^1.0.11",
33+
"ws": "^7.4.4",
34+
"zlib-sync": "^0.1.7"
35+
}
36+
}

src/dispatch/src/gateway.ts

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import EventListener from "events"
2+
import WebSocket from "ws"
3+
import erlpack from "erlpack"
4+
import pako from "pako"
5+
import querystring from "querystring"
6+
7+
export class GatewayProxy extends EventListener {
8+
9+
constructor() {
10+
super()
11+
12+
const server = new WebSocket.Server({ port: 11000 })
13+
server.on("connection", (ws, req) => {
14+
const { encoding } = querystring.parse(req.url.substring(2))
15+
console.log("Starting new session")
16+
console.log(encoding)
17+
const session = new GatewaySession(ws, encoding as string)
18+
this.emit("session", session)
19+
console.log("New session")
20+
})
21+
}
22+
}
23+
24+
export class GatewaySession {
25+
26+
private inflate = new pako.Inflate()
27+
private deflate = new pako.Deflate()
28+
private encoding: string
29+
private wsRemote: WebSocket
30+
private wsLocal: WebSocket
31+
32+
constructor(ws: WebSocket, encoding: string) {
33+
this.encoding = encoding
34+
this.wsRemote = new WebSocket(`wss://gateway.discord.gg/?v=8&encoding=${encoding}&compress=zlib-stream`)
35+
this.wsLocal = ws
36+
37+
this.wsRemote.on("message", (chunk: Buffer) => {
38+
this.inflate.push(chunk, 2)
39+
const result = Buffer.from(this.inflate.result)
40+
41+
this.deflate.push(result, 2)
42+
const outgoing = Buffer.from(this.deflate.result)
43+
44+
this.wsLocal.send(outgoing, e => e ? console.error(e) : undefined)
45+
})
46+
this.wsRemote.on("close", (code, reason) => console.log(`Closed: ${code} ${reason}`))
47+
this.wsLocal.on("message", (chunk: Buffer) => {
48+
this.wsRemote.send(chunk, e => e ? console.error(e) : undefined)
49+
})
50+
}
51+
52+
send(event: string, data: any) {
53+
if (!data.op) data = { op: 0, d: data, s: null, t: event }
54+
55+
let message
56+
if (this.encoding === "etf") {
57+
message = erlpack.pack(data)
58+
} else if (this.encoding === "json") {
59+
message = Buffer.from(JSON.stringify(data))
60+
}
61+
this.deflate.push(message, 2)
62+
this.wsLocal.send(Buffer.from(this.deflate.result))
63+
}
64+
}
65+
66+
export enum PacketDirection {
67+
68+
Incoming = 0,
69+
Outgoing = 1
70+
}

src/dispatch/src/index.ts

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import * as ws from "./gateway"
2+
import FlakeId from "flake-idgen"
3+
4+
const proxy = new ws.GatewayProxy()
5+
const snowflakeGen = new FlakeId()
6+
7+
proxy.on("session", session => {
8+
setTimeout(() => { // Settimeout bc I don't have an events system to wait for ready lol
9+
console.log("Sending artificial message")
10+
session.send("MESSAGE_CREATE", {
11+
id: snowflakeGen.next().readBigInt64BE().toString(),
12+
channel_id: "821523237409914910",
13+
guild_id: "758105437244489799",
14+
author: {
15+
id: "820091309565280306",
16+
username: "Dispatch",
17+
discriminator: "0001",
18+
avatar: "52abf38a25c1a8ca15333a6eeaa727e1",
19+
bot: true,
20+
system: true,
21+
flags: (1 << 12) | (1 << 16)
22+
},
23+
member: {
24+
roles: [],
25+
joined_at: new Date().toString(),
26+
deaf: false,
27+
mute: false
28+
},
29+
timestamp: new Date().toString(),
30+
edited_timestamp: null,
31+
tts: false,
32+
mention_everyone: false,
33+
mentions: [],
34+
mention_roles: [],
35+
mention_channels: [],
36+
attachments: [],
37+
embeds: [{
38+
title: "» Dispatch",
39+
description: "Dispatch is a modding engine for Discord that doesn't require modification of the client.",
40+
type: "rich",
41+
fields: [{
42+
name: "Current Version",
43+
value: "0.0.1",
44+
inline: true
45+
}, {
46+
name: "Website",
47+
value: "https://dispatch.co",
48+
inline: true
49+
}, {
50+
name: "Source",
51+
value: "[GitHub Repo](https://github.com/discord-dispatch/dispatch)",
52+
inline: true
53+
}],
54+
footer: {
55+
text: "Developed by Daedalus#0001 under the MIT license"
56+
},
57+
color: 0x7289DA,
58+
timestamp: new Date().toString()
59+
}],
60+
pinned: false,
61+
type: 0,
62+
flags: 1 << 6,
63+
interaction: {
64+
id: snowflakeGen.next().readBigInt64BE().toString(),
65+
type: 2,
66+
name: "info",
67+
user: {
68+
id: "268071134057070592",
69+
username: "Daedalus",
70+
discriminator: "0001",
71+
avatar: "a_4ae268f6dbb3adfb9c1c45461263ce8d",
72+
bot: false,
73+
flags: (1 << 8) | (1 << 9) | (1 << 17),
74+
}
75+
}
76+
})
77+
}, 10_000)
78+
})

src/dispatch/tsconfig.json

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"compilerOptions": {
3+
"module": "commonjs",
4+
"esModuleInterop": true,
5+
"target": "es2020",
6+
"moduleResolution": "node",
7+
"sourceMap": true,
8+
"outDir": "dist"
9+
},
10+
"lib": ["es2020"]
11+
}

src/index.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ async function handleRequest(request) {
4141
return quoteMessage(body)
4242
} else {
4343
return new Response(JSON.stringify({
44-
type: 3,
44+
type: 4,
4545
data: {
4646
flags: 64,
4747
content: `
@@ -68,7 +68,7 @@ Click [here](https://discord.com/api/oauth2/authorize?client_id=8128922189257769
6868
*/
6969
async function error(message) {
7070
return new Response(JSON.stringify({
71-
type: 3,
71+
type: 4,
7272
data: {
7373
flags: 64,
7474
content: `**Error:** ${message}`

0 commit comments

Comments
 (0)