refactor(server): use core Logger instead of console.log (#416)
* refactor(server): use core Logger instead of console.log - Add logger.ts module wrapping @esengine/ecs-framework's createLogger - Replace all console.log/warn/error with structured logger calls - Add @esengine/ecs-framework as dependency for Logger support - Fix type errors in auth/providers.test.ts and ECSRoom.test.ts - Refactor withRateLimit mixin with elegant type helper functions * chore: update pnpm-lock.yaml * fix(server): fix ReDoS vulnerability in route path regex
This commit is contained in:
@@ -3,8 +3,11 @@
|
||||
* @en Room manager
|
||||
*/
|
||||
|
||||
import { Room, type RoomOptions } from './Room.js'
|
||||
import type { Player } from './Player.js'
|
||||
import { Room, type RoomOptions } from './Room.js';
|
||||
import type { Player } from './Player.js';
|
||||
import { createLogger } from '../logger.js';
|
||||
|
||||
const logger = createLogger('Room');
|
||||
|
||||
/**
|
||||
* @zh 房间类型
|
||||
@@ -25,15 +28,15 @@ interface RoomDefinition {
|
||||
* @en Room manager
|
||||
*/
|
||||
export class RoomManager {
|
||||
private _definitions: Map<string, RoomDefinition> = new Map()
|
||||
private _rooms: Map<string, Room> = new Map()
|
||||
private _playerToRoom: Map<string, string> = new Map()
|
||||
private _nextRoomId = 1
|
||||
private _definitions: Map<string, RoomDefinition> = new Map();
|
||||
private _rooms: Map<string, Room> = new Map();
|
||||
private _playerToRoom: Map<string, string> = new Map();
|
||||
private _nextRoomId = 1;
|
||||
|
||||
private _sendFn: (conn: any, type: string, data: unknown) => void
|
||||
private _sendFn: (conn: any, type: string, data: unknown) => void;
|
||||
|
||||
constructor(sendFn: (conn: any, type: string, data: unknown) => void) {
|
||||
this._sendFn = sendFn
|
||||
this._sendFn = sendFn;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -41,7 +44,7 @@ export class RoomManager {
|
||||
* @en Define room type
|
||||
*/
|
||||
define<T extends Room>(name: string, roomClass: RoomClass<T>): void {
|
||||
this._definitions.set(name, { roomClass })
|
||||
this._definitions.set(name, { roomClass });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,33 +52,33 @@ export class RoomManager {
|
||||
* @en Create room
|
||||
*/
|
||||
async create(name: string, options?: RoomOptions): Promise<Room | null> {
|
||||
const def = this._definitions.get(name)
|
||||
const def = this._definitions.get(name);
|
||||
if (!def) {
|
||||
console.warn(`[RoomManager] Room type not found: ${name}`)
|
||||
return null
|
||||
logger.warn(`Room type not found: ${name}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
const roomId = this._generateRoomId()
|
||||
const room = new def.roomClass()
|
||||
const roomId = this._generateRoomId();
|
||||
const room = new def.roomClass();
|
||||
|
||||
room._init({
|
||||
id: roomId,
|
||||
sendFn: this._sendFn,
|
||||
broadcastFn: (type, data) => {
|
||||
for (const player of room.players) {
|
||||
player.send(type, data)
|
||||
player.send(type, data);
|
||||
}
|
||||
},
|
||||
disposeFn: () => {
|
||||
this._rooms.delete(roomId)
|
||||
},
|
||||
})
|
||||
this._rooms.delete(roomId);
|
||||
}
|
||||
});
|
||||
|
||||
this._rooms.set(roomId, room)
|
||||
await room._create(options)
|
||||
this._rooms.set(roomId, room);
|
||||
await room._create(options);
|
||||
|
||||
console.log(`[Room] Created: ${name} (${roomId})`)
|
||||
return room
|
||||
logger.info(`Created: ${name} (${roomId})`);
|
||||
return room;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,22 +92,22 @@ export class RoomManager {
|
||||
options?: RoomOptions
|
||||
): Promise<{ room: Room; player: Player } | null> {
|
||||
// 查找可加入的房间
|
||||
let room = this._findAvailableRoom(name)
|
||||
let room = this._findAvailableRoom(name);
|
||||
|
||||
// 没有则创建
|
||||
if (!room) {
|
||||
room = await this.create(name, options)
|
||||
if (!room) return null
|
||||
room = await this.create(name, options);
|
||||
if (!room) return null;
|
||||
}
|
||||
|
||||
// 加入房间
|
||||
const player = await room._addPlayer(playerId, conn)
|
||||
if (!player) return null
|
||||
const player = await room._addPlayer(playerId, conn);
|
||||
if (!player) return null;
|
||||
|
||||
this._playerToRoom.set(playerId, room.id)
|
||||
this._playerToRoom.set(playerId, room.id);
|
||||
|
||||
console.log(`[Room] Player ${playerId} joined ${room.id}`)
|
||||
return { room, player }
|
||||
logger.info(`Player ${playerId} joined ${room.id}`);
|
||||
return { room, player };
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -116,16 +119,16 @@ export class RoomManager {
|
||||
playerId: string,
|
||||
conn: any
|
||||
): Promise<{ room: Room; player: Player } | null> {
|
||||
const room = this._rooms.get(roomId)
|
||||
if (!room) return null
|
||||
const room = this._rooms.get(roomId);
|
||||
if (!room) return null;
|
||||
|
||||
const player = await room._addPlayer(playerId, conn)
|
||||
if (!player) return null
|
||||
const player = await room._addPlayer(playerId, conn);
|
||||
if (!player) return null;
|
||||
|
||||
this._playerToRoom.set(playerId, room.id)
|
||||
this._playerToRoom.set(playerId, room.id);
|
||||
|
||||
console.log(`[Room] Player ${playerId} joined ${room.id}`)
|
||||
return { room, player }
|
||||
logger.info(`Player ${playerId} joined ${room.id}`);
|
||||
return { room, player };
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,16 +136,16 @@ export class RoomManager {
|
||||
* @en Player leave
|
||||
*/
|
||||
async leave(playerId: string, reason?: string): Promise<void> {
|
||||
const roomId = this._playerToRoom.get(playerId)
|
||||
if (!roomId) return
|
||||
const roomId = this._playerToRoom.get(playerId);
|
||||
if (!roomId) return;
|
||||
|
||||
const room = this._rooms.get(roomId)
|
||||
const room = this._rooms.get(roomId);
|
||||
if (room) {
|
||||
await room._removePlayer(playerId, reason)
|
||||
await room._removePlayer(playerId, reason);
|
||||
}
|
||||
|
||||
this._playerToRoom.delete(playerId)
|
||||
console.log(`[Room] Player ${playerId} left ${roomId}`)
|
||||
this._playerToRoom.delete(playerId);
|
||||
logger.info(`Player ${playerId} left ${roomId}`);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -150,12 +153,12 @@ export class RoomManager {
|
||||
* @en Handle message
|
||||
*/
|
||||
handleMessage(playerId: string, type: string, data: unknown): void {
|
||||
const roomId = this._playerToRoom.get(playerId)
|
||||
if (!roomId) return
|
||||
const roomId = this._playerToRoom.get(playerId);
|
||||
if (!roomId) return;
|
||||
|
||||
const room = this._rooms.get(roomId)
|
||||
const room = this._rooms.get(roomId);
|
||||
if (room) {
|
||||
room._handleMessage(type, data, playerId)
|
||||
room._handleMessage(type, data, playerId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,7 +167,7 @@ export class RoomManager {
|
||||
* @en Get room
|
||||
*/
|
||||
getRoom(roomId: string): Room | undefined {
|
||||
return this._rooms.get(roomId)
|
||||
return this._rooms.get(roomId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -172,8 +175,8 @@ export class RoomManager {
|
||||
* @en Get player's room
|
||||
*/
|
||||
getPlayerRoom(playerId: string): Room | undefined {
|
||||
const roomId = this._playerToRoom.get(playerId)
|
||||
return roomId ? this._rooms.get(roomId) : undefined
|
||||
const roomId = this._playerToRoom.get(playerId);
|
||||
return roomId ? this._rooms.get(roomId) : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -181,7 +184,7 @@ export class RoomManager {
|
||||
* @en Get all rooms
|
||||
*/
|
||||
getRooms(): ReadonlyArray<Room> {
|
||||
return Array.from(this._rooms.values())
|
||||
return Array.from(this._rooms.values());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -189,17 +192,17 @@ export class RoomManager {
|
||||
* @en Get all rooms of a type
|
||||
*/
|
||||
getRoomsByType(name: string): Room[] {
|
||||
const def = this._definitions.get(name)
|
||||
if (!def) return []
|
||||
const def = this._definitions.get(name);
|
||||
if (!def) return [];
|
||||
|
||||
return Array.from(this._rooms.values()).filter(
|
||||
room => room instanceof def.roomClass
|
||||
)
|
||||
(room) => room instanceof def.roomClass
|
||||
);
|
||||
}
|
||||
|
||||
private _findAvailableRoom(name: string): Room | null {
|
||||
const def = this._definitions.get(name)
|
||||
if (!def) return null
|
||||
const def = this._definitions.get(name);
|
||||
if (!def) return null;
|
||||
|
||||
for (const room of this._rooms.values()) {
|
||||
if (
|
||||
@@ -208,14 +211,14 @@ export class RoomManager {
|
||||
!room.isLocked &&
|
||||
!room.isDisposed
|
||||
) {
|
||||
return room
|
||||
return room;
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
|
||||
private _generateRoomId(): string {
|
||||
return `room_${this._nextRoomId++}`
|
||||
return `room_${this._nextRoomId++}`;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user