@@ -4,6 +4,7 @@ import { CONFIG } from '../config.js';
44import { DrawPayload , DrawBatchPayload , AuthenticatedSocket } from './types.js' ;
55import { LobbyService } from '../services/lobby.service.js' ;
66import jwt from 'jsonwebtoken' ;
7+ import { getLobbyUserCount , getUsersInLobby , broadcastToLobby , broadcastToOthers } from '../utils/socketUtils.js' ;
78
89export const setupSocket = ( io : Server ) => {
910 // Authentication Middleware
@@ -33,26 +34,36 @@ export const setupSocket = (io: Server) => {
3334 socket . on ( CONFIG . EVENTS . CLIENT . JOIN_LOBBY , async ( lobbyName : string ) => {
3435 console . log ( `[Socket] ${ socket . id } joining lobby: ${ lobbyName } ` ) ;
3536
36- // 1. Join the Socket.io room channel
37- socket . join ( lobbyName ) ;
37+ try {
38+ // 1. Get User
39+ const user = ( socket as AuthenticatedSocket ) . user ;
40+ if ( ! user || ! user . id ) {
41+ console . error ( `[Socket] Error: User not found on socket ${ socket . id } ` ) ;
42+ return ;
43+ }
3844
39- const user = ( socket as AuthenticatedSocket ) . user ;
40- if ( ! user ) {
41- console . error ( `[Socket] Error: User not found on socket ${ socket . id } ` ) ;
42- return ;
43- }
45+ // 2. Validate Join (Service checks existence, ban status, and capacity)
46+ const currentCount = getLobbyUserCount ( io , lobbyName ) ;
4447
45- try {
46- // 2. Broadcast to others that a new user joined (First, to avoid race conditions)
47- socket . to ( lobbyName ) . emit ( CONFIG . EVENTS . SERVER . USER_JOINED , user ) ;
48+ try {
49+ await LobbyService . verifyCanJoin ( lobbyName , user . id , currentCount ) ;
50+ } catch ( e : any ) {
51+ console . error ( `[Socket] Join blocked: ${ e . message } ` ) ;
52+ socket . emit ( CONFIG . EVENTS . SERVER . ERROR , { message : e . message } ) ;
53+ return ;
54+ }
55+
56+ // 3. Join the Socket.io room channel
57+ socket . join ( lobbyName ) ;
58+
59+ // 4. Broadcast to others that a new user joined
60+ broadcastToOthers ( socket , lobbyName , CONFIG . EVENTS . SERVER . USER_JOINED , user ) ;
4861
49- // 3. Send list of connected users to the new user
50- // We fetch sockets AFTER joining so the user is included in the list
51- const sockets = await io . in ( lobbyName ) . fetchSockets ( ) ;
52- const users = sockets . map ( s => s . data . user ) . filter ( u => u ) ;
62+ // 5. Send list of connected users to the new user
63+ const users = await getUsersInLobby ( io , lobbyName ) ;
5364 socket . emit ( CONFIG . EVENTS . SERVER . LOBBY_USERS , users ) ;
5465
55- // 4 . Get current state from Service & Send to user
66+ // 6 . Get current state from Service & Send to user
5667 const state = await CanvasService . getState ( lobbyName ) ;
5768 socket . emit ( CONFIG . EVENTS . SERVER . INIT_STATE , state ) ;
5869 } catch ( error ) {
@@ -75,7 +86,7 @@ export const setupSocket = (io: Server) => {
7586 // 2. Broadcast if successful
7687 if ( success ) {
7788 // Send to everyone in the room INCLUDING the sender (for consistency)
78- io . to ( lobbyName ) . emit ( CONFIG . EVENTS . SERVER . PIXEL_UPDATE , { x, y, color } ) ;
89+ broadcastToLobby ( io , lobbyName , CONFIG . EVENTS . SERVER . PIXEL_UPDATE , { x, y, color } ) ;
7990 }
8091 } ) ;
8192
@@ -105,7 +116,7 @@ export const setupSocket = (io: Server) => {
105116 // 2. Broadcast batch if any successful
106117 if ( successfulUpdates . length > 0 ) {
107118 // Send to everyone in the room INCLUDING the sender (for consistency)
108- io . to ( lobbyName ) . emit ( CONFIG . EVENTS . SERVER . PIXEL_UPDATE_BATCH , { pixels : successfulUpdates } ) ;
119+ broadcastToLobby ( io , lobbyName , CONFIG . EVENTS . SERVER . PIXEL_UPDATE_BATCH , { pixels : successfulUpdates } ) ;
109120 }
110121 } ) ;
111122
@@ -115,10 +126,10 @@ export const setupSocket = (io: Server) => {
115126 // Notify rooms that user is leaving
116127 for ( const room of socket . rooms ) {
117128 if ( room !== socket . id ) {
118- socket . to ( room ) . emit ( CONFIG . EVENTS . SERVER . USER_LEFT , ( socket as AuthenticatedSocket ) . user ) ;
129+ broadcastToOthers ( socket , room , CONFIG . EVENTS . SERVER . USER_LEFT , ( socket as AuthenticatedSocket ) . user ) ;
119130
120131 // Check if room is empty (excluding this socket)
121- const socketsInRoom = await io . in ( room ) . fetchSockets ( ) ;
132+ const socketsInRoom = await getUsersInLobby ( io , room ) ;
122133 const remainingUsers = socketsInRoom . length - 1 ; // fetchSockets includes the disconnecting socket
123134
124135 if ( remainingUsers <= 0 ) {
0 commit comments