Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
246 changes: 124 additions & 122 deletions backend/src/config/socket-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,158 +8,160 @@ let ioServer: Server | undefined;
export const roomManager = new RoomManager();

export function initializeSocket(server: HTTPServer) {
const io = new Server(server, {
cors: {
origin: process.env.CORS_ORIGIN || "*",
methods: ["GET", "POST"],
},
});

ioServer = io;

roomManager.clearAllRooms();

io.on("connection", (socket) => {
const userId = (socket.handshake.query.userId as string) || (socket.handshake.headers["user-id"] as string);

if (userId) {
userSocketMap.set(userId, socket.id);
}
const io = new Server(server, {
cors: {
origin: process.env.CORS_ORIGIN || "*",
methods: ["GET", "POST"],
},
});

logger.info(`A user connected ${socket.id}`);
ioServer = io;

socket.emit("rooms:list", roomManager.listRooms());
//roomManager.clearAllRooms();

socket.on("room:create", (data: { roomName?: string }) => {
try {
const room = roomManager.createRoom(socket.id, data?.roomName);
socket.join(room.id);
io.on("connection", (socket) => {
const userId =
(socket.handshake.query.userId as string) ||
(socket.handshake.headers["user-id"] as string);

socket.emit("room:created", {
success: true,
room: roomManager.getRoomInfo(room.id),
});
if (userId) {
userSocketMap.set(userId, socket.id);
}

logger.info(`Created room ${room.id} for user ${socket.id}`);
io.emit("rooms:list", roomManager.listRooms());
} catch (err) {
logger.error("Error creating room", { error: err });
socket.emit("room:error", { message: "Failed to create room" });
}
});
logger.info(`A user connected ${socket.id}`);

socket.on("room:join", (data: { roomId: string }) => {
try {
const success = roomManager.joinRoom(data.roomId, socket.id);
console.log("joinRoom result:", data, success);
socket.emit("rooms:list", roomManager.listRooms());

if (!success) {
socket.emit("room:error", { message: "Room not found" });
return;
}
socket.on("room:create", (data: { roomName?: string }) => {
try {
const room = roomManager.createRoom(socket.id, data?.roomName);
socket.join(room.id);

socket.join(data.roomId);
socket.emit("room:created", {
success: true,
room: roomManager.getRoomInfo(room.id),
});

socket.emit("room:joined", {
success: true,
room: roomManager.getRoomInfo(data.roomId),
logger.info(`Created room ${room.id} for user ${socket.id}`);
io.emit("rooms:list", roomManager.listRooms());
} catch (err) {
logger.error("Error creating room", { error: err });
socket.emit("room:error", { message: "Failed to create room" });
}
});

// Notify others in the room
socket.to(data.roomId).emit("player:joined", {
playerId: socket.id,
room: roomManager.getRoomInfo(data.roomId),
socket.on("room:join", (data: { roomId: string }) => {
try {
const success = roomManager.joinRoom(data.roomId, socket.id);
console.log("joinRoom result:", data, success);

if (!success) {
socket.emit("room:error", { message: "Room not found" });
return;
}

socket.join(data.roomId);

socket.emit("room:joined", {
success: true,
room: roomManager.getRoomInfo(data.roomId),
});

// Notify others in the room
socket.to(data.roomId).emit("player:joined", {
playerId: socket.id,
room: roomManager.getRoomInfo(data.roomId),
});

// Broadcast updated room list
io.emit("rooms:list", roomManager.listRooms());
} catch (err) {
logger.error("Error joining room", { error: err });
socket.emit("room:error", { message: "Failed to join room" });
}
});

// Broadcast updated room list
io.emit("rooms:list", roomManager.listRooms());
} catch (err) {
logger.error("Error joining room", { error: err });
socket.emit("room:error", { message: "Failed to join room" });
}
});

socket.on("room:leave", (data: { roomId: string }) => {
try {
roomManager.leaveRoom(data.roomId, socket.id);
socket.leave(data.roomId);

socket.emit("room:left", { success: true });

// Notify others in the room
socket.to(data.roomId).emit("player:left", {
playerId: socket.id,
room: roomManager.getRoomInfo(data.roomId),
socket.on("room:leave", (data: { roomId: string }) => {
try {
roomManager.leaveRoom(data.roomId, socket.id);
socket.leave(data.roomId);

socket.emit("room:left", { success: true });

// Notify others in the room
socket.to(data.roomId).emit("player:left", {
playerId: socket.id,
room: roomManager.getRoomInfo(data.roomId),
});

// Broadcast updated room list
io.emit("rooms:list", roomManager.listRooms());
} catch (err) {
logger.error("Error leaving room", { error: err });
socket.emit("room:error", { message: "Failed to leave room" });
}
});

// Broadcast updated room list
io.emit("rooms:list", roomManager.listRooms());
} catch (err) {
logger.error("Error leaving room", { error: err });
socket.emit("room:error", { message: "Failed to leave room" });
}
});
socket.on("rooms:get", () => {
socket.emit("rooms:list", roomManager.listRooms());
});

socket.on("rooms:get", () => {
socket.emit("rooms:list", roomManager.listRooms());
});
socket.on("room:get", (data: { roomId: string }) => {
const roomInfo = roomManager.getRoomInfo(data.roomId);
if (roomInfo) {
socket.emit("room:info", roomInfo);
} else {
socket.emit("room:error", { message: "Room not found" });
}
});

socket.on("room:get", (data: { roomId: string }) => {
const roomInfo = roomManager.getRoomInfo(data.roomId);
if (roomInfo) {
socket.emit("room:info", roomInfo);
} else {
socket.emit("room:error", { message: "Room not found" });
}
});
// CHAT MESSAGES

// CHAT MESSAGES
socket.on("chat message", (msg) => {
try {
logger.info("Message received from backend", { message: msg });
io.emit("chat message", msg);
} catch (err) {
logger.error("Error handling chat message", { error: err });
}
});

socket.on("chat message", (msg) => {
try {
logger.info("Message received from backend", { message: msg });
io.emit("chat message", msg);
} catch (err) {
logger.error("Error handling chat message", { error: err });
}
});
// DISCONNECT HANDLING

// DISCONNECT HANDLING
socket.on("disconnect", (reason) => {
logger.info(`User ${socket.id} disconnected`, { reason });

socket.on("disconnect", (reason) => {
logger.info(`User ${socket.id} disconnected`, { reason });
// Find and leave any room the player was in
const playerRoom = roomManager.getPlayerRoom(socket.id);
if (playerRoom) {
roomManager.leaveRoom(playerRoom.id, socket.id);

// Find and leave any room the player was in
const playerRoom = roomManager.getPlayerRoom(socket.id);
if (playerRoom) {
roomManager.leaveRoom(playerRoom.id, socket.id);
// Notify others in the room
socket.to(playerRoom.id).emit("player:left", {
playerId: socket.id,
room: roomManager.getRoomInfo(playerRoom.id),
});

// Notify others in the room
socket.to(playerRoom.id).emit("player:left", {
playerId: socket.id,
room: roomManager.getRoomInfo(playerRoom.id),
// Broadcast updated room list
io.emit("rooms:list", roomManager.listRooms());
}
});

// Broadcast updated room list
io.emit("rooms:list", roomManager.listRooms());
}
socket.on("error", (err) => {
logger.error("Socket Error", { error: err });
});
});

socket.on("error", (err) => {
logger.error("Socket Error", { error: err });
io.on("connect_error", (err) => {
logger.error("Global socket connection error", { error: err });
});
});

io.on("connect_error", (err) => {
logger.error("Global socket connection error", { error: err });
});

return io;
return io;
}

export const getIO = (): Server => {
if (!ioServer) {
throw new Error("Socket.io not initialized! Call initSocket first.");
}
return ioServer;
if (!ioServer) {
throw new Error("Socket.io not initialized! Call initSocket first.");
}
return ioServer;
};
16 changes: 8 additions & 8 deletions frontend/TASK.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,19 +120,19 @@ This document contains step-by-step tasks for implementing the frontend UI for C

- [x] Create choice selection interface
- [x] Design choice buttons (rock/paper/scissors)
- [ ] Add choice animation
- [ ] Create result display
- [ ] Show round history
- [ ] Design score tracker
- [x] Add choice animation
- [x] Create result display
- [x] Show round history
- [x] Design score tracker

### TASK-F302: Rock Paper Scissors Game Page

- [x] Create game page route
- [ ] Implement choice selection
- [x] Implement choice selection
- [ ] Add countdown timer
- [ ] Display both players' choices
- [ ] Show round winner
- [ ] Track best-of-N series
- [x] Display both players' choices
- [x] Show round winner
- [x] Track best-of-N series

### TASK-F303: Rock Paper Scissors Multiplayer

Expand Down
Loading