@esengine/server 4.4.0 → 4.5.1

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.
package/dist/index.d.ts CHANGED
@@ -1,9 +1,11 @@
1
- import { S as ServerConfig, G as GameServer, A as ApiDefinition, M as MsgDefinition, H as HttpDefinition, a as HttpRoutes, b as HttpRouterOptions } from './index-lcuKuQsL.js';
2
- export { d as ApiContext, C as CorsOptions, i as HttpHandler, f as HttpMethod, g as HttpRequest, h as HttpResponse, e as MsgContext, c as ServerConnection } from './index-lcuKuQsL.js';
3
- export { I as IPlayer, P as Player, R as Room, a as RoomOptions } from './Room-BnKpl5Sj.js';
4
- export { o as onMessage } from './decorators-DY8nZ8Nh.js';
1
+ import { a as ServerConfig, G as GameServer, b as ApiDefinition, c as MsgDefinition, H as HttpDefinition, d as HttpRoutes, e as HttpRouterOptions, I as IDistributedAdapter, f as ServerRegistration, R as RoomRegistration, g as RoomQuery, h as RoomSnapshot, D as DistributedEvent, i as DistributedEventType, j as DistributedEventHandler, U as Unsubscribe, k as DistributedRoomManagerConfig, l as RoutingRequest, m as RoutingResult } from './index-B1sr5YAl.js';
2
+ export { A as ApiContext, C as CorsOptions, s as DistributedConfig, q as HttpHandler, n as HttpMethod, o as HttpRequest, p as HttpResponse, M as MsgContext, S as ServerConnection, r as ServerStatus } from './index-B1sr5YAl.js';
3
+ import { R as Room, a as RoomOptions, P as Player } from './Room-5owFVIFR.js';
4
+ export { I as IPlayer } from './Room-5owFVIFR.js';
5
+ export { ECSRoom, ECSRoomConfig, onMessage } from './ecs/index.js';
5
6
  import { IncomingMessage, ServerResponse } from 'node:http';
6
7
  export { ErrorCode, RpcError } from '@esengine/rpc';
8
+ import '@esengine/ecs-framework';
7
9
 
8
10
  /**
9
11
  * @zh 游戏服务器核心
@@ -31,11 +33,584 @@ export { ErrorCode, RpcError } from '@esengine/rpc';
31
33
  */
32
34
  declare function createServer(config?: ServerConfig): Promise<GameServer>;
33
35
 
