quake2ts 0.0.572 → 0.0.574

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.
Files changed (38) hide show
  1. package/package.json +1 -1
  2. package/packages/client/dist/browser/index.global.js.map +1 -1
  3. package/packages/client/dist/cjs/index.cjs +2 -2
  4. package/packages/client/dist/cjs/index.cjs.map +1 -1
  5. package/packages/client/dist/esm/index.js +2 -2
  6. package/packages/client/dist/esm/index.js.map +1 -1
  7. package/packages/client/dist/tsconfig.tsbuildinfo +1 -1
  8. package/packages/engine/dist/browser/index.global.js +16 -16
  9. package/packages/engine/dist/browser/index.global.js.map +1 -1
  10. package/packages/engine/dist/cjs/index.cjs +123 -14
  11. package/packages/engine/dist/cjs/index.cjs.map +1 -1
  12. package/packages/engine/dist/esm/index.js +122 -14
  13. package/packages/engine/dist/esm/index.js.map +1 -1
  14. package/packages/engine/dist/tsconfig.tsbuildinfo +1 -1
  15. package/packages/engine/dist/types/index.d.ts +1 -0
  16. package/packages/engine/dist/types/index.d.ts.map +1 -1
  17. package/packages/engine/dist/types/render/instancing.d.ts +12 -0
  18. package/packages/engine/dist/types/render/instancing.d.ts.map +1 -0
  19. package/packages/engine/dist/types/render/renderer.d.ts +4 -0
  20. package/packages/engine/dist/types/render/renderer.d.ts.map +1 -1
  21. package/packages/game/dist/tsconfig.tsbuildinfo +1 -1
  22. package/packages/test-utils/dist/index.cjs +133 -0
  23. package/packages/test-utils/dist/index.cjs.map +1 -1
  24. package/packages/test-utils/dist/index.d.cts +84 -2
  25. package/packages/test-utils/dist/index.d.ts +84 -2
  26. package/packages/test-utils/dist/index.js +126 -0
  27. package/packages/test-utils/dist/index.js.map +1 -1
  28. package/packages/tools/dist/browser/index.global.js +2 -1
  29. package/packages/tools/dist/browser/index.global.js.map +1 -1
  30. package/packages/tools/dist/cjs/index.cjs +175 -2
  31. package/packages/tools/dist/cjs/index.cjs.map +1 -1
  32. package/packages/tools/dist/esm/index.js +170 -1
  33. package/packages/tools/dist/esm/index.js.map +1 -1
  34. package/packages/tools/dist/tsconfig.tsbuildinfo +1 -1
  35. package/packages/tools/dist/types/index.d.ts +1 -0
  36. package/packages/tools/dist/types/index.d.ts.map +1 -1
  37. package/packages/tools/dist/types/modelExport.d.ts +19 -0
  38. package/packages/tools/dist/types/modelExport.d.ts.map +1 -0
@@ -3,7 +3,7 @@ import { Mock } from 'vitest';
3
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, MonsterMove, DamageMod, PlayerInventory, BaseItem, WeaponId, WeaponItem, HealthItem, ArmorItem, AmmoItemId, PowerupItem, GameExports } from '@quake2ts/game';
6
- import { NetworkTransport, Server, ServerStatic, Client, ClientState } from '@quake2ts/server';
6
+ import { NetworkTransport, Server, ServerStatic, Client, ClientState, ClientFrame } 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';
@@ -485,6 +485,44 @@ declare function createMockRConClient(password?: string): MockRConClient;
485
485
  */
486
486
  declare function simulateServerCommand(server: any, command: string): string;
487
487
 
