quake2ts 0.0.214 → 0.0.216

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.
@@ -201,7 +201,8 @@ function createClient(index, net) {
201
201
  lastMessage: 0,
202
202
  lastConnect: Date.now(),
203
203
  challenge: 0,
204
- messageQueue: []
204
+ messageQueue: [],
205
+ lastPacketEntities: []
205
206
  };
206
207
  }
207
208
  function createEmptyUserCommand() {
@@ -345,6 +346,24 @@ var NULL_STATE = {
345
346
  sound: 0,
346
347
  event: 0
347
348
  };
349
+ function writeRemoveEntity(number, writer) {
350
+ let bits = U_REMOVE;
351
+ if (number >= 256) {
352
+ bits |= U_NUMBER16;
353
+ }
354
+ if (bits & 65280) {
355
+ bits |= U_MOREBITS1;
356
+ }
357
+ writer.writeByte(bits & 255);
358
+ if (bits & U_MOREBITS1) {
359
+ writer.writeByte(bits >> 8 & 255);
360
+ }
361
+ if (bits & U_NUMBER16) {
362
+ writer.writeShort(number);
363
+ } else {
364
+ writer.writeByte(number);
365
+ }
366
+ }
348
367
  function writeDeltaEntity(from, to, writer, force, newEntity) {
349
368
  let bits = 0;
350
369
  if (newEntity) {
@@ -796,10 +815,33 @@ var DedicatedServer = class {
796
815
  });
797
816
  this.game.init(0);
798
817
  this.game.spawnWorld();
818
+ this.populateBaselines();
799
819
  this.sv.state = 2 /* Game */;
800
820
  this.frameInterval = setInterval(() => this.runFrame(), FRAME_TIME_MS);
801
821
  console.log("Server started.");
802
822
  }
823
+ populateBaselines() {
824
+ if (!this.game) return;
825
+ this.game.entities.forEachEntity((ent) => {
826
+ if (ent.index >= import_shared4.MAX_EDICTS) return;
827
+ if (ent.modelindex > 0 || ent.solid !== import_game.Solid.Not) {
828
+ this.sv.baselines[ent.index] = {
829
+ number: ent.index,
830
+ origin: { ...ent.origin },
831
+ angles: { ...ent.angles },
832
+ modelIndex: ent.modelindex,
833
+ frame: ent.frame,
834
+ skinNum: ent.skin,
835
+ effects: ent.effects,
836
+ renderfx: ent.renderfx,
837
+ solid: ent.solid,
838
+ sound: ent.sounds,
839
+ // Assuming ent.sounds maps to 'sound' field in EntityState
840
+ event: 0
841
+ };
842
+ }
843
+ });
844
+ }
803
845
  stop() {
804
846
  if (this.frameInterval) clearInterval(this.frameInterval);
805
847
  if (this.wss) this.wss.close();
@@ -1019,12 +1061,20 @@ var DedicatedServer = class {
1019
1061
  writePlayerState(writer, ps);
1020
1062
  writer.writeByte(import_shared4.ServerCommand.packetentities);
1021
1063
  const entities = snapshot.packetEntities || [];
1064
+ const currentEntityIds = [];
1022
1065
  for (const entity of entities) {
1066
+ currentEntityIds.push(entity.number);
1023
1067
  writeDeltaEntity({}, entity, writer, false, true);
1024
1068
  }
1069
+ for (const oldId of client.lastPacketEntities) {
1070
+ if (!currentEntityIds.includes(oldId)) {
1071
+ writeRemoveEntity(oldId, writer);
1072
+ }
1073
+ }
1025
1074
  writer.writeShort(0);
1026
1075
  client.net.send(writer.getData());
1027
1076
  client.lastFrame = this.sv.frame;
1077
+ client.lastPacketEntities = currentEntityIds;
1028
1078
  }
1029
1079
  // GameEngine Implementation
1030
1080
  trace(start, end) {
@@ -27,6 +27,7 @@ declare class DedicatedServer implements GameEngine {
27
27
  private entityIndex;
28
28
  constructor(port?: number);
29
29
  start(mapName: string): Promise<void>;
30
+ private populateBaselines;
30
31
  stop(): void;
31
32
  private handleConnection;
32
33
  private onClientMessage;
@@ -90,6 +91,7 @@ interface Client {
90
91
  lastConnect: number;
91
92
  challenge: number;
92
93
  messageQueue: Uint8Array[];
94
+ lastPacketEntities: number[];
93
95
  }
94
96
  declare function createClient(index: number, net: NetDriver): Client;
95
97
 
@@ -27,6 +27,7 @@ declare class DedicatedServer implements GameEngine {
27
27
  private entityIndex;
28
28
  constructor(port?: number);
29
29
  start(mapName: string): Promise<void>;
30
+ private populateBaselines;
30
31
  stop(): void;
31
32
  private handleConnection;
32
33
  private onClientMessage;
@@ -90,6 +91,7 @@ interface Client {
90
91
  lastConnect: number;
91
92
  challenge: number;
92
93
  messageQueue: Uint8Array[];
94
+ lastPacketEntities: number[];
93
95
  }
94
96
  declare function createClient(index: number, net: NetDriver): Client;
95
97
 
@@ -112,7 +112,7 @@ var WebSocketNetDriver = class {
112
112
 
113
113
  // src/dedicated.ts
114
114
  import { WebSocketServer } from "ws";
115
- import { createGame, MulticastType } from "@quake2ts/game";
115
+ import { createGame, MulticastType, Solid } from "@quake2ts/game";
116
116
 
117
117
  // src/client.ts
118
118
  import { UPDATE_BACKUP } from "@quake2ts/shared";
@@ -161,7 +161,8 @@ function createClient(index, net) {
161
161
  lastMessage: 0,
162
162
  lastConnect: Date.now(),
163
163
  challenge: 0,
164
- messageQueue: []
164
+ messageQueue: [],
165
+ lastPacketEntities: []
165
166
  };
166
167
  }
167
168
  function createEmptyUserCommand() {
@@ -305,6 +306,24 @@ var NULL_STATE = {
305
306
  sound: 0,
306
307
  event: 0
307
308
  };
309
+ function writeRemoveEntity(number, writer) {
310
+ let bits = U_REMOVE;
311
+ if (number >= 256) {
312
+ bits |= U_NUMBER16;
313
+ }
314
+ if (bits & 65280) {
315
+ bits |= U_MOREBITS1;
316
+ }
317
+ writer.writeByte(bits & 255);
318
+ if (bits & U_MOREBITS1) {
319
+ writer.writeByte(bits >> 8 & 255);
320
+ }
321
+ if (bits & U_NUMBER16) {
322
+ writer.writeShort(number);
323
+ } else {
324
+ writer.writeByte(number);
325
+ }
326
+ }
308
327
  function writeDeltaEntity(from, to, writer, force, newEntity) {
309
328
  let bits = 0;
310
329
  if (newEntity) {
@@ -756,10 +775,33 @@ var DedicatedServer = class {
756
775
  });
757
776
  this.game.init(0);
758
777
  this.game.spawnWorld();
778
+ this.populateBaselines();
759
779
  this.sv.state = 2 /* Game */;
760
780
  this.frameInterval = setInterval(() => this.runFrame(), FRAME_TIME_MS);
761
781
  console.log("Server started.");
762
782
  }
783
+ populateBaselines() {
784
+ if (!this.game) return;
785
+ this.game.entities.forEachEntity((ent) => {
786
+ if (ent.index >= MAX_EDICTS) return;
787
+ if (ent.modelindex > 0 || ent.solid !== Solid.Not) {
788
+ this.sv.baselines[ent.index] = {
789
+ number: ent.index,
790
+ origin: { ...ent.origin },
791
+ angles: { ...ent.angles },
792
+ modelIndex: ent.modelindex,
793
+ frame: ent.frame,
794
+ skinNum: ent.skin,
795
+ effects: ent.effects,
796
+ renderfx: ent.renderfx,
797
+ solid: ent.solid,
798
+ sound: ent.sounds,
799
+ // Assuming ent.sounds maps to 'sound' field in EntityState
800
+ event: 0
801
+ };
802
+ }
803
+ });
804
+ }
763
805
  stop() {
764
806
  if (this.frameInterval) clearInterval(this.frameInterval);
765
807
  if (this.wss) this.wss.close();
@@ -979,12 +1021,20 @@ var DedicatedServer = class {
979
1021
  writePlayerState(writer, ps);
980
1022
  writer.writeByte(ServerCommand2.packetentities);
981
1023
  const entities = snapshot.packetEntities || [];
1024
+ const currentEntityIds = [];
982
1025
  for (const entity of entities) {
1026
+ currentEntityIds.push(entity.number);
983
1027
  writeDeltaEntity({}, entity, writer, false, true);
984
1028
  }
1029
+ for (const oldId of client.lastPacketEntities) {
1030
+ if (!currentEntityIds.includes(oldId)) {
1031
+ writeRemoveEntity(oldId, writer);
1032
+ }
1033
+ }
985
1034
  writer.writeShort(0);
986
1035
  client.net.send(writer.getData());
987
1036
  client.lastFrame = this.sv.frame;
1037
+ client.lastPacketEntities = currentEntityIds;
988
1038
  }
989
1039
  // GameEngine Implementation
990
1040
  trace(start, end) {