36
+ /**
37
+ * @zh Schema 验证类型定义
38
+ * @en Schema validation type definitions
39
+ */
40
+ /**
41
+ * @zh 验证错误
42
+ * @en Validation error
43
+ */
44
+ interface ValidationError {
45
+ /**
46
+ * @zh 错误路径(如 ['user', 'name'])
47
+ * @en Error path (e.g., ['user', 'name'])
48
+ */
49
+ path: string[];
50
+ /**
51
+ * @zh 错误消息
52
+ * @en Error message
53
+ */
54
+ message: string;
55
+ /**
56
+ * @zh 预期类型
57
+ * @en Expected type
58
+ */
59
+ expected?: string;
60
+ /**
61
+ * @zh 实际值
62
+ * @en Actual value
63
+ */
64
+ received?: unknown;
65
+ }
66
+ /**
67
+ * @zh 验证成功结果
68
+ * @en Validation success result
69
+ */
70
+ interface ValidationSuccess<T> {
71
+ success: true;
72
+ data: T;
73
+ }
74
+ /**
75
+ * @zh 验证失败结果
76
+ * @en Validation failure result
77
+ */
78
+ interface ValidationFailure {
79
+ success: false;
80
+ error: ValidationError;
81
+ }
82
+ /**
83
+ * @zh 验证结果
84
+ * @en Validation result
85
+ */
86
+ type ValidationResult<T> = ValidationSuccess<T> | ValidationFailure;
87
+ /**
88
+ * @zh 验证器接口
89
+ * @en Validator interface
90
+ */
91
+ interface Validator<T> {
92
+ /**
93
+ * @zh 类型名称(用于错误消息)
94
+ * @en Type name (for error messages)
95
+ */
96
+ readonly typeName: string;
97
+ /**
98
+ * @zh 验证值
99
+ * @en Validate value
100
+ *
101
+ * @param value - @zh 待验证的值 @en Value to validate
102
+ * @param path - @zh 当前路径(用于错误报告)@en Current path (for error reporting)
103
+ * @returns @zh 验证结果 @en Validation result
104
+ */
105
+ validate(value: unknown, path?: string[]): ValidationResult<T>;
106
+ /**
107
+ * @zh 类型守卫检查
108
+ * @en Type guard check
109
+ *
110
+ * @param value - @zh 待检查的值 @en Value to check
111
+ * @returns @zh 是否为指定类型 @en Whether value is of specified type
112
+ */
113
+ is(value: unknown): value is T;
114
+ /**
115
+ * @zh 标记为可选
116
+ * @en Mark as optional
117
+ */
118
+ optional(): Validator<T | undefined>;
119
+ /**
120
+ * @zh 设置默认值
121
+ * @en Set default value
122
+ *
123
+ * @param defaultValue - @zh 默认值 @en Default value
124
+ */
125
+ default(defaultValue: T): Validator<T>;
126
+ /**
127
+ * @zh 允许 null
128
+ * @en Allow null
129
+ */
130
+ nullable(): Validator<T | null>;
131
+ }
132
+ /**
133
+ * @zh 从验证器推断类型
134
+ * @en Infer type from validator
135
+ */
136
+ type Infer<V extends Validator<unknown>> = V extends Validator<infer T> ? T : never;
137
+ /**
138
+ * @zh 对象 Schema 定义
139
+ * @en Object schema definition
140
+ */
141
+ type ObjectShape = Record<string, Validator<unknown>>;
142
+ /**
143
+ * @zh 从对象 Shape 推断类型
144
+ * @en Infer type from object shape
145
+ */
146
+ type InferShape<T extends ObjectShape> = {
147
+ [K in keyof T]: Infer<T[K]>;
148
+ };
149
+ /**
150
+ * @zh 验证器选项
151
+ * @en Validator options
152
+ */
153
+ interface ValidatorOptions {
154
+ /**
155
+ * @zh 是否可选
156
+ * @en Whether optional
157
+ */
158
+ isOptional?: boolean;
159
+ /**
160
+ * @zh 默认值
161
+ * @en Default value
162
+ */
163
+ defaultValue?: unknown;
164
+ /**
165
+ * @zh 是否允许 null
166
+ * @en Whether nullable
167
+ */
168
+ isNullable?: boolean;
169
+ }
170
+
171
+ /**
172
+ * @zh 基础验证器抽象类
173
+ * @en Base validator abstract class
174
+ *
175
+ * @zh 所有验证器的基类,提供通用的验证逻辑
176
+ * @en Base class for all validators, providing common validation logic
177
+ */
178
+
179
+ /**
180
+ * @zh 基础验证器抽象类
181
+ * @en Base validator abstract class
182
+ */
183
+ declare abstract class BaseValidator<T> implements Validator<T> {
184
+ abstract readonly typeName: string;
185
+ protected _options: ValidatorOptions;
186
+ /**
187
+ * @zh 核心验证逻辑(子类实现)
188
+ * @en Core validation logic (implemented by subclass)
189
+ */
190
+ protected abstract _validate(value: unknown, path: string[]): ValidationResult<T>;
191
+ validate(value: unknown, path?: string[]): ValidationResult<T>;
192
+ is(value: unknown): value is T;
193
+ optional(): Validator<T | undefined>;
194
+ default(defaultValue: T): Validator<T>;
195
+ nullable(): Validator<T | null>;
196
+ /**
197
+ * @zh 克隆验证器(用于链式调用)
198
+ * @en Clone validator (for chaining)
199
+ */
200
+ protected abstract _clone(): BaseValidator<T>;
201
+ }
202
+
203
+ /**
204
+ * @zh 基础类型验证器
205
+ * @en Primitive type validators
206
+ */
207
+
208
+ /**
209
+ * @zh 字符串验证器
210
+ * @en String validator
211
+ */
212
+ declare class StringValidator extends BaseValidator<string> {
213
+ readonly typeName = "string";
214
+ private _stringOptions;
215
+ protected _validate(value: unknown, path: string[]): ValidationResult<string>;
216
+ protected _clone(): StringValidator;
217
+ /**
218
+ * @zh 设置最小长度
219
+ * @en Set minimum length
220
+ */
221
+ min(length: number): StringValidator;
222
+ /**
223
+ * @zh 设置最大长度
224
+ * @en Set maximum length
225
+ */
226
+ max(length: number): StringValidator;
227
+ /**
228
+ * @zh 设置长度范围
229
+ * @en Set length range
230
+ */
231
+ length(min: number, max: number): StringValidator;
232
+ /**
233
+ * @zh 设置正则模式
234
+ * @en Set regex pattern
235
+ */
236
+ regex(pattern: RegExp): StringValidator;
237
+ /**
238
+ * @zh 邮箱格式验证
239
+ * @en Email format validation
240
+ */
241
+ email(): StringValidator;
242
+ /**
243
+ * @zh URL 格式验证
244
+ * @en URL format validation
245
+ */
246
+ url(): StringValidator;
247
+ }
248
+ /**
249
+ * @zh 数字验证器
250
+ * @en Number validator
251
+ */
252
+ declare class NumberValidator extends BaseValidator<number> {
253
+ readonly typeName = "number";
254
+ private _numberOptions;
255
+ protected _validate(value: unknown, path: string[]): ValidationResult<number>;
256
+ protected _clone(): NumberValidator;
257
+ /**
258
+ * @zh 设置最小值
259
+ * @en Set minimum value
260
+ */
261
+ min(value: number): NumberValidator;
262
+ /**
263
+ * @zh 设置最大值
264
+ * @en Set maximum value
265
+ */
266
+ max(value: number): NumberValidator;
267
+ /**
268
+ * @zh 设置范围
269
+ * @en Set range
270
+ */
271
+ range(min: number, max: number): NumberValidator;
272
+ /**
273
+ * @zh 要求为整数
274
+ * @en Require integer
275
+ */
276
+ int(): NumberValidator;
277
+ /**
278
+ * @zh 要求为正数
279
+ * @en Require positive
280
+ */
281
+ positive(): NumberValidator;
282
+ /**
283
+ * @zh 要求为负数
284
+ * @en Require negative
285
+ */
286
+ negative(): NumberValidator;
287
+ }
288
+ /**
289
+ * @zh 布尔验证器
290
+ * @en Boolean validator
291
+ */
292
+ declare class BooleanValidator extends BaseValidator<boolean> {
293
+ readonly typeName = "boolean";
294
+ protected _validate(value: unknown, path: string[]): ValidationResult<boolean>;
295
+ protected _clone(): BooleanValidator;
296
+ }
297
+ /**
298
+ * @zh 字面量验证器
299
+ * @en Literal validator
300
+ */
301
+ declare class LiteralValidator<T extends string | number | boolean> extends BaseValidator<T> {
302
+ readonly typeName: string;
303
+ private readonly _literal;
304
+ constructor(literal: T);
305
+ protected _validate(value: unknown, path: string[]): ValidationResult<T>;
306
+ protected _clone(): LiteralValidator<T>;
307
+ }
308
+ /**
309
+ * @zh 任意类型验证器
310
+ * @en Any type validator
311
+ */
312
+ declare class AnyValidator extends BaseValidator<unknown> {
313
+ readonly typeName = "any";
314
+ protected _validate(value: unknown): ValidationResult<unknown>;
315
+ protected _clone(): AnyValidator;
316
+ }
317
+ /**
318
+ * @zh 创建字符串验证器
319
+ * @en Create string validator
320
+ */
321
+ declare function string(): StringValidator;
322
+ /**
323
+ * @zh 创建数字验证器
324
+ * @en Create number validator
325
+ */
326
+ declare function number(): NumberValidator;
327
+ /**
328
+ * @zh 创建布尔验证器
329
+ * @en Create boolean validator
330
+ */
331
+ declare function boolean(): BooleanValidator;
332
+ /**
333
+ * @zh 创建字面量验证器
334
+ * @en Create literal validator
335
+ */
336
+ declare function literal<T extends string | number | boolean>(value: T): LiteralValidator<T>;
337
+ /**
338
+ * @zh 创建任意类型验证器
339
+ * @en Create any type validator
340
+ */
341
+ declare function any(): AnyValidator;
342
+
343
+ /**
344
+ * @zh 复合类型验证器
345
+ * @en Composite type validators
346
+ */
347
+
348
+ /**
349
+ * @zh 对象验证器
350
+ * @en Object validator
351
+ */
352
+ declare class ObjectValidator<T extends ObjectShape> extends BaseValidator<InferShape<T>> {
353
+ readonly typeName = "object";
354
+ private readonly _shape;
355
+ private _objectOptions;
356
+ constructor(shape: T);
357
+ protected _validate(value: unknown, path: string[]): ValidationResult<InferShape<T>>;
358
+ protected _clone(): ObjectValidator<T>;
359
+ /**
360
+ * @zh 严格模式(不允许额外字段)
361
+ * @en Strict mode (no extra fields allowed)
362
+ */
363
+ strict(): ObjectValidator<T>;
364
+ /**
365
+ * @zh 部分模式(所有字段可选)
366
+ * @en Partial mode (all fields optional)
367
+ */
368
+ partial(): ObjectValidator<{
369
+ [K in keyof T]: ReturnType<T[K]['optional']>;
370
+ }>;
371
+ /**
372
+ * @zh 选择部分字段
373
+ * @en Pick specific fields
374
+ */
375
+ pick<K extends keyof T>(...keys: K[]): ObjectValidator<Pick<T, K>>;
376
+ /**
377
+ * @zh 排除部分字段
378
+ * @en Omit specific fields
379
+ */
380
+ omit<K extends keyof T>(...keys: K[]): ObjectValidator<Omit<T, K>>;
381
+ /**
382
+ * @zh 扩展对象 Schema
383
+ * @en Extend object schema
384
+ */
385
+ extend<U extends ObjectShape>(shape: U): ObjectValidator<T & U>;
386
+ }
387
+ /**
388
+ * @zh 数组验证器
389
+ * @en Array validator
390
+ */
391
+ declare class ArrayValidator<T> extends BaseValidator<T[]> {
392
+ readonly typeName = "array";
393
+ private readonly _element;
394
+ private _arrayOptions;
395
+ constructor(element: Validator<T>);
396
+ protected _validate(value: unknown, path: string[]): ValidationResult<T[]>;
397
+ protected _clone(): ArrayValidator<T>;
398
+ /**
399
+ * @zh 设置最小长度
400
+ * @en Set minimum length
401
+ */
402
+ min(length: number): ArrayValidator<T>;
403
+ /**
404
+ * @zh 设置最大长度
405
+ * @en Set maximum length
406
+ */
407
+ max(length: number): ArrayValidator<T>;
408
+ /**
409
+ * @zh 设置长度范围
410
+ * @en Set length range
411
+ */
412
+ length(min: number, max: number): ArrayValidator<T>;
413
+ /**
414
+ * @zh 要求非空数组
415
+ * @en Require non-empty array
416
+ */
417
+ nonempty(): ArrayValidator<T>;
418
+ }
419
+ /**
420
+ * @zh 元组验证器
421
+ * @en Tuple validator
422
+ */
423
+ declare class TupleValidator<T extends readonly Validator<unknown>[]> extends BaseValidator<{
424
+ [K in keyof T]: T[K] extends Validator<infer U> ? U : never;
425
+ }> {
426
+ readonly typeName = "tuple";
427
+ private readonly _elements;
428
+ constructor(elements: T);
429
+ protected _validate(value: unknown, path: string[]): ValidationResult<{
430
+ [K in keyof T]: T[K] extends Validator<infer U> ? U : never;
431
+ }>;
432
+ protected _clone(): TupleValidator<T>;
433
+ }
434
+ /**
435
+ * @zh 联合类型验证器
436
+ * @en Union type validator
437
+ */
438
+ declare class UnionValidator<T extends readonly Validator<unknown>[]> extends BaseValidator<T[number] extends Validator<infer U> ? U : never> {
439
+ readonly typeName: string;
440
+ private readonly _variants;
441
+ constructor(variants: T);
442
+ protected _validate(value: unknown, path: string[]): ValidationResult<T[number] extends Validator<infer U> ? U : never>;
443
+ protected _clone(): UnionValidator<T>;
444
+ }
445
+ /**
446
+ * @zh 记录类型验证器
447
+ * @en Record type validator
448
+ */
449
+ declare class RecordValidator<T> extends BaseValidator<Record<string, T>> {
450
+ readonly typeName = "record";
451
+ private readonly _valueValidator;
452
+ constructor(valueValidator: Validator<T>);
453
+ protected _validate(value: unknown, path: string[]): ValidationResult<Record<string, T>>;
454
+ protected _clone(): RecordValidator<T>;
455
+ }
456
+ /**
457
+ * @zh 枚举验证器
458
+ * @en Enum validator
459
+ */
460
+ declare class EnumValidator<T extends readonly (string | number)[]> extends BaseValidator<T[number]> {
461
+ readonly typeName: string;
462
+ private readonly _values;
463
+ private readonly _valuesArray;
464
+ constructor(values: T);
465
+ protected _validate(value: unknown, path: string[]): ValidationResult<T[number]>;
466
+ protected _clone(): EnumValidator<T>;
467
+ }
468
+ /**
469
+ * @zh 创建对象验证器
470
+ * @en Create object validator
471
+ */
472
+ declare function object<T extends ObjectShape>(shape: T): ObjectValidator<T>;
473
+ /**
474
+ * @zh 创建数组验证器
475
+ * @en Create array validator
476
+ */
477
+ declare function array<T>(element: Validator<T>): ArrayValidator<T>;
478
+ /**
479
+ * @zh 创建元组验证器
480
+ * @en Create tuple validator
481
+ */
482
+ declare function tuple<T extends readonly Validator<unknown>[]>(elements: T): TupleValidator<T>;
483
+ /**
484
+ * @zh 创建联合类型验证器
485
+ * @en Create union type validator
486
+ */
487
+ declare function union<T extends readonly Validator<unknown>[]>(variants: T): UnionValidator<T>;
488
+ /**
489
+ * @zh 创建记录类型验证器
490
+ * @en Create record type validator
491
+ */
492
+ declare function record<T>(valueValidator: Validator<T>): RecordValidator<T>;
493
+ /**
494
+ * @zh 创建枚举验证器
495
+ * @en Create enum validator
496
+ */
497
+ declare function nativeEnum<T extends readonly (string | number)[]>(values: T): EnumValidator<T>;
498
+
499
+ /**
500
+ * @zh Schema 构建器命名空间
501
+ * @en Schema builder namespace
502
+ *
503
+ * @example
504
+ * ```typescript
505
+ * import { s } from '@esengine/server';
506
+ *
507
+ * const UserSchema = s.object({
508
+ * id: s.string(),
509
+ * name: s.string().min(1).max(50),
510
+ * age: s.number().int().min(0).max(150),
511
+ * email: s.string().email().optional(),
512
+ * role: s.enum(['admin', 'user', 'guest'] as const),
513
+ * tags: s.array(s.string()),
514
+ * metadata: s.record(s.any()).optional()
515
+ * });
516
+ *
517
+ * type User = s.infer<typeof UserSchema>;
518
+ * ```
519
+ */
520
+ declare const s: {
521
+ readonly string: typeof string;
522
+ readonly number: typeof number;
523
+ readonly boolean: typeof boolean;
524
+ readonly literal: typeof literal;
525
+ readonly any: typeof any;
526
+ readonly object: typeof object;
527
+ readonly array: typeof array;
528
+ readonly tuple: typeof tuple;
529
+ readonly union: typeof union;
530
+ readonly record: typeof record;
531
+ /**
532
+ * @zh 创建枚举验证器
533
+ * @en Create enum validator
534
+ *
535
+ * @example
536
+ * ```typescript
537
+ * const RoleSchema = s.enum(['admin', 'user', 'guest'] as const);
538
+ * type Role = s.infer<typeof RoleSchema>; // 'admin' | 'user' | 'guest'
539
+ * ```
540
+ */
541
+ readonly enum: typeof nativeEnum;
542
+ /**
543
+ * @zh 类型推断辅助(仅用于类型层面)
544
+ * @en Type inference helper (type-level only)
545
+ *
546
+ * @zh 这是一个类型辅助,用于从验证器推断类型
547
+ * @en This is a type helper to infer types from validators
548
+ */
549
+ readonly infer: <V extends Validator<unknown>>() => Infer<V>;
550
+ };
551
+ /**
552
+ * @zh 类型推断辅助类型
553
+ * @en Type inference helper type
554
+ */
555
+ declare namespace s {
556
+ /**
557
+ * @zh 从验证器推断类型
558
+ * @en Infer type from validator
559
+ */
560
+ type infer<V extends Validator<unknown>> = Infer<V>;
561
+ }
562
+ /**
563
+ * @zh 验证数据并抛出错误
564
+ * @en Validate data and throw error
565
+ *
566
+ * @param validator - @zh 验证器 @en Validator
567
+ * @param value - @zh 待验证的值 @en Value to validate
568
+ * @returns @zh 验证通过的数据 @en Validated data
569
+ * @throws @zh 验证失败时抛出错误 @en Throws when validation fails
570
+ */
571
+ declare function parse<T>(validator: Validator<T>, value: unknown): T;
572
+ /**
573
+ * @zh 安全验证数据(不抛出错误)
574
+ * @en Safely validate data (no throw)
575
+ *
576
+ * @param validator - @zh 验证器 @en Validator
577
+ * @param value - @zh 待验证的值 @en Value to validate
578
+ * @returns @zh 验证结果 @en Validation result
579
+ */
580
+ declare function safeParse<T>(validator: Validator<T>, value: unknown): ValidationResult<T>;
581
+ /**
582
+ * @zh 创建类型守卫函数
583
+ * @en Create type guard function
584
+ *
585
+ * @param validator - @zh 验证器 @en Validator
586
+ * @returns @zh 类型守卫函数 @en Type guard function
587
+ *
588
+ * @example
589
+ * ```typescript
590
+ * const isUser = createGuard(UserSchema);
591
+ * if (isUser(data)) {
592
+ * // data is User
593
+ * }
594
+ * ```
595
+ */
596
+ declare function createGuard<T>(validator: Validator<T>): (value: unknown) => value is T;
597
+
34
598
  /**
35
599
  * @zh API、消息和 HTTP 定义助手
36
600
  * @en API, message, and HTTP definition helpers
37
601
  */
