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
+ }
0 commit comments