488
+ interface MasterServer {
489
+ registerServer(info: ServerInfo): Promise<boolean>;
490
+ heartbeat(serverAddress: string): Promise<boolean>;
491
+ getServerList(filter?: ServerListFilter): Promise<ServerInfo[]>;
492
+ }
493
+ interface ServerInfo {
494
+ address: string;
495
+ name: string;
496
+ map: string;
497
+ players: number;
498
+ maxPlayers: number;
499
+ gametype: string;
500
+ version: string;
501
+ password?: boolean;
502
+ }
503
+ interface ServerListFilter {
504
+ gametype?: string;
505
+ map?: string;
506
+ notEmpty?: boolean;
507
+ notFull?: boolean;
508
+ }
509
+ /**
510
+ * Creates a mock master server for testing server registration and browsing
511
+ * @param overrides - Optional overrides for the master server behavior
512
+ */
513
+ declare function createMockMasterServer(overrides?: Partial<MasterServer>): MasterServer;
514
+ /**
515
+ * Creates a mock server info object
516
+ * @param overrides - Optional overrides
517
+ */
518
+ declare function createMockServerInfo(overrides?: Partial<ServerInfo>): ServerInfo;
519
+ /**
520
+ * Simulates the process of a game server registering with the master server
521
+ * @param server - The mock game server instance (typed as any to accept mock)
522
+ * @param master - The mock master server
523
+ */
524
+ declare function simulateServerRegistration(server: any, master: MasterServer): Promise<boolean>;
525
+
488
526
  type MockServerContext = Server & {
489
527
  clients: (Client | null)[];
490
528
  entities?: Entity[];
@@ -562,6 +600,50 @@ declare function verifySnapshotConsistency(snapshots: Snapshot[]): ConsistencyRe
562
600
  */
563
601
  declare function simulateSnapshotDelivery(snapshot: Snapshot, reliability?: number): Promise<Snapshot | null>;
564
602
 
603
+ interface RateLimiter {
604
+ bytesPerSecond: number;
605
+ allow(bytes: number): boolean;
606
+ update(deltaSeconds: number): void;
607
+ reset(): void;
608
+ getUsage(): number;
609
+ }
610
+ interface Message {
611
+ data: Uint8Array;
612
+ size: number;
613
+ timestamp: number;
614
+ }
615
+ interface BandwidthScenario {
616
+ bandwidth: number;
617
+ clients: Client[];
618
+ duration: number;
619
+ totalBytesSent: number;
620
+ totalBytesReceived: number;
621
+ droppedPackets: number;
622
+ }
623
+ /**
624
+ * Creates a mock rate limiter for bandwidth testing
625
+ * @param bytesPerSecond - Maximum bytes per second allowed
626
+ */
627
+ declare function createMockRateLimiter(bytesPerSecond: number): RateLimiter;
628
+ /**
629
+ * Simulates bandwidth limiting on a stream of messages
630
+ * @param messages - Array of messages to process
631
+ * @param bandwidth - Bandwidth limit in bytes per second
632
+ * @returns Filtered array of messages that passed the bandwidth check
633
+ */
634
+ declare function simulateBandwidthLimit(messages: Message[], bandwidth: number): Message[];
635
+ /**
636
+ * Calculates the size of a client snapshot in bytes
637
+ * @param snapshot - The client frame snapshot
638
+ */
639
+ declare function measureSnapshotSize(snapshot: ClientFrame): number;
640
+ /**
641
+ * Creates a scenario for testing bandwidth limits with multiple clients
642
+ * @param bandwidth - Bandwidth limit per client or total
643
+ * @param numClients - Number of clients to simulate
644
+ */
645
+ declare function createBandwidthTestScenario(bandwidth: number, numClients: number): BandwidthScenario;
646
+
565
647
  interface BrowserSetupOptions {
566
648
  url?: string;
567
649
  pretendToBeVisual?: boolean;
@@ -809,4 +891,4 @@ interface VisualScenario {
809
891
  */
810
892
  declare function createVisualTestScenario(page: Page, sceneName: string): VisualScenario;
811
893
 
812
- 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 MockAI, type MockDamageInfo, type MockEngine, type MockGame, type MockMonsterAI, MockPointerLock, type MockRAF, type MockRConClient, type MockServer, type MockServerConsole, 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, createCombatTestContext, createControlledTimer, createCustomNetworkCondition, createDeltaSnapshot, createEntity, createEntityFactory, createEntityStateFactory, createGameStateSnapshotFactory, createItemEntityFactory, createMockAI, createMockAmmoItem, createMockArmorItem, createMockAudioContext, createMockCanvas, createMockCanvasContext2D, createMockConnection, createMockDamageInfo, createMockEngine, createMockGPUAdapter, createMockGPUCanvasContext, createMockGPUDevice, createMockGame, createMockGameExports, createMockGameState, createMockHandshake, createMockHealthItem, createMockImage, createMockImageData, createMockIndexedDB, createMockInventory, createMockItem, createMockLocalStorage, createMockMonsterAI, createMockMonsterMove, createMockNetDriver, createMockNetworkAddress, createMockPerformance, createMockPowerupItem, createMockRAF, createMockRConClient, createMockServer, createMockServerClient, createMockServerConsole, createMockServerState, createMockServerStatic, createMockSessionStorage, createMockTransport, createMockUDPSocket, createMockUserInfo, createMockWeapon, createMockWeaponItem, createMockWebGL2Context, createMonsterEntityFactory, createMultiplayerTestScenario, createNetChanMock, createPhysicsTestContext, createPlayerEntityFactory, createPlayerStateFactory, createPlaywrightTestClient, createProjectileEntityFactory, createServerSnapshot, createSpawnTestContext, createStorageTestScenario, createTestContext, createTriggerEntityFactory, createVisualTestScenario, makeAxisBrush, makeBrushFromMinsMaxs, makeBspModel, makeLeaf, makeLeafModel, makeNode, makePlane, mockMonsterAttacks, serializeUserInfo, setupBrowserEnvironment, setupMockAudioContext, setupNodeEnvironment, setupWebGPUMocks, simulateFrames, simulateFramesWithMock, simulateHandshake, simulateNetworkCondition, simulatePlayerInput, simulatePlayerJoin, simulatePlayerLeave, simulateServerCommand, simulateServerTick, simulateSnapshotDelivery, teardownBrowserEnvironment, teardownMockAudioContext, throttleBandwidth, verifySnapshotConsistency, waitForGameReady };
894
+ export { type AudioEvent, type BandwidthScenario, 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 MasterServer, type Message, type MockAI, type MockDamageInfo, type MockEngine, type MockGame, type MockMonsterAI, MockPointerLock, type MockRAF, type MockRConClient, type MockServer, type MockServerConsole, type MockServerContext, MockTransport, type MockUDPSocket, type MultiplayerScenario, type NetworkAddress, type NetworkCondition, type NetworkConfig, type NetworkSimulator, type NodeSetupOptions, type PlaywrightOptions, type PlaywrightTestClient, type RateLimiter, type ServerInfo, type ServerListFilter, type Snapshot, type StorageScenario, type TestContext, type UserInfo, type VisualDiff, type VisualScenario, captureAudioEvents, captureCanvasDrawCalls, captureGameScreenshot, captureGameState, compareScreenshots, createBandwidthTestScenario, createBinaryStreamMock, createBinaryWriterMock, createCombatTestContext, createControlledTimer, createCustomNetworkCondition, createDeltaSnapshot, createEntity, createEntityFactory, createEntityStateFactory, createGameStateSnapshotFactory, createItemEntityFactory, createMockAI, createMockAmmoItem, createMockArmorItem, createMockAudioContext, createMockCanvas, createMockCanvasContext2D, createMockConnection, createMockDamageInfo, createMockEngine, createMockGPUAdapter, createMockGPUCanvasContext, createMockGPUDevice, createMockGame, createMockGameExports, createMockGameState, createMockHandshake, createMockHealthItem, createMockImage, createMockImageData, createMockIndexedDB, createMockInventory, createMockItem, createMockLocalStorage, createMockMasterServer, createMockMonsterAI, createMockMonsterMove, createMockNetDriver, createMockNetworkAddress, createMockPerformance, createMockPowerupItem, createMockRAF, createMockRConClient, createMockRateLimiter, createMockServer, createMockServerClient, createMockServerConsole, createMockServerInfo, createMockServerState, createMockServerStatic, createMockSessionStorage, createMockTransport, createMockUDPSocket, createMockUserInfo, createMockWeapon, createMockWeaponItem, createMockWebGL2Context, createMonsterEntityFactory, createMultiplayerTestScenario, createNetChanMock, createPhysicsTestContext, createPlayerEntityFactory, createPlayerStateFactory, createPlaywrightTestClient, createProjectileEntityFactory, createServerSnapshot, createSpawnTestContext, createStorageTestScenario, createTestContext, createTriggerEntityFactory, createVisualTestScenario, makeAxisBrush, makeBrushFromMinsMaxs, makeBspModel, makeLeaf, makeLeafModel, makeNode, makePlane, measureSnapshotSize, mockMonsterAttacks, serializeUserInfo, setupBrowserEnvironment, setupMockAudioContext, setupNodeEnvironment, setupWebGPUMocks, simulateBandwidthLimit, simulateFrames, simulateFramesWithMock, simulateHandshake, simulateNetworkCondition, simulatePlayerInput, simulatePlayerJoin, simulatePlayerLeave, simulateServerCommand, simulateServerRegistration, simulateServerTick, simulateSnapshotDelivery, teardownBrowserEnvironment, teardownMockAudioContext, throttleBandwidth, verifySnapshotConsistency, waitForGameReady };
@@ -3,7 +3,7 @@ import { Mock } from 'vitest';
3
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, MonsterMove, DamageMod, PlayerInventory, BaseItem, WeaponId, WeaponItem, HealthItem, ArmorItem, AmmoItemId, PowerupItem, GameExports } from '@quake2ts/game';
6
- import { NetworkTransport, Server, ServerStatic, Client, ClientState } from '@quake2ts/server';
6
+ import { NetworkTransport, Server, ServerStatic, Client, ClientState, ClientFrame } 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';
@@ -485,6 +485,44 @@ declare function createMockRConClient(password?: string): MockRConClient;
485
485
  */
486
486
  declare function simulateServerCommand(server: any, command: string): string;
487
487
 
488
+ interface MasterServer {
489
+ registerServer(info: ServerInfo): Promise<boolean>;
490
+ heartbeat(serverAddress: string): Promise<boolean>;
491
+ getServerList(filter?: ServerListFilter): Promise<ServerInfo[]>;
492
+ }
493
+ interface ServerInfo {
494
+ address: string;
495
+ name: string;
496
+ map: string;
497
+ players: number;
498
+ maxPlayers: number;
499
+ gametype: string;
500
+ version: string;
501
+ password?: boolean;
502
+ }
503
+ interface ServerListFilter {
504
+ gametype?: string;
505
+ map?: string;
506
+ notEmpty?: boolean;
507
+ notFull?: boolean;
508
+ }
509
+ /**
510
+ * Creates a mock master server for testing server registration and browsing
511
+ * @param overrides - Optional overrides for the master server behavior
512
+ */
513
+ declare function createMockMasterServer(overrides?: Partial<MasterServer>): MasterServer;
514
+ /**
515
+ * Creates a mock server info object
516
+ * @param overrides - Optional overrides
517
+ */
518
+ declare function createMockServerInfo(overrides?: Partial<ServerInfo>): ServerInfo;
519
+ /**
520
+ * Simulates the process of a game server registering with the master server
521
+ * @param server - The mock game server instance (typed as any to accept mock)
522
+ * @param master - The mock master server
523
+ */
524
+ declare function simulateServerRegistration(server: any, master: MasterServer): Promise<boolean>;
525
+
488
526
  type MockServerContext = Server & {
489
527
  clients: (Client | null)[];
490
528
  entities?: Entity[];
@@ -562,6 +600,50 @@ declare function verifySnapshotConsistency(snapshots: Snapshot[]): ConsistencyRe
562
600
  */
563
601
  declare function simulateSnapshotDelivery(snapshot: Snapshot, reliability?: number): Promise<Snapshot | null>;
564
602
 
603
+ interface RateLimiter {
604
+ bytesPerSecond: number;
605
+ allow(bytes: number): boolean;
606
+ update(deltaSeconds: number): void;
607
+ reset(): void;
608
+ getUsage(): number;
609
+ }
610
+ interface Message {
611
+ data: Uint8Array;
612
+ size: number;
613
+ timestamp: number;
614
+ }
615
+ interface BandwidthScenario {
616
+ bandwidth: number;
617
+ clients: Client[];
618
+ duration: number;
619
+ totalBytesSent: number;
620
+ totalBytesReceived: number;
621
+ droppedPackets: number;
622
+ }
623
+ /**
624
+ * Creates a mock rate limiter for bandwidth testing
625
+ * @param bytesPerSecond - Maximum bytes per second allowed
626
+ */
627
+ declare function createMockRateLimiter(bytesPerSecond: number): RateLimiter;
628
+ /**
629
+ * Simulates bandwidth limiting on a stream of messages
630
+ * @param messages - Array of messages to process
631
+ * @param bandwidth - Bandwidth limit in bytes per second
632
+ * @returns Filtered array of messages that passed the bandwidth check
633
+ */
634
+ declare function simulateBandwidthLimit(messages: Message[], bandwidth: number): Message[];
635
+ /**
636
+ * Calculates the size of a client snapshot in bytes
637
+ * @param snapshot - The client frame snapshot
638
+ */
639
+ declare function measureSnapshotSize(snapshot: ClientFrame): number;
640
+ /**
641
+ * Creates a scenario for testing bandwidth limits with multiple clients
642
+ * @param bandwidth - Bandwidth limit per client or total
643
+ * @param numClients - Number of clients to simulate
644
+ */
645
+ declare function createBandwidthTestScenario(bandwidth: number, numClients: number): BandwidthScenario;
646
+
565
647
  interface BrowserSetupOptions {
566
648
  url?: string;
567
649
  pretendToBeVisual?: boolean;
@@ -809,4 +891,4 @@ interface VisualScenario {
809
891
  */
810
892
  declare function createVisualTestScenario(page: Page, sceneName: string): VisualScenario;
811
893
 
812
- 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 MockAI, type MockDamageInfo, type MockEngine, type MockGame, type MockMonsterAI, MockPointerLock, type MockRAF, type MockRConClient, type MockServer, type MockServerConsole, 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, createCombatTestContext, createControlledTimer, createCustomNetworkCondition, createDeltaSnapshot, createEntity, createEntityFactory, createEntityStateFactory, createGameStateSnapshotFactory, createItemEntityFactory, createMockAI, createMockAmmoItem, createMockArmorItem, createMockAudioContext, createMockCanvas, createMockCanvasContext2D, createMockConnection, createMockDamageInfo, createMockEngine, createMockGPUAdapter, createMockGPUCanvasContext, createMockGPUDevice, createMockGame, createMockGameExports, createMockGameState, createMockHandshake, createMockHealthItem, createMockImage, createMockImageData, createMockIndexedDB, createMockInventory, createMockItem, createMockLocalStorage, createMockMonsterAI, createMockMonsterMove, createMockNetDriver, createMockNetworkAddress, createMockPerformance, createMockPowerupItem, createMockRAF, createMockRConClient, createMockServer, createMockServerClient, createMockServerConsole, createMockServerState, createMockServerStatic, createMockSessionStorage, createMockTransport, createMockUDPSocket, createMockUserInfo, createMockWeapon, createMockWeaponItem, createMockWebGL2Context, createMonsterEntityFactory, createMultiplayerTestScenario, createNetChanMock, createPhysicsTestContext, createPlayerEntityFactory, createPlayerStateFactory, createPlaywrightTestClient, createProjectileEntityFactory, createServerSnapshot, createSpawnTestContext, createStorageTestScenario, createTestContext, createTriggerEntityFactory, createVisualTestScenario, makeAxisBrush, makeBrushFromMinsMaxs, makeBspModel, makeLeaf, makeLeafModel, makeNode, makePlane, mockMonsterAttacks, serializeUserInfo, setupBrowserEnvironment, setupMockAudioContext, setupNodeEnvironment, setupWebGPUMocks, simulateFrames, simulateFramesWithMock, simulateHandshake, simulateNetworkCondition, simulatePlayerInput, simulatePlayerJoin, simulatePlayerLeave, simulateServerCommand, simulateServerTick, simulateSnapshotDelivery, teardownBrowserEnvironment, teardownMockAudioContext, throttleBandwidth, verifySnapshotConsistency, waitForGameReady };
894
+ export { type AudioEvent, type BandwidthScenario, 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 MasterServer, type Message, type MockAI, type MockDamageInfo, type MockEngine, type MockGame, type MockMonsterAI, MockPointerLock, type MockRAF, type MockRConClient, type MockServer, type MockServerConsole, type MockServerContext, MockTransport, type MockUDPSocket, type MultiplayerScenario, type NetworkAddress, type NetworkCondition, type NetworkConfig, type NetworkSimulator, type NodeSetupOptions, type PlaywrightOptions, type PlaywrightTestClient, type RateLimiter, type ServerInfo, type ServerListFilter, type Snapshot, type StorageScenario, type TestContext, type UserInfo, type VisualDiff, type VisualScenario, captureAudioEvents, captureCanvasDrawCalls, captureGameScreenshot, captureGameState, compareScreenshots, createBandwidthTestScenario, createBinaryStreamMock, createBinaryWriterMock, createCombatTestContext, createControlledTimer, createCustomNetworkCondition, createDeltaSnapshot, createEntity, createEntityFactory, createEntityStateFactory, createGameStateSnapshotFactory, createItemEntityFactory, createMockAI, createMockAmmoItem, createMockArmorItem, createMockAudioContext, createMockCanvas, createMockCanvasContext2D, createMockConnection, createMockDamageInfo, createMockEngine, createMockGPUAdapter, createMockGPUCanvasContext, createMockGPUDevice, createMockGame, createMockGameExports, createMockGameState, createMockHandshake, createMockHealthItem, createMockImage, createMockImageData, createMockIndexedDB, createMockInventory, createMockItem, createMockLocalStorage, createMockMasterServer, createMockMonsterAI, createMockMonsterMove, createMockNetDriver, createMockNetworkAddress, createMockPerformance, createMockPowerupItem, createMockRAF, createMockRConClient, createMockRateLimiter, createMockServer, createMockServerClient, createMockServerConsole, createMockServerInfo, createMockServerState, createMockServerStatic, createMockSessionStorage, createMockTransport, createMockUDPSocket, createMockUserInfo, createMockWeapon, createMockWeaponItem, createMockWebGL2Context, createMonsterEntityFactory, createMultiplayerTestScenario, createNetChanMock, createPhysicsTestContext, createPlayerEntityFactory, createPlayerStateFactory, createPlaywrightTestClient, createProjectileEntityFactory, createServerSnapshot, createSpawnTestContext, createStorageTestScenario, createTestContext, createTriggerEntityFactory, createVisualTestScenario, makeAxisBrush, makeBrushFromMinsMaxs, makeBspModel, makeLeaf, makeLeafModel, makeNode, makePlane, measureSnapshotSize, mockMonsterAttacks, serializeUserInfo, setupBrowserEnvironment, setupMockAudioContext, setupNodeEnvironment, setupWebGPUMocks, simulateBandwidthLimit, simulateFrames, simulateFramesWithMock, simulateHandshake, simulateNetworkCondition, simulatePlayerInput, simulatePlayerJoin, simulatePlayerLeave, simulateServerCommand, simulateServerRegistration, simulateServerTick, simulateSnapshotDelivery, teardownBrowserEnvironment, teardownMockAudioContext, throttleBandwidth, verifySnapshotConsistency, waitForGameReady };
@@ -1069,6 +1069,60 @@ function simulateServerCommand(server, command) {
1069
1069
  return "Unknown command handler";
1070
1070
  }
1071
1071
 
1072
+ // src/server/mocks/master.ts
1073
+ function createMockMasterServer(overrides = {}) {
1074
+ const servers = /* @__PURE__ */ new Map();
1075
+ return {
1076
+ registerServer: async (info) => {
1077
+ servers.set(info.address, info);
1078
+ return true;
1079
+ },
1080
+ heartbeat: async (serverAddress) => {
1081
+ return servers.has(serverAddress);
1082
+ },
1083
+ getServerList: async (filter) => {
1084
+ let list = Array.from(servers.values());
1085
+ if (filter) {
1086
+ if (filter.gametype) {
1087
+ list = list.filter((s) => s.gametype === filter.gametype);
1088
+ }
1089
+ if (filter.map) {
1090
+ list = list.filter((s) => s.map === filter.map);
1091
+ }
1092
+ if (filter.notEmpty) {
1093
+ list = list.filter((s) => s.players > 0);
1094
+ }
1095
+ if (filter.notFull) {
1096
+ list = list.filter((s) => s.players < s.maxPlayers);
1097
+ }
1098
+ }
1099
+ return list;
1100
+ },
1101
+ ...overrides
1102
+ };
1103
+ }
1104
+ function createMockServerInfo(overrides = {}) {
1105
+ return {
1106
+ address: "127.0.0.1:27910",
1107
+ name: "Quake 2 Test Server",
1108
+ map: "q2dm1",
1109
+ players: 0,
1110
+ maxPlayers: 16,
1111
+ gametype: "deathmatch",
1112
+ version: "1.0",
1113
+ ...overrides
1114
+ };
1115
+ }
1116
+ async function simulateServerRegistration(server, master) {
1117
+ const info = createMockServerInfo({
1118
+ name: server.name || "Test Server",
1119
+ map: server.mapName || "q2dm1",
1120
+ players: server.clients ? server.clients.filter((c) => c && c.state >= 2).length : 0,
1121
+ maxPlayers: server.maxClients || 16
1122
+ });
1123
+ return master.registerServer(info);
1124
+ }
1125
+
1072
1126
  // src/server/helpers/multiplayer.ts
1073
1127
  import { ClientState as ClientState3 } from "@quake2ts/server";
1074
1128
  function createMultiplayerTestScenario(numPlayers = 2) {
@@ -1221,6 +1275,71 @@ async function simulateSnapshotDelivery(snapshot, reliability = 1) {
1221
1275
  return snapshot;
1222
1276
  }
1223
1277
 
1278
+ // src/server/helpers/bandwidth.ts
1279
+ function createMockRateLimiter(bytesPerSecond) {
1280
+ let bucket = bytesPerSecond;
1281
+ const maxBucket = bytesPerSecond;
1282
+ let usage = 0;
1283
+ return {
1284
+ bytesPerSecond,
1285
+ allow(bytes) {
1286
+ if (bucket >= bytes) {
1287
+ bucket -= bytes;
1288
+ usage += bytes;
1289
+ return true;
1290
+ }
1291
+ return false;
1292
+ },
1293
+ update(deltaSeconds) {
1294
+ bucket += bytesPerSecond * deltaSeconds;
1295
+ if (bucket > maxBucket) {
1296
+ bucket = maxBucket;
1297
+ }
1298
+ },
1299
+ reset() {
1300
+ bucket = maxBucket;
1301
+ usage = 0;
1302
+ },
1303
+ getUsage() {
1304
+ return usage;
1305
+ }
1306
+ };
1307
+ }
1308
+ function simulateBandwidthLimit(messages, bandwidth) {
1309
+ const limiter = createMockRateLimiter(bandwidth);
1310
+ const result = [];
1311
+ let lastTime = messages.length > 0 ? messages[0].timestamp : 0;
1312
+ for (const msg of messages) {
1313
+ const delta = (msg.timestamp - lastTime) / 1e3;
1314
+ if (delta > 0) {
1315
+ limiter.update(delta);
1316
+ }
1317
+ lastTime = msg.timestamp;
1318
+ if (limiter.allow(msg.size)) {
1319
+ result.push(msg);
1320
+ }
1321
+ }
1322
+ return result;
1323
+ }
1324
+ function measureSnapshotSize(snapshot) {
1325
+ let size = 0;
1326
+ size += snapshot.areaBytes;
1327
+ size += 200;
1328
+ size += snapshot.entities.length * 20;
1329
+ return size;
1330
+ }
1331
+ function createBandwidthTestScenario(bandwidth, numClients) {
1332
+ const clients = [];
1333
+ return {
1334
+ bandwidth,
1335
+ clients,
1336
+ duration: 0,
1337
+ totalBytesSent: 0,
1338
+ totalBytesReceived: 0,
1339
+ droppedPackets: 0
1340
+ };
1341
+ }
1342
+
1224
1343
  // src/setup/browser.ts
1225
1344
  import { JSDOM } from "jsdom";
1226
1345
  import { Canvas, Image, ImageData } from "@napi-rs/canvas";
@@ -2358,6 +2477,7 @@ export {
2358
2477
  captureGameScreenshot,
2359
2478
  captureGameState,
2360
2479
  compareScreenshots,
2480
+ createBandwidthTestScenario,
2361
2481
  createBinaryStreamMock,
2362
2482
  createBinaryWriterMock,
2363
2483
  createCombatTestContext,
@@ -2392,6 +2512,7 @@ export {
2392
2512
  createMockInventory,
2393
2513
  createMockItem,
2394
2514
  createMockLocalStorage,
2515
+ createMockMasterServer,
2395
2516
  createMockMonsterAI,
2396
2517
  createMockMonsterMove,
2397
2518
  createMockNetDriver,
@@ -2400,9 +2521,11 @@ export {
2400
2521
  createMockPowerupItem,
2401
2522
  createMockRAF,
2402
2523
  createMockRConClient,
2524
+ createMockRateLimiter,
2403
2525
  createMockServer,
2404
2526
  createMockServerClient,
2405
2527
  createMockServerConsole,
2528
+ createMockServerInfo,
2406
2529
  createMockServerState,
2407
2530
  createMockServerStatic,
2408
2531
  createMockSessionStorage,
@@ -2435,12 +2558,14 @@ export {
2435
2558
  makeLeafModel,
2436
2559
  makeNode,
2437
2560
  makePlane,
2561
+ measureSnapshotSize,
2438
2562
  mockMonsterAttacks,
2439
2563
  serializeUserInfo,
2440
2564
  setupBrowserEnvironment,
2441
2565
  setupMockAudioContext,
2442
2566
  setupNodeEnvironment,
2443
2567
  setupWebGPUMocks,
2568
+ simulateBandwidthLimit,
2444
2569
  simulateFrames,
2445
2570
  simulateFramesWithMock,
2446
2571
  simulateHandshake,
@@ -2449,6 +2574,7 @@ export {
2449
2574
  simulatePlayerJoin,
2450
2575
  simulatePlayerLeave,
2451
2576
  simulateServerCommand,
2577
+ simulateServerRegistration,
2452
2578
  simulateServerTick,
2453
2579
  simulateSnapshotDelivery,
2454
2580
  stairTrace,