diff --git a/apps/server/src/handlers/GameHandler.ts b/apps/server/src/handlers/GameHandler.ts index 5d25f82..1ff30ac 100644 --- a/apps/server/src/handlers/GameHandler.ts +++ b/apps/server/src/handlers/GameHandler.ts @@ -49,4 +49,14 @@ } }); +}; + +/** + * 切断時のゲームクリーンアップ処理 + */ +export const handleGameDisconnect = (io: Server, gameManager: GameManager, playerId: string) => { + // ゲームからの除外処理 + gameManager.removePlayer(playerId); + // 全体にプレイヤー削除を通知 + io.emit(SocketEvents.REMOVE_PLAYER, playerId); }; \ No newline at end of file diff --git a/apps/server/src/handlers/RoomHandler.ts b/apps/server/src/handlers/RoomHandler.ts index be60e7b..e5f6ebe 100644 --- a/apps/server/src/handlers/RoomHandler.ts +++ b/apps/server/src/handlers/RoomHandler.ts @@ -17,4 +17,17 @@ io.to(roomId).emit(SocketEvents.ROOM_UPDATE, room); }); +}; + +/** + * 切断時のルームクリーンアップ処理 + */ +export const handleRoomDisconnect = (io: Server, socket: Socket, roomManager: RoomManager) => { + // ルームからの除外処理 + const updatedRooms = roomManager.removePlayer(socket.id); + + // 更新があったルーム(オーナー変更など)にのみ通知を飛ばす + updatedRooms.forEach(room => { + io.to(room.roomId).emit(SocketEvents.ROOM_UPDATE, room); + }); }; \ No newline at end of file diff --git a/apps/server/src/network/SocketManager.ts b/apps/server/src/network/SocketManager.ts index ee6eb3e..791be78 100644 --- a/apps/server/src/network/SocketManager.ts +++ b/apps/server/src/network/SocketManager.ts @@ -2,8 +2,8 @@ import { GameManager } from "../managers/GameManager.js"; import { RoomManager } from "../managers/RoomManager.js"; import { SocketEvents } from "@repo/shared/src/protocol/events"; -import { registerRoomHandlers } from "../handlers/RoomHandler.js"; -import { registerGameHandlers } from "../handlers/GameHandler.js"; +import { registerRoomHandlers, handleRoomDisconnect } from "../handlers/RoomHandler.js"; +import { registerGameHandlers, handleGameDisconnect } from "../handlers/GameHandler.js"; export class SocketManager { private io: Server; @@ -13,34 +13,26 @@ constructor(io: Server, gameManager: GameManager) { this.io = io; this.gameManager = gameManager; - this.roomManager = new RoomManager(); // 新設したRoomManagerをインスタンス化 + this.roomManager = new RoomManager(); } public initialize() { this.io.on(SocketEvents.CONNECT, (socket: Socket) => { console.log(`✅ User connected: ${socket.id}`); - // 各ハンドラに処理を委譲(ルーティング) registerRoomHandlers(this.io, socket, this.roomManager); registerGameHandlers(this.io, socket, this.gameManager, this.roomManager); - // 切断時イベント群 socket.on(SocketEvents.DISCONNECT, () => { console.log(`❌ User disconnected: ${socket.id}`); - // 1. ゲームからの除外処理 - this.gameManager.removePlayer(socket.id); - this.io.emit(SocketEvents.REMOVE_PLAYER, socket.id); + // 順番を厳守して実行 + // 1. まずゲーム世界から消す(データ参照ができなくなる前に実行) + handleGameDisconnect(this.io, this.gameManager, socket.id); - // 2. ルームからの除外処理 - const updatedRooms = this.roomManager.removePlayer(socket.id); - - // 更新があったルーム(オーナー変更など)にのみ通知を飛ばす - updatedRooms.forEach(room => { - this.io.to(room.roomId).emit(SocketEvents.ROOM_UPDATE, room); - }); + // 2. 次にルームの枠組みから消す(オーナー移譲などのロジックを最後に実行) + handleRoomDisconnect(this.io, socket, this.roomManager); }); - }); } } \ No newline at end of file diff --git "a/docs/01_Env/ENV_01_\347\222\260\345\242\203\346\247\213\347\257\211\343\203\273\346\212\200\350\241\223\343\202\271\343\202\277\343\203\203\343\202\257.txt" "b/docs/01_Env/ENV_01_\347\222\260\345\242\203\346\247\213\347\257\211\343\203\273\346\212\200\350\241\223\343\202\271\343\202\277\343\203\203\343\202\257.txt" index 66d1fc0..fb7b4b7 100644 --- "a/docs/01_Env/ENV_01_\347\222\260\345\242\203\346\247\213\347\257\211\343\203\273\346\212\200\350\241\223\343\202\271\343\202\277\343\203\203\343\202\257.txt" +++ "b/docs/01_Env/ENV_01_\347\222\260\345\242\203\346\247\213\347\257\211\343\203\273\346\212\200\350\241\223\343\202\271\343\202\277\343\203\203\343\202\257.txt" @@ -67,6 +67,7 @@ └── shared/ # 【最重要】「真実」の定義場所(型、定数、純粋ロジック) ├── src/ │ ├── config/ # 共通定数(gameConfig.ts) + │ ├── logic/ # 共通ロジック(gridMap.ts) │ ├── protocol/ # 通信イベント定義(events.ts) │ ├── types/ # 型定義(map.ts, payloads.ts, player.ts, room.ts) │ └── index.ts # エントリーポイント (tsupビルド対象) diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts index d4e7df7..e1bba2b 100644 --- a/packages/shared/src/index.ts +++ b/packages/shared/src/index.ts @@ -1,7 +1,7 @@ // shared パッケージ公開 API export * from './config/gameConfig'; -export * from './types/room'; +export * from "./protocol/events"; +export * from './types/map'; export * from './types/payloads'; export * from './types/player'; -export * from './types/map'; -export * from "./protocol/events"; \ No newline at end of file +export * from './types/room'; \ No newline at end of file