38
602
 
603
+ /**
604
+ * @zh 带 Schema 的 API 定义选项
605
+ * @en API definition options with schema
606
+ */
607
+ interface ApiDefinitionWithSchema<TReq, TRes, TData = Record<string, unknown>> extends ApiDefinition<TReq, TRes, TData> {
608
+ /**
609
+ * @zh 请求数据 Schema(自动验证)
610
+ * @en Request data schema (auto validation)
611
+ */
612
+ schema?: Validator<TReq>;
613
+ }
39
614
  /**
40
615
  * @zh 定义 API 处理器
41
616
  * @en Define API handler
@@ -52,8 +627,62 @@ declare function createServer(config?: ServerConfig): Promise<GameServer>;
52
627
  * }
53
628
  * })
54
629
  * ```
630
+ *
631
+ * @example
632
+ * ```typescript
633
+ * // 使用 Schema 验证 | With schema validation
634
+ * import { defineApi, s } from '@esengine/server'
635
+ *
636
+ * const MoveSchema = s.object({
637
+ * x: s.number(),
638
+ * y: s.number()
639
+ * });
640
+ *
641
+ * export default defineApi({
642
+ * schema: MoveSchema,
643
+ * handler(req, ctx) {
644
+ * // req 已验证,类型安全 | req is validated, type-safe
645
+ * console.log(req.x, req.y);
646
+ * }
647
+ * })
648
+ * ```
649
+ */
650
+ declare function defineApi<TReq, TRes, TData = Record<string, unknown>>(definition: ApiDefinitionWithSchema<TReq, TRes, TData>): ApiDefinitionWithSchema<TReq, TRes, TData>;
651
+ /**
652
+ * @zh 使用 Schema 定义 API 处理器(类型自动推断)
653
+ * @en Define API handler with schema (auto type inference)
654
+ *
655
+ * @example
656
+ * ```typescript
657
+ * import { defineApiWithSchema, s } from '@esengine/server'
658
+ *
659
+ * const MoveSchema = s.object({
660
+ * x: s.number(),
661
+ * y: s.number()
662
+ * });
663
+ *
664
+ * export default defineApiWithSchema(MoveSchema, {
665
+ * handler(req, ctx) {
666
+ * // req 类型自动推断为 { x: number, y: number }
667
+ * // req type is auto-inferred as { x: number, y: number }
668
+ * console.log(req.x, req.y);
669
+ * return { success: true };
670
+ * }
671
+ * })
672
+ * ```
55
673
  */
