@@ -47,12 +47,14 @@ export type C2RSocketData = {
47
47
originIP : IP | null // 客户端 IP 地址(若开启 ProxyProtocol 入站,从其中解析)
48
48
proxyProtocol : boolean | null // 是否启用 Proxy Protocol v2 出站
49
49
FML : 0 | 1 | 2 | null // 是否为 Forge Mod Loader (2) 客户端,0 代表非 FML
50
+ timeouts : NodeJS . Timer [ ] // 存储所有的 timeout
50
51
}
51
52
52
53
// Relay to server socket data
53
54
type R2SSocketData = {
54
55
client : Bun . Socket < C2RSocketData > | null // 客户端连接
55
56
sendBuffer : ArrayBufferSink // 发送缓冲区
57
+ timeouts : NodeJS . Timer [ ] // 存储所有的 timeout
56
58
}
57
59
58
60
const writeToBuffer = (
@@ -77,6 +79,10 @@ const sendBuffer = (
77
79
}
78
80
}
79
81
82
+ const clearAllTimeouts = ( timeouts : NodeJS . Timer [ ] ) => {
83
+ timeouts . forEach ( timeout => clearTimeout ( timeout ) )
84
+ }
85
+
80
86
export const InboundSchema = z
81
87
. object ( {
82
88
bind : z . string ( ) . default ( '0.0.0.0:25565' ) ,
@@ -142,6 +148,7 @@ export class MinecraftProxy {
142
148
remoteSocket . data = {
143
149
client : clientSocket ,
144
150
sendBuffer : new ArrayBufferSink ( ) ,
151
+ timeouts : [ ] ,
145
152
}
146
153
remoteSocket . data . sendBuffer . start ( {
147
154
asUint8Array : true ,
@@ -162,6 +169,7 @@ export class MinecraftProxy {
162
169
writeToBuffer ( clientSocket . data . remote , initPacket )
163
170
} ,
164
171
close : remoteSocket => {
172
+ remoteSocket . data . sendBuffer . end ( )
165
173
clientSocket . end ( )
166
174
} ,
167
175
end : remoteSocket => {
@@ -229,6 +237,7 @@ export class MinecraftProxy {
229
237
originIP : null ,
230
238
proxyProtocol : null ,
231
239
FML : null ,
240
+ timeouts : [ ] ,
232
241
}
233
242
234
243
logger . debug (
@@ -246,16 +255,19 @@ export class MinecraftProxy {
246
255
clientSocket . data . originIP = IP . parse ( clientSocket . remoteAddress )
247
256
248
257
// 若 3 秒内未成功读取握手包,则断开连接
249
- setTimeout ( ( ) => {
258
+ const handshakeTimeout = setTimeout ( ( ) => {
250
259
if ( clientSocket . data . state === null ) {
251
260
logger . warn (
252
261
`${ colorHash ( clientSocket . data . connId ) } Handshake timeout` ,
253
262
)
254
263
clientSocket . end ( )
255
264
}
256
265
} , 3000 )
266
+ clientSocket . data . timeouts . push ( handshakeTimeout )
257
267
} ,
258
268
close : async clientSocket => {
269
+ clientSocket . data . sendBuffer . end ( )
270
+ clearAllTimeouts ( clientSocket . data . timeouts )
259
271
if ( clientSocket . data . username ) {
260
272
this . onlinePlayers . delete ( clientSocket . data . username )
261
273
}
@@ -417,14 +429,15 @@ export class MinecraftProxy {
417
429
418
430
if ( nextState === State . Login ) {
419
431
// 若 3 秒内未成功读取登录包,则断开连接
420
- setTimeout ( ( ) => {
432
+ const loginTimeout = setTimeout ( ( ) => {
421
433
if ( clientSocket . data . state !== State . Play ) {
422
434
logger . warn (
423
435
`${ colorHash ( clientSocket . data . connId ) } Login timeout` ,
424
436
)
425
437
clientSocket . end ( )
426
438
}
427
439
} , 3000 )
440
+ clientSocket . data . timeouts . push ( loginTimeout )
428
441
}
429
442
}
430
443
} // 考虑一次发送两个数据包,应当直接在后面处理登录
0 commit comments