quake2ts 0.0.563 → 0.0.564
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/package.json +1 -1
- package/packages/engine/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/engine/dist/types/assets/crossReference.d.ts +9 -27
- package/packages/engine/dist/types/assets/crossReference.d.ts.map +1 -1
- package/packages/engine/dist/types/assets/streamingPak.d.ts +28 -0
- package/packages/engine/dist/types/assets/streamingPak.d.ts.map +1 -0
- package/packages/test-utils/dist/index.cjs +238 -0
- package/packages/test-utils/dist/index.cjs.map +1 -1
- package/packages/test-utils/dist/index.d.cts +152 -3
- package/packages/test-utils/dist/index.d.ts +152 -3
- package/packages/test-utils/dist/index.js +223 -0
- package/packages/test-utils/dist/index.js.map +1 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as vitest from 'vitest';
|
|
2
2
|
import { Mock } from 'vitest';
|
|
3
|
-
import { Vec3, CollisionPlane, CollisionBrush, CollisionNode, CollisionLeaf, CollisionModel, PlayerState, EntityState, createRandomGenerator, NetDriver } from '@quake2ts/shared';
|
|
3
|
+
import { Vec3, CollisionPlane, CollisionBrush, CollisionNode, CollisionLeaf, CollisionModel, PlayerState, EntityState, createRandomGenerator, NetDriver, UserCommand } from '@quake2ts/shared';
|
|
4
4
|
export { intersects, ladderTrace, stairTrace } from '@quake2ts/shared';
|
|
5
5
|
import { GameStateSnapshot, Entity, ScriptHookRegistry, SpawnContext, EntitySystem, SpawnRegistry } from '@quake2ts/game';
|
|
6
|
-
import { NetworkTransport, Server, ServerStatic, Client } from '@quake2ts/server';
|
|
6
|
+
import { NetworkTransport, Server, ServerStatic, Client, ClientState } from '@quake2ts/server';
|
|
7
7
|
import { ImageData } from '@napi-rs/canvas';
|
|
8
8
|
import { LaunchOptions, BrowserContextOptions, Browser, BrowserContext, Page } from 'playwright';
|
|
9
9
|
import { Server as Server$1 } from 'http';
|
|
@@ -267,6 +267,155 @@ interface MockServer {
|
|
|
267
267
|
*/
|
|
268
268
|
declare function createMockServer(overrides?: Partial<MockServer>): MockServer;
|
|
269
269
|
|
|
270
|
+
/**
|
|
271
|
+
* Interface representing connection state for testing.
|
|
272
|
+
*/
|
|
273
|
+
interface Connection {
|
|
274
|
+
state: ClientState;
|
|
275
|
+
address: string;
|
|
276
|
+
challenge: number;
|
|
277
|
+
userInfo: UserInfo;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Stages of the client connection handshake.
|
|
281
|
+
*/
|
|
282
|
+
declare enum HandshakeStage {
|
|
283
|
+
None = 0,
|
|
284
|
+
Challenge = 1,
|
|
285
|
+
Connect = 2,
|
|
286
|
+
Info = 3,
|
|
287
|
+
Active = 4
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Interface representing a handshake state.
|
|
291
|
+
*/
|
|
292
|
+
interface Handshake {
|
|
293
|
+
stage: HandshakeStage;
|
|
294
|
+
clientNum: number;
|
|
295
|
+
challenge: number;
|
|
296
|
+
qport: number;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Interface for UserInfo structure.
|
|
300
|
+
*/
|
|
301
|
+
interface UserInfo {
|
|
302
|
+
name: string;
|
|
303
|
+
skin: string;
|
|
304
|
+
model: string;
|
|
305
|
+
fov: number;
|
|
306
|
+
hand: number;
|
|
307
|
+
rate: number;
|
|
308
|
+
msg: number;
|
|
309
|
+
spectator?: number;
|
|
310
|
+
[key: string]: string | number | undefined;
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Helper to serialize UserInfo to Quake 2 info string format.
|
|
314
|
+
* Format: \key\value\key2\value2
|
|
315
|
+
*/
|
|
316
|
+
declare function serializeUserInfo(info: UserInfo): string;
|
|
317
|
+
/**
|
|
318
|
+
* Creates a mock UserInfo object.
|
|
319
|
+
* @param overrides Optional overrides for the user info.
|
|
320
|
+
*/
|
|
321
|
+
declare function createMockUserInfo(overrides?: Partial<UserInfo>): UserInfo;
|
|
322
|
+
/**
|
|
323
|
+
* Creates a mock connection object (Client) with specific state.
|
|
324
|
+
* @param state The client state (default: Connected).
|
|
325
|
+
* @param overrides Optional overrides for the client.
|
|
326
|
+
*/
|
|
327
|
+
declare function createMockConnection(state?: ClientState, overrides?: Partial<Client>): Client;
|
|
328
|
+
/**
|
|
329
|
+
* Creates a mock handshake object.
|
|
330
|
+
* @param stage The stage of the handshake (default: None).
|
|
331
|
+
*/
|
|
332
|
+
declare function createMockHandshake(stage?: HandshakeStage): Handshake;
|
|
333
|
+
/**
|
|
334
|
+
* Simulates a handshake between a mock client and server.
|
|
335
|
+
* Note: This is a high-level simulation helper.
|
|
336
|
+
* @param client The mock client connection.
|
|
337
|
+
* @param server The mock server instance.
|
|
338
|
+
* @returns Promise that resolves to true if handshake succeeded.
|
|
339
|
+
*/
|
|
340
|
+
declare function simulateHandshake(client: Client, server: any): Promise<boolean>;
|
|
341
|
+
|
|
342
|
+
type MockServerContext = Server & {
|
|
343
|
+
clients: (Client | null)[];
|
|
344
|
+
entities?: Entity[];
|
|
345
|
+
};
|
|
346
|
+
interface MultiplayerScenario {
|
|
347
|
+
server: MockServerContext;
|
|
348
|
+
clients: Client[];
|
|
349
|
+
entities: Entity[];
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Creates a multiplayer test scenario with a mock server and a number of clients.
|
|
353
|
+
* @param numPlayers Number of players to simulate.
|
|
354
|
+
*/
|
|
355
|
+
declare function createMultiplayerTestScenario(numPlayers?: number): MultiplayerScenario;
|
|
356
|
+
/**
|
|
357
|
+
* Simulates a player joining the server.
|
|
358
|
+
* @param server The mock server instance.
|
|
359
|
+
* @param userInfo Optional user info overrides.
|
|
360
|
+
*/
|
|
361
|
+
declare function simulatePlayerJoin(server: MockServerContext, userInfo?: Partial<UserInfo>): Promise<Client>;
|
|
362
|
+
/**
|
|
363
|
+
* Simulates a player leaving the server.
|
|
364
|
+
* @param server The mock server instance.
|
|
365
|
+
* @param clientNum The client number to disconnect.
|
|
366
|
+
*/
|
|
367
|
+
declare function simulatePlayerLeave(server: MockServerContext, clientNum: number): void;
|
|
368
|
+
/**
|
|
369
|
+
* Simulates a single server frame update.
|
|
370
|
+
* @param server The mock server instance.
|
|
371
|
+
* @param deltaTime Time step in seconds (default: 0.1).
|
|
372
|
+
*/
|
|
373
|
+
declare function simulateServerTick(server: MockServerContext, deltaTime?: number): void;
|
|
374
|
+
/**
|
|
375
|
+
* Simulates player input for a specific client.
|
|
376
|
+
* @param client The server client.
|
|
377
|
+
* @param input The input command.
|
|
378
|
+
*/
|
|
379
|
+
declare function simulatePlayerInput(client: Client, input: Partial<UserCommand>): void;
|
|
380
|
+
|
|
381
|
+
interface Snapshot {
|
|
382
|
+
serverTime: number;
|
|
383
|
+
playerState: any;
|
|
384
|
+
entities: EntityState[];
|
|
385
|
+
}
|
|
386
|
+
interface DeltaSnapshot {
|
|
387
|
+
snapshot: Snapshot;
|
|
388
|
+
deltaEntities: EntityState[];
|
|
389
|
+
removedEntities: number[];
|
|
390
|
+
}
|
|
391
|
+
interface ConsistencyReport {
|
|
392
|
+
valid: boolean;
|
|
393
|
+
errors: string[];
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Creates a client-specific snapshot from the server state.
|
|
397
|
+
* @param serverState The current server state.
|
|
398
|
+
* @param clientNum The client number to generate snapshot for.
|
|
399
|
+
*/
|
|
400
|
+
declare function createServerSnapshot(serverState: Server, clientNum: number): Snapshot;
|
|
401
|
+
/**
|
|
402
|
+
* Calculates the delta between two snapshots.
|
|
403
|
+
* @param oldSnapshot The baseline snapshot.
|
|
404
|
+
* @param newSnapshot The current snapshot.
|
|
405
|
+
*/
|
|
406
|
+
declare function createDeltaSnapshot(oldSnapshot: Snapshot, newSnapshot: Snapshot): DeltaSnapshot;
|
|
407
|
+
/**
|
|
408
|
+
* Verifies the consistency of a sequence of snapshots.
|
|
409
|
+
* @param snapshots Array of snapshots ordered by time.
|
|
410
|
+
*/
|
|
411
|
+
declare function verifySnapshotConsistency(snapshots: Snapshot[]): ConsistencyReport;
|
|
412
|
+
/**
|
|
413
|
+
* Simulates network delivery of a snapshot with potential packet loss.
|
|
414
|
+
* @param snapshot The snapshot to deliver.
|
|
415
|
+
* @param reliability Probability of successful delivery (0.0 to 1.0).
|
|
416
|
+
*/
|
|
417
|
+
declare function simulateSnapshotDelivery(snapshot: Snapshot, reliability?: number): Promise<Snapshot | null>;
|
|
418
|
+
|
|
270
419
|
interface BrowserSetupOptions {
|
|
271
420
|
url?: string;
|
|
272
421
|
pretendToBeVisual?: boolean;
|
|
@@ -509,4 +658,4 @@ interface VisualScenario {
|
|
|
509
658
|
*/
|
|
510
659
|
declare function createVisualTestScenario(page: Page, sceneName: string): VisualScenario;
|
|
511
660
|
|
|
512
|
-
export { type AudioEvent, type BinaryStreamMock, type BinaryWriterMock, type BrowserSetupOptions, type ControlledTimer, type DrawCall, type GameState, type GameStateCapture, InputInjector, type MockEngine, type MockGame, MockPointerLock, type MockRAF, type MockServer, MockTransport, type MockUDPSocket, type NetworkAddress, type NetworkCondition, type NetworkConfig, type NetworkSimulator, type NodeSetupOptions, type PlaywrightOptions, type PlaywrightTestClient, type StorageScenario, type TestContext, type VisualDiff, type VisualScenario, captureAudioEvents, captureCanvasDrawCalls, captureGameScreenshot, captureGameState, compareScreenshots, createBinaryStreamMock, createBinaryWriterMock, createControlledTimer, createCustomNetworkCondition, createEntity, createEntityStateFactory, createGameStateSnapshotFactory, createMockAudioContext, createMockCanvas, createMockCanvasContext2D, createMockEngine, createMockGame, createMockGameState, createMockImage, createMockImageData, createMockIndexedDB, createMockLocalStorage, createMockNetworkAddress, createMockPerformance, createMockRAF, createMockServer, createMockServerClient, createMockServerState, createMockServerStatic, createMockSessionStorage, createMockTransport, createMockUDPSocket, createMockWebGL2Context, createNetChanMock, createPlayerStateFactory, createPlaywrightTestClient, createSpawnContext, createStorageTestScenario, createTestContext, createVisualTestScenario, makeAxisBrush, makeBrushFromMinsMaxs, makeBspModel, makeLeaf, makeLeafModel, makeNode, makePlane, setupBrowserEnvironment, setupMockAudioContext, setupNodeEnvironment, simulateFrames, simulateFramesWithMock, simulateNetworkCondition, teardownBrowserEnvironment, teardownMockAudioContext, throttleBandwidth, waitForGameReady };
|
|
661
|
+
export { type AudioEvent, type BinaryStreamMock, type BinaryWriterMock, type BrowserSetupOptions, type Connection, type ConsistencyReport, type ControlledTimer, type DeltaSnapshot, type DrawCall, type GameState, type GameStateCapture, type Handshake, HandshakeStage, InputInjector, type MockEngine, type MockGame, MockPointerLock, type MockRAF, type MockServer, type MockServerContext, MockTransport, type MockUDPSocket, type MultiplayerScenario, type NetworkAddress, type NetworkCondition, type NetworkConfig, type NetworkSimulator, type NodeSetupOptions, type PlaywrightOptions, type PlaywrightTestClient, type Snapshot, type StorageScenario, type TestContext, type UserInfo, type VisualDiff, type VisualScenario, captureAudioEvents, captureCanvasDrawCalls, captureGameScreenshot, captureGameState, compareScreenshots, createBinaryStreamMock, createBinaryWriterMock, createControlledTimer, createCustomNetworkCondition, createDeltaSnapshot, createEntity, createEntityStateFactory, createGameStateSnapshotFactory, createMockAudioContext, createMockCanvas, createMockCanvasContext2D, createMockConnection, createMockEngine, createMockGame, createMockGameState, createMockHandshake, createMockImage, createMockImageData, createMockIndexedDB, createMockLocalStorage, createMockNetworkAddress, createMockPerformance, createMockRAF, createMockServer, createMockServerClient, createMockServerState, createMockServerStatic, createMockSessionStorage, createMockTransport, createMockUDPSocket, createMockUserInfo, createMockWebGL2Context, createMultiplayerTestScenario, createNetChanMock, createPlayerStateFactory, createPlaywrightTestClient, createServerSnapshot, createSpawnContext, createStorageTestScenario, createTestContext, createVisualTestScenario, makeAxisBrush, makeBrushFromMinsMaxs, makeBspModel, makeLeaf, makeLeafModel, makeNode, makePlane, serializeUserInfo, setupBrowserEnvironment, setupMockAudioContext, setupNodeEnvironment, simulateFrames, simulateFramesWithMock, simulateHandshake, simulateNetworkCondition, simulatePlayerInput, simulatePlayerJoin, simulatePlayerLeave, simulateServerTick, simulateSnapshotDelivery, teardownBrowserEnvironment, teardownMockAudioContext, throttleBandwidth, verifySnapshotConsistency, waitForGameReady };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as vitest from 'vitest';
|
|
2
2
|
import { Mock } from 'vitest';
|
|
3
|
-
import { Vec3, CollisionPlane, CollisionBrush, CollisionNode, CollisionLeaf, CollisionModel, PlayerState, EntityState, createRandomGenerator, NetDriver } from '@quake2ts/shared';
|
|
3
|
+
import { Vec3, CollisionPlane, CollisionBrush, CollisionNode, CollisionLeaf, CollisionModel, PlayerState, EntityState, createRandomGenerator, NetDriver, UserCommand } from '@quake2ts/shared';
|
|
4
4
|
export { intersects, ladderTrace, stairTrace } from '@quake2ts/shared';
|
|
5
5
|
import { GameStateSnapshot, Entity, ScriptHookRegistry, SpawnContext, EntitySystem, SpawnRegistry } from '@quake2ts/game';
|
|
6
|
-
import { NetworkTransport, Server, ServerStatic, Client } from '@quake2ts/server';
|
|
6
|
+
import { NetworkTransport, Server, ServerStatic, Client, ClientState } from '@quake2ts/server';
|
|
7
7
|
import { ImageData } from '@napi-rs/canvas';
|
|
8
8
|
import { LaunchOptions, BrowserContextOptions, Browser, BrowserContext, Page } from 'playwright';
|
|
9
9
|
import { Server as Server$1 } from 'http';
|
|
@@ -267,6 +267,155 @@ interface MockServer {
|
|
|
267
267
|
*/
|
|
268
268
|
declare function createMockServer(overrides?: Partial<MockServer>): MockServer;
|
|
269
269
|
|
|
270
|
+
/**
|
|
271
|
+
* Interface representing connection state for testing.
|
|
272
|
+
*/
|
|
273
|
+
interface Connection {
|
|
274
|
+
state: ClientState;
|
|
275
|
+
address: string;
|
|
276
|
+
challenge: number;
|
|
277
|
+
userInfo: UserInfo;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Stages of the client connection handshake.
|
|
281
|
+
*/
|
|
282
|
+
declare enum HandshakeStage {
|
|
283
|
+
None = 0,
|
|
284
|
+
Challenge = 1,
|
|
285
|
+
Connect = 2,
|
|
286
|
+
Info = 3,
|
|
287
|
+
Active = 4
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Interface representing a handshake state.
|
|
291
|
+
*/
|
|
292
|
+
interface Handshake {
|
|
293
|
+
stage: HandshakeStage;
|
|
294
|
+
clientNum: number;
|
|
295
|
+
challenge: number;
|
|
296
|
+
qport: number;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Interface for UserInfo structure.
|
|
300
|
+
*/
|
|
301
|
+
interface UserInfo {
|
|
302
|
+
name: string;
|
|
303
|
+
skin: string;
|
|
304
|
+
model: string;
|
|
305
|
+
fov: number;
|
|
306
|
+
hand: number;
|
|
307
|
+
rate: number;
|
|
308
|
+
msg: number;
|
|
309
|
+
spectator?: number;
|
|
310
|
+
[key: string]: string | number | undefined;
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Helper to serialize UserInfo to Quake 2 info string format.
|
|
314
|
+
* Format: \key\value\key2\value2
|
|
315
|
+
*/
|
|
316
|
+
declare function serializeUserInfo(info: UserInfo): string;
|
|
317
|
+
/**
|
|
318
|
+
* Creates a mock UserInfo object.
|
|
319
|
+
* @param overrides Optional overrides for the user info.
|
|
320
|
+
*/
|
|
321
|
+
declare function createMockUserInfo(overrides?: Partial<UserInfo>): UserInfo;
|
|
322
|
+
/**
|
|
323
|
+
* Creates a mock connection object (Client) with specific state.
|
|
324
|
+
* @param state The client state (default: Connected).
|
|
325
|
+
* @param overrides Optional overrides for the client.
|
|
326
|
+
*/
|
|
327
|
+
declare function createMockConnection(state?: ClientState, overrides?: Partial<Client>): Client;
|
|
328
|
+
/**
|
|
329
|
+
* Creates a mock handshake object.
|
|
330
|
+
* @param stage The stage of the handshake (default: None).
|
|
331
|
+
*/
|
|
332
|
+
declare function createMockHandshake(stage?: HandshakeStage): Handshake;
|
|
333
|
+
/**
|
|
334
|
+
* Simulates a handshake between a mock client and server.
|
|
335
|
+
* Note: This is a high-level simulation helper.
|
|
336
|
+
* @param client The mock client connection.
|
|
337
|
+
* @param server The mock server instance.
|
|
338
|
+
* @returns Promise that resolves to true if handshake succeeded.
|
|
339
|
+
*/
|
|
340
|
+
declare function simulateHandshake(client: Client, server: any): Promise<boolean>;
|
|
341
|
+
|
|
342
|
+
type MockServerContext = Server & {
|
|
343
|
+
clients: (Client | null)[];
|
|
344
|
+
entities?: Entity[];
|
|
345
|
+
};
|
|
346
|
+
interface MultiplayerScenario {
|
|
347
|
+
server: MockServerContext;
|
|
348
|
+
clients: Client[];
|
|
349
|
+
entities: Entity[];
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Creates a multiplayer test scenario with a mock server and a number of clients.
|
|
353
|
+
* @param numPlayers Number of players to simulate.
|
|
354
|
+
*/
|
|
355
|
+
declare function createMultiplayerTestScenario(numPlayers?: number): MultiplayerScenario;
|
|
356
|
+
/**
|
|
357
|
+
* Simulates a player joining the server.
|
|
358
|
+
* @param server The mock server instance.
|
|
359
|
+
* @param userInfo Optional user info overrides.
|
|
360
|
+
*/
|
|
361
|
+
declare function simulatePlayerJoin(server: MockServerContext, userInfo?: Partial<UserInfo>): Promise<Client>;
|
|
362
|
+
/**
|
|
363
|
+
* Simulates a player leaving the server.
|
|
364
|
+
* @param server The mock server instance.
|
|
365
|
+
* @param clientNum The client number to disconnect.
|
|
366
|
+
*/
|
|
367
|
+
declare function simulatePlayerLeave(server: MockServerContext, clientNum: number): void;
|
|
368
|
+
/**
|
|
369
|
+
* Simulates a single server frame update.
|
|
370
|
+
* @param server The mock server instance.
|
|
371
|
+
* @param deltaTime Time step in seconds (default: 0.1).
|
|
372
|
+
*/
|
|
373
|
+
declare function simulateServerTick(server: MockServerContext, deltaTime?: number): void;
|
|
374
|
+
/**
|
|
375
|
+
* Simulates player input for a specific client.
|
|
376
|
+
* @param client The server client.
|
|
377
|
+
* @param input The input command.
|
|
378
|
+
*/
|
|
379
|
+
declare function simulatePlayerInput(client: Client, input: Partial<UserCommand>): void;
|
|
380
|
+
|
|
381
|
+
interface Snapshot {
|
|
382
|
+
serverTime: number;
|
|
383
|
+
playerState: any;
|
|
384
|
+
entities: EntityState[];
|
|
385
|
+
}
|
|
386
|
+
interface DeltaSnapshot {
|
|
387
|
+
snapshot: Snapshot;
|
|
388
|
+
deltaEntities: EntityState[];
|
|
389
|
+
removedEntities: number[];
|
|
390
|
+
}
|
|
391
|
+
interface ConsistencyReport {
|
|
392
|
+
valid: boolean;
|
|
393
|
+
errors: string[];
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Creates a client-specific snapshot from the server state.
|
|
397
|
+
* @param serverState The current server state.
|
|
398
|
+
* @param clientNum The client number to generate snapshot for.
|
|
399
|
+
*/
|
|
400
|
+
declare function createServerSnapshot(serverState: Server, clientNum: number): Snapshot;
|
|
401
|
+
/**
|
|
402
|
+
* Calculates the delta between two snapshots.
|
|
403
|
+
* @param oldSnapshot The baseline snapshot.
|
|
404
|
+
* @param newSnapshot The current snapshot.
|
|
405
|
+
*/
|
|
406
|
+
declare function createDeltaSnapshot(oldSnapshot: Snapshot, newSnapshot: Snapshot): DeltaSnapshot;
|
|
407
|
+
/**
|
|
408
|
+
* Verifies the consistency of a sequence of snapshots.
|
|
409
|
+
* @param snapshots Array of snapshots ordered by time.
|
|
410
|
+
*/
|
|
411
|
+
declare function verifySnapshotConsistency(snapshots: Snapshot[]): ConsistencyReport;
|
|
412
|
+
/**
|
|
413
|
+
* Simulates network delivery of a snapshot with potential packet loss.
|
|
414
|
+
* @param snapshot The snapshot to deliver.
|
|
415
|
+
* @param reliability Probability of successful delivery (0.0 to 1.0).
|
|
416
|
+
*/
|
|
417
|
+
declare function simulateSnapshotDelivery(snapshot: Snapshot, reliability?: number): Promise<Snapshot | null>;
|
|
418
|
+
|
|
270
419
|
interface BrowserSetupOptions {
|
|
271
420
|
url?: string;
|
|
272
421
|
pretendToBeVisual?: boolean;
|
|
@@ -509,4 +658,4 @@ interface VisualScenario {
|
|
|
509
658
|
*/
|
|
510
659
|
declare function createVisualTestScenario(page: Page, sceneName: string): VisualScenario;
|
|
511
660
|
|
|
512
|
-
export { type AudioEvent, type BinaryStreamMock, type BinaryWriterMock, type BrowserSetupOptions, type ControlledTimer, type DrawCall, type GameState, type GameStateCapture, InputInjector, type MockEngine, type MockGame, MockPointerLock, type MockRAF, type MockServer, MockTransport, type MockUDPSocket, type NetworkAddress, type NetworkCondition, type NetworkConfig, type NetworkSimulator, type NodeSetupOptions, type PlaywrightOptions, type PlaywrightTestClient, type StorageScenario, type TestContext, type VisualDiff, type VisualScenario, captureAudioEvents, captureCanvasDrawCalls, captureGameScreenshot, captureGameState, compareScreenshots, createBinaryStreamMock, createBinaryWriterMock, createControlledTimer, createCustomNetworkCondition, createEntity, createEntityStateFactory, createGameStateSnapshotFactory, createMockAudioContext, createMockCanvas, createMockCanvasContext2D, createMockEngine, createMockGame, createMockGameState, createMockImage, createMockImageData, createMockIndexedDB, createMockLocalStorage, createMockNetworkAddress, createMockPerformance, createMockRAF, createMockServer, createMockServerClient, createMockServerState, createMockServerStatic, createMockSessionStorage, createMockTransport, createMockUDPSocket, createMockWebGL2Context, createNetChanMock, createPlayerStateFactory, createPlaywrightTestClient, createSpawnContext, createStorageTestScenario, createTestContext, createVisualTestScenario, makeAxisBrush, makeBrushFromMinsMaxs, makeBspModel, makeLeaf, makeLeafModel, makeNode, makePlane, setupBrowserEnvironment, setupMockAudioContext, setupNodeEnvironment, simulateFrames, simulateFramesWithMock, simulateNetworkCondition, teardownBrowserEnvironment, teardownMockAudioContext, throttleBandwidth, waitForGameReady };
|
|
661
|
+
export { type AudioEvent, type BinaryStreamMock, type BinaryWriterMock, type BrowserSetupOptions, type Connection, type ConsistencyReport, type ControlledTimer, type DeltaSnapshot, type DrawCall, type GameState, type GameStateCapture, type Handshake, HandshakeStage, InputInjector, type MockEngine, type MockGame, MockPointerLock, type MockRAF, type MockServer, type MockServerContext, MockTransport, type MockUDPSocket, type MultiplayerScenario, type NetworkAddress, type NetworkCondition, type NetworkConfig, type NetworkSimulator, type NodeSetupOptions, type PlaywrightOptions, type PlaywrightTestClient, type Snapshot, type StorageScenario, type TestContext, type UserInfo, type VisualDiff, type VisualScenario, captureAudioEvents, captureCanvasDrawCalls, captureGameScreenshot, captureGameState, compareScreenshots, createBinaryStreamMock, createBinaryWriterMock, createControlledTimer, createCustomNetworkCondition, createDeltaSnapshot, createEntity, createEntityStateFactory, createGameStateSnapshotFactory, createMockAudioContext, createMockCanvas, createMockCanvasContext2D, createMockConnection, createMockEngine, createMockGame, createMockGameState, createMockHandshake, createMockImage, createMockImageData, createMockIndexedDB, createMockLocalStorage, createMockNetworkAddress, createMockPerformance, createMockRAF, createMockServer, createMockServerClient, createMockServerState, createMockServerStatic, createMockSessionStorage, createMockTransport, createMockUDPSocket, createMockUserInfo, createMockWebGL2Context, createMultiplayerTestScenario, createNetChanMock, createPlayerStateFactory, createPlaywrightTestClient, createServerSnapshot, createSpawnContext, createStorageTestScenario, createTestContext, createVisualTestScenario, makeAxisBrush, makeBrushFromMinsMaxs, makeBspModel, makeLeaf, makeLeafModel, makeNode, makePlane, serializeUserInfo, setupBrowserEnvironment, setupMockAudioContext, setupNodeEnvironment, simulateFrames, simulateFramesWithMock, simulateHandshake, simulateNetworkCondition, simulatePlayerInput, simulatePlayerJoin, simulatePlayerLeave, simulateServerTick, simulateSnapshotDelivery, teardownBrowserEnvironment, teardownMockAudioContext, throttleBandwidth, verifySnapshotConsistency, waitForGameReady };
|
|
@@ -603,6 +603,214 @@ function createMockServer(overrides) {
|
|
|
603
603
|
};
|
|
604
604
|
}
|
|
605
605
|
|
|
606
|
+
// src/server/mocks/connection.ts
|
|
607
|
+
import { ClientState as ClientState2 } from "@quake2ts/server";
|
|
608
|
+
var HandshakeStage = /* @__PURE__ */ ((HandshakeStage2) => {
|
|
609
|
+
HandshakeStage2[HandshakeStage2["None"] = 0] = "None";
|
|
610
|
+
HandshakeStage2[HandshakeStage2["Challenge"] = 1] = "Challenge";
|
|
611
|
+
HandshakeStage2[HandshakeStage2["Connect"] = 2] = "Connect";
|
|
612
|
+
HandshakeStage2[HandshakeStage2["Info"] = 3] = "Info";
|
|
613
|
+
HandshakeStage2[HandshakeStage2["Active"] = 4] = "Active";
|
|
614
|
+
return HandshakeStage2;
|
|
615
|
+
})(HandshakeStage || {});
|
|
616
|
+
function serializeUserInfo(info) {
|
|
617
|
+
return Object.entries(info).reduce((acc, [key, value]) => {
|
|
618
|
+
if (value !== void 0) {
|
|
619
|
+
return `${acc}\\${key}\\${value}`;
|
|
620
|
+
}
|
|
621
|
+
return acc;
|
|
622
|
+
}, "");
|
|
623
|
+
}
|
|
624
|
+
function createMockUserInfo(overrides) {
|
|
625
|
+
return {
|
|
626
|
+
name: "Player",
|
|
627
|
+
skin: "male/grunt",
|
|
628
|
+
model: "male/grunt",
|
|
629
|
+
fov: 90,
|
|
630
|
+
hand: 0,
|
|
631
|
+
rate: 25e3,
|
|
632
|
+
msg: 1,
|
|
633
|
+
...overrides
|
|
634
|
+
};
|
|
635
|
+
}
|
|
636
|
+
function createMockConnection(state = ClientState2.Connected, overrides) {
|
|
637
|
+
return createMockServerClient(0, {
|
|
638
|
+
state,
|
|
639
|
+
userInfo: serializeUserInfo(createMockUserInfo()),
|
|
640
|
+
challenge: Math.floor(Math.random() * 1e5),
|
|
641
|
+
...overrides
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
function createMockHandshake(stage = 0 /* None */) {
|
|
645
|
+
return {
|
|
646
|
+
stage,
|
|
647
|
+
clientNum: -1,
|
|
648
|
+
challenge: 0,
|
|
649
|
+
qport: Math.floor(Math.random() * 65536)
|
|
650
|
+
};
|
|
651
|
+
}
|
|
652
|
+
async function simulateHandshake(client, server) {
|
|
653
|
+
const challenge = Math.floor(Math.random() * 1e5);
|
|
654
|
+
client.challenge = challenge;
|
|
655
|
+
if (server && server.clients) {
|
|
656
|
+
}
|
|
657
|
+
client.state = ClientState2.Connected;
|
|
658
|
+
client.state = ClientState2.Active;
|
|
659
|
+
return true;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
// src/server/helpers/multiplayer.ts
|
|
663
|
+
import { ClientState as ClientState3 } from "@quake2ts/server";
|
|
664
|
+
function createMultiplayerTestScenario(numPlayers = 2) {
|
|
665
|
+
const baseServer = createMockServerState();
|
|
666
|
+
const clients = [];
|
|
667
|
+
const entities = [];
|
|
668
|
+
const server = {
|
|
669
|
+
...baseServer,
|
|
670
|
+
clients: new Array(numPlayers).fill(null),
|
|
671
|
+
entities: []
|
|
672
|
+
};
|
|
673
|
+
for (let i = 0; i < numPlayers; i++) {
|
|
674
|
+
const client = createMockServerClient(i, {
|
|
675
|
+
state: ClientState3.Active,
|
|
676
|
+
userInfo: serializeUserInfo(createMockUserInfo({ name: `Player${i}` }))
|
|
677
|
+
});
|
|
678
|
+
const entity = {
|
|
679
|
+
classname: "player",
|
|
680
|
+
s: { origin: { x: 0, y: 0, z: 0 }, number: i + 1 },
|
|
681
|
+
client
|
|
682
|
+
};
|
|
683
|
+
client.edict = entity;
|
|
684
|
+
server.clients[i] = client;
|
|
685
|
+
clients.push(client);
|
|
686
|
+
entities.push(entity);
|
|
687
|
+
}
|
|
688
|
+
server.entities = entities;
|
|
689
|
+
return {
|
|
690
|
+
server,
|
|
691
|
+
clients,
|
|
692
|
+
entities
|
|
693
|
+
};
|
|
694
|
+
}
|
|
695
|
+
async function simulatePlayerJoin(server, userInfo) {
|
|
696
|
+
const index = server.clients.findIndex((c) => !c || c.state === ClientState3.Free);
|
|
697
|
+
if (index === -1) {
|
|
698
|
+
throw new Error("Server full");
|
|
699
|
+
}
|
|
700
|
+
const client = createMockServerClient(index, {
|
|
701
|
+
state: ClientState3.Connected,
|
|
702
|
+
userInfo: serializeUserInfo(createMockUserInfo(userInfo))
|
|
703
|
+
});
|
|
704
|
+
server.clients[index] = client;
|
|
705
|
+
client.state = ClientState3.Active;
|
|
706
|
+
const entity = {
|
|
707
|
+
classname: "player",
|
|
708
|
+
s: { origin: { x: 0, y: 0, z: 0 }, number: index + 1 },
|
|
709
|
+
client
|
|
710
|
+
};
|
|
711
|
+
client.edict = entity;
|
|
712
|
+
if (server.entities && Array.isArray(server.entities)) {
|
|
713
|
+
server.entities[index + 1] = entity;
|
|
714
|
+
}
|
|
715
|
+
return client;
|
|
716
|
+
}
|
|
717
|
+
function simulatePlayerLeave(server, clientNum) {
|
|
718
|
+
const client = server.clients[clientNum];
|
|
719
|
+
if (client) {
|
|
720
|
+
client.state = ClientState3.Free;
|
|
721
|
+
client.edict = null;
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
function simulateServerTick(server, deltaTime = 0.1) {
|
|
725
|
+
server.time += deltaTime;
|
|
726
|
+
server.frame++;
|
|
727
|
+
server.clients.forEach((client) => {
|
|
728
|
+
if (client && client.state === ClientState3.Active) {
|
|
729
|
+
}
|
|
730
|
+
});
|
|
731
|
+
}
|
|
732
|
+
function simulatePlayerInput(client, input) {
|
|
733
|
+
const cmd = {
|
|
734
|
+
msec: 100,
|
|
735
|
+
buttons: 0,
|
|
736
|
+
angles: { x: 0, y: 0, z: 0 },
|
|
737
|
+
forwardmove: 0,
|
|
738
|
+
sidemove: 0,
|
|
739
|
+
upmove: 0,
|
|
740
|
+
sequence: client.lastCmd.sequence + 1,
|
|
741
|
+
lightlevel: 0,
|
|
742
|
+
impulse: 0,
|
|
743
|
+
...input
|
|
744
|
+
};
|
|
745
|
+
client.lastCmd = cmd;
|
|
746
|
+
client.commandQueue.push(cmd);
|
|
747
|
+
client.commandCount++;
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
// src/server/helpers/snapshot.ts
|
|
751
|
+
function createServerSnapshot(serverState, clientNum) {
|
|
752
|
+
const visibleEntities = [];
|
|
753
|
+
if (serverState.baselines) {
|
|
754
|
+
serverState.baselines.forEach((ent, index) => {
|
|
755
|
+
if (ent && index !== clientNum + 1) {
|
|
756
|
+
visibleEntities.push({ ...ent });
|
|
757
|
+
}
|
|
758
|
+
});
|
|
759
|
+
}
|
|
760
|
+
return {
|
|
761
|
+
serverTime: serverState.time,
|
|
762
|
+
playerState: {
|
|
763
|
+
origin: { x: 0, y: 0, z: 0 },
|
|
764
|
+
viewangles: { x: 0, y: 0, z: 0 },
|
|
765
|
+
pm_type: 0
|
|
766
|
+
},
|
|
767
|
+
entities: visibleEntities
|
|
768
|
+
};
|
|
769
|
+
}
|
|
770
|
+
function createDeltaSnapshot(oldSnapshot, newSnapshot) {
|
|
771
|
+
const deltaEntities = [];
|
|
772
|
+
const removedEntities = [];
|
|
773
|
+
const oldMap = new Map(oldSnapshot.entities.map((e) => [e.number, e]));
|
|
774
|
+
const newMap = new Map(newSnapshot.entities.map((e) => [e.number, e]));
|
|
775
|
+
newSnapshot.entities.forEach((newEnt) => {
|
|
776
|
+
const oldEnt = oldMap.get(newEnt.number);
|
|
777
|
+
if (!oldEnt) {
|
|
778
|
+
deltaEntities.push(newEnt);
|
|
779
|
+
} else if (JSON.stringify(newEnt) !== JSON.stringify(oldEnt)) {
|
|
780
|
+
deltaEntities.push(newEnt);
|
|
781
|
+
}
|
|
782
|
+
});
|
|
783
|
+
oldSnapshot.entities.forEach((oldEnt) => {
|
|
784
|
+
if (!newMap.has(oldEnt.number)) {
|
|
785
|
+
removedEntities.push(oldEnt.number);
|
|
786
|
+
}
|
|
787
|
+
});
|
|
788
|
+
return {
|
|
789
|
+
snapshot: newSnapshot,
|
|
790
|
+
deltaEntities,
|
|
791
|
+
removedEntities
|
|
792
|
+
};
|
|
793
|
+
}
|
|
794
|
+
function verifySnapshotConsistency(snapshots) {
|
|
795
|
+
const report = { valid: true, errors: [] };
|
|
796
|
+
if (snapshots.length < 2) return report;
|
|
797
|
+
for (let i = 1; i < snapshots.length; i++) {
|
|
798
|
+
const prev = snapshots[i - 1];
|
|
799
|
+
const curr = snapshots[i];
|
|
800
|
+
if (curr.serverTime <= prev.serverTime) {
|
|
801
|
+
report.valid = false;
|
|
802
|
+
report.errors.push(`Snapshot ${i} has time ${curr.serverTime} <= prev ${prev.serverTime}`);
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
return report;
|
|
806
|
+
}
|
|
807
|
+
async function simulateSnapshotDelivery(snapshot, reliability = 1) {
|
|
808
|
+
if (Math.random() > reliability) {
|
|
809
|
+
return null;
|
|
810
|
+
}
|
|
811
|
+
return snapshot;
|
|
812
|
+
}
|
|
813
|
+
|
|
606
814
|
// src/setup/browser.ts
|
|
607
815
|
import { JSDOM } from "jsdom";
|
|
608
816
|
import { Canvas, Image, ImageData } from "@napi-rs/canvas";
|
|
@@ -1668,6 +1876,7 @@ function createVisualTestScenario(page, sceneName) {
|
|
|
1668
1876
|
};
|
|
1669
1877
|
}
|
|
1670
1878
|
export {
|
|
1879
|
+
HandshakeStage,
|
|
1671
1880
|
InputInjector,
|
|
1672
1881
|
MockPointerLock,
|
|
1673
1882
|
MockTransport,
|
|
@@ -1680,15 +1889,18 @@ export {
|
|
|
1680
1889
|
createBinaryWriterMock,
|
|
1681
1890
|
createControlledTimer,
|
|
1682
1891
|
createCustomNetworkCondition,
|
|
1892
|
+
createDeltaSnapshot,
|
|
1683
1893
|
createEntity,
|
|
1684
1894
|
createEntityStateFactory,
|
|
1685
1895
|
createGameStateSnapshotFactory,
|
|
1686
1896
|
createMockAudioContext,
|
|
1687
1897
|
createMockCanvas,
|
|
1688
1898
|
createMockCanvasContext2D,
|
|
1899
|
+
createMockConnection,
|
|
1689
1900
|
createMockEngine,
|
|
1690
1901
|
createMockGame,
|
|
1691
1902
|
createMockGameState,
|
|
1903
|
+
createMockHandshake,
|
|
1692
1904
|
createMockImage,
|
|
1693
1905
|
createMockImageData,
|
|
1694
1906
|
createMockIndexedDB,
|
|
@@ -1703,10 +1915,13 @@ export {
|
|
|
1703
1915
|
createMockSessionStorage,
|
|
1704
1916
|
createMockTransport,
|
|
1705
1917
|
createMockUDPSocket,
|
|
1918
|
+
createMockUserInfo,
|
|
1706
1919
|
createMockWebGL2Context,
|
|
1920
|
+
createMultiplayerTestScenario,
|
|
1707
1921
|
createNetChanMock,
|
|
1708
1922
|
createPlayerStateFactory,
|
|
1709
1923
|
createPlaywrightTestClient,
|
|
1924
|
+
createServerSnapshot,
|
|
1710
1925
|
createSpawnContext,
|
|
1711
1926
|
createStorageTestScenario,
|
|
1712
1927
|
createTestContext,
|
|
@@ -1720,16 +1935,24 @@ export {
|
|
|
1720
1935
|
makeLeafModel,
|
|
1721
1936
|
makeNode,
|
|
1722
1937
|
makePlane,
|
|
1938
|
+
serializeUserInfo,
|
|
1723
1939
|
setupBrowserEnvironment,
|
|
1724
1940
|
setupMockAudioContext,
|
|
1725
1941
|
setupNodeEnvironment,
|
|
1726
1942
|
simulateFrames,
|
|
1727
1943
|
simulateFramesWithMock,
|
|
1944
|
+
simulateHandshake,
|
|
1728
1945
|
simulateNetworkCondition,
|
|
1946
|
+
simulatePlayerInput,
|
|
1947
|
+
simulatePlayerJoin,
|
|
1948
|
+
simulatePlayerLeave,
|
|
1949
|
+
simulateServerTick,
|
|
1950
|
+
simulateSnapshotDelivery,
|
|
1729
1951
|
stairTrace,
|
|
1730
1952
|
teardownBrowserEnvironment,
|
|
1731
1953
|
teardownMockAudioContext,
|
|
1732
1954
|
throttleBandwidth,
|
|
1955
|
+
verifySnapshotConsistency,
|
|
1733
1956
|
waitForGameReady
|
|
1734
1957
|
};
|
|
1735
1958
|
//# sourceMappingURL=index.js.map
|