56
- declare function defineApi<TReq, TRes, TData = Record<string, unknown>>(definition: ApiDefinition<TReq, TRes, TData>): ApiDefinition<TReq, TRes, TData>;
674
+ declare function defineApiWithSchema<TReq, TRes, TData = Record<string, unknown>>(schema: Validator<TReq>, definition: Omit<ApiDefinition<TReq, TRes, TData>, 'validate'>): ApiDefinitionWithSchema<TReq, TRes, TData>;
675
+ /**
676
+ * @zh 带 Schema 的消息定义选项
677
+ * @en Message definition options with schema
678
+ */
679
+ interface MsgDefinitionWithSchema<TMsg, TData = Record<string, unknown>> extends MsgDefinition<TMsg, TData> {
680
+ /**
681
+ * @zh 消息数据 Schema(自动验证)
682
+ * @en Message data schema (auto validation)
683
+ */
684
+ schema?: Validator<TMsg>;
685
+ }
57
686
  /**
58
687
  * @zh 定义消息处理器
59
688
  * @en Define message handler
@@ -69,8 +698,50 @@ declare function defineApi<TReq, TRes, TData = Record<string, unknown>>(definiti
69
698
  * }
70
699
  * })
71
700
  * ```
701
+ *
702
+ * @example
703
+ * ```typescript
704
+ * // 使用 Schema 验证 | With schema validation
705
+ * import { defineMsg, s } from '@esengine/server'
706
+ *
707
+ * const InputSchema = s.object({
708
+ * keys: s.array(s.string()),
709
+ * timestamp: s.number()
710
+ * });
711
+ *
712
+ * export default defineMsg({
713
+ * schema: InputSchema,
714
+ * handler(msg, ctx) {
715
+ * // msg 已验证,类型安全 | msg is validated, type-safe
716
+ * console.log(msg.keys, msg.timestamp);
717
+ * }
718
+ * })
719
+ * ```
720
+ */
721
+ declare function defineMsg<TMsg, TData = Record<string, unknown>>(definition: MsgDefinitionWithSchema<TMsg, TData>): MsgDefinitionWithSchema<TMsg, TData>;
722
+ /**
723
+ * @zh 使用 Schema 定义消息处理器(类型自动推断)
724
+ * @en Define message handler with schema (auto type inference)
725
+ *
726
+ * @example
727
+ * ```typescript
728
+ * import { defineMsgWithSchema, s } from '@esengine/server'
729
+ *
730
+ * const InputSchema = s.object({
731
+ * keys: s.array(s.string()),
732
+ * timestamp: s.number()
733
+ * });
734
+ *
735
+ * export default defineMsgWithSchema(InputSchema, {
736
+ * handler(msg, ctx) {
737
+ * // msg 类型自动推断
738
+ * // msg type is auto-inferred
739
+ * console.log(msg.keys, msg.timestamp);
740
+ * }
741
+ * })
742
+ * ```
72
743
  */
73
- declare function defineMsg<TMsg, TData = Record<string, unknown>>(definition: MsgDefinition<TMsg, TData>): MsgDefinition<TMsg, TData>;
744
+ declare function defineMsgWithSchema<TMsg, TData = Record<string, unknown>>(schema: Validator<TMsg>, definition: MsgDefinition<TMsg, TData>): MsgDefinitionWithSchema<TMsg, TData>;
74
745
  /**
75
746
  * @zh 定义 HTTP 路由处理器
76
747
  * @en Define HTTP route handler
@@ -133,4 +804,779 @@ declare function defineHttp<TBody = unknown>(definition: HttpDefinition<TBody>):
133
804
  */
134
805
  declare function createHttpRouter(routes: HttpRoutes, options?: HttpRouterOptions): (req: IncomingMessage, res: ServerResponse) => Promise<boolean>;
135
806
 
