44 HttpRequest ,
55 HttpResponse ,
66 SSLApp ,
7+ WebSocket ,
78 us_listen_socket ,
89 us_socket_context_t ,
910} from 'uWebSockets.js'
@@ -38,7 +39,9 @@ import { EntityManager } from '@shared/system/EntityManager.js'
3839import { MessageListComponent } from '@shared/component/MessageComponent.js'
3940import { ChatComponent } from '../../component/tag/TagChatComponent.js'
4041import { WebSocketComponent } from '../../component/WebsocketComponent.js'
41- type MessageHandler = ( ws : any , message : any ) => void
42+
43+ type PlayerData = { player ?: Player }
44+ type MessageHandler = ( ws : WebSocket < PlayerData > , message : ClientMessage ) => void
4245
4346export class WebsocketSystem {
4447 private port : number = 8001
@@ -132,7 +135,7 @@ export class WebsocketSystem {
132135 res . end ( JSON . stringify ( healthData ) )
133136 } )
134137
135- app . ws ( '/*' , {
138+ app . ws < PlayerData > ( '/*' , {
136139 idleTimeout : 32 ,
137140 maxBackpressure : 1024 ,
138141 maxPayloadLength : 512 ,
@@ -160,8 +163,8 @@ export class WebsocketSystem {
160163 return
161164 }
162165
163- res . upgrade (
164- { } , // WebSocket handler will go here
166+ res . upgrade < PlayerData > (
167+ { } ,
165168 req . getHeader ( 'sec-websocket-key' ) ,
166169 req . getHeader ( 'sec-websocket-protocol' ) ,
167170 req . getHeader ( 'sec-websocket-extensions' ) ,
@@ -178,15 +181,21 @@ export class WebsocketSystem {
178181 }
179182
180183 private initializeMessageHandlers ( ) {
181- this . addMessageHandler ( ClientMessageType . INPUT , this . handleInputMessage . bind ( this ) )
182- this . addMessageHandler ( ClientMessageType . CHAT_MESSAGE , this . handleChatMessage . bind ( this ) )
184+ this . addMessageHandler (
185+ ClientMessageType . INPUT ,
186+ this . handleInputMessage . bind ( this ) as MessageHandler
187+ )
188+ this . addMessageHandler (
189+ ClientMessageType . CHAT_MESSAGE ,
190+ this . handleChatMessage . bind ( this ) as MessageHandler
191+ )
183192 this . addMessageHandler (
184193 ClientMessageType . PROXIMITY_PROMPT_INTERACT ,
185- this . handleProximityPromptInteractMessage . bind ( this )
194+ this . handleProximityPromptInteractMessage . bind ( this ) as MessageHandler
186195 )
187196 this . addMessageHandler (
188197 ClientMessageType . SET_PLAYER_NAME ,
189- this . handleSetPlayerNameMessage . bind ( this )
198+ this . handleSetPlayerNameMessage . bind ( this ) as MessageHandler
190199 )
191200 }
192201
@@ -198,8 +207,8 @@ export class WebsocketSystem {
198207 this . messageHandlers . delete ( type )
199208 }
200209
201- private onMessage ( ws : any , message : any ) {
202- const clientMessage : ClientMessage = unpack ( message )
210+ private onMessage ( ws : WebSocket < PlayerData > , message : ArrayBuffer ) {
211+ const clientMessage : ClientMessage = unpack ( Buffer . from ( message ) )
203212 const handler = this . messageHandlers . get ( clientMessage . t )
204213 if ( handler ) {
205214 handler ( ws , clientMessage )
@@ -209,12 +218,12 @@ export class WebsocketSystem {
209218 // TODO: Create EventOnPlayerConnect and EventOnPlayerDisconnect to respects ECS
210219 // Might be useful to query the chat and send a message to all players when a player connects or disconnects
211220 // Also could append scriptable events to be triggered on connect/disconnect depending on the game
212- private async onConnect ( ws : any ) {
221+ private async onConnect ( ws : WebSocket < PlayerData > ) {
213222 const ipBuffer = ws . getRemoteAddressAsText ( ) as ArrayBuffer
214223 const ip = Buffer . from ( ipBuffer ) . toString ( )
215224 if ( await this . isRateLimited ( ip ) ) {
216225 // Respond to the client indicating that the connection is rate limited
217- return ws . close ( 429 , 'Rate limit exceeded' )
226+ return ws . close ( )
218227 }
219228 const player = new Player ( ws , Math . random ( ) * 5 , 5 , Math . random ( ) * 5 )
220229 const connectionMessage : ConnectionMessage = {
@@ -223,7 +232,7 @@ export class WebsocketSystem {
223232 tickRate : config . SERVER_TICKRATE ,
224233 }
225234 // player.entity.addComponent(new RandomizeComponent(player.entity.id))
226- ws . player = player
235+ ws . getUserData ( ) . player = player
227236 ws . send ( NetworkSystem . compress ( connectionMessage ) , true )
228237
229238 EventSystem . addEvent (
@@ -236,12 +245,12 @@ export class WebsocketSystem {
236245 this . players . push ( player )
237246 }
238247
239- private onDrain ( ws : any ) {
248+ private onDrain ( ws : WebSocket < PlayerData > ) {
240249 console . log ( 'WebSocket backpressure: ' + ws . getBufferedAmount ( ) )
241250 }
242251
243- private onClose ( ws : any ) {
244- const disconnectedPlayer : Player = ws . player
252+ private onClose ( ws : WebSocket < PlayerData > ) {
253+ const disconnectedPlayer = ws . getUserData ( ) . player
245254 if ( ! disconnectedPlayer ) {
246255 console . error ( 'Disconnect: Player not found?' , ws )
247256 return
@@ -260,8 +269,8 @@ export class WebsocketSystem {
260269 entity . removeComponent ( WebSocketComponent )
261270 }
262271
263- private async handleInputMessage ( ws : any , message : InputMessage ) {
264- const player : Player = ws . player
272+ private handleInputMessage ( ws : WebSocket < PlayerData > , message : InputMessage ) {
273+ const player = ws . getUserData ( ) . player
265274 if ( ! player ) {
266275 console . error ( `Player with WS ${ ws } not found.` )
267276 return
@@ -283,9 +292,13 @@ export class WebsocketSystem {
283292 this . inputProcessingSystem . receiveInputPacket ( player . entity , message )
284293 }
285294
286- private handleChatMessage ( ws : any , message : ChatMessage ) {
295+ private handleChatMessage ( ws : WebSocket < PlayerData > , message : ChatMessage ) {
287296 console . log ( 'Chat message received' , message )
288- const player : Player = ws . player
297+ const player = ws . getUserData ( ) . player
298+ if ( ! player ) {
299+ console . error ( `Player with WS ${ ws } not found.` )
300+ return
301+ }
289302
290303 const { content } = message
291304 if ( ! content || typeof content !== 'string' || content . length === 0 ) {
@@ -301,8 +314,11 @@ export class WebsocketSystem {
301314
302315 EventSystem . addEvent ( new MessageEvent ( player . entity . id , playerName , content ) )
303316 }
304- private handleProximityPromptInteractMessage ( ws : any , message : ProximityPromptInteractMessage ) {
305- const player : Player = ws . player
317+ private handleProximityPromptInteractMessage (
318+ ws : WebSocket < PlayerData > ,
319+ message : ProximityPromptInteractMessage
320+ ) {
321+ const player = ws . getUserData ( ) . player
306322 if ( ! player ) {
307323 console . error ( `Player with WS ${ ws } not found.` )
308324 return
@@ -311,8 +327,8 @@ export class WebsocketSystem {
311327 EventSystem . addEvent ( new ProximityPromptInteractEvent ( player . entity . id , eId ) )
312328 }
313329
314- private handleSetPlayerNameMessage ( ws : any , message : SetPlayerNameMessage ) {
315- const player : Player = ws . player
330+ private handleSetPlayerNameMessage ( ws : WebSocket < PlayerData > , message : SetPlayerNameMessage ) {
331+ const player = ws . getUserData ( ) . player
316332 if ( ! player ) {
317333 console . error ( `Player with WS ${ ws } not found.` )
318334 return
0 commit comments