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
|
@@ -2445,11 +2445,33 @@ var createEmptyEntityState = () => ({
|
|
|
2445
2445
|
angles: { x: 0, y: 0, z: 0 },
|
|
2446
2446
|
sound: 0,
|
|
2447
2447
|
event: 0,
|
|
2448
|
-
solid: 0
|
|
2448
|
+
solid: 0,
|
|
2449
|
+
bits: 0
|
|
2450
|
+
});
|
|
2451
|
+
var createEmptyProtocolPlayerState = () => ({
|
|
2452
|
+
pm_type: 0,
|
|
2453
|
+
origin: { x: 0, y: 0, z: 0 },
|
|
2454
|
+
velocity: { x: 0, y: 0, z: 0 },
|
|
2455
|
+
pm_time: 0,
|
|
2456
|
+
pm_flags: 0,
|
|
2457
|
+
gravity: 0,
|
|
2458
|
+
delta_angles: { x: 0, y: 0, z: 0 },
|
|
2459
|
+
viewoffset: { x: 0, y: 0, z: 0 },
|
|
2460
|
+
viewangles: { x: 0, y: 0, z: 0 },
|
|
2461
|
+
kick_angles: { x: 0, y: 0, z: 0 },
|
|
2462
|
+
gun_index: 0,
|
|
2463
|
+
gun_frame: 0,
|
|
2464
|
+
gun_offset: { x: 0, y: 0, z: 0 },
|
|
2465
|
+
gun_angles: { x: 0, y: 0, z: 0 },
|
|
2466
|
+
blend: [0, 0, 0, 0],
|
|
2467
|
+
fov: 0,
|
|
2468
|
+
rdflags: 0,
|
|
2469
|
+
stats: new Array(32).fill(0)
|
|
2449
2470
|
});
|
|
2450
2471
|
var NetworkMessageParser = class {
|
|
2451
|
-
constructor(stream) {
|
|
2472
|
+
constructor(stream, handler) {
|
|
2452
2473
|
this.stream = stream;
|
|
2474
|
+
this.handler = handler;
|
|
2453
2475
|
}
|
|
2454
2476
|
parseMessage() {
|
|
2455
2477
|
while (this.stream.hasMore()) {
|
|
@@ -2461,15 +2483,18 @@ var NetworkMessageParser = class {
|
|
|
2461
2483
|
case ServerCommand.nop:
|
|
2462
2484
|
break;
|
|
2463
2485
|
case ServerCommand.disconnect:
|
|
2464
|
-
|
|
2486
|
+
if (this.handler) this.handler.onDisconnect();
|
|
2487
|
+
else console.log("Server disconnected");
|
|
2465
2488
|
break;
|
|
2466
2489
|
case ServerCommand.reconnect:
|
|
2467
|
-
|
|
2490
|
+
if (this.handler) this.handler.onReconnect();
|
|
2491
|
+
else console.log("Server reconnect");
|
|
2468
2492
|
break;
|
|
2469
2493
|
case ServerCommand.print:
|
|
2470
2494
|
const printId = this.stream.readByte();
|
|
2471
2495
|
const printMsg = this.stream.readString();
|
|
2472
|
-
|
|
2496
|
+
if (this.handler) this.handler.onPrint(printId, printMsg);
|
|
2497
|
+
else console.log(`[Server Print ${printId}]: ${printMsg}`);
|
|
2473
2498
|
break;
|
|
2474
2499
|
case ServerCommand.serverdata:
|
|
2475
2500
|
this.parseServerData();
|
|
@@ -2482,7 +2507,8 @@ var NetworkMessageParser = class {
|
|
|
2482
2507
|
break;
|
|
2483
2508
|
case ServerCommand.centerprint:
|
|
2484
2509
|
const centerMsg = this.stream.readString();
|
|
2485
|
-
|
|
2510
|
+
if (this.handler) this.handler.onCenterPrint(centerMsg);
|
|
2511
|
+
else console.log(`[Center Print]: ${centerMsg}`);
|
|
2486
2512
|
break;
|
|
2487
2513
|
case ServerCommand.download:
|
|
2488
2514
|
this.parseDownload();
|
|
@@ -2498,10 +2524,12 @@ var NetworkMessageParser = class {
|
|
|
2498
2524
|
break;
|
|
2499
2525
|
case ServerCommand.stufftext:
|
|
2500
2526
|
const text = this.stream.readString();
|
|
2501
|
-
|
|
2527
|
+
if (this.handler) this.handler.onStuffText(text);
|
|
2528
|
+
else console.log(`[StuffText]: ${text}`);
|
|
2502
2529
|
break;
|
|
2503
2530
|
case ServerCommand.layout:
|
|
2504
2531
|
const layout = this.stream.readString();
|
|
2532
|
+
if (this.handler) this.handler.onLayout(layout);
|
|
2505
2533
|
break;
|
|
2506
2534
|
case ServerCommand.inventory:
|
|
2507
2535
|
this.parseInventory();
|
|
@@ -2531,58 +2559,89 @@ var NetworkMessageParser = class {
|
|
|
2531
2559
|
const gameDir = this.stream.readString();
|
|
2532
2560
|
const playerNum = this.stream.readShort();
|
|
2533
2561
|
const levelName = this.stream.readString();
|
|
2534
|
-
|
|
2562
|
+
if (this.handler) {
|
|
2563
|
+
this.handler.onServerData(protocol, serverCount, attractLoop, gameDir, playerNum, levelName);
|
|
2564
|
+
} else {
|
|
2565
|
+
console.log(`Server Data: Protocol ${protocol}, Level ${levelName}, GameDir ${gameDir}`);
|
|
2566
|
+
}
|
|
2535
2567
|
}
|
|
2536
2568
|
parseConfigString() {
|
|
2537
2569
|
const index = this.stream.readShort();
|
|
2538
2570
|
const str3 = this.stream.readString();
|
|
2571
|
+
if (this.handler) {
|
|
2572
|
+
this.handler.onConfigString(index, str3);
|
|
2573
|
+
}
|
|
2539
2574
|
}
|
|
2540
2575
|
parseDownload() {
|
|
2541
2576
|
const size = this.stream.readShort();
|
|
2542
2577
|
const percent = this.stream.readByte();
|
|
2578
|
+
let data;
|
|
2543
2579
|
if (size > 0) {
|
|
2544
|
-
this.stream.readData(size);
|
|
2580
|
+
data = this.stream.readData(size);
|
|
2581
|
+
}
|
|
2582
|
+
if (this.handler) {
|
|
2583
|
+
this.handler.onDownload(size, percent, data);
|
|
2545
2584
|
}
|
|
2546
2585
|
}
|
|
2547
2586
|
parseInventory() {
|
|
2548
2587
|
const MAX_ITEMS22 = 256;
|
|
2588
|
+
const inventory = new Array(MAX_ITEMS22);
|
|
2549
2589
|
for (let i = 0; i < MAX_ITEMS22; i++) {
|
|
2550
|
-
this.stream.readShort();
|
|
2590
|
+
inventory[i] = this.stream.readShort();
|
|
2591
|
+
}
|
|
2592
|
+
if (this.handler) {
|
|
2593
|
+
this.handler.onInventory(inventory);
|
|
2551
2594
|
}
|
|
2552
2595
|
}
|
|
2553
2596
|
parseSound() {
|
|
2554
2597
|
const flags = this.stream.readByte();
|
|
2555
2598
|
const soundNum = this.stream.readByte();
|
|
2599
|
+
let volume;
|
|
2600
|
+
let attenuation;
|
|
2601
|
+
let offset;
|
|
2602
|
+
let ent;
|
|
2603
|
+
let pos;
|
|
2556
2604
|
if (flags & 1) {
|
|
2557
|
-
this.stream.readByte();
|
|
2605
|
+
volume = this.stream.readByte();
|
|
2558
2606
|
}
|
|
2559
2607
|
if (flags & 2) {
|
|
2560
|
-
this.stream.readByte();
|
|
2608
|
+
attenuation = this.stream.readByte();
|
|
2561
2609
|
}
|
|
2562
2610
|
if (flags & 16) {
|
|
2563
|
-
this.stream.readByte();
|
|
2611
|
+
offset = this.stream.readByte();
|
|
2564
2612
|
}
|
|
2565
2613
|
if (flags & 8) {
|
|
2566
|
-
this.stream.readShort();
|
|
2614
|
+
ent = this.stream.readShort();
|
|
2567
2615
|
}
|
|
2568
2616
|
if (flags & 4) {
|
|
2569
|
-
const
|
|
2570
|
-
this.stream.readPos(
|
|
2617
|
+
const p = { x: 0, y: 0, z: 0 };
|
|
2618
|
+
this.stream.readPos(p);
|
|
2619
|
+
pos = p;
|
|
2620
|
+
}
|
|
2621
|
+
if (this.handler) {
|
|
2622
|
+
this.handler.onSound(flags, soundNum, volume, attenuation, offset, ent, pos);
|
|
2571
2623
|
}
|
|
2572
2624
|
}
|
|
2573
2625
|
parseMuzzleFlash() {
|
|
2574
2626
|
const ent = this.stream.readShort();
|
|
2575
2627
|
const weapon = this.stream.readByte();
|
|
2628
|
+
if (this.handler) this.handler.onMuzzleFlash(ent, weapon);
|
|
2576
2629
|
}
|
|
2577
2630
|
parseMuzzleFlash2() {
|
|
2578
2631
|
const ent = this.stream.readShort();
|
|
2579
2632
|
const weapon = this.stream.readByte();
|
|
2633
|
+
if (this.handler) this.handler.onMuzzleFlash2(ent, weapon);
|
|
2580
2634
|
}
|
|
2581
2635
|
parseTempEntity() {
|
|
2582
2636
|
const type = this.stream.readByte();
|
|
2583
2637
|
const pos = { x: 0, y: 0, z: 0 };
|
|
2584
2638
|
const pos2 = { x: 0, y: 0, z: 0 };
|
|
2585
2639
|
const dir = { x: 0, y: 0, z: 0 };
|
|
2640
|
+
let cnt;
|
|
2641
|
+
let color;
|
|
2642
|
+
let ent;
|
|
2643
|
+
let srcEnt;
|
|
2644
|
+
let destEnt;
|
|
2586
2645
|
switch (type) {
|
|
2587
2646
|
case TempEntity.BLOOD:
|
|
2588
2647
|
this.stream.readPos(pos);
|
|
@@ -2591,29 +2650,23 @@ var NetworkMessageParser = class {
|
|
|
2591
2650
|
case TempEntity.GUNSHOT:
|
|
2592
2651
|
case TempEntity.SPARKS:
|
|
2593
2652
|
case TempEntity.BULLET_SPARKS:
|
|
2594
|
-
this.stream.readPos(pos);
|
|
2595
|
-
this.stream.readDir(dir);
|
|
2596
|
-
break;
|
|
2597
2653
|
case TempEntity.SCREEN_SPARKS:
|
|
2598
2654
|
case TempEntity.SHIELD_SPARKS:
|
|
2599
|
-
this.stream.readPos(pos);
|
|
2600
|
-
this.stream.readDir(dir);
|
|
2601
|
-
break;
|
|
2602
2655
|
case TempEntity.SHOTGUN:
|
|
2603
2656
|
this.stream.readPos(pos);
|
|
2604
2657
|
this.stream.readDir(dir);
|
|
2605
2658
|
break;
|
|
2606
2659
|
case TempEntity.SPLASH:
|
|
2607
|
-
this.stream.readByte();
|
|
2660
|
+
cnt = this.stream.readByte();
|
|
2608
2661
|
this.stream.readPos(pos);
|
|
2609
2662
|
this.stream.readDir(dir);
|
|
2610
|
-
this.stream.readByte();
|
|
2663
|
+
color = this.stream.readByte();
|
|
2611
2664
|
break;
|
|
2612
2665
|
case TempEntity.LASER_SPARKS:
|
|
2613
|
-
this.stream.readByte();
|
|
2666
|
+
cnt = this.stream.readByte();
|
|
2614
2667
|
this.stream.readPos(pos);
|
|
2615
2668
|
this.stream.readDir(dir);
|
|
2616
|
-
this.stream.readByte();
|
|
2669
|
+
color = this.stream.readByte();
|
|
2617
2670
|
break;
|
|
2618
2671
|
case TempEntity.BLUEHYPERBLASTER:
|
|
2619
2672
|
this.stream.readPos(pos);
|
|
@@ -2630,21 +2683,13 @@ var NetworkMessageParser = class {
|
|
|
2630
2683
|
case TempEntity.EXPLOSION2:
|
|
2631
2684
|
case TempEntity.GRENADE_EXPLOSION:
|
|
2632
2685
|
case TempEntity.GRENADE_EXPLOSION_WATER:
|
|
2633
|
-
this.stream.readPos(pos);
|
|
2634
|
-
break;
|
|
2635
2686
|
case TempEntity.PLASMA_EXPLOSION:
|
|
2636
|
-
this.stream.readPos(pos);
|
|
2637
|
-
break;
|
|
2638
2687
|
case TempEntity.EXPLOSION1:
|
|
2639
2688
|
case TempEntity.EXPLOSION1_BIG:
|
|
2640
2689
|
case TempEntity.ROCKET_EXPLOSION:
|
|
2641
2690
|
case TempEntity.ROCKET_EXPLOSION_WATER:
|
|
2642
2691
|
case TempEntity.EXPLOSION1_NP:
|
|
2643
|
-
this.stream.readPos(pos);
|
|
2644
|
-
break;
|
|
2645
2692
|
case TempEntity.BFG_EXPLOSION:
|
|
2646
|
-
this.stream.readPos(pos);
|
|
2647
|
-
break;
|
|
2648
2693
|
case TempEntity.BFG_BIGEXPLOSION:
|
|
2649
2694
|
this.stream.readPos(pos);
|
|
2650
2695
|
break;
|
|
@@ -2658,7 +2703,7 @@ var NetworkMessageParser = class {
|
|
|
2658
2703
|
break;
|
|
2659
2704
|
case TempEntity.PARASITE_ATTACK:
|
|
2660
2705
|
case TempEntity.MEDIC_CABLE_ATTACK:
|
|
2661
|
-
this.stream.readShort();
|
|
2706
|
+
ent = this.stream.readShort();
|
|
2662
2707
|
this.stream.readPos(pos);
|
|
2663
2708
|
this.stream.readPos(pos2);
|
|
2664
2709
|
break;
|
|
@@ -2666,26 +2711,26 @@ var NetworkMessageParser = class {
|
|
|
2666
2711
|
this.stream.readPos(pos);
|
|
2667
2712
|
break;
|
|
2668
2713
|
case TempEntity.GRAPPLE_CABLE:
|
|
2669
|
-
this.stream.readShort();
|
|
2714
|
+
ent = this.stream.readShort();
|
|
2670
2715
|
this.stream.readPos(pos);
|
|
2671
2716
|
this.stream.readPos(pos2);
|
|
2672
2717
|
this.stream.readPos(dir);
|
|
2673
2718
|
break;
|
|
2674
2719
|
case TempEntity.WELDING_SPARKS:
|
|
2675
|
-
this.stream.readByte();
|
|
2720
|
+
cnt = this.stream.readByte();
|
|
2676
2721
|
this.stream.readPos(pos);
|
|
2677
2722
|
this.stream.readDir(dir);
|
|
2678
|
-
this.stream.readByte();
|
|
2723
|
+
color = this.stream.readByte();
|
|
2679
2724
|
break;
|
|
2680
2725
|
case TempEntity.GREENBLOOD:
|
|
2681
2726
|
this.stream.readPos(pos);
|
|
2682
2727
|
this.stream.readDir(dir);
|
|
2683
2728
|
break;
|
|
2684
2729
|
case TempEntity.TUNNEL_SPARKS:
|
|
2685
|
-
this.stream.readByte();
|
|
2730
|
+
cnt = this.stream.readByte();
|
|
2686
2731
|
this.stream.readPos(pos);
|
|
2687
2732
|
this.stream.readDir(dir);
|
|
2688
|
-
this.stream.readByte();
|
|
2733
|
+
color = this.stream.readByte();
|
|
2689
2734
|
break;
|
|
2690
2735
|
case TempEntity.BLASTER2:
|
|
2691
2736
|
case TempEntity.FLECHETTE:
|
|
@@ -2693,8 +2738,8 @@ var NetworkMessageParser = class {
|
|
|
2693
2738
|
this.stream.readDir(dir);
|
|
2694
2739
|
break;
|
|
2695
2740
|
case TempEntity.LIGHTNING:
|
|
2696
|
-
this.stream.readShort();
|
|
2697
|
-
this.stream.readShort();
|
|
2741
|
+
srcEnt = this.stream.readShort();
|
|
2742
|
+
destEnt = this.stream.readShort();
|
|
2698
2743
|
this.stream.readPos(pos);
|
|
2699
2744
|
this.stream.readPos(pos2);
|
|
2700
2745
|
break;
|
|
@@ -2707,29 +2752,26 @@ var NetworkMessageParser = class {
|
|
|
2707
2752
|
break;
|
|
2708
2753
|
case TempEntity.FLASHLIGHT:
|
|
2709
2754
|
this.stream.readPos(pos);
|
|
2710
|
-
this.stream.readShort();
|
|
2755
|
+
ent = this.stream.readShort();
|
|
2711
2756
|
break;
|
|
2712
2757
|
case TempEntity.FORCEWALL:
|
|
2713
2758
|
this.stream.readPos(pos);
|
|
2714
2759
|
this.stream.readPos(pos2);
|
|
2715
|
-
this.stream.readByte();
|
|
2760
|
+
color = this.stream.readByte();
|
|
2716
2761
|
break;
|
|
2717
2762
|
case TempEntity.HEATBEAM:
|
|
2718
|
-
this.stream.readShort();
|
|
2763
|
+
ent = this.stream.readShort();
|
|
2719
2764
|
this.stream.readPos(pos);
|
|
2720
2765
|
this.stream.readPos(pos2);
|
|
2721
2766
|
this.stream.readPos(dir);
|
|
2722
2767
|
break;
|
|
2723
2768
|
case TempEntity.MONSTER_HEATBEAM:
|
|
2724
|
-
this.stream.readShort();
|
|
2769
|
+
ent = this.stream.readShort();
|
|
2725
2770
|
this.stream.readPos(pos);
|
|
2726
2771
|
this.stream.readPos(pos2);
|
|
2727
2772
|
this.stream.readPos(dir);
|
|
2728
2773
|
break;
|
|
2729
2774
|
case TempEntity.HEATBEAM_SPARKS:
|
|
2730
|
-
this.stream.readPos(pos);
|
|
2731
|
-
this.stream.readDir(dir);
|
|
2732
|
-
break;
|
|
2733
2775
|
case TempEntity.HEATBEAM_STEAM:
|
|
2734
2776
|
this.stream.readPos(pos);
|
|
2735
2777
|
this.stream.readDir(dir);
|
|
@@ -2737,17 +2779,17 @@ var NetworkMessageParser = class {
|
|
|
2737
2779
|
case TempEntity.STEAM:
|
|
2738
2780
|
const steamId = this.stream.readShort();
|
|
2739
2781
|
if (steamId !== -1) {
|
|
2740
|
-
this.stream.readByte();
|
|
2782
|
+
cnt = this.stream.readByte();
|
|
2741
2783
|
this.stream.readPos(pos);
|
|
2742
2784
|
this.stream.readDir(dir);
|
|
2743
|
-
this.stream.readByte();
|
|
2785
|
+
color = this.stream.readByte();
|
|
2744
2786
|
this.stream.readShort();
|
|
2745
2787
|
this.stream.readLong();
|
|
2746
2788
|
} else {
|
|
2747
|
-
this.stream.readByte();
|
|
2789
|
+
cnt = this.stream.readByte();
|
|
2748
2790
|
this.stream.readPos(pos);
|
|
2749
2791
|
this.stream.readDir(dir);
|
|
2750
|
-
this.stream.readByte();
|
|
2792
|
+
color = this.stream.readByte();
|
|
2751
2793
|
this.stream.readShort();
|
|
2752
2794
|
}
|
|
2753
2795
|
break;
|
|
@@ -2774,7 +2816,7 @@ var NetworkMessageParser = class {
|
|
|
2774
2816
|
this.stream.readPos(pos);
|
|
2775
2817
|
break;
|
|
2776
2818
|
case TempEntity.WIDOWBEAMOUT:
|
|
2777
|
-
|
|
2819
|
+
this.stream.readShort();
|
|
2778
2820
|
this.stream.readPos(pos);
|
|
2779
2821
|
break;
|
|
2780
2822
|
case TempEntity.NUKEBLAST:
|
|
@@ -2787,97 +2829,139 @@ var NetworkMessageParser = class {
|
|
|
2787
2829
|
console.warn(`CL_ParseTEnt: bad type ${type}`);
|
|
2788
2830
|
break;
|
|
2789
2831
|
}
|
|
2832
|
+
if (this.handler) {
|
|
2833
|
+
this.handler.onTempEntity(type, pos, pos2, dir, cnt, color, ent, srcEnt, destEnt);
|
|
2834
|
+
}
|
|
2790
2835
|
}
|
|
2791
2836
|
parseSpawnBaseline() {
|
|
2792
2837
|
const bits = this.parseEntityBits();
|
|
2793
|
-
|
|
2838
|
+
const entity = createEmptyEntityState();
|
|
2839
|
+
this.parseDelta(createEmptyEntityState(), entity, bits.number, bits.bits);
|
|
2840
|
+
if (this.handler) {
|
|
2841
|
+
this.handler.onSpawnBaseline(entity);
|
|
2842
|
+
}
|
|
2794
2843
|
}
|
|
2795
2844
|
parseFrame() {
|
|
2796
2845
|
const serverFrame = this.stream.readLong();
|
|
2797
2846
|
const deltaFrame = this.stream.readLong();
|
|
2798
2847
|
const surpressCount = this.stream.readByte();
|
|
2799
2848
|
const areaBytes = this.stream.readByte();
|
|
2800
|
-
this.stream.readData(areaBytes);
|
|
2849
|
+
const areaBits = this.stream.readData(areaBytes);
|
|
2801
2850
|
const piCmd = this.stream.readByte();
|
|
2802
2851
|
if (piCmd !== ServerCommand.playerinfo) {
|
|
2803
2852
|
throw new Error(`Expected svc_playerinfo after svc_frame, got ${piCmd}`);
|
|
2804
2853
|
}
|
|
2805
|
-
this.parsePlayerState();
|
|
2854
|
+
const playerState = this.parsePlayerState();
|
|
2806
2855
|
const peCmd = this.stream.readByte();
|
|
2807
2856
|
if (peCmd !== ServerCommand.packetentities && peCmd !== ServerCommand.deltapacketentities) {
|
|
2808
2857
|
throw new Error(`Expected svc_packetentities after svc_playerinfo, got ${peCmd}`);
|
|
2809
2858
|
}
|
|
2810
|
-
|
|
2859
|
+
const isDelta = peCmd === ServerCommand.deltapacketentities;
|
|
2860
|
+
const entities = this.collectPacketEntities();
|
|
2861
|
+
if (this.handler) {
|
|
2862
|
+
this.handler.onFrame({
|
|
2863
|
+
serverFrame,
|
|
2864
|
+
deltaFrame,
|
|
2865
|
+
surpressCount,
|
|
2866
|
+
areaBytes,
|
|
2867
|
+
areaBits,
|
|
2868
|
+
playerState,
|
|
2869
|
+
packetEntities: {
|
|
2870
|
+
delta: isDelta,
|
|
2871
|
+
entities
|
|
2872
|
+
}
|
|
2873
|
+
});
|
|
2874
|
+
}
|
|
2811
2875
|
}
|
|
2812
2876
|
parsePlayerState() {
|
|
2877
|
+
const ps = createEmptyProtocolPlayerState();
|
|
2813
2878
|
const flags = this.stream.readShort();
|
|
2814
|
-
if (flags & 1) this.stream.readByte();
|
|
2879
|
+
if (flags & 1) ps.pm_type = this.stream.readByte();
|
|
2815
2880
|
if (flags & 2) {
|
|
2816
|
-
this.stream.readShort();
|
|
2817
|
-
this.stream.readShort();
|
|
2818
|
-
this.stream.readShort();
|
|
2881
|
+
ps.origin.x = this.stream.readShort() * 0.125;
|
|
2882
|
+
ps.origin.y = this.stream.readShort() * 0.125;
|
|
2883
|
+
ps.origin.z = this.stream.readShort() * 0.125;
|
|
2819
2884
|
}
|
|
2820
2885
|
if (flags & 4) {
|
|
2821
|
-
this.stream.readShort();
|
|
2822
|
-
this.stream.readShort();
|
|
2823
|
-
this.stream.readShort();
|
|
2886
|
+
ps.velocity.x = this.stream.readShort() * 0.125;
|
|
2887
|
+
ps.velocity.y = this.stream.readShort() * 0.125;
|
|
2888
|
+
ps.velocity.z = this.stream.readShort() * 0.125;
|
|
2824
2889
|
}
|
|
2825
|
-
if (flags & 8) this.stream.readByte();
|
|
2826
|
-
if (flags & 16) this.stream.readByte();
|
|
2827
|
-
if (flags & 32) this.stream.readShort();
|
|
2890
|
+
if (flags & 8) ps.pm_time = this.stream.readByte();
|
|
2891
|
+
if (flags & 16) ps.pm_flags = this.stream.readByte();
|
|
2892
|
+
if (flags & 32) ps.gravity = this.stream.readShort();
|
|
2828
2893
|
if (flags & 64) {
|
|
2829
|
-
this.stream.readShort();
|
|
2830
|
-
this.stream.readShort();
|
|
2831
|
-
this.stream.readShort();
|
|
2894
|
+
ps.delta_angles.x = this.stream.readShort() * (180 / 32768);
|
|
2895
|
+
ps.delta_angles.y = this.stream.readShort() * (180 / 32768);
|
|
2896
|
+
ps.delta_angles.z = this.stream.readShort() * (180 / 32768);
|
|
2832
2897
|
}
|
|
2833
2898
|
if (flags & 128) {
|
|
2834
|
-
this.stream.readChar();
|
|
2835
|
-
this.stream.readChar();
|
|
2836
|
-
this.stream.readChar();
|
|
2899
|
+
ps.viewoffset.x = this.stream.readChar() * 0.25;
|
|
2900
|
+
ps.viewoffset.y = this.stream.readChar() * 0.25;
|
|
2901
|
+
ps.viewoffset.z = this.stream.readChar() * 0.25;
|
|
2837
2902
|
}
|
|
2838
2903
|
if (flags & 256) {
|
|
2839
|
-
this.stream.readAngle16();
|
|
2840
|
-
this.stream.readAngle16();
|
|
2841
|
-
this.stream.readAngle16();
|
|
2904
|
+
ps.viewangles.x = this.stream.readAngle16();
|
|
2905
|
+
ps.viewangles.y = this.stream.readAngle16();
|
|
2906
|
+
ps.viewangles.z = this.stream.readAngle16();
|
|
2842
2907
|
}
|
|
2843
2908
|
if (flags & 512) {
|
|
2844
|
-
this.stream.readChar();
|
|
2845
|
-
this.stream.readChar();
|
|
2846
|
-
this.stream.readChar();
|
|
2909
|
+
ps.kick_angles.x = this.stream.readChar() * 0.25;
|
|
2910
|
+
ps.kick_angles.y = this.stream.readChar() * 0.25;
|
|
2911
|
+
ps.kick_angles.z = this.stream.readChar() * 0.25;
|
|
2847
2912
|
}
|
|
2848
|
-
if (flags & 4096) this.stream.readByte();
|
|
2913
|
+
if (flags & 4096) ps.gun_index = this.stream.readByte();
|
|
2849
2914
|
if (flags & 8192) {
|
|
2850
|
-
this.stream.readByte();
|
|
2851
|
-
this.stream.readChar();
|
|
2852
|
-
this.stream.readChar();
|
|
2853
|
-
this.stream.readChar();
|
|
2854
|
-
this.stream.readChar();
|
|
2855
|
-
this.stream.readChar();
|
|
2856
|
-
this.stream.readChar();
|
|
2915
|
+
ps.gun_frame = this.stream.readByte();
|
|
2916
|
+
ps.gun_offset.x = this.stream.readChar() * 0.25;
|
|
2917
|
+
ps.gun_offset.y = this.stream.readChar() * 0.25;
|
|
2918
|
+
ps.gun_offset.z = this.stream.readChar() * 0.25;
|
|
2919
|
+
ps.gun_angles.x = this.stream.readChar() * 0.25;
|
|
2920
|
+
ps.gun_angles.y = this.stream.readChar() * 0.25;
|
|
2921
|
+
ps.gun_angles.z = this.stream.readChar() * 0.25;
|
|
2857
2922
|
}
|
|
2858
2923
|
if (flags & 1024) {
|
|
2859
|
-
this.stream.readByte();
|
|
2860
|
-
this.stream.readByte();
|
|
2861
|
-
this.stream.readByte();
|
|
2862
|
-
this.stream.readByte();
|
|
2924
|
+
ps.blend[0] = this.stream.readByte();
|
|
2925
|
+
ps.blend[1] = this.stream.readByte();
|
|
2926
|
+
ps.blend[2] = this.stream.readByte();
|
|
2927
|
+
ps.blend[3] = this.stream.readByte();
|
|
2863
2928
|
}
|
|
2864
|
-
if (flags & 2048) this.stream.readByte();
|
|
2865
|
-
if (flags & 16384) this.stream.readByte();
|
|
2929
|
+
if (flags & 2048) ps.fov = this.stream.readByte();
|
|
2930
|
+
if (flags & 16384) ps.rdflags = this.stream.readByte();
|
|
2866
2931
|
const statbits = this.stream.readLong();
|
|
2867
2932
|
for (let i = 0; i < 32; i++) {
|
|
2868
2933
|
if (statbits & 1 << i) {
|
|
2869
|
-
this.stream.readShort();
|
|
2934
|
+
ps.stats[i] = this.stream.readShort();
|
|
2870
2935
|
}
|
|
2871
2936
|
}
|
|
2937
|
+
return ps;
|
|
2872
2938
|
}
|
|
2873
2939
|
parsePacketEntities(delta) {
|
|
2940
|
+
const entities = this.collectPacketEntities();
|
|
2941
|
+
if (this.handler) {
|
|
2942
|
+
this.handler.onFrame({
|
|
2943
|
+
serverFrame: 0,
|
|
2944
|
+
deltaFrame: 0,
|
|
2945
|
+
surpressCount: 0,
|
|
2946
|
+
areaBytes: 0,
|
|
2947
|
+
areaBits: new Uint8Array(),
|
|
2948
|
+
playerState: createEmptyProtocolPlayerState(),
|
|
2949
|
+
packetEntities: { delta, entities }
|
|
2950
|
+
});
|
|
2951
|
+
}
|
|
2952
|
+
}
|
|
2953
|
+
collectPacketEntities() {
|
|
2954
|
+
const entities = [];
|
|
2874
2955
|
while (true) {
|
|
2875
2956
|
const bits = this.parseEntityBits();
|
|
2876
2957
|
if (bits.number === 0) {
|
|
2877
2958
|
break;
|
|
2878
2959
|
}
|
|
2879
|
-
|
|
2960
|
+
const entity = createEmptyEntityState();
|
|
2961
|
+
this.parseDelta(createEmptyEntityState(), entity, bits.number, bits.bits);
|
|
2962
|
+
entities.push(entity);
|
|
2880
2963
|
}
|
|
2964
|
+
return entities;
|
|
2881
2965
|
}
|
|
2882
2966
|
parseEntityBits() {
|
|
2883
2967
|
let total = this.stream.readByte();
|
|
@@ -2921,6 +3005,7 @@ var NetworkMessageParser = class {
|
|
|
2921
3005
|
to.event = from.event;
|
|
2922
3006
|
to.solid = from.solid;
|
|
2923
3007
|
to.number = number;
|
|
3008
|
+
to.bits = bits;
|
|
2924
3009
|
if (bits & U_MODEL) to.modelindex = this.stream.readByte();
|
|
2925
3010
|
if (bits & U_MODEL2) to.modelindex2 = this.stream.readByte();
|
|
2926
3011
|
if (bits & U_MODEL3) to.modelindex3 = this.stream.readByte();
|
|
@@ -2966,6 +3051,13 @@ var NetworkMessageParser = class {
|
|
|
2966
3051
|
if (bits & U_SOLID) to.solid = this.stream.readShort();
|
|
2967
3052
|
}
|
|
2968
3053
|
};
|
|
3054
|
+
var PlaybackState = /* @__PURE__ */ ((PlaybackState2) => {
|
|
3055
|
+
PlaybackState2[PlaybackState2["Stopped"] = 0] = "Stopped";
|
|
3056
|
+
PlaybackState2[PlaybackState2["Playing"] = 1] = "Playing";
|
|
3057
|
+
PlaybackState2[PlaybackState2["Paused"] = 2] = "Paused";
|
|
3058
|
+
PlaybackState2[PlaybackState2["Finished"] = 3] = "Finished";
|
|
3059
|
+
return PlaybackState2;
|
|
3060
|
+
})(PlaybackState || {});
|
|
2969
3061
|
var DemoPlaybackController = class {
|
|
2970
3062
|
// ms (10Hz default)
|
|
2971
3063
|
constructor() {
|
|
@@ -2975,6 +3067,9 @@ var DemoPlaybackController = class {
|
|
|
2975
3067
|
this.accumulatedTime = 0;
|
|
2976
3068
|
this.frameDuration = 100;
|
|
2977
3069
|
}
|
|
3070
|
+
setHandler(handler) {
|
|
3071
|
+
this.handler = handler;
|
|
3072
|
+
}
|
|
2978
3073
|
loadDemo(buffer) {
|
|
2979
3074
|
this.reader = new DemoReader(buffer);
|
|
2980
3075
|
this.state = 0;
|
|
@@ -3012,7 +3107,7 @@ var DemoPlaybackController = class {
|
|
|
3012
3107
|
this.state = 3;
|
|
3013
3108
|
return;
|
|
3014
3109
|
}
|
|
3015
|
-
const parser = new NetworkMessageParser(block.data);
|
|
3110
|
+
const parser = new NetworkMessageParser(block.data, this.handler);
|
|
3016
3111
|
parser.parseMessage();
|
|
3017
3112
|
this.accumulatedTime -= this.frameDuration;
|
|
3018
3113
|
}
|
|
@@ -3190,32 +3285,32 @@ var WaterLevel = /* @__PURE__ */ ((WaterLevel3) => {
|
|
|
3190
3285
|
WaterLevel3[WaterLevel3["Under"] = 3] = "Under";
|
|
3191
3286
|
return WaterLevel3;
|
|
3192
3287
|
})(WaterLevel || {});
|
|
3193
|
-
var PmFlag = /* @__PURE__ */ ((
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
return
|
|
3288
|
+
var PmFlag = /* @__PURE__ */ ((PmFlag22) => {
|
|
3289
|
+
PmFlag22[PmFlag22["Ducked"] = 1] = "Ducked";
|
|
3290
|
+
PmFlag22[PmFlag22["JumpHeld"] = 2] = "JumpHeld";
|
|
3291
|
+
PmFlag22[PmFlag22["OnGround"] = 4] = "OnGround";
|
|
3292
|
+
PmFlag22[PmFlag22["TimeWaterJump"] = 8] = "TimeWaterJump";
|
|
3293
|
+
PmFlag22[PmFlag22["TimeLand"] = 16] = "TimeLand";
|
|
3294
|
+
PmFlag22[PmFlag22["TimeTeleport"] = 32] = "TimeTeleport";
|
|
3295
|
+
PmFlag22[PmFlag22["NoPositionalPrediction"] = 64] = "NoPositionalPrediction";
|
|
3296
|
+
PmFlag22[PmFlag22["OnLadder"] = 128] = "OnLadder";
|
|
3297
|
+
PmFlag22[PmFlag22["NoAngularPrediction"] = 256] = "NoAngularPrediction";
|
|
3298
|
+
PmFlag22[PmFlag22["IgnorePlayerCollision"] = 512] = "IgnorePlayerCollision";
|
|
3299
|
+
PmFlag22[PmFlag22["TimeTrick"] = 1024] = "TimeTrick";
|
|
3300
|
+
return PmFlag22;
|
|
3206
3301
|
})(PmFlag || {});
|
|
3207
3302
|
function hasPmFlag(flags, flag) {
|
|
3208
3303
|
return (flags & flag) !== 0;
|
|
3209
3304
|
}
|
|
3210
|
-
var PmType = /* @__PURE__ */ ((
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
return
|
|
3305
|
+
var PmType = /* @__PURE__ */ ((PmType22) => {
|
|
3306
|
+
PmType22[PmType22["Normal"] = 0] = "Normal";
|
|
3307
|
+
PmType22[PmType22["Grapple"] = 1] = "Grapple";
|
|
3308
|
+
PmType22[PmType22["NoClip"] = 2] = "NoClip";
|
|
3309
|
+
PmType22[PmType22["Spectator"] = 3] = "Spectator";
|
|
3310
|
+
PmType22[PmType22["Dead"] = 4] = "Dead";
|
|
3311
|
+
PmType22[PmType22["Gib"] = 5] = "Gib";
|
|
3312
|
+
PmType22[PmType22["Freeze"] = 6] = "Freeze";
|
|
3313
|
+
return PmType22;
|
|
3219
3314
|
})(PmType || {});
|
|
3220
3315
|
var PlayerButton = /* @__PURE__ */ ((PlayerButton2) => {
|
|
3221
3316
|
PlayerButton2[PlayerButton2["None"] = 0] = "None";
|
|
@@ -3845,6 +3940,158 @@ var Draw_Hud = (renderer, ps, client, health, armor, ammo, stats) => {
|
|
|
3845
3940
|
renderer.end2D();
|
|
3846
3941
|
};
|
|
3847
3942
|
|
|
3943
|
+
// src/demo/handler.ts
|
|
3944
|
+
var MAX_CONFIGSTRINGS3 = 2048;
|
|
3945
|
+
var ClientNetworkHandler = class {
|
|
3946
|
+
constructor() {
|
|
3947
|
+
this.configstrings = new Array(MAX_CONFIGSTRINGS3).fill("");
|
|
3948
|
+
this.entities = /* @__PURE__ */ new Map();
|
|
3949
|
+
// Current frame entities
|
|
3950
|
+
this.baselines = /* @__PURE__ */ new Map();
|
|
3951
|
+
this.latestFrame = null;
|
|
3952
|
+
// Stats for HUD
|
|
3953
|
+
this.stats = new Array(32).fill(0);
|
|
3954
|
+
this.inventory = new Array(256).fill(0);
|
|
3955
|
+
}
|
|
3956
|
+
onServerData(protocol, serverCount, attractLoop, gameDir, playerNum, levelName) {
|
|
3957
|
+
console.log(`Demo: Server Data - Protocol: ${protocol}, Level: ${levelName}`);
|
|
3958
|
+
this.configstrings.fill("");
|
|
3959
|
+
this.entities.clear();
|
|
3960
|
+
this.baselines.clear();
|
|
3961
|
+
this.latestFrame = null;
|
|
3962
|
+
}
|
|
3963
|
+
onConfigString(index, str3) {
|
|
3964
|
+
this.configstrings[index] = str3;
|
|
3965
|
+
}
|
|
3966
|
+
onSpawnBaseline(entity) {
|
|
3967
|
+
this.baselines.set(entity.number, structuredClone(entity));
|
|
3968
|
+
}
|
|
3969
|
+
onFrame(frame) {
|
|
3970
|
+
this.latestFrame = frame;
|
|
3971
|
+
this.stats = [...frame.playerState.stats];
|
|
3972
|
+
const packetEntities = frame.packetEntities;
|
|
3973
|
+
const newEntities = /* @__PURE__ */ new Map();
|
|
3974
|
+
if (packetEntities.delta) {
|
|
3975
|
+
for (const [num, ent] of this.entities) {
|
|
3976
|
+
newEntities.set(num, structuredClone(ent));
|
|
3977
|
+
}
|
|
3978
|
+
} else {
|
|
3979
|
+
}
|
|
3980
|
+
for (const partial of packetEntities.entities) {
|
|
3981
|
+
if (partial.bits & U_REMOVE) {
|
|
3982
|
+
newEntities.delete(partial.number);
|
|
3983
|
+
continue;
|
|
3984
|
+
}
|
|
3985
|
+
const number = partial.number;
|
|
3986
|
+
let source;
|
|
3987
|
+
if (packetEntities.delta && this.entities.has(number)) {
|
|
3988
|
+
source = this.entities.get(number);
|
|
3989
|
+
} else if (this.baselines.has(number)) {
|
|
3990
|
+
source = this.baselines.get(number);
|
|
3991
|
+
} else {
|
|
3992
|
+
source = createEmptyEntityState();
|
|
3993
|
+
}
|
|
3994
|
+
const final = structuredClone(source);
|
|
3995
|
+
this.applyDelta(final, partial);
|
|
3996
|
+
newEntities.set(number, final);
|
|
3997
|
+
}
|
|
3998
|
+
this.entities = newEntities;
|
|
3999
|
+
}
|
|
4000
|
+
applyDelta(to, from) {
|
|
4001
|
+
const bits = from.bits;
|
|
4002
|
+
to.number = from.number;
|
|
4003
|
+
if (bits & U_MODEL) to.modelindex = from.modelindex;
|
|
4004
|
+
if (bits & U_MODEL2) to.modelindex2 = from.modelindex2;
|
|
4005
|
+
if (bits & U_MODEL3) to.modelindex3 = from.modelindex3;
|
|
4006
|
+
if (bits & U_MODEL4) to.modelindex4 = from.modelindex4;
|
|
4007
|
+
if (bits & U_FRAME8) to.frame = from.frame;
|
|
4008
|
+
if (bits & U_FRAME16) to.frame = from.frame;
|
|
4009
|
+
if (bits & U_SKIN8 || bits & U_SKIN16) to.skinnum = from.skinnum;
|
|
4010
|
+
if (bits & U_EFFECTS8 || bits & U_EFFECTS16) to.effects = from.effects;
|
|
4011
|
+
if (bits & U_RENDERFX8 || bits & U_RENDERFX16) to.renderfx = from.renderfx;
|
|
4012
|
+
if (bits & U_ORIGIN1) to.origin.x = from.origin.x;
|
|
4013
|
+
if (bits & U_ORIGIN2) to.origin.y = from.origin.y;
|
|
4014
|
+
if (bits & U_ORIGIN3) to.origin.z = from.origin.z;
|
|
4015
|
+
if (bits & U_ANGLE1) to.angles.x = from.angles.x;
|
|
4016
|
+
if (bits & U_ANGLE2) to.angles.y = from.angles.y;
|
|
4017
|
+
if (bits & U_ANGLE3) to.angles.z = from.angles.z;
|
|
4018
|
+
if (bits & U_OLDORIGIN) {
|
|
4019
|
+
to.old_origin.x = from.old_origin.x;
|
|
4020
|
+
to.old_origin.y = from.old_origin.y;
|
|
4021
|
+
to.old_origin.z = from.old_origin.z;
|
|
4022
|
+
}
|
|
4023
|
+
if (bits & U_SOUND) to.sound = from.sound;
|
|
4024
|
+
if (bits & U_EVENT) to.event = from.event;
|
|
4025
|
+
if (bits & U_SOLID) to.solid = from.solid;
|
|
4026
|
+
}
|
|
4027
|
+
onCenterPrint(msg) {
|
|
4028
|
+
console.log(`[Center]: ${msg}`);
|
|
4029
|
+
}
|
|
4030
|
+
onStuffText(msg) {
|
|
4031
|
+
}
|
|
4032
|
+
onPrint(level, msg) {
|
|
4033
|
+
}
|
|
4034
|
+
onSound(flags, soundNum, volume, attenuation, offset, ent, pos) {
|
|
4035
|
+
}
|
|
4036
|
+
onTempEntity(type, pos, pos2, dir, cnt, color, ent, srcEnt, destEnt) {
|
|
4037
|
+
}
|
|
4038
|
+
onLayout(layout) {
|
|
4039
|
+
}
|
|
4040
|
+
onInventory(inventory) {
|
|
4041
|
+
this.inventory = [...inventory];
|
|
4042
|
+
}
|
|
4043
|
+
onMuzzleFlash(ent, weapon) {
|
|
4044
|
+
}
|
|
4045
|
+
onMuzzleFlash2(ent, weapon) {
|
|
4046
|
+
}
|
|
4047
|
+
onDisconnect() {
|
|
4048
|
+
}
|
|
4049
|
+
onReconnect() {
|
|
4050
|
+
}
|
|
4051
|
+
onDownload(size, percent, data) {
|
|
4052
|
+
}
|
|
4053
|
+
getPredictionState() {
|
|
4054
|
+
if (!this.latestFrame) return defaultPredictionState();
|
|
4055
|
+
const ps = this.latestFrame.playerState;
|
|
4056
|
+
const inventory = {
|
|
4057
|
+
ammo: {
|
|
4058
|
+
caps: [],
|
|
4059
|
+
counts: []
|
|
4060
|
+
},
|
|
4061
|
+
ownedWeapons: /* @__PURE__ */ new Set(),
|
|
4062
|
+
armor: null,
|
|
4063
|
+
powerups: /* @__PURE__ */ new Map(),
|
|
4064
|
+
keys: /* @__PURE__ */ new Set()
|
|
4065
|
+
};
|
|
4066
|
+
const origin = { ...ps.origin };
|
|
4067
|
+
const velocity = { ...ps.velocity };
|
|
4068
|
+
const viewangles = { ...ps.viewangles };
|
|
4069
|
+
const deltaAngles = { ...ps.delta_angles };
|
|
4070
|
+
return {
|
|
4071
|
+
origin,
|
|
4072
|
+
velocity,
|
|
4073
|
+
viewangles,
|
|
4074
|
+
pmFlags: ps.pm_flags,
|
|
4075
|
+
pmType: ps.pm_type,
|
|
4076
|
+
waterlevel: WaterLevel.None,
|
|
4077
|
+
gravity: ps.gravity,
|
|
4078
|
+
deltaAngles,
|
|
4079
|
+
client: {
|
|
4080
|
+
inventory,
|
|
4081
|
+
weaponStates: {
|
|
4082
|
+
states: /* @__PURE__ */ new Map()
|
|
4083
|
+
}
|
|
4084
|
+
},
|
|
4085
|
+
health: ps.stats[1],
|
|
4086
|
+
// STAT_HEALTH
|
|
4087
|
+
armor: ps.stats[4],
|
|
4088
|
+
// STAT_ARMOR
|
|
4089
|
+
ammo: ps.stats[2]
|
|
4090
|
+
// STAT_AMMO
|
|
4091
|
+
};
|
|
4092
|
+
}
|
|
4093
|
+
};
|
|
4094
|
+
|
|
3848
4095
|
// src/input/bindings.ts
|
|
3849
4096
|
var DEFAULT_BINDINGS = [
|
|
3850
4097
|
{ code: "KeyW", command: "+forward" },
|
|
@@ -4338,6 +4585,8 @@ function createClient(imports) {
|
|
|
4338
4585
|
const prediction = new ClientPrediction(imports.engine.trace);
|
|
4339
4586
|
const view = new ViewEffects();
|
|
4340
4587
|
const demoPlayback = new DemoPlaybackController();
|
|
4588
|
+
const demoHandler = new ClientNetworkHandler();
|
|
4589
|
+
demoPlayback.setHandler(demoHandler);
|
|
4341
4590
|
let latestFrame;
|
|
4342
4591
|
let lastRendered;
|
|
4343
4592
|
let lastView;
|
|
@@ -4354,14 +4603,19 @@ function createClient(imports) {
|
|
|
4354
4603
|
return prediction.enqueueCommand(command);
|
|
4355
4604
|
},
|
|
4356
4605
|
render(sample) {
|
|
4357
|
-
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
}
|
|
4361
|
-
if (sample.previous?.state && sample.latest?.state) {
|
|
4362
|
-
lastRendered = interpolatePredictionState(sample.previous.state, sample.latest.state, sample.alpha);
|
|
4606
|
+
const playbackState = demoPlayback.getState();
|
|
4607
|
+
if (playbackState === PlaybackState.Playing) {
|
|
4608
|
+
lastRendered = demoHandler.getPredictionState();
|
|
4363
4609
|
} else {
|
|
4364
|
-
|
|
4610
|
+
if (sample.latest?.state) {
|
|
4611
|
+
prediction.setAuthoritative(sample.latest);
|
|
4612
|
+
latestFrame = sample.latest;
|
|
4613
|
+
}
|
|
4614
|
+
if (sample.previous?.state && sample.latest?.state) {
|
|
4615
|
+
lastRendered = interpolatePredictionState(sample.previous.state, sample.latest.state, sample.alpha);
|
|
4616
|
+
} else {
|
|
4617
|
+
lastRendered = sample.latest?.state ?? sample.previous?.state ?? prediction.getPredictedState();
|
|
4618
|
+
}
|
|
4365
4619
|
}
|
|
4366
4620
|
const frameTimeMs = sample.latest && sample.previous ? Math.max(0, sample.latest.timeMs - sample.previous.timeMs) : 0;
|
|
4367
4621
|
lastView = view.sample(lastRendered, frameTimeMs);
|
|
@@ -4420,7 +4674,8 @@ function createClient(imports) {
|
|
|
4420
4674
|
get camera() {
|
|
4421
4675
|
return camera;
|
|
4422
4676
|
},
|
|
4423
|
-
demoPlayback
|
|
4677
|
+
demoPlayback,
|
|
4678
|
+
demoHandler
|
|
4424
4679
|
};
|
|
4425
4680
|
}
|
|
4426
4681
|
// Annotate the CommonJS export names for ESM import in node:
|