136
- export { ApiDefinition, GameServer, HttpDefinition, HttpRoutes, MsgDefinition, ServerConfig, createHttpRouter, createServer, defineApi, defineHttp, defineMsg };
807
+ /**
808
+ * @zh 内存分布式适配器
809
+ * @en Memory distributed adapter
810
+ *
811
+ * @zh 用于单机模式和测试的内存实现。所有数据存储在进程内存中。
812
+ * @en In-memory implementation for single-server mode and testing. All data stored in process memory.
813
+ */
814
+
815
+ /**
816
+ * @zh 内存适配器配置
817
+ * @en Memory adapter configuration
818
+ */
819
+ interface MemoryAdapterConfig {
820
+ /**
821
+ * @zh 服务器 TTL(毫秒),超时后视为离线
822
+ * @en Server TTL (ms), considered offline after timeout
823
+ * @default 15000
824
+ */
825
+ serverTtl?: number;
826
+ /**
827
+ * @zh 是否启用 TTL 检查
828
+ * @en Whether to enable TTL check
829
+ * @default true
830
+ */
831
+ enableTtlCheck?: boolean;
832
+ /**
833
+ * @zh TTL 检查间隔(毫秒)
834
+ * @en TTL check interval (ms)
835
+ * @default 5000
836
+ */
837
+ ttlCheckInterval?: number;
838
+ }
839
+ /**
840
+ * @zh 内存分布式适配器
841
+ * @en Memory distributed adapter
842
+ */
843
+ declare class MemoryAdapter implements IDistributedAdapter {
844
+ private readonly _config;
845
+ private _connected;
846
+ private readonly _servers;
847
+ private readonly _rooms;
848
+ private readonly _snapshots;
849
+ private readonly _locks;
850
+ private readonly _subscribers;
851
+ private _subscriberId;
852
+ private _ttlCheckTimer;
853
+ constructor(config?: MemoryAdapterConfig);
854
+ connect(): Promise<void>;
855
+ disconnect(): Promise<void>;
856
+ isConnected(): boolean;
857
+ registerServer(server: ServerRegistration): Promise<void>;
858
+ unregisterServer(serverId: string): Promise<void>;
859
+ heartbeat(serverId: string): Promise<void>;
860
+ getServers(): Promise<ServerRegistration[]>;
861
+ getServer(serverId: string): Promise<ServerRegistration | null>;
862
+ updateServer(serverId: string, updates: Partial<ServerRegistration>): Promise<void>;
863
+ registerRoom(room: RoomRegistration): Promise<void>;
864
+ unregisterRoom(roomId: string): Promise<void>;
865
+ updateRoom(roomId: string, updates: Partial<RoomRegistration>): Promise<void>;
866
+ getRoom(roomId: string): Promise<RoomRegistration | null>;
867
+ queryRooms(query: RoomQuery): Promise<RoomRegistration[]>;
868
+ findAvailableRoom(roomType: string): Promise<RoomRegistration | null>;
869
+ getRoomsByServer(serverId: string): Promise<RoomRegistration[]>;
870
+ saveSnapshot(snapshot: RoomSnapshot): Promise<void>;
871
+ loadSnapshot(roomId: string): Promise<RoomSnapshot | null>;
872
+ deleteSnapshot(roomId: string): Promise<void>;
873
+ publish(event: DistributedEvent): Promise<void>;
874
+ subscribe(pattern: DistributedEventType | '*', handler: DistributedEventHandler): Promise<Unsubscribe>;
875
+ sendToRoom(roomId: string, messageType: string, data: unknown, playerId?: string): Promise<void>;
876
+ acquireLock(key: string, ttlMs: number): Promise<boolean>;
877
+ releaseLock(key: string): Promise<void>;
878
+ extendLock(key: string, ttlMs: number): Promise<boolean>;
879
+ private _ensureConnected;
880
+ private _countRoomsByServer;
881
+ private _checkServerTtl;
882
+ /**
883
+ * @zh 清除所有数据(仅用于测试)
884
+ * @en Clear all data (for testing only)
885
+ */
886
+ _clear(): void;
887
+ /**
888
+ * @zh 获取内部状态(仅用于测试)
889
+ * @en Get internal state (for testing only)
890
+ */
891
+ _getState(): {
892
+ servers: Map<string, ServerRegistration>;
893
+ rooms: Map<string, RoomRegistration>;
894
+ snapshots: Map<string, RoomSnapshot>;
895
+ };
896
+ }
897
+
898
+ /**
899
+ * @zh Redis 分布式适配器
900
+ * @en Redis distributed adapter
901
+ *
902
+ * @zh 基于 Redis 的分布式房间适配器,支持 Pub/Sub、分布式锁和状态持久化
903
+ * @en Redis-based distributed room adapter with Pub/Sub, distributed lock and state persistence
904
+ */
905
+
906
+ /**
907
+ * @zh Redis 客户端接口(兼容 ioredis)
908
+ * @en Redis client interface (compatible with ioredis)
909
+ */
910
+ interface RedisClient {
911
+ get(key: string): Promise<string | null>;
912
+ set(key: string, value: string, ...args: (string | number)[]): Promise<string | null>;
913
+ del(...keys: string[]): Promise<number>;
914
+ expire(key: string, seconds: number): Promise<number>;
915
+ ttl(key: string): Promise<number>;
916
+ hget(key: string, field: string): Promise<string | null>;
917
+ hset(key: string, ...args: (string | number | Buffer)[]): Promise<number>;
918
+ hdel(key: string, ...fields: string[]): Promise<number>;
919
+ hgetall(key: string): Promise<Record<string, string>>;
920
+ hmset(key: string, ...args: (string | number | Buffer)[]): Promise<'OK'>;
921
+ sadd(key: string, ...members: string[]): Promise<number>;
922
+ srem(key: string, ...members: string[]): Promise<number>;
923
+ smembers(key: string): Promise<string[]>;
924
+ publish(channel: string, message: string): Promise<number>;
925
+ subscribe(channel: string): Promise<number>;
926
+ psubscribe(pattern: string): Promise<number>;
927
+ unsubscribe(...channels: string[]): Promise<number>;
928
+ punsubscribe(...patterns: string[]): Promise<number>;
929
+ on(event: 'message', callback: (channel: string, message: string) => void): void;
930
+ on(event: 'pmessage', callback: (pattern: string, channel: string, message: string) => void): void;
931
+ on(event: string, callback: (...args: unknown[]) => void): void;
932
+ off(event: 'message', callback: (channel: string, message: string) => void): void;
933
+ off(event: 'pmessage', callback: (pattern: string, channel: string, message: string) => void): void;
934
+ off(event: string, callback: (...args: unknown[]) => void): void;
935
+ eval(script: string, numkeys: number, ...args: (string | number)[]): Promise<unknown>;
936
+ duplicate(): RedisClient;
937
+ quit(): Promise<'OK'>;
938
+ disconnect(): void;
939
+ }
940
+ /**
941
+ * @zh Redis 连接工厂
942
+ * @en Redis connection factory
943
+ */
944
+ type RedisClientFactory = () => RedisClient | Promise<RedisClient>;
945
+ /**
946
+ * @zh Redis 适配器配置
947
+ * @en Redis adapter configuration
948
+ */
949
+ interface RedisAdapterConfig {
950
+ /**
951
+ * @zh Redis 客户端工厂(惰性连接)
952
+ * @en Redis client factory (lazy connection)
953
+ *
954
+ * @example
955
+ * ```typescript
956
+ * import Redis from 'ioredis'
957
+ * const adapter = new RedisAdapter({
958
+ * factory: () => new Redis('redis://localhost:6379')
959
+ * })
960
+ * ```
961
+ */
962
+ factory: RedisClientFactory;
963
+ /**
964
+ * @zh 键前缀
965
+ * @en Key prefix
966
+ * @default 'dist:'
967
+ */
968
+ prefix?: string;
969
+ /**
970
+ * @zh 服务器 TTL(秒)
971
+ * @en Server TTL (seconds)
972
+ * @default 30
973
+ */
974
+ serverTtl?: number;
975
+ /**
976
+ * @zh 房间 TTL(秒),0 = 永不过期
977
+ * @en Room TTL (seconds), 0 = never expire
978
+ * @default 0
979
+ */
980
+ roomTtl?: number;
981
+ /**
982
+ * @zh 快照 TTL(秒)
983
+ * @en Snapshot TTL (seconds)
984
+ * @default 86400 (24 hours)
985
+ */
986
+ snapshotTtl?: number;
987
+ /**
988
+ * @zh Pub/Sub 频道名
989
+ * @en Pub/Sub channel name
990
+ * @default 'distributed:events'
991
+ */
992
+ channel?: string;
993
+ }
994
+ /**
995
+ * @zh Redis 分布式适配器
996
+ * @en Redis distributed adapter
997
+ *
998
+ * @example
999
+ * ```typescript
1000
+ * import Redis from 'ioredis'
1001
+ * import { RedisAdapter, DistributedRoomManager } from '@esengine/server'
1002
+ *
1003
+ * const adapter = new RedisAdapter({
1004
+ * factory: () => new Redis('redis://localhost:6379'),
1005
+ * prefix: 'game:'
1006
+ * })
1007
+ *
1008
+ * const manager = new DistributedRoomManager(adapter, {
1009
+ * serverId: 'server-1',
1010
+ * serverAddress: 'localhost',
1011
+ * serverPort: 3000
1012
+ * }, sendFn)
1013
+ *
1014
+ * await manager.start()
1015
+ * ```
1016
+ */
1017
+ declare class RedisAdapter implements IDistributedAdapter {
1018
+ private readonly _config;
1019
+ private _client;
1020
+ private _subscriber;
1021
+ private _connected;
1022
+ private readonly _lockTokens;
1023
+ private readonly _handlers;
1024
+ private _messageHandler;
1025
+ constructor(config: RedisAdapterConfig);
1026
+ private _key;
1027
+ private _serverKey;
1028
+ private _roomKey;
1029
+ private _snapshotKey;
1030
+ private _lockKey;
1031
+ private _serversSetKey;
1032
+ private _roomsSetKey;
1033
+ private _serverRoomsKey;
1034
+ connect(): Promise<void>;
1035
+ disconnect(): Promise<void>;
1036
+ isConnected(): boolean;
1037
+ private _ensureConnected;
1038
+ registerServer(server: ServerRegistration): Promise<void>;
1039
+ unregisterServer(serverId: string): Promise<void>;
1040
+ heartbeat(serverId: string): Promise<void>;
1041
+ getServers(): Promise<ServerRegistration[]>;
1042
+ getServer(serverId: string): Promise<ServerRegistration | null>;
1043
+ updateServer(serverId: string, updates: Partial<ServerRegistration>): Promise<void>;
1044
+ registerRoom(room: RoomRegistration): Promise<void>;
1045
+ unregisterRoom(roomId: string): Promise<void>;
1046
+ updateRoom(roomId: string, updates: Partial<RoomRegistration>): Promise<void>;
1047
+ getRoom(roomId: string): Promise<RoomRegistration | null>;
1048
+ queryRooms(query: RoomQuery): Promise<RoomRegistration[]>;
1049
+ findAvailableRoom(roomType: string): Promise<RoomRegistration | null>;
1050
+ getRoomsByServer(serverId: string): Promise<RoomRegistration[]>;
1051
+ saveSnapshot(snapshot: RoomSnapshot): Promise<void>;
1052
+ loadSnapshot(roomId: string): Promise<RoomSnapshot | null>;
1053
+ deleteSnapshot(roomId: string): Promise<void>;
1054
+ publish(event: DistributedEvent): Promise<void>;
1055
+ subscribe(pattern: DistributedEventType | '*', handler: DistributedEventHandler): Promise<Unsubscribe>;
1056
+ sendToRoom(roomId: string, messageType: string, data: unknown, playerId?: string): Promise<void>;
1057
+ private _dispatchEvent;
1058
+ acquireLock(key: string, ttlMs: number): Promise<boolean>;
1059
+ releaseLock(key: string): Promise<void>;
1060
+ extendLock(key: string, ttlMs: number): Promise<boolean>;
1061
+ }
1062
+ /**
1063
+ * @zh 创建 Redis 适配器
1064
+ * @en Create Redis adapter
1065
+ */
1066
+ declare function createRedisAdapter(config: RedisAdapterConfig): RedisAdapter;
1067
+
1068
+ /**
1069
+ * @zh 负载均衡路由器
1070
+ * @en Load-balanced router for server selection
1071
+ */
1072
+
1073
+ /**
1074
+ * @zh 负载均衡策略
1075
+ * @en Load balancing strategy
1076
+ */
1077
+ type LoadBalanceStrategy = 'round-robin' | 'least-rooms' | 'least-players' | 'random' | 'weighted';
1078
+ /**
1079
+ * @zh 负载均衡路由器配置
1080
+ * @en Load-balanced router configuration
1081
+ */
1082
+ interface LoadBalancedRouterConfig {
1083
+ /**
1084
+ * @zh 负载均衡策略
1085
+ * @en Load balancing strategy
1086
+ * @default 'least-rooms'
1087
+ */
1088
+ strategy?: LoadBalanceStrategy;
1089
+ /**
1090
+ * @zh 本地服务器优先
1091
+ * @en Prefer local server
1092
+ * @default true
1093
+ */
1094
+ preferLocal?: boolean;
1095
+ /**
1096
+ * @zh 本地服务器优先阈值(0-1之间,表示本地服务器负载低于此比例时优先使用本地)
1097
+ * @en Local server preference threshold (0-1, prefer local if load is below this ratio)
1098
+ * @default 0.8
1099
+ */
1100
+ localPreferenceThreshold?: number;
1101
+ }
1102
+ /**
1103
+ * @zh 负载均衡路由器
1104
+ * @en Load-balanced router for selecting optimal server
1105
+ *
1106
+ * @example
1107
+ * ```typescript
1108
+ * const router = new LoadBalancedRouter({
1109
+ * strategy: 'least-rooms',
1110
+ * preferLocal: true
1111
+ * });
1112
+ *
1113
+ * const bestServer = router.selectServer(servers, 'server-1');
1114
+ * ```
1115
+ */
1116
+ declare class LoadBalancedRouter {
1117
+ private readonly _config;
1118
+ private _roundRobinIndex;
1119
+ constructor(config?: LoadBalancedRouterConfig);
1120
+ /**
1121
+ * @zh 选择最优服务器
1122
+ * @en Select optimal server
1123
+ *
1124
+ * @param servers - 可用服务器列表 | Available servers
1125
+ * @param localServerId - 本地服务器 ID | Local server ID
1126
+ * @returns 最优服务器,如果没有可用服务器返回 null | Optimal server, or null if none available
1127
+ */
1128
+ selectServer(servers: ServerRegistration[], localServerId?: string): ServerRegistration | null;
1129
+ /**
1130
+ * @zh 选择创建房间的最优服务器
1131
+ * @en Select optimal server for room creation
1132
+ */
1133
+ selectServerForCreation(servers: ServerRegistration[], localServerId?: string): ServerRegistration | null;
1134
+ /**
1135
+ * @zh 重置轮询索引
1136
+ * @en Reset round-robin index
1137
+ */
1138
+ resetRoundRobin(): void;
1139
+ private _selectRoundRobin;
1140
+ private _selectLeastRooms;
1141
+ private _selectLeastPlayers;
1142
+ private _selectRandom;
1143
+ private _selectWeighted;
1144
+ }
1145
+ /**
1146
+ * @zh 创建负载均衡路由器
1147
+ * @en Create load-balanced router
1148
+ */
1149
+ declare function createLoadBalancedRouter(config?: LoadBalancedRouterConfig): LoadBalancedRouter;
1150
+
1151
+ /**
1152
+ * @zh 房间管理器
1153
+ * @en Room manager
1154
+ */
1155
+
1156
+ /**
1157
+ * @zh 房间类型
1158
+ * @en Room class type
1159
+ */
1160
+ type RoomClass<T extends Room = Room> = new () => T;
1161
+ /**
1162
+ * @zh 房间定义
1163
+ * @en Room definition
1164
+ */
1165
+ interface RoomDefinition {
1166
+ roomClass: RoomClass;
1167
+ }
1168
+ /**
1169
+ * @zh 房间管理器
1170
+ * @en Room manager
1171
+ *
1172
+ * @zh 管理房间的创建、加入、离开等操作。可被 DistributedRoomManager 继承以支持分布式功能。
1173
+ * @en Manages room creation, joining, leaving, etc. Can be extended by DistributedRoomManager for distributed features.
1174
+ */
1175
+ declare class RoomManager {
1176
+ /**
1177
+ * @zh 房间类型定义映射
1178
+ * @en Room type definitions map
1179
+ */
1180
+ protected _definitions: Map<string, RoomDefinition>;
1181
+ /**
1182
+ * @zh 房间实例映射
1183
+ * @en Room instances map
1184
+ */
1185
+ protected _rooms: Map<string, Room>;
1186
+ /**
1187
+ * @zh 玩家到房间的映射
1188
+ * @en Player to room mapping
1189
+ */
1190
+ protected _playerToRoom: Map<string, string>;
1191
+ /**
1192
+ * @zh 下一个房间 ID 计数器
1193
+ * @en Next room ID counter
1194
+ */
1195
+ protected _nextRoomId: number;
1196
+ /**
1197
+ * @zh 消息发送函数
1198
+ * @en Message send function
1199
+ */
1200
+ protected _sendFn: (conn: any, type: string, data: unknown) => void;
1201
+ /**
1202
+ * @zh 二进制发送函数
1203
+ * @en Binary send function
1204
+ */
1205
+ protected _sendBinaryFn?: (conn: any, data: Uint8Array) => void;
1206
+ constructor(sendFn: (conn: any, type: string, data: unknown) => void, sendBinaryFn?: (conn: any, data: Uint8Array) => void);
1207
+ /**
1208
+ * @zh 注册房间类型
1209
+ * @en Define room type
1210
+ */
1211
+ define<T extends Room>(name: string, roomClass: RoomClass<T>): void;
1212
+ /**
1213
+ * @zh 创建房间
1214
+ * @en Create room
1215
+ *
1216
+ * @param name - 房间类型名称 | Room type name
1217
+ * @param options - 房间配置 | Room options
1218
+ * @returns 房间实例或 null | Room instance or null
1219
+ */
1220
+ create(name: string, options?: RoomOptions): Promise<Room | null>;
1221
+ /**
1222
+ * @zh 房间创建后的回调
1223
+ * @en Callback after room is created
1224
+ *
1225
+ * @param _name - 房间类型名称 | Room type name
1226
+ * @param _room - 房间实例 | Room instance
1227
+ */
1228
+ protected _onRoomCreated(_name: string, _room: Room): Promise<void>;
1229
+ /**
1230
+ * @zh 加入或创建房间
1231
+ * @en Join or create room
1232
+ *
1233
+ * @param name - 房间类型名称 | Room type name
1234
+ * @param playerId - 玩家 ID | Player ID
1235
+ * @param conn - 玩家连接 | Player connection
1236
+ * @param options - 房间配置 | Room options
1237
+ * @returns 房间和玩家实例或 null | Room and player instance or null
1238
+ */
1239
+ joinOrCreate(name: string, playerId: string, conn: any, options?: RoomOptions): Promise<{
1240
+ room: Room;
1241
+ player: Player;
1242
+ } | null>;
1243
+ /**
1244
+ * @zh 加入指定房间
1245
+ * @en Join specific room
1246
+ *
1247
+ * @param roomId - 房间 ID | Room ID
1248
+ * @param playerId - 玩家 ID | Player ID
1249
+ * @param conn - 玩家连接 | Player connection
1250
+ * @returns 房间和玩家实例或 null | Room and player instance or null
1251
+ */
1252
+ joinById(roomId: string, playerId: string, conn: any): Promise<{
1253
+ room: Room;
1254
+ player: Player;
1255
+ } | null>;
1256
+ /**
1257
+ * @zh 玩家离开
1258
+ * @en Player leave
1259
+ *
1260
+ * @param playerId - 玩家 ID | Player ID
1261
+ * @param reason - 离开原因 | Leave reason
1262
+ */
1263
+ leave(playerId: string, reason?: string): Promise<void>;
1264
+ /**
1265
+ * @zh 处理消息
1266
+ * @en Handle message
1267
+ */
1268
+ handleMessage(playerId: string, type: string, data: unknown): void;
1269
+ /**
1270
+ * @zh 获取房间
1271
+ * @en Get room
1272
+ */
1273
+ getRoom(roomId: string): Room | undefined;
1274
+ /**
1275
+ * @zh 获取玩家所在房间
1276
+ * @en Get player's room
1277
+ */
1278
+ getPlayerRoom(playerId: string): Room | undefined;
1279
+ /**
1280
+ * @zh 获取所有房间
1281
+ * @en Get all rooms
1282
+ */
1283
+ getRooms(): ReadonlyArray<Room>;
1284
+ /**
1285
+ * @zh 获取指定类型的所有房间
1286
+ * @en Get all rooms of a type
1287
+ */
1288
+ getRoomsByType(name: string): Room[];
1289
+ /**
1290
+ * @zh 查找可用房间
1291
+ * @en Find available room
1292
+ *
1293
+ * @param name - 房间类型名称 | Room type name
1294
+ * @returns 可用房间或 null | Available room or null
1295
+ */
1296
+ protected _findAvailableRoom(name: string): Room | null;
1297
+ /**
1298
+ * @zh 生成房间 ID
1299
+ * @en Generate room ID
1300
+ *
1301
+ * @returns 新的房间 ID | New room ID
1302
+ */
1303
+ protected _generateRoomId(): string;
1304
+ /**
1305
+ * @zh 获取房间定义
1306
+ * @en Get room definition
1307
+ *
1308
+ * @param name - 房间类型名称 | Room type name
1309
+ * @returns 房间定义或 undefined | Room definition or undefined
1310
+ */
1311
+ protected _getDefinition(name: string): RoomDefinition | undefined;
1312
+ /**
1313
+ * @zh 内部创建房间实例
1314
+ * @en Internal create room instance
1315
+ *
1316
+ * @param name - 房间类型名称 | Room type name
1317
+ * @param options - 房间配置 | Room options
1318
+ * @param roomId - 可选的房间 ID(用于分布式恢复) | Optional room ID (for distributed recovery)
1319
+ * @returns 房间实例或 null | Room instance or null
1320
+ */
1321
+ protected _createRoomInstance(name: string, options?: RoomOptions, roomId?: string): Promise<Room | null>;
1322
+ /**
1323
+ * @zh 房间销毁回调
1324
+ * @en Room disposed callback
1325
+ *
1326
+ * @param roomId - 房间 ID | Room ID
1327
+ */
1328
+ protected _onRoomDisposed(roomId: string): void;
1329
+ /**
1330
+ * @zh 玩家加入房间后的回调
1331
+ * @en Callback after player joins room
1332
+ *
1333
+ * @param playerId - 玩家 ID | Player ID
1334
+ * @param roomId - 房间 ID | Room ID
1335
+ * @param player - 玩家实例 | Player instance
1336
+ */
1337
+ protected _onPlayerJoined(playerId: string, roomId: string, _player: Player): void;
1338
+ /**
1339
+ * @zh 玩家离开房间后的回调
1340
+ * @en Callback after player leaves room
1341
+ *
1342
+ * @param playerId - 玩家 ID | Player ID
1343
+ * @param _roomId - 房间 ID | Room ID
1344
+ */
1345
+ protected _onPlayerLeft(playerId: string, _roomId: string): void;
1346
+ }
1347
+
1348
+ /**
1349
+ * @zh 分布式房间管理器
1350
+ * @en Distributed room manager
1351
+ *
1352
+ * @zh 继承 RoomManager,添加分布式功能支持。包括跨服务器房间注册、
1353
+ * 玩家路由、状态同步和故障转移。
1354
+ * @en Extends RoomManager with distributed features. Includes cross-server room
1355
+ * registration, player routing, state synchronization, and failover.
1356
+ */
1357
+
1358
+ /**
1359
+ * @zh 分布式房间管理器配置(内部使用)
1360
+ * @en Distributed room manager configuration (internal use)
1361
+ */
1362
+ interface InternalConfig extends Required<Omit<DistributedRoomManagerConfig, 'metadata'>> {
1363
+ metadata: Record<string, unknown>;
1364
+ }
1365
+ /**
1366
+ * @zh 分布式房间管理器
1367
+ * @en Distributed room manager
1368
+ *
1369
+ * @zh 扩展基础 RoomManager,添加以下功能:
1370
+ * - 服务器注册和心跳
1371
+ * - 跨服务器房间注册
1372
+ * - 玩家路由和重定向
1373
+ * - 状态快照和恢复
1374
+ * - 分布式锁防止竞态
1375
+ * @en Extends base RoomManager with:
1376
+ * - Server registration and heartbeat
1377
+ * - Cross-server room registration
1378
+ * - Player routing and redirection
1379
+ * - State snapshots and recovery
1380
+ * - Distributed locks to prevent race conditions
1381
+ */
1382
+ declare class DistributedRoomManager extends RoomManager {
1383
+ private readonly _adapter;
1384
+ private readonly _config;
1385
+ private readonly _serverId;
1386
+ private _heartbeatTimer;
1387
+ private _snapshotTimer;
1388
+ private _subscriptions;
1389
+ private _isShuttingDown;
1390
+ /**
1391
+ * @zh 创建分布式房间管理器
1392
+ * @en Create distributed room manager
1393
+ *
1394
+ * @param adapter - 分布式适配器 | Distributed adapter
1395
+ * @param config - 配置 | Configuration
1396
+ * @param sendFn - 消息发送函数 | Message send function
1397
+ * @param sendBinaryFn - 二进制发送函数 | Binary send function
1398
+ */
1399
+ constructor(adapter: IDistributedAdapter, config: DistributedRoomManagerConfig, sendFn: (conn: any, type: string, data: unknown) => void, sendBinaryFn?: (conn: any, data: Uint8Array) => void);
1400
+ /**
1401
+ * @zh 获取服务器 ID
1402
+ * @en Get server ID
1403
+ */
1404
+ get serverId(): string;
1405
+ /**
1406
+ * @zh 获取分布式适配器
1407
+ * @en Get distributed adapter
1408
+ */
1409
+ get adapter(): IDistributedAdapter;
1410
+ /**
1411
+ * @zh 获取配置
1412
+ * @en Get configuration
1413
+ */
1414
+ get config(): Readonly<InternalConfig>;
1415
+ /**
1416
+ * @zh 启动分布式房间管理器
1417
+ * @en Start distributed room manager
1418
+ */
1419
+ start(): Promise<void>;
1420
+ /**
1421
+ * @zh 停止分布式房间管理器
1422
+ * @en Stop distributed room manager
1423
+ *
1424
+ * @param graceful - 是否优雅关闭(等待玩家退出)| Whether to gracefully shutdown (wait for players)
1425
+ */
1426
+ stop(graceful?: boolean): Promise<void>;
1427
+ /**
1428
+ * @zh 房间创建后注册到分布式系统
1429
+ * @en Register room to distributed system after creation
1430
+ */
1431
+ protected _onRoomCreated(name: string, room: Room): Promise<void>;
1432
+ /**
1433
+ * @zh 房间销毁时从分布式系统注销
1434
+ * @en Unregister room from distributed system when disposed
1435
+ */
1436
+ protected _onRoomDisposed(roomId: string): void;
1437
+ /**
1438
+ * @zh 玩家加入后更新分布式房间信息
1439
+ * @en Update distributed room info after player joins
1440
+ */
1441
+ protected _onPlayerJoined(playerId: string, roomId: string, player: Player): void;
1442
+ /**
1443
+ * @zh 玩家离开后更新分布式房间信息
1444
+ * @en Update distributed room info after player leaves
1445
+ */
1446
+ protected _onPlayerLeft(playerId: string, roomId: string): void;
1447
+ /**
1448
+ * @zh 路由玩家到合适的房间/服务器
1449
+ * @en Route player to appropriate room/server
1450
+ *
1451
+ * @param request - 路由请求 | Routing request
1452
+ * @returns 路由结果 | Routing result
1453
+ */
1454
+ route(request: RoutingRequest): Promise<RoutingResult>;
1455
+ /**
1456
+ * @zh 加入或创建房间(分布式版本)
1457
+ * @en Join or create room (distributed version)
1458
+ *
1459
+ * @zh 此方法会:
1460
+ * 1. 先在分布式注册表中查找可用房间
1461
+ * 2. 如果找到其他服务器的房间,返回重定向
1462
+ * 3. 如果找到本地房间或需要创建,在本地处理
1463
+ * @en This method will:
1464
+ * 1. First search for available room in distributed registry
1465
+ * 2. If room found on another server, return redirect
1466
+ * 3. If local room found or creation needed, handle locally
1467
+ */
1468
+ joinOrCreateDistributed(name: string, playerId: string, conn: any, options?: RoomOptions): Promise<{
1469
+ room: Room;
1470
+ player: Player;
1471
+ } | {
1472
+ redirect: string;
1473
+ } | null>;
1474
+ /**
1475
+ * @zh 保存房间状态快照
1476
+ * @en Save room state snapshot
1477
+ *
1478
+ * @param roomId - 房间 ID | Room ID
1479
+ */
1480
+ saveSnapshot(roomId: string): Promise<void>;
1481
+ /**
1482
+ * @zh 从快照恢复房间
1483
+ * @en Restore room from snapshot
1484
+ *
1485
+ * @param roomId - 房间 ID | Room ID
1486
+ * @returns 是否成功恢复 | Whether restore was successful
1487
+ */
1488
+ restoreFromSnapshot(roomId: string): Promise<boolean>;
1489
+ /**
1490
+ * @zh 注册服务器到分布式系统
1491
+ * @en Register server to distributed system
1492
+ */
1493
+ private _registerServer;
1494
+ /**
1495
+ * @zh 订阅分布式事件
1496
+ * @en Subscribe to distributed events
1497
+ */
1498
+ private _subscribeToEvents;
1499
+ /**
1500
+ * @zh 启动心跳定时器
1501
+ * @en Start heartbeat timer
1502
+ */
1503
+ private _startHeartbeat;
1504
+ /**
1505
+ * @zh 启动快照定时器
1506
+ * @en Start snapshot timer
1507
+ */
1508
+ private _startSnapshotTimer;
1509
+ /**
1510
+ * @zh 保存所有房间快照
1511
+ * @en Save all room snapshots
1512
+ */
1513
+ private _saveAllSnapshots;
1514
+ /**
1515
+ * @zh 路由到指定房间
1516
+ * @en Route to specific room
1517
+ */
1518
+ private _routeToRoom;
1519
+ /**
1520
+ * @zh 按类型路由
1521
+ * @en Route by type
1522
+ */
1523
+ private _routeByType;
1524
+ /**
1525
+ * @zh 处理服务器离线事件
1526
+ * @en Handle server offline event
1527
+ */
1528
+ private _handleServerOffline;
1529
+ /**
1530
+ * @zh 尝试从离线服务器恢复房间
1531
+ * @en Try to recover rooms from offline server
1532
+ */
1533
+ private _tryRecoverRoomsFromServer;
1534
+ /**
1535
+ * @zh 处理跨服务器房间消息
1536
+ * @en Handle cross-server room message
1537
+ */
1538
+ private _handleRoomMessage;
1539
+ /**
1540
+ * @zh 统计总玩家数
1541
+ * @en Count total players
1542
+ */
1543
+ private _countTotalPlayers;
1544
+ /**
1545
+ * @zh 根据房间实例获取定义
1546
+ * @en Get definition by room instance
1547
+ */
1548
+ private _getDefinitionByRoom;
1549
+ /**
1550
+ * @zh 休眠指定时间
1551
+ * @en Sleep for specified time
1552
+ */
1553
+ private _sleep;
1554
+ /**
1555
+ * @zh 向其他服务器的房间发送消息
1556
+ * @en Send message to room on another server
1557
+ *
1558
+ * @param roomId - 房间 ID | Room ID
1559
+ * @param messageType - 消息类型 | Message type
1560
+ * @param data - 消息数据 | Message data
1561
+ * @param playerId - 发送者玩家 ID(可选)| Sender player ID (optional)
1562
+ */
1563
+ sendToRemoteRoom(roomId: string, messageType: string, data: unknown, playerId?: string): Promise<void>;
1564
+ /**
1565
+ * @zh 获取所有在线服务器
1566
+ * @en Get all online servers
1567
+ */
1568
+ getServers(): Promise<ServerRegistration[]>;
1569
+ /**
1570
+ * @zh 查询分布式房间
1571
+ * @en Query distributed rooms
1572
+ */
1573
+ queryDistributedRooms(query: {
1574
+ roomType?: string;
1575
+ hasSpace?: boolean;
1576
+ notLocked?: boolean;
1577
+ metadata?: Record<string, unknown>;
1578
+ limit?: number;
1579
+ }): Promise<RoomRegistration[]>;
1580
+ }
1581
+
1582
+ export { AnyValidator, ApiDefinition, type ApiDefinitionWithSchema, ArrayValidator, BooleanValidator, DistributedEvent, DistributedEventHandler, DistributedEventType, DistributedRoomManager, DistributedRoomManagerConfig, EnumValidator, GameServer, HttpDefinition, HttpRoutes, IDistributedAdapter, type Infer, type InferShape, LiteralValidator, type LoadBalanceStrategy, LoadBalancedRouter, type LoadBalancedRouterConfig, MemoryAdapter, type MemoryAdapterConfig, MsgDefinition, type MsgDefinitionWithSchema, NumberValidator, type ObjectShape, ObjectValidator, Player, RecordValidator, RedisAdapter, type RedisAdapterConfig, type RedisClient, type RedisClientFactory, Room, type RoomClass, RoomManager, RoomOptions, RoomQuery, RoomRegistration, RoomSnapshot, RoutingRequest, RoutingResult, ServerConfig, ServerRegistration, StringValidator, TupleValidator, UnionValidator, type ValidationError, type ValidationFailure, type ValidationResult, type ValidationSuccess, type Validator, any, array, boolean, createGuard, createHttpRouter, createLoadBalancedRouter, createRedisAdapter, createServer, defineApi, defineApiWithSchema, defineHttp, defineMsg, defineMsgWithSchema, literal, nativeEnum, number, object, parse, record, s, safeParse, string, tuple, union };