1
1
import type { Logger } from 'winston' ;
2
+ import { IpV4Addr , IpV6Addr } from './ip-addr' ;
3
+ import type { IpAddr } from './ip-addr' ;
2
4
import type Processor from './Processor' ;
3
5
import { AudioNotFoundResult , ThrottledUidResult , UnknownUidResult } from './Processor' ;
4
6
import type Stream from './Stream' ;
@@ -7,16 +9,26 @@ export enum Command {
7
9
checkUid = 0 ,
8
10
getAudio = 1 ,
9
11
ping = 2 ,
12
+ quit = 3 ,
10
13
}
11
14
12
- export enum Response {
15
+ export enum AuthResponse {
13
16
invalidAuth = 0 ,
14
17
validAuth = 1 ,
18
+ }
19
+
20
+ export enum CheckUidResponse {
15
21
unknownUid = 0 ,
16
22
throttledUid = 2 ,
17
23
validUid = 1 ,
24
+ }
25
+
26
+ export enum GetAudioResponse {
18
27
audioNotFound = 0 ,
19
28
audioFound = 1 ,
29
+ }
30
+
31
+ export enum PingResponse {
20
32
pong = 0 ,
21
33
}
22
34
@@ -39,25 +51,39 @@ const handleClient = async (
39
51
} , authTimeout ) ;
40
52
} ) ,
41
53
( async ( ) => {
42
- const credentialsLength = await stream . readUint8 ( ) ;
43
- const credentials = ( await stream . readExact ( credentialsLength ) ) . toString ( 'ascii ' ) ;
54
+ const clientIdLength = await stream . readUint8 ( ) ;
55
+ const clientId = ( await stream . readExact ( clientIdLength ) ) . toString ( 'utf-8 ' ) ;
44
56
45
- if ( ! credentials . includes ( ':' ) ) {
46
- logger ?. info ( 'Malformed credentials' ) ;
47
- stream . writeUint8 ( Response . invalidAuth ) ;
48
- return null ;
57
+ const secretLength = await stream . readUint8 ( ) ;
58
+ const secret = ( await stream . readExact ( secretLength ) ) . toString ( 'utf-8' ) ;
59
+
60
+ const inetVersion = await stream . readUint8 ( ) ;
61
+ let localIp : IpAddr ;
62
+
63
+ switch ( inetVersion ) {
64
+ case 4 :
65
+ localIp = new IpV4Addr ( await stream . readExact ( 4 ) ) ;
66
+ break ;
67
+
68
+ case 6 :
69
+ localIp = new IpV6Addr ( await stream . readExact ( 16 ) ) ;
70
+ break ;
71
+
72
+ default :
73
+ logger ?. info ( `Invalid INET version "${ inetVersion } "` ) ;
74
+ stream . writeUint8 ( AuthResponse . invalidAuth ) ;
75
+ return null ;
49
76
}
50
77
51
- const [ clientId , secret ] = credentials . split ( ':' , 2 ) ;
52
- const authResult = await processor . authenticate ( clientId , secret ) ;
78
+ const authResult = await processor . authenticate ( clientId , secret , localIp ) ;
53
79
54
80
if ( ! authResult ) {
55
81
logger ?. info ( `Unknown client ID "${ clientId } " or invalid secret` ) ;
56
- stream . writeUint8 ( Response . invalidAuth ) ;
82
+ stream . writeUint8 ( AuthResponse . invalidAuth ) ;
57
83
return null ;
58
84
}
59
85
60
- stream . writeUint8 ( Response . validAuth ) ;
86
+ stream . writeUint8 ( AuthResponse . validAuth ) ;
61
87
return clientId ;
62
88
} ) ( ) ,
63
89
] ) ;
@@ -83,16 +109,16 @@ const handleClient = async (
83
109
const response = await processor . checkUid ( clientId , uid ) ;
84
110
85
111
if ( response instanceof UnknownUidResult ) {
86
- stream . writeUint8 ( Response . unknownUid ) ;
112
+ stream . writeUint8 ( CheckUidResponse . unknownUid ) ;
87
113
break ;
88
114
}
89
115
90
116
if ( response instanceof ThrottledUidResult ) {
91
- stream . writeUint8 ( Response . throttledUid ) ;
117
+ stream . writeUint8 ( CheckUidResponse . throttledUid ) ;
92
118
break ;
93
119
}
94
120
95
- stream . writeUint8 ( Response . validUid ) ;
121
+ stream . writeUint8 ( CheckUidResponse . validUid ) ;
96
122
stream . writeUint8 ( response . achievementIds . length ) ;
97
123
98
124
for ( const achievementId of response . achievementIds ) {
@@ -107,20 +133,23 @@ const handleClient = async (
107
133
const result = await processor . getAudio ( id ) ;
108
134
109
135
if ( result instanceof AudioNotFoundResult ) {
110
- stream . writeUint8 ( Response . audioNotFound ) ;
136
+ stream . writeUint8 ( GetAudioResponse . audioNotFound ) ;
111
137
break ;
112
138
}
113
139
114
- stream . writeUint8 ( Response . audioFound ) ;
140
+ stream . writeUint8 ( GetAudioResponse . audioFound ) ;
115
141
stream . writeUInt32LE ( result . data . length ) ;
116
142
stream . writeAll ( result . data ) ;
117
143
break ;
118
144
}
119
145
120
146
case Command . ping :
121
- stream . writeUint8 ( Response . pong ) ;
147
+ stream . writeUint8 ( PingResponse . pong ) ;
122
148
break ;
123
149
150
+ case Command . quit :
151
+ return ;
152
+
124
153
default :
125
154
logger ?. info ( `Unknown command: ${ commandCode } ` ) ;
126
155
return ;
0 commit comments