@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/{Room-BnKpl5Sj.d.ts → Room-5owFVIFR.d.ts} +18 -0
- package/dist/auth/index.d.ts +4 -4
- package/dist/auth/testing/index.d.ts +2 -2
- package/dist/chunk-NWZLKNGV.js +2045 -0
- package/dist/chunk-NWZLKNGV.js.map +1 -0
- package/dist/{chunk-FACTBKJ3.js → chunk-T3QJOPNG.js} +37 -2
- package/dist/chunk-T3QJOPNG.js.map +1 -0
- package/dist/chunk-ZUTL4RI7.js +285 -0
- package/dist/chunk-ZUTL4RI7.js.map +1 -0
- package/dist/ecs/index.d.ts +31 -4
- package/dist/ecs/index.js +3 -280
- package/dist/ecs/index.js.map +1 -1
- package/dist/index-B1sr5YAl.d.ts +1076 -0
- package/dist/index.d.ts +1453 -7
- package/dist/index.js +1502 -4
- package/dist/index.js.map +1 -1
- package/dist/ratelimit/index.d.ts +1 -1
- package/dist/testing/index.d.ts +2 -2
- package/dist/testing/index.js +2 -2
- package/dist/{types-C7sS8Sfi.d.ts → types-BCTRacMF.d.ts} +2 -2
- package/package.json +2 -2
- package/dist/chunk-FACTBKJ3.js.map +0 -1
- package/dist/chunk-M7VONMZJ.js +0 -938
- package/dist/chunk-M7VONMZJ.js.map +0 -1
- package/dist/decorators-DY8nZ8Nh.d.ts +0 -26
- package/dist/index-lcuKuQsL.d.ts +0 -470
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
3
|
-
|
|
4
|
-
export {
|
|
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
|
|
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
|
|
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
|
-
|
|
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 };
|