@esengine/server 4.3.0 → 4.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1076 @@
1
+ import { Connection } from '@esengine/rpc';
2
+ import { IncomingMessage, ServerResponse } from 'node:http';
3
+
4
+ /**
5
+ * @zh HTTP 路由类型定义
6
+ * @en HTTP router type definitions
7
+ */
8
+
9
+ /**
10
+ * @zh HTTP 请求上下文
11
+ * @en HTTP request context
12
+ */
13
+ interface HttpRequest {
14
+ /**
15
+ * @zh 原始请求对象
16
+ * @en Raw request object
17
+ */
18
+ raw: IncomingMessage;
19
+ /**
20
+ * @zh 请求方法
21
+ * @en Request method
22
+ */
23
+ method: string;
24
+ /**
25
+ * @zh 请求路径
26
+ * @en Request path
27
+ */
28
+ path: string;
29
+ /**
30
+ * @zh 路由参数(从 URL 路径提取,如 /users/:id)
31
+ * @en Route parameters (extracted from URL path, e.g., /users/:id)
32
+ */
33
+ params: Record<string, string>;
34
+ /**
35
+ * @zh 查询参数
36
+ * @en Query parameters
37
+ */
38
+ query: Record<string, string>;
39
+ /**
40
+ * @zh 请求头
41
+ * @en Request headers
42
+ */
43
+ headers: Record<string, string | string[] | undefined>;
44
+ /**
45
+ * @zh 解析后的 JSON 请求体
46
+ * @en Parsed JSON body
47
+ */
48
+ body: unknown;
49
+ /**
50
+ * @zh 客户端 IP
51
+ * @en Client IP
52
+ */
53
+ ip: string;
54
+ }
55
+ /**
56
+ * @zh HTTP 响应工具
57
+ * @en HTTP response utilities
58
+ */
59
+ interface HttpResponse {
60
+ /**
61
+ * @zh 原始响应对象
62
+ * @en Raw response object
63
+ */
64
+ raw: ServerResponse;
65
+ /**
66
+ * @zh 设置状态码
67
+ * @en Set status code
68
+ */
69
+ status(code: number): HttpResponse;
70
+ /**
71
+ * @zh 设置响应头
72
+ * @en Set response header
73
+ */
74
+ header(name: string, value: string): HttpResponse;
75
+ /**
76
+ * @zh 发送 JSON 响应
77
+ * @en Send JSON response
78
+ */
79
+ json(data: unknown): void;
80
+ /**
81
+ * @zh 发送文本响应
82
+ * @en Send text response
83
+ */
84
+ text(data: string): void;
85
+ /**
86
+ * @zh 发送错误响应
87
+ * @en Send error response
88
+ */
89
+ error(code: number, message: string): void;
90
+ }
91
+ /**
92
+ * @zh HTTP 路由处理器
93
+ * @en HTTP route handler
94
+ */
95
+ type HttpHandler = (req: HttpRequest, res: HttpResponse) => void | Promise<void>;
96
+ /**
97
+ * @zh HTTP 中间件函数
98
+ * @en HTTP middleware function
99
+ *
100
+ * @example
101
+ * ```typescript
102
+ * const authMiddleware: HttpMiddleware = async (req, res, next) => {
103
+ * if (!req.headers.authorization) {
104
+ * res.error(401, 'Unauthorized');
105
+ * return;
106
+ * }
107
+ * await next();
108
+ * };
109
+ * ```
110
+ */
111
+ type HttpMiddleware = (req: HttpRequest, res: HttpResponse, next: () => Promise<void>) => void | Promise<void>;
112
+ /**
113
+ * @zh 带中间件和超时的路由处理器定义
114
+ * @en Route handler definition with middleware and timeout support
115
+ */
116
+ interface HttpHandlerDefinition {
117
+ /**
118
+ * @zh 处理函数
119
+ * @en Handler function
120
+ */
121
+ handler: HttpHandler;
122
+ /**
123
+ * @zh 路由级中间件
124
+ * @en Route-level middlewares
125
+ */
126
+ middlewares?: HttpMiddleware[];
127
+ /**
128
+ * @zh 路由级超时时间(毫秒),覆盖全局设置
129
+ * @en Route-level timeout in milliseconds, overrides global setting
130
+ */
131
+ timeout?: number;
132
+ }
133
+ /**
134
+ * @zh HTTP 路由方法配置(支持简单处理器或完整定义)
135
+ * @en HTTP route method configuration (supports simple handler or full definition)
136
+ */
137
+ type HttpMethodHandler = HttpHandler | HttpHandlerDefinition;
138
+ /**
139
+ * @zh HTTP 路由方法映射
140
+ * @en HTTP route methods mapping
141
+ */
142
+ interface HttpRouteMethods {
143
+ GET?: HttpMethodHandler;
144
+ POST?: HttpMethodHandler;
145
+ PUT?: HttpMethodHandler;
146
+ DELETE?: HttpMethodHandler;
147
+ PATCH?: HttpMethodHandler;
148
+ OPTIONS?: HttpMethodHandler;
149
+ }
150
+ /**
151
+ * @zh HTTP 路由配置
152
+ * @en HTTP routes configuration
153
+ *
154
+ * @example
155
+ * ```typescript
156
+ * const routes: HttpRoutes = {
157
+ * // 简单处理器
158
+ * '/health': (req, res) => res.json({ ok: true }),
159
+ *
160
+ * // 按方法分开
161
+ * '/users': {
162
+ * GET: (req, res) => res.json([]),
163
+ * POST: (req, res) => res.json({ created: true })
164
+ * },
165
+ *
166
+ * // 路由参数
167
+ * '/users/:id': {
168
+ * GET: (req, res) => res.json({ id: req.params.id }),
169
+ * DELETE: {
170
+ * handler: (req, res) => res.json({ deleted: true }),
171
+ * middlewares: [authMiddleware],
172
+ * timeout: 5000
173
+ * }
174
+ * }
175
+ * };
176
+ * ```
177
+ */
178
+ type HttpRoutes = Record<string, HttpMethodHandler | HttpRouteMethods>;
179
+ /**
180
+ * @zh CORS 配置
181
+ * @en CORS configuration
182
+ */
183
+ interface CorsOptions {
184
+ /**
185
+ * @zh 允许的来源
186
+ * @en Allowed origins
187
+ */
188
+ origin?: string | string[] | boolean;
189
+ /**
190
+ * @zh 允许的方法
191
+ * @en Allowed methods
192
+ */
193
+ methods?: string[];
194
+ /**
195
+ * @zh 允许的请求头
196
+ * @en Allowed headers
197
+ */
198
+ allowedHeaders?: string[];
199
+ /**
200
+ * @zh 是否允许携带凭证
201
+ * @en Allow credentials
202
+ */
203
+ credentials?: boolean;
204
+ /**
205
+ * @zh 预检请求缓存时间(秒)
206
+ * @en Preflight cache max age
207
+ */
208
+ maxAge?: number;
209
+ }
210
+ /**
211
+ * @zh HTTP 路由器选项
212
+ * @en HTTP router options
213
+ */
214
+ interface HttpRouterOptions {
215
+ /**
216
+ * @zh CORS 配置
217
+ * @en CORS configuration
218
+ */
219
+ cors?: CorsOptions | boolean;
220
+ /**
221
+ * @zh 全局请求超时时间(毫秒)
222
+ * @en Global request timeout in milliseconds
223
+ */
224
+ timeout?: number;
225
+ /**
226
+ * @zh 全局中间件
227
+ * @en Global middlewares
228
+ */
229
+ middlewares?: HttpMiddleware[];
230
+ }
231
+
232
+ /**
233
+ * @zh 分布式适配器接口
234
+ * @en Distributed adapter interface
235
+ *
236
+ * @zh 定义分布式房间系统的存储和通信层抽象
237
+ * @en Defines the storage and communication layer abstraction for distributed room system
238
+ */
239
+
240
+ /**
241
+ * @zh 分布式适配器接口
242
+ * @en Distributed adapter interface
243
+ *
244
+ * @zh 所有分布式后端(Redis、消息队列等)都需要实现此接口
245
+ * @en All distributed backends (Redis, message queue, etc.) must implement this interface
246
+ */
247
+ interface IDistributedAdapter {
248
+ /**
249
+ * @zh 连接到分布式后端
250
+ * @en Connect to distributed backend
251
+ */
252
+ connect(): Promise<void>;
253
+ /**
254
+ * @zh 断开连接
255
+ * @en Disconnect from backend
256
+ */
257
+ disconnect(): Promise<void>;
258
+ /**
259
+ * @zh 检查是否已连接
260
+ * @en Check if connected
261
+ */
262
+ isConnected(): boolean;
263
+ /**
264
+ * @zh 注册服务器
265
+ * @en Register server
266
+ *
267
+ * @param server - 服务器注册信息 | Server registration info
268
+ */
269
+ registerServer(server: ServerRegistration): Promise<void>;
270
+ /**
271
+ * @zh 注销服务器
272
+ * @en Unregister server
273
+ *
274
+ * @param serverId - 服务器 ID | Server ID
275
+ */
276
+ unregisterServer(serverId: string): Promise<void>;
277
+ /**
278
+ * @zh 更新服务器心跳
279
+ * @en Update server heartbeat
280
+ *
281
+ * @param serverId - 服务器 ID | Server ID
282
+ */
283
+ heartbeat(serverId: string): Promise<void>;
284
+ /**
285
+ * @zh 获取所有在线服务器
286
+ * @en Get all online servers
287
+ */
288
+ getServers(): Promise<ServerRegistration[]>;
289
+ /**
290
+ * @zh 获取指定服务器
291
+ * @en Get specific server
292
+ *
293
+ * @param serverId - 服务器 ID | Server ID
294
+ */
295
+ getServer(serverId: string): Promise<ServerRegistration | null>;
296
+ /**
297
+ * @zh 更新服务器信息
298
+ * @en Update server info
299
+ *
300
+ * @param serverId - 服务器 ID | Server ID
301
+ * @param updates - 更新内容 | Updates
302
+ */
303
+ updateServer(serverId: string, updates: Partial<ServerRegistration>): Promise<void>;
304
+ /**
305
+ * @zh 注册房间
306
+ * @en Register room
307
+ *
308
+ * @param room - 房间注册信息 | Room registration info
309
+ */
310
+ registerRoom(room: RoomRegistration): Promise<void>;
311
+ /**
312
+ * @zh 注销房间
313
+ * @en Unregister room
314
+ *
315
+ * @param roomId - 房间 ID | Room ID
316
+ */
317
+ unregisterRoom(roomId: string): Promise<void>;
318
+ /**
319
+ * @zh 更新房间信息
320
+ * @en Update room info
321
+ *
322
+ * @param roomId - 房间 ID | Room ID
323
+ * @param updates - 更新内容 | Updates
324
+ */
325
+ updateRoom(roomId: string, updates: Partial<RoomRegistration>): Promise<void>;
326
+ /**
327
+ * @zh 获取房间信息
328
+ * @en Get room info
329
+ *
330
+ * @param roomId - 房间 ID | Room ID
331
+ */
332
+ getRoom(roomId: string): Promise<RoomRegistration | null>;
333
+ /**
334
+ * @zh 查询房间列表
335
+ * @en Query room list
336
+ *
337
+ * @param query - 查询条件 | Query criteria
338
+ */
339
+ queryRooms(query: RoomQuery): Promise<RoomRegistration[]>;
340
+ /**
341
+ * @zh 获取指定类型的可用房间(用于 joinOrCreate)
342
+ * @en Get available room of type (for joinOrCreate)
343
+ *
344
+ * @param roomType - 房间类型 | Room type
345
+ */
346
+ findAvailableRoom(roomType: string): Promise<RoomRegistration | null>;
347
+ /**
348
+ * @zh 获取服务器的所有房间
349
+ * @en Get all rooms of a server
350
+ *
351
+ * @param serverId - 服务器 ID | Server ID
352
+ */
353
+ getRoomsByServer(serverId: string): Promise<RoomRegistration[]>;
354
+ /**
355
+ * @zh 保存房间状态快照
356
+ * @en Save room state snapshot
357
+ *
358
+ * @param snapshot - 状态快照 | State snapshot
359
+ */
360
+ saveSnapshot(snapshot: RoomSnapshot): Promise<void>;
361
+ /**
362
+ * @zh 加载房间状态快照
363
+ * @en Load room state snapshot
364
+ *
365
+ * @param roomId - 房间 ID | Room ID
366
+ */
367
+ loadSnapshot(roomId: string): Promise<RoomSnapshot | null>;
368
+ /**
369
+ * @zh 删除房间状态
370
+ * @en Delete room state
371
+ *
372
+ * @param roomId - 房间 ID | Room ID
373
+ */
374
+ deleteSnapshot(roomId: string): Promise<void>;
375
+ /**
376
+ * @zh 发布事件
377
+ * @en Publish event
378
+ *
379
+ * @param event - 分布式事件 | Distributed event
380
+ */
381
+ publish(event: DistributedEvent): Promise<void>;
382
+ /**
383
+ * @zh 订阅事件
384
+ * @en Subscribe to events
385
+ *
386
+ * @param pattern - 事件类型模式(支持 '*' 通配符) | Event type pattern (supports '*' wildcard)
387
+ * @param handler - 事件处理器 | Event handler
388
+ * @returns 取消订阅函数 | Unsubscribe function
389
+ */
390
+ subscribe(pattern: DistributedEventType | '*', handler: DistributedEventHandler): Promise<Unsubscribe>;
391
+ /**
392
+ * @zh 向特定房间发送消息(跨服务器)
393
+ * @en Send message to specific room (cross-server)
394
+ *
395
+ * @param roomId - 房间 ID | Room ID
396
+ * @param messageType - 消息类型 | Message type
397
+ * @param data - 消息数据 | Message data
398
+ * @param playerId - 发送者玩家 ID(可选) | Sender player ID (optional)
399
+ */
400
+ sendToRoom(roomId: string, messageType: string, data: unknown, playerId?: string): Promise<void>;
401
+ /**
402
+ * @zh 获取分布式锁
403
+ * @en Acquire distributed lock
404
+ *
405
+ * @param key - 锁的键名 | Lock key
406
+ * @param ttlMs - 锁的生存时间(毫秒) | Lock TTL (ms)
407
+ * @returns 是否成功获取锁 | Whether lock was acquired
408
+ */
409
+ acquireLock(key: string, ttlMs: number): Promise<boolean>;
410
+ /**
411
+ * @zh 释放分布式锁
412
+ * @en Release distributed lock
413
+ *
414
+ * @param key - 锁的键名 | Lock key
415
+ */
416
+ releaseLock(key: string): Promise<void>;
417
+ /**
418
+ * @zh 扩展锁的生存时间
419
+ * @en Extend lock TTL
420
+ *
421
+ * @param key - 锁的键名 | Lock key
422
+ * @param ttlMs - 新的生存时间(毫秒) | New TTL (ms)
423
+ * @returns 是否成功扩展 | Whether extension was successful
424
+ */
425
+ extendLock(key: string, ttlMs: number): Promise<boolean>;
426
+ }
427
+
428
+ /**
429
+ * @zh 分布式房间支持类型定义
430
+ * @en Distributed room support type definitions
431
+ */
432
+ /**
433
+ * @zh 服务器状态
434
+ * @en Server status
435
+ */
436
+ type ServerStatus = 'online' | 'draining' | 'offline';
437
+ /**
438
+ * @zh 服务器注册信息
439
+ * @en Server registration info
440
+ */
441
+ interface ServerRegistration {
442
+ /**
443
+ * @zh 服务器唯一标识
444
+ * @en Server unique identifier
445
+ */
446
+ serverId: string;
447
+ /**
448
+ * @zh 服务器地址(供客户端连接)
449
+ * @en Server address (for client connection)
450
+ */
451
+ address: string;
452
+ /**
453
+ * @zh 服务器端口
454
+ * @en Server port
455
+ */
456
+ port: number;
457
+ /**
458
+ * @zh 当前房间数量
459
+ * @en Current room count
460
+ */
461
+ roomCount: number;
462
+ /**
463
+ * @zh 当前玩家数量
464
+ * @en Current player count
465
+ */
466
+ playerCount: number;
467
+ /**
468
+ * @zh 服务器容量(最大房间数)
469
+ * @en Server capacity (max rooms)
470
+ */
471
+ capacity: number;
472
+ /**
473
+ * @zh 服务器状态
474
+ * @en Server status
475
+ */
476
+ status: ServerStatus;
477
+ /**
478
+ * @zh 最后心跳时间戳
479
+ * @en Last heartbeat timestamp
480
+ */
481
+ lastHeartbeat: number;
482
+ /**
483
+ * @zh 服务器元数据
484
+ * @en Server metadata
485
+ */
486
+ metadata?: Record<string, unknown>;
487
+ }
488
+ /**
489
+ * @zh 房间注册信息
490
+ * @en Room registration info
491
+ */
492
+ interface RoomRegistration {
493
+ /**
494
+ * @zh 房间唯一标识
495
+ * @en Room unique identifier
496
+ */
497
+ roomId: string;
498
+ /**
499
+ * @zh 房间类型名称
500
+ * @en Room type name
501
+ */
502
+ roomType: string;
503
+ /**
504
+ * @zh 所在服务器 ID
505
+ * @en Host server ID
506
+ */
507
+ serverId: string;
508
+ /**
509
+ * @zh 服务器地址
510
+ * @en Server address
511
+ */
512
+ serverAddress: string;
513
+ /**
514
+ * @zh 当前玩家数量
515
+ * @en Current player count
516
+ */
517
+ playerCount: number;
518
+ /**
519
+ * @zh 最大玩家数量
520
+ * @en Max player count
521
+ */
522
+ maxPlayers: number;
523
+ /**
524
+ * @zh 房间是否已锁定
525
+ * @en Whether room is locked
526
+ */
527
+ isLocked: boolean;
528
+ /**
529
+ * @zh 房间元数据(标签、自定义属性等)
530
+ * @en Room metadata (tags, custom properties, etc.)
531
+ */
532
+ metadata: Record<string, unknown>;
533
+ /**
534
+ * @zh 创建时间戳
535
+ * @en Creation timestamp
536
+ */
537
+ createdAt: number;
538
+ /**
539
+ * @zh 更新时间戳
540
+ * @en Update timestamp
541
+ */
542
+ updatedAt: number;
543
+ }
544
+ /**
545
+ * @zh 房间查询条件
546
+ * @en Room query criteria
547
+ */
548
+ interface RoomQuery {
549
+ /**
550
+ * @zh 房间类型
551
+ * @en Room type
552
+ */
553
+ roomType?: string;
554
+ /**
555
+ * @zh 服务器 ID(查询特定服务器上的房间)
556
+ * @en Server ID (query rooms on specific server)
557
+ */
558
+ serverId?: string;
559
+ /**
560
+ * @zh 是否有空位
561
+ * @en Whether has available space
562
+ */
563
+ hasSpace?: boolean;
564
+ /**
565
+ * @zh 是否未锁定
566
+ * @en Whether not locked
567
+ */
568
+ notLocked?: boolean;
569
+ /**
570
+ * @zh 元数据过滤
571
+ * @en Metadata filter
572
+ */
573
+ metadata?: Record<string, unknown>;
574
+ /**
575
+ * @zh 返回数量限制
576
+ * @en Result limit
577
+ */
578
+ limit?: number;
579
+ /**
580
+ * @zh 偏移量(分页)
581
+ * @en Offset (pagination)
582
+ */
583
+ offset?: number;
584
+ }
585
+ /**
586
+ * @zh 玩家快照
587
+ * @en Player snapshot
588
+ */
589
+ interface PlayerSnapshot {
590
+ /**
591
+ * @zh 玩家 ID
592
+ * @en Player ID
593
+ */
594
+ id: string;
595
+ /**
596
+ * @zh 玩家数据
597
+ * @en Player data
598
+ */
599
+ data: Record<string, unknown>;
600
+ }
601
+ /**
602
+ * @zh 房间状态快照
603
+ * @en Room state snapshot
604
+ */
605
+ interface RoomSnapshot<TState = unknown> {
606
+ /**
607
+ * @zh 房间 ID
608
+ * @en Room ID
609
+ */
610
+ roomId: string;
611
+ /**
612
+ * @zh 房间类型
613
+ * @en Room type
614
+ */
615
+ roomType: string;
616
+ /**
617
+ * @zh 房间状态
618
+ * @en Room state
619
+ */
620
+ state: TState;
621
+ /**
622
+ * @zh 玩家列表
623
+ * @en Player list
624
+ */
625
+ players: PlayerSnapshot[];
626
+ /**
627
+ * @zh 快照版本号
628
+ * @en Snapshot version
629
+ */
630
+ version: number;
631
+ /**
632
+ * @zh 快照时间戳
633
+ * @en Snapshot timestamp
634
+ */
635
+ timestamp: number;
636
+ }
637
+ /**
638
+ * @zh 分布式事件类型
639
+ * @en Distributed event types
640
+ */
641
+ type DistributedEventType = 'room:created' | 'room:disposed' | 'room:updated' | 'room:locked' | 'room:unlocked' | 'room:message' | 'room:migrated' | 'player:joined' | 'player:left' | 'server:online' | 'server:offline' | 'server:draining';
642
+ /**
643
+ * @zh 分布式事件
644
+ * @en Distributed event
645
+ */
646
+ interface DistributedEvent<T = unknown> {
647
+ /**
648
+ * @zh 事件类型
649
+ * @en Event type
650
+ */
651
+ type: DistributedEventType;
652
+ /**
653
+ * @zh 发送方服务器 ID
654
+ * @en Sender server ID
655
+ */
656
+ serverId: string;
657
+ /**
658
+ * @zh 相关房间 ID(可选)
659
+ * @en Related room ID (optional)
660
+ */
661
+ roomId?: string;
662
+ /**
663
+ * @zh 事件载荷
664
+ * @en Event payload
665
+ */
666
+ payload: T;
667
+ /**
668
+ * @zh 事件时间戳
669
+ * @en Event timestamp
670
+ */
671
+ timestamp: number;
672
+ }
673
+ /**
674
+ * @zh 事件处理器
675
+ * @en Event handler
676
+ */
677
+ type DistributedEventHandler<T = unknown> = (event: DistributedEvent<T>) => void;
678
+ /**
679
+ * @zh 取消订阅函数
680
+ * @en Unsubscribe function
681
+ */
682
+ type Unsubscribe = () => void;
683
+ /**
684
+ * @zh 分布式房间管理器配置
685
+ * @en Distributed room manager configuration
686
+ */
687
+ interface DistributedRoomManagerConfig {
688
+ /**
689
+ * @zh 服务器 ID(唯一标识)
690
+ * @en Server ID (unique identifier)
691
+ */
692
+ serverId: string;
693
+ /**
694
+ * @zh 服务器公开地址(供客户端连接)
695
+ * @en Server public address (for client connection)
696
+ */
697
+ serverAddress: string;
698
+ /**
699
+ * @zh 服务器端口
700
+ * @en Server port
701
+ */
702
+ serverPort: number;
703
+ /**
704
+ * @zh 心跳间隔(毫秒)
705
+ * @en Heartbeat interval (ms)
706
+ * @default 5000
707
+ */
708
+ heartbeatInterval?: number;
709
+ /**
710
+ * @zh 状态快照间隔(毫秒),0 = 禁用
711
+ * @en State snapshot interval (ms), 0 = disabled
712
+ * @default 30000
713
+ */
714
+ snapshotInterval?: number;
715
+ /**
716
+ * @zh 房间迁移超时(毫秒)
717
+ * @en Room migration timeout (ms)
718
+ * @default 10000
719
+ */
720
+ migrationTimeout?: number;
721
+ /**
722
+ * @zh 是否启用自动故障转移
723
+ * @en Whether to enable automatic failover
724
+ * @default true
725
+ */
726
+ enableFailover?: boolean;
727
+ /**
728
+ * @zh 服务器容量(最大房间数)
729
+ * @en Server capacity (max rooms)
730
+ * @default 100
731
+ */
732
+ capacity?: number;
733
+ /**
734
+ * @zh 服务器元数据
735
+ * @en Server metadata
736
+ */
737
+ metadata?: Record<string, unknown>;
738
+ }
739
+ /**
740
+ * @zh 服务器分布式配置(用于 createServer)
741
+ * @en Server distributed configuration (for createServer)
742
+ */
743
+ interface DistributedConfig extends Omit<DistributedRoomManagerConfig, 'serverPort'> {
744
+ /**
745
+ * @zh 是否启用分布式模式
746
+ * @en Whether to enable distributed mode
747
+ * @default false
748
+ */
749
+ enabled: boolean;
750
+ /**
751
+ * @zh 分布式适配器(可选,默认使用 MemoryAdapter)
752
+ * @en Distributed adapter (optional, defaults to MemoryAdapter)
753
+ */
754
+ adapter?: IDistributedAdapter;
755
+ /**
756
+ * @zh 服务器端口(可选,默认使用服务器配置的端口)
757
+ * @en Server port (optional, defaults to server config port)
758
+ */
759
+ serverPort?: number;
760
+ }
761
+ /**
762
+ * @zh 路由结果类型
763
+ * @en Routing result type
764
+ */
765
+ type RoutingResultType = 'local' | 'redirect' | 'create' | 'unavailable';
766
+ /**
767
+ * @zh 路由结果
768
+ * @en Routing result
769
+ */
770
+ interface RoutingResult {
771
+ /**
772
+ * @zh 路由类型
773
+ * @en Routing type
774
+ */
775
+ type: RoutingResultType;
776
+ /**
777
+ * @zh 目标服务器地址(redirect 时)
778
+ * @en Target server address (for redirect)
779
+ */
780
+ serverAddress?: string;
781
+ /**
782
+ * @zh 目标房间 ID
783
+ * @en Target room ID
784
+ */
785
+ roomId?: string;
786
+ /**
787
+ * @zh 错误信息(unavailable 时)
788
+ * @en Error message (for unavailable)
789
+ */
790
+ reason?: string;
791
+ }
792
+ /**
793
+ * @zh 路由请求
794
+ * @en Routing request
795
+ */
796
+ interface RoutingRequest {
797
+ /**
798
+ * @zh 玩家 ID
799
+ * @en Player ID
800
+ */
801
+ playerId: string;
802
+ /**
803
+ * @zh 房间类型(joinOrCreate 时)
804
+ * @en Room type (for joinOrCreate)
805
+ */
806
+ roomType?: string;
807
+ /**
808
+ * @zh 房间 ID(joinById 时)
809
+ * @en Room ID (for joinById)
810
+ */
811
+ roomId?: string;
812
+ /**
813
+ * @zh 首选服务器 ID
814
+ * @en Preferred server ID
815
+ */
816
+ preferredServerId?: string;
817
+ /**
818
+ * @zh 房间查询条件
819
+ * @en Room query criteria
820
+ */
821
+ query?: RoomQuery;
822
+ }
823
+
824
+ /**
825
+ * @zh ESEngine Server 类型定义
826
+ * @en ESEngine Server type definitions
827
+ */
828
+
829
+ /**
830
+ * @zh 服务器配置
831
+ * @en Server configuration
832
+ */
833
+ interface ServerConfig {
834
+ /**
835
+ * @zh 监听端口
836
+ * @en Listen port
837
+ * @default 3000
838
+ */
839
+ port?: number;
840
+ /**
841
+ * @zh API 目录路径
842
+ * @en API directory path
843
+ * @default 'src/api'
844
+ */
845
+ apiDir?: string;
846
+ /**
847
+ * @zh 消息处理器目录路径
848
+ * @en Message handlers directory path
849
+ * @default 'src/msg'
850
+ */
851
+ msgDir?: string;
852
+ /**
853
+ * @zh HTTP 路由目录路径
854
+ * @en HTTP routes directory path
855
+ * @default 'src/http'
856
+ *
857
+ * @zh 文件命名规则:
858
+ * - `login.ts` → POST /api/login
859
+ * - `users/[id].ts` → /api/users/:id
860
+ * - `health.ts` (method: 'GET') → GET /api/health
861
+ * @en File naming convention:
862
+ * - `login.ts` → POST /api/login
863
+ * - `users/[id].ts` → /api/users/:id
864
+ * - `health.ts` (method: 'GET') → GET /api/health
865
+ */
866
+ httpDir?: string;
867
+ /**
868
+ * @zh HTTP 路由前缀
869
+ * @en HTTP routes prefix
870
+ * @default '/api'
871
+ */
872
+ httpPrefix?: string;
873
+ /**
874
+ * @zh 游戏 Tick 速率 (每秒)
875
+ * @en Game tick rate (per second)
876
+ * @default 20
877
+ */
878
+ tickRate?: number;
879
+ /**
880
+ * @zh HTTP 路由配置(内联定义,与 httpDir 文件路由合并)
881
+ * @en HTTP routes configuration (inline definition, merged with httpDir file routes)
882
+ */
883
+ http?: HttpRoutes;
884
+ /**
885
+ * @zh CORS 配置
886
+ * @en CORS configuration
887
+ * @default true
888
+ */
889
+ cors?: CorsOptions | boolean;
890
+ /**
891
+ * @zh 服务器启动回调
892
+ * @en Server start callback
893
+ */
894
+ onStart?: (port: number) => void;
895
+ /**
896
+ * @zh 连接建立回调
897
+ * @en Connection established callback
898
+ */
899
+ onConnect?: (conn: ServerConnection) => void | Promise<void>;
900
+ /**
901
+ * @zh 连接断开回调
902
+ * @en Connection closed callback
903
+ */
904
+ onDisconnect?: (conn: ServerConnection) => void | Promise<void>;
905
+ /**
906
+ * @zh 分布式模式配置
907
+ * @en Distributed mode configuration
908
+ *
909
+ * @example
910
+ * ```typescript
911
+ * const server = await createServer({
912
+ * port: 3000,
913
+ * distributed: {
914
+ * enabled: true,
915
+ * adapter: new RedisAdapter({ factory: () => new Redis() }),
916
+ * serverId: 'server-1',
917
+ * serverAddress: 'ws://192.168.1.100',
918
+ * serverPort: 3000
919
+ * }
920
+ * });
921
+ * ```
922
+ */
923
+ distributed?: DistributedConfig;
924
+ }
925
+ /**
926
+ * @zh 服务器连接(扩展 RPC Connection)
927
+ * @en Server connection (extends RPC Connection)
928
+ */
929
+ interface ServerConnection<TData = Record<string, unknown>> extends Connection<TData> {
930
+ /**
931
+ * @zh 连接唯一标识(继承自 Connection)
932
+ * @en Connection unique identifier (inherited from Connection)
933
+ */
934
+ readonly id: string;
935
+ /**
936
+ * @zh 用户自定义数据
937
+ * @en User-defined data
938
+ */
939
+ data: TData;
940
+ }
941
+ /**
942
+ * @zh API 处理器上下文
943
+ * @en API handler context
944
+ */
945
+ interface ApiContext<TData = Record<string, unknown>> {
946
+ /**
947
+ * @zh 当前连接
948
+ * @en Current connection
949
+ */
950
+ conn: ServerConnection<TData>;
951
+ /**
952
+ * @zh 服务器实例
953
+ * @en Server instance
954
+ */
955
+ server: GameServer;
956
+ }
957
+ /**
958
+ * @zh API 定义选项
959
+ * @en API definition options
960
+ */
961
+ interface ApiDefinition<TReq = unknown, TRes = unknown, TData = Record<string, unknown>> {
962
+ /**
963
+ * @zh API 处理函数
964
+ * @en API handler function
965
+ */
966
+ handler: (req: TReq, ctx: ApiContext<TData>) => TRes | Promise<TRes>;
967
+ }
968
+ /**
969
+ * @zh 消息处理器上下文
970
+ * @en Message handler context
971
+ */
972
+ interface MsgContext<TData = Record<string, unknown>> {
973
+ /**
974
+ * @zh 当前连接
975
+ * @en Current connection
976
+ */
977
+ conn: ServerConnection<TData>;
978
+ /**
979
+ * @zh 服务器实例
980
+ * @en Server instance
981
+ */
982
+ server: GameServer;
983
+ }
984
+ /**
985
+ * @zh 消息定义选项
986
+ * @en Message definition options
987
+ */
988
+ interface MsgDefinition<TMsg = unknown, TData = Record<string, unknown>> {
989
+ /**
990
+ * @zh 消息处理函数
991
+ * @en Message handler function
992
+ */
993
+ handler: (msg: TMsg, ctx: MsgContext<TData>) => void | Promise<void>;
994
+ }
995
+ /**
996
+ * @zh 游戏服务器接口
997
+ * @en Game server interface
998
+ */
999
+ interface GameServer {
1000
+ /**
1001
+ * @zh 启动服务器
1002
+ * @en Start server
1003
+ */
1004
+ start(): Promise<void>;
1005
+ /**
1006
+ * @zh 停止服务器
1007
+ * @en Stop server
1008
+ */
1009
+ stop(): Promise<void>;
1010
+ /**
1011
+ * @zh 广播消息
1012
+ * @en Broadcast message
1013
+ */
1014
+ broadcast<T>(name: string, data: T): void;
1015
+ /**
1016
+ * @zh 发送消息给指定连接
1017
+ * @en Send message to specific connection
1018
+ */
1019
+ send<T>(conn: ServerConnection, name: string, data: T): void;
1020
+ /**
1021
+ * @zh 获取所有连接
1022
+ * @en Get all connections
1023
+ */
1024
+ readonly connections: ReadonlyArray<ServerConnection>;
1025
+ /**
1026
+ * @zh 当前 Tick
1027
+ * @en Current tick
1028
+ */
1029
+ readonly tick: number;
1030
+ /**
1031
+ * @zh 注册房间类型
1032
+ * @en Define room type
1033
+ */
1034
+ define(name: string, roomClass: new () => unknown): void;
1035
+ }
1036
+ /**
1037
+ * @zh HTTP 请求方法
1038
+ * @en HTTP request method
1039
+ */
1040
+ type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
1041
+ /**
1042
+ * @zh HTTP 定义选项
1043
+ * @en HTTP definition options
1044
+ *
1045
+ * @example
1046
+ * ```typescript
1047
+ * // src/http/login.ts
1048
+ * import { defineHttp } from '@esengine/server'
1049
+ *
1050
+ * export default defineHttp({
1051
+ * method: 'POST',
1052
+ * handler: async (req, res) => {
1053
+ * const { username, password } = req.body
1054
+ * // ... authentication logic
1055
+ * res.json({ token: '...', userId: '...' })
1056
+ * }
1057
+ * })
1058
+ * ```
1059
+ */
1060
+ interface HttpDefinition<TBody = unknown> {
1061
+ /**
1062
+ * @zh 请求方法
1063
+ * @en Request method
1064
+ * @default 'POST'
1065
+ */
1066
+ method?: HttpMethod;
1067
+ /**
1068
+ * @zh 处理函数
1069
+ * @en Handler function
1070
+ */
1071
+ handler: (req: HttpRequest & {
1072
+ body: TBody;
1073
+ }, res: HttpResponse) => void | Promise<void>;
1074
+ }
1075
+
1076
+ export type { ApiContext as A, CorsOptions as C, DistributedEvent as D, GameServer as G, HttpDefinition as H, IDistributedAdapter as I, MsgContext as M, RoomRegistration as R, ServerConnection as S, Unsubscribe as U, ServerConfig as a, ApiDefinition as b, MsgDefinition as c, HttpRoutes as d, HttpRouterOptions as e, ServerRegistration as f, RoomQuery as g, RoomSnapshot as h, DistributedEventType as i, DistributedEventHandler as j, DistributedRoomManagerConfig as k, RoutingRequest as l, RoutingResult as m, HttpMethod as n, HttpRequest as o, HttpResponse as p, HttpHandler as q, ServerStatus as r, DistributedConfig as s };