diff --git a/apps/server/src/application/coordinators/disconnectCoordinator.ts b/apps/server/src/application/coordinators/disconnectCoordinator.ts new file mode 100644 index 0000000..4d40e81 --- /dev/null +++ b/apps/server/src/application/coordinators/disconnectCoordinator.ts @@ -0,0 +1,28 @@ +/** + * disconnectCoordinator + * DISCONNECTイベントの調停を行い,ゲーム離脱処理とルーム離脱処理を順序実行する + */ +import { GameManager } from "@server/domains/game/GameManager"; +import { RoomManager } from "@server/domains/room/RoomManager"; +import { handleGameDisconnect } from "@server/network/handlers/GameHandler"; +import { handleRoomDisconnect } from "@server/network/handlers/RoomHandler"; + +type DisconnectCoordinatorParams = { + io: Parameters[0]; + socketId: string; + gameManager: GameManager; + roomManager: RoomManager; +}; + +/** 切断時にゲーム処理とルーム処理を調停し,一貫した離脱処理を実行する */ +export const disconnectCoordinator = ({ + io, + socketId, + gameManager, + roomManager, +}: DisconnectCoordinatorParams) => { + const roomId = roomManager.getRoomByPlayerId(socketId)?.roomId; + + handleGameDisconnect(io, gameManager, roomId, socketId); + handleRoomDisconnect(io, socketId, roomManager); +}; diff --git a/apps/server/src/application/coordinators/readyForGameCoordinator.ts b/apps/server/src/application/coordinators/readyForGameCoordinator.ts new file mode 100644 index 0000000..407dc01 --- /dev/null +++ b/apps/server/src/application/coordinators/readyForGameCoordinator.ts @@ -0,0 +1,34 @@ +/** + * readyForGameCoordinator + * READY_FOR_GAMEイベントの調停を行い,所属ルーム解決と準備状態通知を橋渡しする + */ +import { + type GameOutputPort, + type ReadyForGamePort, + type ReadyForGameRoomPort, +} from "@server/domains/game/application/ports/gameUseCasePorts"; +import { readyForGameUseCase } from "@server/domains/game/application/useCases/readyForGameUseCase"; + +type ReadyForGameCoordinatorParams = { + socketId: string; + gameManager: ReadyForGamePort; + roomManager: ReadyForGameRoomPort; + output: Pick; +}; + +/** READY_FOR_GAME受信時に所属ルームを解決し,準備状態ユースケースを実行する */ +export const readyForGameCoordinator = ({ + socketId, + gameManager, + roomManager, + output, +}: ReadyForGameCoordinatorParams) => { + const room = roomManager.getRoomByPlayerId(socketId); + + readyForGameUseCase({ + socketId, + roomId: room?.roomId, + gameManager, + output, + }); +}; diff --git a/apps/server/src/application/coordinators/startGameCoordinator.ts b/apps/server/src/application/coordinators/startGameCoordinator.ts index a4308fb..9ea5920 100644 --- a/apps/server/src/application/coordinators/startGameCoordinator.ts +++ b/apps/server/src/application/coordinators/startGameCoordinator.ts @@ -1,14 +1,20 @@ +/** + * startGameCoordinator + * START_GAMEイベントの調停を行い,ルーム状態更新とゲーム開始処理を橋渡しする + */ import { roomConsts } from "@repo/shared"; import { GameManager } from "@server/domains/game/GameManager"; -import { type GameOutputPort } from "@server/domains/game/application/ports/gameUseCasePorts"; +import { + type GameOutputPort, + type StartGameRoomPort, +} from "@server/domains/game/application/ports/gameUseCasePorts"; import { startGameUseCase } from "@server/domains/game/application/useCases/startGameUseCase"; -import { RoomManager } from "@server/domains/room/RoomManager"; import { logEvent } from "@server/logging/logEvent"; type StartGameCoordinatorParams = { ownerId: string; gameManager: GameManager; - roomManager: RoomManager; + roomManager: StartGameRoomPort; output: Pick< GameOutputPort, | "publishUpdatePlayerToRoom" @@ -18,6 +24,7 @@ >; }; +/** START_GAME受信時にルーム状態遷移を判定し,ゲーム開始ユースケースを実行する */ export const startGameCoordinator = ({ ownerId, gameManager, diff --git a/apps/server/src/domains/game/GameManager.ts b/apps/server/src/domains/game/GameManager.ts index 118abb7..c6f5a6f 100644 --- a/apps/server/src/domains/game/GameManager.ts +++ b/apps/server/src/domains/game/GameManager.ts @@ -1,3 +1,7 @@ +/** + * GameManager + * ゲームセッション集合の生成,更新,参照管理を統括する + */ import { type TickData } from "./loop/GameLoop"; import { Player } from "./entities/player/Player.js"; import { GameRoomSession } from "./application/services/GameRoomSession"; @@ -5,6 +9,7 @@ import { GamePlayerOperationService } from "./application/services/GamePlayerOperationService"; // プレイヤー集合の生成・更新・参照管理クラス +/** ゲームセッションのライフサイクルとプレイヤー操作を統括するマネージャ */ export class GameManager { private sessions: Map; private playerToRoom: Map; diff --git a/apps/server/src/domains/game/application/ports/gameUseCasePorts.ts b/apps/server/src/domains/game/application/ports/gameUseCasePorts.ts index 659e636..c3f8e0f 100644 --- a/apps/server/src/domains/game/application/ports/gameUseCasePorts.ts +++ b/apps/server/src/domains/game/application/ports/gameUseCasePorts.ts @@ -1,6 +1,11 @@ +/** + * gameUseCasePorts + * ゲーム系ユースケースが利用する入力ポートと出力ポートの契約を定義する + */ import type { TickData } from "../../loop/GameLoop"; import type { gridMapTypes, playerTypes, roomTypes } from "@repo/shared"; +/** ゲーム開始ユースケースが利用するゲーム管理入力ポート */ export interface StartGamePort { startRoomSession( roomId: string, @@ -11,19 +16,35 @@ getRoomStartTime(roomId: string): number | undefined; } +/** ゲーム開始調停で利用するルーム管理入力ポート */ +export interface StartGameRoomPort { + getRoomByOwnerId(ownerId: string): roomTypes.Room | undefined; + markRoomPlaying(roomId: string): roomTypes.Room | undefined; + markRoomWaiting(roomId: string): roomTypes.Room | undefined; +} + +/** 準備完了調停で利用するルーム解決入力ポート */ +export interface ReadyForGameRoomPort { + getRoomByPlayerId(playerId: string): roomTypes.Room | undefined; +} + +/** 準備完了ユースケースが利用するゲーム状態参照入力ポート */ export interface ReadyForGamePort { getRoomPlayers(roomId: string): playerTypes.PlayerData[]; getRoomStartTime(roomId: string): number | undefined; } +/** 移動入力ユースケースが利用するプレイヤー操作入力ポート */ export interface MovePlayerPort { movePlayer(id: string, x: number, y: number): void; } +/** 切断ユースケースが利用するプレイヤー削除入力ポート */ export interface DisconnectPlayerPort { removePlayer(id: string): void; } +/** ゲーム系ユースケースが利用する送信出力ポート */ export interface GameOutputPort { publishPongToSocket(payload: { clientTime: number; serverTime: number }): void; publishUpdatePlayerToRoom(roomId: roomTypes.Room["roomId"], playerData: playerTypes.PlayerData): void; diff --git a/apps/server/src/domains/game/application/services/GamePlayerOperationService.ts b/apps/server/src/domains/game/application/services/GamePlayerOperationService.ts index 9c039c7..e6af25b 100644 --- a/apps/server/src/domains/game/application/services/GamePlayerOperationService.ts +++ b/apps/server/src/domains/game/application/services/GamePlayerOperationService.ts @@ -1,9 +1,14 @@ +/** + * GamePlayerOperationService + * ゲームセッション内のプレイヤー移動と離脱操作を管理する + */ import { logEvent } from "@server/logging/logEvent"; import { GameRoomSession } from "./GameRoomSession"; type SessionStore = Map; type PlayerRoomIndex = Map; +/** プレイヤー移動とセッション離脱処理を提供するサービス */ export class GamePlayerOperationService { constructor( private sessions: SessionStore, diff --git a/apps/server/src/domains/game/application/services/GameRoomSession.ts b/apps/server/src/domains/game/application/services/GameRoomSession.ts index 4ac08b7..4e31055 100644 --- a/apps/server/src/domains/game/application/services/GameRoomSession.ts +++ b/apps/server/src/domains/game/application/services/GameRoomSession.ts @@ -1,3 +1,7 @@ +/** + * GameRoomSession + * 1ルーム分のゲーム進行状態とゲームループ実行を管理する + */ import { logEvent } from "@server/logging/logEvent"; import { GameLoop, type TickData } from "../../loop/GameLoop"; import { Player } from "../../entities/player/Player.js"; @@ -8,6 +12,7 @@ setPlayerPosition, } from "../../entities/player/playerMovement.js"; +/** ルーム単位のゲーム状態とループ進行を保持するセッションクラス */ export class GameRoomSession { private players: Map; private mapStore: MapStore; diff --git a/apps/server/src/domains/game/application/services/GameSessionLifecycleService.ts b/apps/server/src/domains/game/application/services/GameSessionLifecycleService.ts index 333d259..0b22870 100644 --- a/apps/server/src/domains/game/application/services/GameSessionLifecycleService.ts +++ b/apps/server/src/domains/game/application/services/GameSessionLifecycleService.ts @@ -1,3 +1,7 @@ +/** + * GameSessionLifecycleService + * ゲームセッションの開始,参照,終了時クリーンアップを管理する + */ import { config } from "@repo/shared"; import { type TickData } from "../../loop/GameLoop"; import { logEvent } from "@server/logging/logEvent"; @@ -6,6 +10,7 @@ type SessionStore = Map; type PlayerRoomIndex = Map; +/** ゲームセッションのライフサイクル操作を提供するサービス */ export class GameSessionLifecycleService { constructor( private sessions: SessionStore, diff --git a/apps/server/src/domains/game/application/useCases/disconnectUseCase.ts b/apps/server/src/domains/game/application/useCases/disconnectUseCase.ts index 865ec74..bb6ca19 100644 --- a/apps/server/src/domains/game/application/useCases/disconnectUseCase.ts +++ b/apps/server/src/domains/game/application/useCases/disconnectUseCase.ts @@ -1,3 +1,7 @@ +/** + * disconnectUseCase + * 切断したプレイヤーをゲーム状態から除外し,必要に応じて通知を行う + */ import type { DisconnectPlayerPort, GameOutputPort } from "../ports/gameUseCasePorts"; import { logEvent } from "@server/logging/logEvent"; @@ -8,6 +12,7 @@ output: Pick; }; +/** プレイヤー切断時の状態更新と通知を実行する */ export const disconnectUseCase = ({ gameManager, roomId, diff --git a/apps/server/src/domains/game/application/useCases/movePlayerUseCase.ts b/apps/server/src/domains/game/application/useCases/movePlayerUseCase.ts index 9bcece1..400b1ae 100644 --- a/apps/server/src/domains/game/application/useCases/movePlayerUseCase.ts +++ b/apps/server/src/domains/game/application/useCases/movePlayerUseCase.ts @@ -1,3 +1,7 @@ +/** + * movePlayerUseCase + * プレイヤー移動入力を受け取り,ゲーム管理へ反映する + */ import type { playerTypes } from "@repo/shared"; import type { MovePlayerPort } from "../ports/gameUseCasePorts"; @@ -7,6 +11,7 @@ move: playerTypes.MovePayload; }; +/** プレイヤー移動入力をゲーム管理へ委譲する */ export const movePlayerUseCase = ({ gameManager, playerId, diff --git a/apps/server/src/domains/game/application/useCases/pingUseCase.ts b/apps/server/src/domains/game/application/useCases/pingUseCase.ts index 42e8fbd..c357d66 100644 --- a/apps/server/src/domains/game/application/useCases/pingUseCase.ts +++ b/apps/server/src/domains/game/application/useCases/pingUseCase.ts @@ -1,3 +1,7 @@ +/** + * pingUseCase + * PING受信時に時刻情報付きPONGを返して遅延計測を支援する + */ import type { GameOutputPort } from "../ports/gameUseCasePorts"; type PingUseCaseParams = { @@ -5,6 +9,7 @@ output: Pick; }; +/** クライアント時刻を受け取りサーバー時刻付きで応答する */ export const pingUseCase = ({ clientTime, output, diff --git a/apps/server/src/domains/game/application/useCases/readyForGameUseCase.ts b/apps/server/src/domains/game/application/useCases/readyForGameUseCase.ts index f8a72c0..f4696ad 100644 --- a/apps/server/src/domains/game/application/useCases/readyForGameUseCase.ts +++ b/apps/server/src/domains/game/application/useCases/readyForGameUseCase.ts @@ -1,3 +1,7 @@ +/** + * readyForGameUseCase + * READY_FOR_GAME受信時に現在プレイヤー状態と開始時刻を返却する + */ import type { ReadyForGamePort } from "../ports/gameUseCasePorts"; import type { GameOutputPort } from "../ports/gameUseCasePorts"; import { logEvent } from "@server/logging/logEvent"; @@ -9,6 +13,7 @@ output: Pick; }; +/** 準備完了通知に対してルーム状態を返却し,開始済みなら開始時刻も通知する */ export const readyForGameUseCase = ({ socketId, roomId, diff --git a/apps/server/src/domains/game/application/useCases/startGameUseCase.ts b/apps/server/src/domains/game/application/useCases/startGameUseCase.ts index 0b853c8..f4075f0 100644 --- a/apps/server/src/domains/game/application/useCases/startGameUseCase.ts +++ b/apps/server/src/domains/game/application/useCases/startGameUseCase.ts @@ -1,3 +1,7 @@ +/** + * startGameUseCase + * ルーム内プレイヤーでゲームセッションを開始し,進行イベントを通知する + */ import type { GameOutputPort, StartGamePort } from "../ports/gameUseCasePorts"; import { logEvent } from "@server/logging/logEvent"; @@ -15,6 +19,7 @@ >; }; +/** ゲームセッション開始とティック通知,終了通知を実行する */ export const startGameUseCase = ({ roomId, playerIds, diff --git a/apps/server/src/domains/game/entities/map/MapStore.ts b/apps/server/src/domains/game/entities/map/MapStore.ts index 15b03f8..3880749 100644 --- a/apps/server/src/domains/game/entities/map/MapStore.ts +++ b/apps/server/src/domains/game/entities/map/MapStore.ts @@ -1,9 +1,13 @@ -// apps/server/src/domains/game/entities/map/MapStore.ts +/** + * MapStore + * 塗り状態グリッドと差分更新キューを保持して提供する + */ import type { gridMapTypes } from "@repo/shared"; import { createInitialGridColors } from "./mapGrid.js"; import { paintCellIfChanged } from "./mapPainting.js"; import { drainPendingUpdates } from "./mapUpdates.js"; +/** ルーム内マップの塗り状態と更新差分を管理するストア */ export class MapStore { // 全マスの現在の色(teamId)を保持 private gridColors: number[]; diff --git a/apps/server/src/domains/game/entities/map/mapGrid.ts b/apps/server/src/domains/game/entities/map/mapGrid.ts index c08cc21..f230acf 100644 --- a/apps/server/src/domains/game/entities/map/mapGrid.ts +++ b/apps/server/src/domains/game/entities/map/mapGrid.ts @@ -1,5 +1,10 @@ +/** + * mapGrid + * マップ配列の初期状態を生成する + */ import { config } from "@repo/shared"; +/** マップ全セルを未塗り状態で初期化した配列を返す */ export const createInitialGridColors = (): number[] => { const totalCells = config.GAME_CONFIG.GRID_COLS * config.GAME_CONFIG.GRID_ROWS; return new Array(totalCells).fill(-1); diff --git a/apps/server/src/domains/game/entities/map/mapPainting.ts b/apps/server/src/domains/game/entities/map/mapPainting.ts index c03eab1..8ffe9fb 100644 --- a/apps/server/src/domains/game/entities/map/mapPainting.ts +++ b/apps/server/src/domains/game/entities/map/mapPainting.ts @@ -1,3 +1,7 @@ +/** + * mapPainting + * マップセルの塗り更新と差分追加処理を提供する + */ import type { gridMapTypes } from "@repo/shared"; type PaintCellParams = { @@ -7,6 +11,7 @@ teamId: number; }; +/** マップセルの色が変わった場合のみ差分へ追加する */ export const paintCellIfChanged = ({ gridColors, pendingUpdates, diff --git a/apps/server/src/domains/game/entities/map/mapUpdates.ts b/apps/server/src/domains/game/entities/map/mapUpdates.ts index 091ed0b..9c51618 100644 --- a/apps/server/src/domains/game/entities/map/mapUpdates.ts +++ b/apps/server/src/domains/game/entities/map/mapUpdates.ts @@ -1,5 +1,10 @@ +/** + * mapUpdates + * マップ差分キューの取り出しとクリア処理を提供する + */ import type { gridMapTypes } from "@repo/shared"; +/** 差分キューを配列として返却し,キューを空にする */ export const drainPendingUpdates = ( pendingUpdates: gridMapTypes.CellUpdate[] ): gridMapTypes.CellUpdate[] => { diff --git a/apps/server/src/domains/game/entities/player/Player.ts b/apps/server/src/domains/game/entities/player/Player.ts index 6e16617..68a033e 100644 --- a/apps/server/src/domains/game/entities/player/Player.ts +++ b/apps/server/src/domains/game/entities/player/Player.ts @@ -1,7 +1,12 @@ +/** + * Player + * サーバー側で保持するプレイヤー状態モデルを定義する + */ import type { playerTypes } from "@repo/shared"; import { config } from "@repo/shared"; // サーバー側保持プレイヤー状態モデル +/** サーバー側プレイヤー座標と所属チームを保持するエンティティ */ export class Player implements playerTypes.PlayerData { public id: string; public x: number = 0; diff --git a/apps/server/src/domains/game/entities/player/playerMovement.ts b/apps/server/src/domains/game/entities/player/playerMovement.ts index b7cd590..a53a88b 100644 --- a/apps/server/src/domains/game/entities/player/playerMovement.ts +++ b/apps/server/src/domains/game/entities/player/playerMovement.ts @@ -1,9 +1,15 @@ +/** + * playerMovement + * プレイヤー座標の検証と更新処理を提供する + */ import { Player } from "./Player.js"; +/** 座標値が有限数かを判定する */ export const isValidPosition = (x: number, y: number): boolean => { return Number.isFinite(x) && Number.isFinite(y); }; +/** プレイヤー座標を新しい値へ更新する */ export const setPlayerPosition = ( player: Player, x: number, diff --git a/apps/server/src/domains/game/entities/player/playerPosition.ts b/apps/server/src/domains/game/entities/player/playerPosition.ts index f0c825a..0a2112c 100644 --- a/apps/server/src/domains/game/entities/player/playerPosition.ts +++ b/apps/server/src/domains/game/entities/player/playerPosition.ts @@ -1,6 +1,11 @@ +/** + * playerPosition + * プレイヤー座標からマップ上のセル位置を解決する + */ import { gridMapLogic } from "@repo/shared"; import { Player } from "./Player.js"; +/** プレイヤー座標に対応するグリッドインデックスを返す */ export const getPlayerGridIndex = (player: Player): number | null => { return gridMapLogic.getGridIndexFromPosition(player.x, player.y); }; diff --git a/apps/server/src/domains/game/entities/player/playerSpawn.ts b/apps/server/src/domains/game/entities/player/playerSpawn.ts index 064a690..c09e4ae 100644 --- a/apps/server/src/domains/game/entities/player/playerSpawn.ts +++ b/apps/server/src/domains/game/entities/player/playerSpawn.ts @@ -1,6 +1,11 @@ +/** + * playerSpawn + * プレイヤー初期生成時のスポーン座標設定を提供する + */ import { config } from "@repo/shared"; import { Player } from "./Player.js"; +/** プレイヤーを生成し,初期スポーン座標を設定して返す */ export const createSpawnedPlayer = (id: string): Player => { const player = new Player(id); player.x = config.GAME_CONFIG.GRID_COLS / 2; diff --git a/apps/server/src/domains/game/loop/GameLoop.ts b/apps/server/src/domains/game/loop/GameLoop.ts index de3617c..c5a9f9e 100644 --- a/apps/server/src/domains/game/loop/GameLoop.ts +++ b/apps/server/src/domains/game/loop/GameLoop.ts @@ -1,3 +1,7 @@ +/** + * GameLoop + * ルーム単位の定周期更新を実行し,プレイヤー状態とマップ差分を集約する + */ import { Player } from "../entities/player/Player.js"; import { MapStore } from "../entities/map/MapStore"; import { getPlayerGridIndex } from "../entities/player/playerPosition.js"; @@ -6,6 +10,7 @@ import { logEvent } from "@server/logging/logEvent"; // コールバックで渡すデータの型定義 +/** 1ティック分のプレイヤー情報とマップ差分を表すデータ */ export interface TickData { players: { id: string; @@ -16,6 +21,7 @@ cellUpdates: gridMapTypes.CellUpdate[]; } +/** ルーム内ゲーム進行を定周期で実行するループ管理クラス */ export class GameLoop { private loopId: NodeJS.Timeout | null = null; private startTime: number = 0; diff --git a/apps/server/src/index.ts b/apps/server/src/index.ts index 77f2750..f7138f6 100644 --- a/apps/server/src/index.ts +++ b/apps/server/src/index.ts @@ -1,3 +1,7 @@ +/** + * index + * サーバー起動時にHTTPサーバー生成とブート処理を実行する + */ import { createHttpServer } from "./network/bootstrap/createHttpServer"; import { boot } from "./network/bootstrap/boot"; import { config } from "@repo/shared"; diff --git a/apps/server/src/logging/logEvent.ts b/apps/server/src/logging/logEvent.ts index 626324c..c521ab8 100644 --- a/apps/server/src/logging/logEvent.ts +++ b/apps/server/src/logging/logEvent.ts @@ -1,3 +1,7 @@ +/** + * logEvent + * 共通ログ出力で利用するイベントログ関数を提供する + */ type LogEventPayload = { event: string; result: string; @@ -6,6 +10,7 @@ [key: string]: unknown; }; +/** スコープ名とイベント情報を標準出力へ記録する */ export const logEvent = (scope: string, payload: LogEventPayload) => { console.log(`[${scope}]`, payload); }; diff --git a/apps/server/src/network/handlers/game/registerGameHandlers.ts b/apps/server/src/network/handlers/game/registerGameHandlers.ts index bdd4cc0..a50c94d 100644 --- a/apps/server/src/network/handlers/game/registerGameHandlers.ts +++ b/apps/server/src/network/handlers/game/registerGameHandlers.ts @@ -7,13 +7,13 @@ import { RoomManager } from "@server/domains/room/RoomManager"; import { protocol } from "@repo/shared"; import { pingUseCase } from "@server/domains/game/application/useCases/pingUseCase"; -import { readyForGameUseCase } from "@server/domains/game/application/useCases/readyForGameUseCase"; import { movePlayerUseCase } from "@server/domains/game/application/useCases/movePlayerUseCase"; import { createCommonHandlerContext } from "@server/network/handlers/CommonHandler"; import { createGameOutputAdapter } from "./createGameOutputAdapter"; import { logEvent } from "@server/logging/logEvent"; import { isMovePayload, isPingPayload } from "@server/network/validation/socketPayloadValidators"; import { startGameCoordinator } from "@server/application/coordinators/startGameCoordinator"; +import { readyForGameCoordinator } from "@server/application/coordinators/readyForGameCoordinator"; /** ゲームイベントの購読とユースケース呼び出しを設定する */ export const registerGameHandlers = ( @@ -54,12 +54,10 @@ // 参加者の準備完了通知を受けて現在状態を返す socket.on(protocol.SocketEvents.READY_FOR_GAME, () => { - const roomId = Array.from(socket.rooms).find((room) => room !== socket.id); - - readyForGameUseCase({ + readyForGameCoordinator({ socketId: socket.id, - roomId, gameManager, + roomManager, output: gameOutputAdapter, }); }); diff --git a/apps/server/src/network/handlers/registerConnectionHandlers.ts b/apps/server/src/network/handlers/registerConnectionHandlers.ts index fa871f9..d5e6917 100644 --- a/apps/server/src/network/handlers/registerConnectionHandlers.ts +++ b/apps/server/src/network/handlers/registerConnectionHandlers.ts @@ -6,9 +6,10 @@ import { GameManager } from "@server/domains/game/GameManager"; import { RoomManager } from "@server/domains/room/RoomManager"; import { protocol } from "@repo/shared"; -import { registerRoomHandlers, handleRoomDisconnect } from "./RoomHandler"; -import { registerGameHandlers, handleGameDisconnect } from "./GameHandler"; +import { registerRoomHandlers } from "./RoomHandler"; +import { registerGameHandlers } from "./GameHandler"; import { logEvent } from "@server/logging/logEvent"; +import { disconnectCoordinator } from "@server/application/coordinators/disconnectCoordinator"; type RegisterConnectionHandlersParams = { io: Server; @@ -41,10 +42,12 @@ socketId: socket.id, }); - const roomId = roomManager.getRoomByPlayerId(socket.id)?.roomId; - - handleGameDisconnect(io, gameManager, roomId, socket.id); - handleRoomDisconnect(io, socket, roomManager); + disconnectCoordinator({ + io, + socketId: socket.id, + gameManager, + roomManager, + }); }); }); }; diff --git a/apps/server/src/network/handlers/room/handleRoomDisconnect.ts b/apps/server/src/network/handlers/room/handleRoomDisconnect.ts index 998b0f9..7c92990 100644 --- a/apps/server/src/network/handlers/room/handleRoomDisconnect.ts +++ b/apps/server/src/network/handlers/room/handleRoomDisconnect.ts @@ -2,7 +2,7 @@ * handleRoomDisconnect * ルーム切断ユースケースを呼び出してルーム状態更新を配信する */ -import { Server, Socket } from "socket.io"; +import { Server } from "socket.io"; import { RoomManager } from "@server/domains/room/RoomManager"; import { roomDisconnectUseCase } from "@server/domains/room/application/useCases/roomDisconnectUseCase"; import { createRoomDisconnectOutputAdapter } from "./createRoomOutputAdapter"; @@ -10,14 +10,14 @@ /** 切断ソケットのルーム離脱処理を実行して更新通知する */ export const handleRoomDisconnect = ( io: Server, - socket: Socket, + socketId: string, roomManager: RoomManager ) => { const roomDisconnectOutputAdapter = createRoomDisconnectOutputAdapter(io); roomDisconnectUseCase({ roomManager, - socketId: socket.id, + socketId, output: roomDisconnectOutputAdapter, }); };