quake2ts 0.0.84 → 0.0.85
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/client/dist/browser/index.global.js +1 -1
- package/packages/client/dist/browser/index.global.js.map +1 -1
- package/packages/client/dist/cjs/index.cjs +382 -127
- package/packages/client/dist/cjs/index.cjs.map +1 -1
- package/packages/client/dist/esm/index.js +382 -127
- package/packages/client/dist/esm/index.js.map +1 -1
- package/packages/client/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/client/dist/types/demo/handler.d.ts +30 -0
- package/packages/client/dist/types/demo/handler.d.ts.map +1 -0
- package/packages/client/dist/types/index.d.ts +2 -0
- package/packages/client/dist/types/index.d.ts.map +1 -1
- package/packages/engine/dist/browser/index.global.js +14 -14
- package/packages/engine/dist/browser/index.global.js.map +1 -1
- package/packages/engine/dist/cjs/index.cjs +235 -97
- package/packages/engine/dist/cjs/index.cjs.map +1 -1
- package/packages/engine/dist/esm/index.js +210 -97
- package/packages/engine/dist/esm/index.js.map +1 -1
- package/packages/engine/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/engine/dist/types/demo/index.d.ts +1 -1
- package/packages/engine/dist/types/demo/index.d.ts.map +1 -1
- package/packages/engine/dist/types/demo/parser.d.ts +84 -3
- package/packages/engine/dist/types/demo/parser.d.ts.map +1 -1
- package/packages/engine/dist/types/demo/playback.d.ts +3 -0
- package/packages/engine/dist/types/demo/playback.d.ts.map +1 -1
- package/packages/engine/dist/types/index.d.ts +2 -0
- package/packages/engine/dist/types/index.d.ts.map +1 -1
- package/packages/game/dist/tsconfig.tsbuildinfo +1 -1
|
@@ -2414,11 +2414,33 @@ var createEmptyEntityState = () => ({
|
|
|
2414
2414
|
angles: { x: 0, y: 0, z: 0 },
|
|
2415
2415
|
sound: 0,
|
|
2416
2416
|
event: 0,
|
|
2417
|
-
solid: 0
|
|
2417
|
+
solid: 0,
|
|
2418
|
+
bits: 0
|
|
2419
|
+
});
|
|
2420
|
+
var createEmptyProtocolPlayerState = () => ({
|
|
2421
|
+
pm_type: 0,
|
|
2422
|
+
origin: { x: 0, y: 0, z: 0 },
|
|
2423
|
+
velocity: { x: 0, y: 0, z: 0 },
|
|
2424
|
+
pm_time: 0,
|
|
2425
|
+
pm_flags: 0,
|
|
2426
|
+
gravity: 0,
|
|
2427
|
+
delta_angles: { x: 0, y: 0, z: 0 },
|
|
2428
|
+
viewoffset: { x: 0, y: 0, z: 0 },
|
|
2429
|
+
viewangles: { x: 0, y: 0, z: 0 },
|
|
2430
|
+
kick_angles: { x: 0, y: 0, z: 0 },
|
|
2431
|
+
gun_index: 0,
|
|
2432
|
+
gun_frame: 0,
|
|
2433
|
+
gun_offset: { x: 0, y: 0, z: 0 },
|
|
2434
|
+
gun_angles: { x: 0, y: 0, z: 0 },
|
|
2435
|
+
blend: [0, 0, 0, 0],
|
|
2436
|
+
fov: 0,
|
|
2437
|
+
rdflags: 0,
|
|
2438
|
+
stats: new Array(32).fill(0)
|
|
2418
2439
|
});
|
|
2419
2440
|
var NetworkMessageParser = class {
|
|
2420
|
-
constructor(stream) {
|
|
2441
|
+
constructor(stream, handler) {
|
|
2421
2442
|
this.stream = stream;
|
|
2443
|
+
this.handler = handler;
|
|
2422
2444
|
}
|
|
2423
2445
|
parseMessage() {
|
|
2424
2446
|
while (this.stream.hasMore()) {
|
|
@@ -2430,15 +2452,18 @@ var NetworkMessageParser = class {
|
|
|
2430
2452
|
case ServerCommand.nop:
|
|
2431
2453
|
break;
|
|
2432
2454
|
case ServerCommand.disconnect:
|
|
2433
|
-
|
|
2455
|
+
if (this.handler) this.handler.onDisconnect();
|
|
2456
|
+
else console.log("Server disconnected");
|
|
2434
2457
|
break;
|
|
2435
2458
|
case ServerCommand.reconnect:
|
|
2436
|
-
|
|
2459
|
+
if (this.handler) this.handler.onReconnect();
|
|
2460
|
+
else console.log("Server reconnect");
|
|
2437
2461
|
break;
|
|
2438
2462
|
case ServerCommand.print:
|
|
2439
2463
|
const printId = this.stream.readByte();
|
|
2440
2464
|
const printMsg = this.stream.readString();
|
|
2441
|
-
|
|
2465
|
+
if (this.handler) this.handler.onPrint(printId, printMsg);
|
|
2466
|
+
else console.log(`[Server Print ${printId}]: ${printMsg}`);
|
|
2442
2467
|
break;
|
|
2443
2468
|
case ServerCommand.serverdata:
|
|
2444
2469
|
this.parseServerData();
|
|
@@ -2451,7 +2476,8 @@ var NetworkMessageParser = class {
|
|
|
2451
2476
|
break;
|
|
2452
2477
|
case ServerCommand.centerprint:
|
|
2453
2478
|
const centerMsg = this.stream.readString();
|
|
2454
|
-
|
|
2479
|
+
if (this.handler) this.handler.onCenterPrint(centerMsg);
|
|
2480
|
+
else console.log(`[Center Print]: ${centerMsg}`);
|
|
2455
2481
|
break;
|
|
2456
2482
|
case ServerCommand.download:
|
|
2457
2483
|
this.parseDownload();
|
|
@@ -2467,10 +2493,12 @@ var NetworkMessageParser = class {
|
|
|
2467
2493
|
break;
|
|
2468
2494
|
case ServerCommand.stufftext:
|
|
2469
2495
|
const text = this.stream.readString();
|
|
2470
|
-
|
|
2496
|
+
if (this.handler) this.handler.onStuffText(text);
|
|
2497
|
+
else console.log(`[StuffText]: ${text}`);
|
|
2471
2498
|
break;
|
|
2472
2499
|
case ServerCommand.layout:
|
|
2473
2500
|
const layout = this.stream.readString();
|
|
2501
|
+
if (this.handler) this.handler.onLayout(layout);
|
|
2474
2502
|
break;
|
|
2475
2503
|
case ServerCommand.inventory:
|
|
2476
2504
|
this.parseInventory();
|
|
@@ -2500,58 +2528,89 @@ var NetworkMessageParser = class {
|
|
|
2500
2528
|
const gameDir = this.stream.readString();
|
|
2501
2529
|
const playerNum = this.stream.readShort();
|
|
2502
2530
|
const levelName = this.stream.readString();
|
|
2503
|
-
|
|
2531
|
+
if (this.handler) {
|
|
2532
|
+
this.handler.onServerData(protocol, serverCount, attractLoop, gameDir, playerNum, levelName);
|
|
2533
|
+
} else {
|
|
2534
|
+
console.log(`Server Data: Protocol ${protocol}, Level ${levelName}, GameDir ${gameDir}`);
|
|
2535
|
+
}
|
|
2504
2536
|
}
|
|
2505
2537
|
parseConfigString() {
|
|
2506
2538
|
const index = this.stream.readShort();
|
|
2507
2539
|
const str3 = this.stream.readString();
|
|
2540
|
+
if (this.handler) {
|
|
2541
|
+
this.handler.onConfigString(index, str3);
|
|
2542
|
+
}
|
|
2508
2543
|
}
|
|
2509
2544
|
parseDownload() {
|
|
2510
2545
|
const size = this.stream.readShort();
|
|
2511
2546
|
const percent = this.stream.readByte();
|
|
2547
|
+
let data;
|
|
2512
2548
|
if (size > 0) {
|
|
2513
|
-
this.stream.readData(size);
|
|
2549
|
+
data = this.stream.readData(size);
|
|
2550
|
+
}
|
|
2551
|
+
if (this.handler) {
|
|
2552
|
+
this.handler.onDownload(size, percent, data);
|
|
2514
2553
|
}
|
|
2515
2554
|
}
|
|
2516
2555
|
parseInventory() {
|
|
2517
2556
|
const MAX_ITEMS22 = 256;
|
|
2557
|
+
const inventory = new Array(MAX_ITEMS22);
|
|
2518
2558
|
for (let i = 0; i < MAX_ITEMS22; i++) {
|
|
2519
|
-
this.stream.readShort();
|
|
2559
|
+
inventory[i] = this.stream.readShort();
|
|
2560
|
+
}
|
|
2561
|
+
if (this.handler) {
|
|
2562
|
+
this.handler.onInventory(inventory);
|
|
2520
2563
|
}
|
|
2521
2564
|
}
|
|
2522
2565
|
parseSound() {
|
|
2523
2566
|
const flags = this.stream.readByte();
|
|
2524
2567
|
const soundNum = this.stream.readByte();
|
|
2568
|
+
let volume;
|
|
2569
|
+
let attenuation;
|
|
2570
|
+
let offset;
|
|
2571
|
+
let ent;
|
|
2572
|
+
let pos;
|
|
2525
2573
|
if (flags & 1) {
|
|
2526
|
-
this.stream.readByte();
|
|
2574
|
+
volume = this.stream.readByte();
|
|
2527
2575
|
}
|
|
2528
2576
|
if (flags & 2) {
|
|
2529
|
-
this.stream.readByte();
|
|
2577
|
+
attenuation = this.stream.readByte();
|
|
2530
2578
|
}
|
|
2531
2579
|
if (flags & 16) {
|
|
2532
|
-
this.stream.readByte();
|
|
2580
|
+
offset = this.stream.readByte();
|
|
2533
2581
|
}
|
|
2534
2582
|
if (flags & 8) {
|
|
2535
|
-
this.stream.readShort();
|
|
2583
|
+
ent = this.stream.readShort();
|
|
2536
2584
|
}
|
|
2537
2585
|
if (flags & 4) {
|
|
2538
|
-
const
|
|
2539
|
-
this.stream.readPos(
|
|
2586
|
+
const p = { x: 0, y: 0, z: 0 };
|
|
2587
|
+
this.stream.readPos(p);
|
|
2588
|
+
pos = p;
|
|
2589
|
+
}
|
|
2590
|
+
if (this.handler) {
|
|
2591
|
+
this.handler.onSound(flags, soundNum, volume, attenuation, offset, ent, pos);
|
|
2540
2592
|
}
|
|
2541
2593
|
}
|
|
2542
2594
|
parseMuzzleFlash() {
|
|
2543
2595
|
const ent = this.stream.readShort();
|
|
2544
2596
|
const weapon = this.stream.readByte();
|
|
2597
|
+
if (this.handler) this.handler.onMuzzleFlash(ent, weapon);
|
|
2545
2598
|
}
|
|
2546
2599
|
parseMuzzleFlash2() {
|
|
2547
2600
|
const ent = this.stream.readShort();
|
|
2548
2601
|
const weapon = this.stream.readByte();
|
|
2602
|
+
if (this.handler) this.handler.onMuzzleFlash2(ent, weapon);
|
|
2549
2603
|
}
|
|
2550
2604
|
parseTempEntity() {
|
|
2551
2605
|
const type = this.stream.readByte();
|
|
2552
2606
|
const pos = { x: 0, y: 0, z: 0 };
|
|
2553
2607
|
const pos2 = { x: 0, y: 0, z: 0 };
|
|
2554
2608
|
const dir = { x: 0, y: 0, z: 0 };
|
|
2609
|
+
let cnt;
|
|
2610
|
+
let color;
|
|
2611
|
+
let ent;
|
|
2612
|
+
let srcEnt;
|
|
2613
|
+
let destEnt;
|
|
2555
2614
|
switch (type) {
|
|
2556
2615
|
case TempEntity.BLOOD:
|
|
2557
2616
|
this.stream.readPos(pos);
|
|
@@ -2560,29 +2619,23 @@ var NetworkMessageParser = class {
|
|
|
2560
2619
|
case TempEntity.GUNSHOT:
|
|
2561
2620
|
case TempEntity.SPARKS:
|
|
2562
2621
|
case TempEntity.BULLET_SPARKS:
|
|
2563
|
-
this.stream.readPos(pos);
|
|
2564
|
-
this.stream.readDir(dir);
|
|
2565
|
-
break;
|
|
2566
2622
|
case TempEntity.SCREEN_SPARKS:
|
|
2567
2623
|
case TempEntity.SHIELD_SPARKS:
|
|
2568
|
-
this.stream.readPos(pos);
|
|
2569
|
-
this.stream.readDir(dir);
|
|
2570
|
-
break;
|
|
2571
2624
|
case TempEntity.SHOTGUN:
|
|
2572
2625
|
this.stream.readPos(pos);
|
|
2573
2626
|
this.stream.readDir(dir);
|
|
2574
2627
|
break;
|
|
2575
2628
|
case TempEntity.SPLASH:
|
|
2576
|
-
this.stream.readByte();
|
|
2629
|
+
cnt = this.stream.readByte();
|
|
2577
2630
|
this.stream.readPos(pos);
|
|
2578
2631
|
this.stream.readDir(dir);
|
|
2579
|
-
this.stream.readByte();
|
|
2632
|
+
color = this.stream.readByte();
|
|
2580
2633
|
break;
|
|
2581
2634
|
case TempEntity.LASER_SPARKS:
|
|
2582
|
-
this.stream.readByte();
|
|
2635
|
+
cnt = this.stream.readByte();
|
|
2583
2636
|
this.stream.readPos(pos);
|
|
2584
2637
|
this.stream.readDir(dir);
|
|
2585
|
-
this.stream.readByte();
|
|
2638
|
+
color = this.stream.readByte();
|
|
2586
2639
|
break;
|
|
2587
2640
|
case TempEntity.BLUEHYPERBLASTER:
|
|
2588
2641
|
this.stream.readPos(pos);
|
|
@@ -2599,21 +2652,13 @@ var NetworkMessageParser = class {
|
|
|
2599
2652
|
case TempEntity.EXPLOSION2:
|
|
2600
2653
|
case TempEntity.GRENADE_EXPLOSION:
|
|
2601
2654
|
case TempEntity.GRENADE_EXPLOSION_WATER:
|
|
2602
|
-
this.stream.readPos(pos);
|
|
2603
|
-
break;
|
|
2604
2655
|
case TempEntity.PLASMA_EXPLOSION:
|
|
2605
|
-
this.stream.readPos(pos);
|
|
2606
|
-
break;
|
|
2607
2656
|
case TempEntity.EXPLOSION1:
|
|
2608
2657
|
case TempEntity.EXPLOSION1_BIG:
|
|
2609
2658
|
case TempEntity.ROCKET_EXPLOSION:
|
|
2610
2659
|
case TempEntity.ROCKET_EXPLOSION_WATER:
|
|
2611
2660
|
case TempEntity.EXPLOSION1_NP:
|
|
2612
|
-
this.stream.readPos(pos);
|
|
2613
|
-
break;
|
|
2614
2661
|
case TempEntity.BFG_EXPLOSION:
|
|
2615
|
-
this.stream.readPos(pos);
|
|
2616
|
-
break;
|
|
2617
2662
|
case TempEntity.BFG_BIGEXPLOSION:
|
|
2618
2663
|
this.stream.readPos(pos);
|
|
2619
2664
|
break;
|
|
@@ -2627,7 +2672,7 @@ var NetworkMessageParser = class {
|
|
|
2627
2672
|
break;
|
|
2628
2673
|
case TempEntity.PARASITE_ATTACK:
|
|
2629
2674
|
case TempEntity.MEDIC_CABLE_ATTACK:
|
|
2630
|
-
this.stream.readShort();
|
|
2675
|
+
ent = this.stream.readShort();
|
|
2631
2676
|
this.stream.readPos(pos);
|
|
2632
2677
|
this.stream.readPos(pos2);
|
|
2633
2678
|
break;
|
|
@@ -2635,26 +2680,26 @@ var NetworkMessageParser = class {
|
|
|
2635
2680
|
this.stream.readPos(pos);
|
|
2636
2681
|
break;
|
|
2637
2682
|
case TempEntity.GRAPPLE_CABLE:
|
|
2638
|
-
this.stream.readShort();
|
|
2683
|
+
ent = this.stream.readShort();
|
|
2639
2684
|
this.stream.readPos(pos);
|
|
2640
2685
|
this.stream.readPos(pos2);
|
|
2641
2686
|
this.stream.readPos(dir);
|
|
2642
2687
|
break;
|
|
2643
2688
|
case TempEntity.WELDING_SPARKS:
|
|
2644
|
-
this.stream.readByte();
|
|
2689
|
+
cnt = this.stream.readByte();
|
|
2645
2690
|
this.stream.readPos(pos);
|
|
2646
2691
|
this.stream.readDir(dir);
|
|
2647
|
-
this.stream.readByte();
|
|
2692
|
+
color = this.stream.readByte();
|
|
2648
2693
|
break;
|
|
2649
2694
|
case TempEntity.GREENBLOOD:
|
|
2650
2695
|
this.stream.readPos(pos);
|
|
2651
2696
|
this.stream.readDir(dir);
|
|
2652
2697
|
break;
|
|
2653
2698
|
case TempEntity.TUNNEL_SPARKS:
|
|
2654
|
-
this.stream.readByte();
|
|
2699
|
+
cnt = this.stream.readByte();
|
|
2655
2700
|
this.stream.readPos(pos);
|
|
2656
2701
|
this.stream.readDir(dir);
|
|
2657
|
-
this.stream.readByte();
|
|
2702
|
+
color = this.stream.readByte();
|
|
2658
2703
|
break;
|
|
2659
2704
|
case TempEntity.BLASTER2:
|
|
2660
2705
|
case TempEntity.FLECHETTE:
|
|
@@ -2662,8 +2707,8 @@ var NetworkMessageParser = class {
|
|
|
2662
2707
|
this.stream.readDir(dir);
|
|
2663
2708
|
break;
|
|
2664
2709
|
case TempEntity.LIGHTNING:
|
|
2665
|
-
this.stream.readShort();
|
|
2666
|
-
this.stream.readShort();
|
|
2710
|
+
srcEnt = this.stream.readShort();
|
|
2711
|
+
destEnt = this.stream.readShort();
|
|
2667
2712
|
this.stream.readPos(pos);
|
|
2668
2713
|
this.stream.readPos(pos2);
|
|
2669
2714
|
break;
|
|
@@ -2676,29 +2721,26 @@ var NetworkMessageParser = class {
|
|
|
2676
2721
|
break;
|
|
2677
2722
|
case TempEntity.FLASHLIGHT:
|
|
2678
2723
|
this.stream.readPos(pos);
|
|
2679
|
-
this.stream.readShort();
|
|
2724
|
+
ent = this.stream.readShort();
|
|
2680
2725
|
break;
|
|
2681
2726
|
case TempEntity.FORCEWALL:
|
|
2682
2727
|
this.stream.readPos(pos);
|
|
2683
2728
|
this.stream.readPos(pos2);
|
|
2684
|
-
this.stream.readByte();
|
|
2729
|
+
color = this.stream.readByte();
|
|
2685
2730
|
break;
|
|
2686
2731
|
case TempEntity.HEATBEAM:
|
|
2687
|
-
this.stream.readShort();
|
|
2732
|
+
ent = this.stream.readShort();
|
|
2688
2733
|
this.stream.readPos(pos);
|
|
2689
2734
|
this.stream.readPos(pos2);
|
|
2690
2735
|
this.stream.readPos(dir);
|
|
2691
2736
|
break;
|
|
2692
2737
|
case TempEntity.MONSTER_HEATBEAM:
|
|
2693
|
-
this.stream.readShort();
|
|
2738
|
+
ent = this.stream.readShort();
|
|
2694
2739
|
this.stream.readPos(pos);
|
|
2695
2740
|
this.stream.readPos(pos2);
|
|
2696
2741
|
this.stream.readPos(dir);
|
|
2697
2742
|
break;
|
|
2698
2743
|
case TempEntity.HEATBEAM_SPARKS:
|
|
2699
|
-
this.stream.readPos(pos);
|
|
2700
|
-
this.stream.readDir(dir);
|
|
2701
|
-
break;
|
|
2702
2744
|
case TempEntity.HEATBEAM_STEAM:
|
|
2703
2745
|
this.stream.readPos(pos);
|
|
2704
2746
|
this.stream.readDir(dir);
|
|
@@ -2706,17 +2748,17 @@ var NetworkMessageParser = class {
|
|
|
2706
2748
|
case TempEntity.STEAM:
|
|
2707
2749
|
const steamId = this.stream.readShort();
|
|
2708
2750
|
if (steamId !== -1) {
|
|
2709
|
-
this.stream.readByte();
|
|
2751
|
+
cnt = this.stream.readByte();
|
|
2710
2752
|
this.stream.readPos(pos);
|
|
2711
2753
|
this.stream.readDir(dir);
|
|
2712
|
-
this.stream.readByte();
|
|
2754
|
+
color = this.stream.readByte();
|
|
2713
2755
|
this.stream.readShort();
|
|
2714
2756
|
this.stream.readLong();
|
|
2715
2757
|
} else {
|
|
2716
|
-
this.stream.readByte();
|
|
2758
|
+
cnt = this.stream.readByte();
|
|
2717
2759
|
this.stream.readPos(pos);
|
|
2718
2760
|
this.stream.readDir(dir);
|
|
2719
|
-
this.stream.readByte();
|
|
2761
|
+
color = this.stream.readByte();
|
|
2720
2762
|
this.stream.readShort();
|
|
2721
2763
|
}
|
|
2722
2764
|
break;
|
|
@@ -2743,7 +2785,7 @@ var NetworkMessageParser = class {
|
|
|
2743
2785
|
this.stream.readPos(pos);
|
|
2744
2786
|
break;
|
|
2745
2787
|
case TempEntity.WIDOWBEAMOUT:
|
|
2746
|
-
|
|
2788
|
+
this.stream.readShort();
|
|
2747
2789
|
this.stream.readPos(pos);
|
|
2748
2790
|
break;
|
|
2749
2791
|
case TempEntity.NUKEBLAST:
|
|
@@ -2756,97 +2798,139 @@ var NetworkMessageParser = class {
|
|
|
2756
2798
|
console.warn(`CL_ParseTEnt: bad type ${type}`);
|
|
2757
2799
|
break;
|
|
2758
2800
|
}
|
|
2801
|
+
if (this.handler) {
|
|
2802
|
+
this.handler.onTempEntity(type, pos, pos2, dir, cnt, color, ent, srcEnt, destEnt);
|
|
2803
|
+
}
|
|
2759
2804
|
}
|
|
2760
2805
|
parseSpawnBaseline() {
|
|
2761
2806
|
const bits = this.parseEntityBits();
|
|
2762
|
-
|
|
2807
|
+
const entity = createEmptyEntityState();
|
|
2808
|
+
this.parseDelta(createEmptyEntityState(), entity, bits.number, bits.bits);
|
|
2809
|
+
if (this.handler) {
|
|
2810
|
+
this.handler.onSpawnBaseline(entity);
|
|
2811
|
+
}
|
|
2763
2812
|
}
|
|
2764
2813
|
parseFrame() {
|
|
2765
2814
|
const serverFrame = this.stream.readLong();
|
|
2766
2815
|
const deltaFrame = this.stream.readLong();
|
|
2767
2816
|
const surpressCount = this.stream.readByte();
|
|
2768
2817
|
const areaBytes = this.stream.readByte();
|
|
2769
|
-
this.stream.readData(areaBytes);
|
|
2818
|
+
const areaBits = this.stream.readData(areaBytes);
|
|
2770
2819
|
const piCmd = this.stream.readByte();
|
|
2771
2820
|
if (piCmd !== ServerCommand.playerinfo) {
|
|
2772
2821
|
throw new Error(`Expected svc_playerinfo after svc_frame, got ${piCmd}`);
|
|
2773
2822
|
}
|
|
2774
|
-
this.parsePlayerState();
|
|
2823
|
+
const playerState = this.parsePlayerState();
|
|
2775
2824
|
const peCmd = this.stream.readByte();
|
|
2776
2825
|
if (peCmd !== ServerCommand.packetentities && peCmd !== ServerCommand.deltapacketentities) {
|
|
2777
2826
|
throw new Error(`Expected svc_packetentities after svc_playerinfo, got ${peCmd}`);
|
|
2778
2827
|
}
|
|
2779
|
-
|
|
2828
|
+
const isDelta = peCmd === ServerCommand.deltapacketentities;
|
|
2829
|
+
const entities = this.collectPacketEntities();
|
|
2830
|
+
if (this.handler) {
|
|
2831
|
+
this.handler.onFrame({
|
|
2832
|
+
serverFrame,
|
|
2833
|
+
deltaFrame,
|
|
2834
|
+
surpressCount,
|
|
2835
|
+
areaBytes,
|
|
2836
|
+
areaBits,
|
|
2837
|
+
playerState,
|
|
2838
|
+
packetEntities: {
|
|
2839
|
+
delta: isDelta,
|
|
2840
|
+
entities
|
|
2841
|
+
}
|
|
2842
|
+
});
|
|
2843
|
+
}
|
|
2780
2844
|
}
|
|
2781
2845
|
parsePlayerState() {
|
|
2846
|
+
const ps = createEmptyProtocolPlayerState();
|
|
2782
2847
|
const flags = this.stream.readShort();
|
|
2783
|
-
if (flags & 1) this.stream.readByte();
|
|
2848
|
+
if (flags & 1) ps.pm_type = this.stream.readByte();
|
|
2784
2849
|
if (flags & 2) {
|
|
2785
|
-
this.stream.readShort();
|
|
2786
|
-
this.stream.readShort();
|
|
2787
|
-
this.stream.readShort();
|
|
2850
|
+
ps.origin.x = this.stream.readShort() * 0.125;
|
|
2851
|
+
ps.origin.y = this.stream.readShort() * 0.125;
|
|
2852
|
+
ps.origin.z = this.stream.readShort() * 0.125;
|
|
2788
2853
|
}
|
|
2789
2854
|
if (flags & 4) {
|
|
2790
|
-
this.stream.readShort();
|
|
2791
|
-
this.stream.readShort();
|
|
2792
|
-
this.stream.readShort();
|
|
2855
|
+
ps.velocity.x = this.stream.readShort() * 0.125;
|
|
2856
|
+
ps.velocity.y = this.stream.readShort() * 0.125;
|
|
2857
|
+
ps.velocity.z = this.stream.readShort() * 0.125;
|
|
2793
2858
|
}
|
|
2794
|
-
if (flags & 8) this.stream.readByte();
|
|
2795
|
-
if (flags & 16) this.stream.readByte();
|
|
2796
|
-
if (flags & 32) this.stream.readShort();
|
|
2859
|
+
if (flags & 8) ps.pm_time = this.stream.readByte();
|
|
2860
|
+
if (flags & 16) ps.pm_flags = this.stream.readByte();
|
|
2861
|
+
if (flags & 32) ps.gravity = this.stream.readShort();
|
|
2797
2862
|
if (flags & 64) {
|
|
2798
|
-
this.stream.readShort();
|
|
2799
|
-
this.stream.readShort();
|
|
2800
|
-
this.stream.readShort();
|
|
2863
|
+
ps.delta_angles.x = this.stream.readShort() * (180 / 32768);
|
|
2864
|
+
ps.delta_angles.y = this.stream.readShort() * (180 / 32768);
|
|
2865
|
+
ps.delta_angles.z = this.stream.readShort() * (180 / 32768);
|
|
2801
2866
|
}
|
|
2802
2867
|
if (flags & 128) {
|
|
2803
|
-
this.stream.readChar();
|
|
2804
|
-
this.stream.readChar();
|
|
2805
|
-
this.stream.readChar();
|
|
2868
|
+
ps.viewoffset.x = this.stream.readChar() * 0.25;
|
|
2869
|
+
ps.viewoffset.y = this.stream.readChar() * 0.25;
|
|
2870
|
+
ps.viewoffset.z = this.stream.readChar() * 0.25;
|
|
2806
2871
|
}
|
|
2807
2872
|
if (flags & 256) {
|
|
2808
|
-
this.stream.readAngle16();
|
|
2809
|
-
this.stream.readAngle16();
|
|
2810
|
-
this.stream.readAngle16();
|
|
2873
|
+
ps.viewangles.x = this.stream.readAngle16();
|
|
2874
|
+
ps.viewangles.y = this.stream.readAngle16();
|
|
2875
|
+
ps.viewangles.z = this.stream.readAngle16();
|
|
2811
2876
|
}
|
|
2812
2877
|
if (flags & 512) {
|
|
2813
|
-
this.stream.readChar();
|
|
2814
|
-
this.stream.readChar();
|
|
2815
|
-
this.stream.readChar();
|
|
2878
|
+
ps.kick_angles.x = this.stream.readChar() * 0.25;
|
|
2879
|
+
ps.kick_angles.y = this.stream.readChar() * 0.25;
|
|
2880
|
+
ps.kick_angles.z = this.stream.readChar() * 0.25;
|
|
2816
2881
|
}
|
|
2817
|
-
if (flags & 4096) this.stream.readByte();
|
|
2882
|
+
if (flags & 4096) ps.gun_index = this.stream.readByte();
|
|
2818
2883
|
if (flags & 8192) {
|
|
2819
|
-
this.stream.readByte();
|
|
2820
|
-
this.stream.readChar();
|
|
2821
|
-
this.stream.readChar();
|
|
2822
|
-
this.stream.readChar();
|
|
2823
|
-
this.stream.readChar();
|
|
2824
|
-
this.stream.readChar();
|
|
2825
|
-
this.stream.readChar();
|
|
2884
|
+
ps.gun_frame = this.stream.readByte();
|
|
2885
|
+
ps.gun_offset.x = this.stream.readChar() * 0.25;
|
|
2886
|
+
ps.gun_offset.y = this.stream.readChar() * 0.25;
|
|
2887
|
+
ps.gun_offset.z = this.stream.readChar() * 0.25;
|
|
2888
|
+
ps.gun_angles.x = this.stream.readChar() * 0.25;
|
|
2889
|
+
ps.gun_angles.y = this.stream.readChar() * 0.25;
|
|
2890
|
+
ps.gun_angles.z = this.stream.readChar() * 0.25;
|
|
2826
2891
|
}
|
|
2827
2892
|
if (flags & 1024) {
|
|
2828
|
-
this.stream.readByte();
|
|
2829
|
-
this.stream.readByte();
|
|
2830
|
-
this.stream.readByte();
|
|
2831
|
-
this.stream.readByte();
|
|
2893
|
+
ps.blend[0] = this.stream.readByte();
|
|
2894
|
+
ps.blend[1] = this.stream.readByte();
|
|
2895
|
+
ps.blend[2] = this.stream.readByte();
|
|
2896
|
+
ps.blend[3] = this.stream.readByte();
|
|
2832
2897
|
}
|
|
2833
|
-
if (flags & 2048) this.stream.readByte();
|
|
2834
|
-
if (flags & 16384) this.stream.readByte();
|
|
2898
|
+
if (flags & 2048) ps.fov = this.stream.readByte();
|
|
2899
|
+
if (flags & 16384) ps.rdflags = this.stream.readByte();
|
|
2835
2900
|
const statbits = this.stream.readLong();
|
|
2836
2901
|
for (let i = 0; i < 32; i++) {
|
|
2837
2902
|
if (statbits & 1 << i) {
|
|
2838
|
-
this.stream.readShort();
|
|
2903
|
+
ps.stats[i] = this.stream.readShort();
|
|
2839
2904
|
}
|
|
2840
2905
|
}
|
|
2906
|
+
return ps;
|
|
2841
2907
|
}
|
|
2842
2908
|
parsePacketEntities(delta) {
|
|
2909
|
+
const entities = this.collectPacketEntities();
|
|
2910
|
+
if (this.handler) {
|
|
2911
|
+
this.handler.onFrame({
|
|
2912
|
+
serverFrame: 0,
|
|
2913
|
+
deltaFrame: 0,
|
|
2914
|
+
surpressCount: 0,
|
|
2915
|
+
areaBytes: 0,
|
|
2916
|
+
areaBits: new Uint8Array(),
|
|
2917
|
+
playerState: createEmptyProtocolPlayerState(),
|
|
2918
|
+
packetEntities: { delta, entities }
|
|
2919
|
+
});
|
|
2920
|
+
}
|
|
2921
|
+
}
|
|
2922
|
+
collectPacketEntities() {
|
|
2923
|
+
const entities = [];
|
|
2843
2924
|
while (true) {
|
|
2844
2925
|
const bits = this.parseEntityBits();
|
|
2845
2926
|
if (bits.number === 0) {
|
|
2846
2927
|
break;
|
|
2847
2928
|
}
|
|
2848
|
-
|
|
2929
|
+
const entity = createEmptyEntityState();
|
|
2930
|
+
this.parseDelta(createEmptyEntityState(), entity, bits.number, bits.bits);
|
|
2931
|
+
entities.push(entity);
|
|
2849
2932
|
}
|
|
2933
|
+
return entities;
|
|
2850
2934
|
}
|
|
2851
2935
|
parseEntityBits() {
|
|
2852
2936
|
let total = this.stream.readByte();
|
|
@@ -2890,6 +2974,7 @@ var NetworkMessageParser = class {
|
|
|
2890
2974
|
to.event = from.event;
|
|
2891
2975
|
to.solid = from.solid;
|
|
2892
2976
|
to.number = number;
|
|
2977
|
+
to.bits = bits;
|
|
2893
2978
|
if (bits & U_MODEL) to.modelindex = this.stream.readByte();
|
|
2894
2979
|
if (bits & U_MODEL2) to.modelindex2 = this.stream.readByte();
|
|
2895
2980
|
if (bits & U_MODEL3) to.modelindex3 = this.stream.readByte();
|
|
@@ -2935,6 +3020,13 @@ var NetworkMessageParser = class {
|
|
|
2935
3020
|
if (bits & U_SOLID) to.solid = this.stream.readShort();
|
|
2936
3021
|
}
|
|
2937
3022
|
};
|
|
3023
|
+
var PlaybackState = /* @__PURE__ */ ((PlaybackState2) => {
|
|
3024
|
+
PlaybackState2[PlaybackState2["Stopped"] = 0] = "Stopped";
|
|
3025
|
+
PlaybackState2[PlaybackState2["Playing"] = 1] = "Playing";
|
|
3026
|
+
PlaybackState2[PlaybackState2["Paused"] = 2] = "Paused";
|
|
3027
|
+
PlaybackState2[PlaybackState2["Finished"] = 3] = "Finished";
|
|
3028
|
+
return PlaybackState2;
|
|
3029
|
+
})(PlaybackState || {});
|
|
2938
3030
|
var DemoPlaybackController = class {
|
|
2939
3031
|
// ms (10Hz default)
|
|
2940
3032
|
constructor() {
|
|
@@ -2944,6 +3036,9 @@ var DemoPlaybackController = class {
|
|
|
2944
3036
|
this.accumulatedTime = 0;
|
|
2945
3037
|
this.frameDuration = 100;
|
|
2946
3038
|
}
|
|
3039
|
+
setHandler(handler) {
|
|
3040
|
+
this.handler = handler;
|
|
3041
|
+
}
|
|
2947
3042
|
loadDemo(buffer) {
|
|
2948
3043
|
this.reader = new DemoReader(buffer);
|
|
2949
3044
|
this.state = 0;
|
|
@@ -2981,7 +3076,7 @@ var DemoPlaybackController = class {
|
|
|
2981
3076
|
this.state = 3;
|
|
2982
3077
|
return;
|
|
2983
3078
|
}
|
|
2984
|
-
const parser = new NetworkMessageParser(block.data);
|
|
3079
|
+
const parser = new NetworkMessageParser(block.data, this.handler);
|
|
2985
3080
|
parser.parseMessage();
|
|
2986
3081
|
this.accumulatedTime -= this.frameDuration;
|
|
2987
3082
|
}
|
|
@@ -3159,32 +3254,32 @@ var WaterLevel = /* @__PURE__ */ ((WaterLevel3) => {
|
|
|
3159
3254
|
WaterLevel3[WaterLevel3["Under"] = 3] = "Under";
|
|
3160
3255
|
return WaterLevel3;
|
|
3161
3256
|
})(WaterLevel || {});
|
|
3162
|
-
var PmFlag = /* @__PURE__ */ ((
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
return
|
|
3257
|
+
var PmFlag = /* @__PURE__ */ ((PmFlag22) => {
|
|
3258
|
+
PmFlag22[PmFlag22["Ducked"] = 1] = "Ducked";
|
|
3259
|
+
PmFlag22[PmFlag22["JumpHeld"] = 2] = "JumpHeld";
|
|
3260
|
+
PmFlag22[PmFlag22["OnGround"] = 4] = "OnGround";
|
|
3261
|
+
PmFlag22[PmFlag22["TimeWaterJump"] = 8] = "TimeWaterJump";
|
|
3262
|
+
PmFlag22[PmFlag22["TimeLand"] = 16] = "TimeLand";
|
|
3263
|
+
PmFlag22[PmFlag22["TimeTeleport"] = 32] = "TimeTeleport";
|
|
3264
|
+
PmFlag22[PmFlag22["NoPositionalPrediction"] = 64] = "NoPositionalPrediction";
|
|
3265
|
+
PmFlag22[PmFlag22["OnLadder"] = 128] = "OnLadder";
|
|
3266
|
+
PmFlag22[PmFlag22["NoAngularPrediction"] = 256] = "NoAngularPrediction";
|
|
3267
|
+
PmFlag22[PmFlag22["IgnorePlayerCollision"] = 512] = "IgnorePlayerCollision";
|
|
3268
|
+
PmFlag22[PmFlag22["TimeTrick"] = 1024] = "TimeTrick";
|
|
3269
|
+
return PmFlag22;
|
|
3175
3270
|
})(PmFlag || {});
|
|
3176
3271
|
function hasPmFlag(flags, flag) {
|
|
3177
3272
|
return (flags & flag) !== 0;
|
|
3178
3273
|
}
|
|
3179
|
-
var PmType = /* @__PURE__ */ ((
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
return
|
|
3274
|
+
var PmType = /* @__PURE__ */ ((PmType22) => {
|
|
3275
|
+
PmType22[PmType22["Normal"] = 0] = "Normal";
|
|
3276
|
+
PmType22[PmType22["Grapple"] = 1] = "Grapple";
|
|
3277
|
+
PmType22[PmType22["NoClip"] = 2] = "NoClip";
|
|
3278
|
+
PmType22[PmType22["Spectator"] = 3] = "Spectator";
|
|
3279
|
+
PmType22[PmType22["Dead"] = 4] = "Dead";
|
|
3280
|
+
PmType22[PmType22["Gib"] = 5] = "Gib";
|
|
3281
|
+
PmType22[PmType22["Freeze"] = 6] = "Freeze";
|
|
3282
|
+
return PmType22;
|
|
3188
3283
|
})(PmType || {});
|
|
3189
3284
|
var PlayerButton = /* @__PURE__ */ ((PlayerButton2) => {
|
|
3190
3285
|
PlayerButton2[PlayerButton2["None"] = 0] = "None";
|
|
@@ -3814,6 +3909,158 @@ var Draw_Hud = (renderer, ps, client, health, armor, ammo, stats) => {
|
|
|
3814
3909
|
renderer.end2D();
|
|
3815
3910
|
};
|
|
3816
3911
|
|
|
3912
|
+
// src/demo/handler.ts
|
|
3913
|
+
var MAX_CONFIGSTRINGS3 = 2048;
|
|
3914
|
+
var ClientNetworkHandler = class {
|
|
3915
|
+
constructor() {
|
|
3916
|
+
this.configstrings = new Array(MAX_CONFIGSTRINGS3).fill("");
|
|
3917
|
+
this.entities = /* @__PURE__ */ new Map();
|
|
3918
|
+
// Current frame entities
|
|
3919
|
+
this.baselines = /* @__PURE__ */ new Map();
|
|
3920
|
+
this.latestFrame = null;
|
|
3921
|
+
// Stats for HUD
|
|
3922
|
+
this.stats = new Array(32).fill(0);
|
|
3923
|
+
this.inventory = new Array(256).fill(0);
|
|
3924
|
+
}
|
|
3925
|
+
onServerData(protocol, serverCount, attractLoop, gameDir, playerNum, levelName) {
|
|
3926
|
+
console.log(`Demo: Server Data - Protocol: ${protocol}, Level: ${levelName}`);
|
|
3927
|
+
this.configstrings.fill("");
|
|
3928
|
+
this.entities.clear();
|
|
3929
|
+
this.baselines.clear();
|
|
3930
|
+
this.latestFrame = null;
|
|
3931
|
+
}
|
|
3932
|
+
onConfigString(index, str3) {
|
|
3933
|
+
this.configstrings[index] = str3;
|
|
3934
|
+
}
|
|
3935
|
+
onSpawnBaseline(entity) {
|
|
3936
|
+
this.baselines.set(entity.number, structuredClone(entity));
|
|
3937
|
+
}
|
|
3938
|
+
onFrame(frame) {
|
|
3939
|
+
this.latestFrame = frame;
|
|
3940
|
+
this.stats = [...frame.playerState.stats];
|
|
3941
|
+
const packetEntities = frame.packetEntities;
|
|
3942
|
+
const newEntities = /* @__PURE__ */ new Map();
|
|
3943
|
+
if (packetEntities.delta) {
|
|
3944
|
+
for (const [num, ent] of this.entities) {
|
|
3945
|
+
newEntities.set(num, structuredClone(ent));
|
|
3946
|
+
}
|
|
3947
|
+
} else {
|
|
3948
|
+
}
|
|
3949
|
+
for (const partial of packetEntities.entities) {
|
|
3950
|
+
if (partial.bits & U_REMOVE) {
|
|
3951
|
+
newEntities.delete(partial.number);
|
|
3952
|
+
continue;
|
|
3953
|
+
}
|
|
3954
|
+
const number = partial.number;
|
|
3955
|
+
let source;
|
|
3956
|
+
if (packetEntities.delta && this.entities.has(number)) {
|
|
3957
|
+
source = this.entities.get(number);
|
|
3958
|
+
} else if (this.baselines.has(number)) {
|
|
3959
|
+
source = this.baselines.get(number);
|
|
3960
|
+
} else {
|
|
3961
|
+
source = createEmptyEntityState();
|
|
3962
|
+
}
|
|
3963
|
+
const final = structuredClone(source);
|
|
3964
|
+
this.applyDelta(final, partial);
|
|
3965
|
+
newEntities.set(number, final);
|
|
3966
|
+
}
|
|
3967
|
+
this.entities = newEntities;
|
|
3968
|
+
}
|
|
3969
|
+
applyDelta(to, from) {
|
|
3970
|
+
const bits = from.bits;
|
|
3971
|
+
to.number = from.number;
|
|
3972
|
+
if (bits & U_MODEL) to.modelindex = from.modelindex;
|
|
3973
|
+
if (bits & U_MODEL2) to.modelindex2 = from.modelindex2;
|
|
3974
|
+
if (bits & U_MODEL3) to.modelindex3 = from.modelindex3;
|
|
3975
|
+
if (bits & U_MODEL4) to.modelindex4 = from.modelindex4;
|
|
3976
|
+
if (bits & U_FRAME8) to.frame = from.frame;
|
|
3977
|
+
if (bits & U_FRAME16) to.frame = from.frame;
|
|
3978
|
+
if (bits & U_SKIN8 || bits & U_SKIN16) to.skinnum = from.skinnum;
|
|
3979
|
+
if (bits & U_EFFECTS8 || bits & U_EFFECTS16) to.effects = from.effects;
|
|
3980
|
+
if (bits & U_RENDERFX8 || bits & U_RENDERFX16) to.renderfx = from.renderfx;
|
|
3981
|
+
if (bits & U_ORIGIN1) to.origin.x = from.origin.x;
|
|
3982
|
+
if (bits & U_ORIGIN2) to.origin.y = from.origin.y;
|
|
3983
|
+
if (bits & U_ORIGIN3) to.origin.z = from.origin.z;
|
|
3984
|
+
if (bits & U_ANGLE1) to.angles.x = from.angles.x;
|
|
3985
|
+
if (bits & U_ANGLE2) to.angles.y = from.angles.y;
|
|
3986
|
+
if (bits & U_ANGLE3) to.angles.z = from.angles.z;
|
|
3987
|
+
if (bits & U_OLDORIGIN) {
|
|
3988
|
+
to.old_origin.x = from.old_origin.x;
|
|
3989
|
+
to.old_origin.y = from.old_origin.y;
|
|
3990
|
+
to.old_origin.z = from.old_origin.z;
|
|
3991
|
+
}
|
|
3992
|
+
if (bits & U_SOUND) to.sound = from.sound;
|
|
3993
|
+
if (bits & U_EVENT) to.event = from.event;
|
|
3994
|
+
if (bits & U_SOLID) to.solid = from.solid;
|
|
3995
|
+
}
|
|
3996
|
+
onCenterPrint(msg) {
|
|
3997
|
+
console.log(`[Center]: ${msg}`);
|
|
3998
|
+
}
|
|
3999
|
+
onStuffText(msg) {
|
|
4000
|
+
}
|
|
4001
|
+
onPrint(level, msg) {
|
|
4002
|
+
}
|
|
4003
|
+
onSound(flags, soundNum, volume, attenuation, offset, ent, pos) {
|
|
4004
|
+
}
|
|
4005
|
+
onTempEntity(type, pos, pos2, dir, cnt, color, ent, srcEnt, destEnt) {
|
|
4006
|
+
}
|
|
4007
|
+
onLayout(layout) {
|
|
4008
|
+
}
|
|
4009
|
+
onInventory(inventory) {
|
|
4010
|
+
this.inventory = [...inventory];
|
|
4011
|
+
}
|
|
4012
|
+
onMuzzleFlash(ent, weapon) {
|
|
4013
|
+
}
|
|
4014
|
+
onMuzzleFlash2(ent, weapon) {
|
|
4015
|
+
}
|
|
4016
|
+
onDisconnect() {
|
|
4017
|
+
}
|
|
4018
|
+
onReconnect() {
|
|
4019
|
+
}
|
|
4020
|
+
onDownload(size, percent, data) {
|
|
4021
|
+
}
|
|
4022
|
+
getPredictionState() {
|
|
4023
|
+
if (!this.latestFrame) return defaultPredictionState();
|
|
4024
|
+
const ps = this.latestFrame.playerState;
|
|
4025
|
+
const inventory = {
|
|
4026
|
+
ammo: {
|
|
4027
|
+
caps: [],
|
|
4028
|
+
counts: []
|
|
4029
|
+
},
|
|
4030
|
+
ownedWeapons: /* @__PURE__ */ new Set(),
|
|
4031
|
+
armor: null,
|
|
4032
|
+
powerups: /* @__PURE__ */ new Map(),
|
|
4033
|
+
keys: /* @__PURE__ */ new Set()
|
|
4034
|
+
};
|
|
4035
|
+
const origin = { ...ps.origin };
|
|
4036
|
+
const velocity = { ...ps.velocity };
|
|
4037
|
+
const viewangles = { ...ps.viewangles };
|
|
4038
|
+
const deltaAngles = { ...ps.delta_angles };
|
|
4039
|
+
return {
|
|
4040
|
+
origin,
|
|
4041
|
+
velocity,
|
|
4042
|
+
viewangles,
|
|
4043
|
+
pmFlags: ps.pm_flags,
|
|
4044
|
+
pmType: ps.pm_type,
|
|
4045
|
+
waterlevel: WaterLevel.None,
|
|
4046
|
+
gravity: ps.gravity,
|
|
4047
|
+
deltaAngles,
|
|
4048
|
+
client: {
|
|
4049
|
+
inventory,
|
|
4050
|
+
weaponStates: {
|
|
4051
|
+
states: /* @__PURE__ */ new Map()
|
|
4052
|
+
}
|
|
4053
|
+
},
|
|
4054
|
+
health: ps.stats[1],
|
|
4055
|
+
// STAT_HEALTH
|
|
4056
|
+
armor: ps.stats[4],
|
|
4057
|
+
// STAT_ARMOR
|
|
4058
|
+
ammo: ps.stats[2]
|
|
4059
|
+
// STAT_AMMO
|
|
4060
|
+
};
|
|
4061
|
+
}
|
|
4062
|
+
};
|
|
4063
|
+
|
|
3817
4064
|
// src/input/bindings.ts
|
|
3818
4065
|
var DEFAULT_BINDINGS = [
|
|
3819
4066
|
{ code: "KeyW", command: "+forward" },
|
|
@@ -4307,6 +4554,8 @@ function createClient(imports) {
|
|
|
4307
4554
|
const prediction = new ClientPrediction(imports.engine.trace);
|
|
4308
4555
|
const view = new ViewEffects();
|
|
4309
4556
|
const demoPlayback = new DemoPlaybackController();
|
|
4557
|
+
const demoHandler = new ClientNetworkHandler();
|
|
4558
|
+
demoPlayback.setHandler(demoHandler);
|
|
4310
4559
|
let latestFrame;
|
|
4311
4560
|
let lastRendered;
|
|
4312
4561
|
let lastView;
|
|
@@ -4323,14 +4572,19 @@ function createClient(imports) {
|
|
|
4323
4572
|
return prediction.enqueueCommand(command);
|
|
4324
4573
|
},
|
|
4325
4574
|
render(sample) {
|
|
4326
|
-
|
|
4327
|
-
|
|
4328
|
-
|
|
4329
|
-
}
|
|
4330
|
-
if (sample.previous?.state && sample.latest?.state) {
|
|
4331
|
-
lastRendered = interpolatePredictionState(sample.previous.state, sample.latest.state, sample.alpha);
|
|
4575
|
+
const playbackState = demoPlayback.getState();
|
|
4576
|
+
if (playbackState === PlaybackState.Playing) {
|
|
4577
|
+
lastRendered = demoHandler.getPredictionState();
|
|
4332
4578
|
} else {
|
|
4333
|
-
|
|
4579
|
+
if (sample.latest?.state) {
|
|
4580
|
+
prediction.setAuthoritative(sample.latest);
|
|
4581
|
+
latestFrame = sample.latest;
|
|
4582
|
+
}
|
|
4583
|
+
if (sample.previous?.state && sample.latest?.state) {
|
|
4584
|
+
lastRendered = interpolatePredictionState(sample.previous.state, sample.latest.state, sample.alpha);
|
|
4585
|
+
} else {
|
|
4586
|
+
lastRendered = sample.latest?.state ?? sample.previous?.state ?? prediction.getPredictedState();
|
|
4587
|
+
}
|
|
4334
4588
|
}
|
|
4335
4589
|
const frameTimeMs = sample.latest && sample.previous ? Math.max(0, sample.latest.timeMs - sample.previous.timeMs) : 0;
|
|
4336
4590
|
lastView = view.sample(lastRendered, frameTimeMs);
|
|
@@ -4389,7 +4643,8 @@ function createClient(imports) {
|
|
|
4389
4643
|
get camera() {
|
|
4390
4644
|
return camera;
|
|
4391
4645
|
},
|
|
4392
|
-
demoPlayback
|
|
4646
|
+
demoPlayback,
|
|
4647
|
+
demoHandler
|
|
4393
4648
|
};
|
|
4394
4649
|
}
|
|
4395
4650
|
export {
|