quake2ts 0.0.220 → 0.0.221

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quake2ts",
3
- "version": "0.0.220",
3
+ "version": "0.0.221",
4
4
  "description": "Quake II re-release port to TypeScript with WebGL renderer - A complete game engine with physics, networking, and BSP rendering",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@8.15.7",
@@ -174,7 +174,8 @@ function createClient(index, net) {
174
174
  playerState: createEmptyPlayerState(),
175
175
  numEntities: 0,
176
176
  firstEntity: 0,
177
- sentTime: 0
177
+ sentTime: 0,
178
+ entities: []
178
179
  });
179
180
  }
180
181
  return {
@@ -825,23 +826,26 @@ var DedicatedServer = class {
825
826
  this.game.entities.forEachEntity((ent) => {
826
827
  if (ent.index >= import_shared4.MAX_EDICTS) return;
827
828
  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
- };
829
+ this.sv.baselines[ent.index] = this.entityToState(ent);
842
830
  }
843
831
  });
844
832
  }
833
+ entityToState(ent) {
834
+ return {
835
+ number: ent.index,
836
+ origin: { ...ent.origin },
837
+ angles: { ...ent.angles },
838
+ modelIndex: ent.modelindex,
839
+ frame: ent.frame,
840
+ skinNum: ent.skin,
841
+ effects: ent.effects,
842
+ renderfx: ent.renderfx,
843
+ solid: ent.solid,
844
+ sound: ent.sounds,
845
+ // Assuming ent.sounds maps to 'sound' field in EntityState
846
+ event: 0
847
+ };
848
+ }
845
849
  stop() {
846
850
  if (this.frameTimeout) clearTimeout(this.frameTimeout);
847
851
  if (this.wss) this.wss.close();
@@ -1036,7 +1040,11 @@ var DedicatedServer = class {
1036
1040
  const writer = new import_shared4.BinaryWriter(MTU);
1037
1041
  writer.writeByte(import_shared4.ServerCommand.frame);
1038
1042
  writer.writeLong(this.sv.frame);
1039
- writer.writeLong(0);
1043
+ let deltaFrame = 0;
1044
+ if (client.lastFrame && client.lastFrame < this.sv.frame && client.lastFrame >= this.sv.frame - import_shared4.UPDATE_BACKUP) {
1045
+ deltaFrame = client.lastFrame;
1046
+ }
1047
+ writer.writeLong(deltaFrame);
1040
1048
  writer.writeByte(0);
1041
1049
  writer.writeByte(0);
1042
1050
  writer.writeByte(import_shared4.ServerCommand.playerinfo);
@@ -1070,13 +1078,26 @@ var DedicatedServer = class {
1070
1078
  writer.writeByte(import_shared4.ServerCommand.packetentities);
1071
1079
  const entities = snapshot.packetEntities || [];
1072
1080
  const currentEntityIds = [];
1073
- for (const entity of entities) {
1081
+ const frameIdx = this.sv.frame % import_shared4.UPDATE_BACKUP;
1082
+ const currentFrame = client.frames[frameIdx];
1083
+ currentFrame.entities = entities;
1084
+ let oldEntities = [];
1085
+ if (deltaFrame > 0) {
1086
+ const oldFrameIdx = deltaFrame % import_shared4.UPDATE_BACKUP;
1087
+ oldEntities = client.frames[oldFrameIdx].entities;
1088
+ }
1089
+ for (const entityState of currentFrame.entities) {
1074
1090
  if (writer.getOffset() > MTU - 200) {
1075
1091
  console.warn("Packet MTU limit reached, dropping remaining entities");
1076
1092
  break;
1077
1093
  }
1078
- currentEntityIds.push(entity.number);
1079
- writeDeltaEntity({}, entity, writer, false, true);
1094
+ currentEntityIds.push(entityState.number);
1095
+ const oldState = oldEntities.find((e) => e.number === entityState.number);
1096
+ if (oldState) {
1097
+ writeDeltaEntity(oldState, entityState, writer, false, false);
1098
+ } else {
1099
+ writeDeltaEntity({}, entityState, writer, false, true);
1100
+ }
1080
1101
  }
1081
1102
  for (const oldId of client.lastPacketEntities) {
1082
1103
  if (writer.getOffset() > MTU - 10) {
@@ -1,4 +1,4 @@
1
- import { NetDriver, ServerCommand, PlayerState, UserCommand, BinaryStream } from '@quake2ts/shared';
1
+ import { NetDriver, ServerCommand, PlayerState, EntityState, UserCommand, BinaryStream } from '@quake2ts/shared';
2
2
  import WebSocket from 'ws';
3
3
  import { GameEngine, MulticastType, Entity } from '@quake2ts/game';
4
4
 
@@ -28,6 +28,7 @@ declare class DedicatedServer implements GameEngine {
28
28
  constructor(port?: number);
29
29
  start(mapName: string): Promise<void>;
30
30
  private populateBaselines;
31
+ private entityToState;
31
32
  stop(): void;
32
33
  private handleConnection;
33
34
  private onClientMessage;
@@ -65,6 +66,7 @@ interface ClientFrame {
65
66
  numEntities: number;
66
67
  firstEntity: number;
67
68
  sentTime: number;
69
+ entities: EntityState[];
68
70
  }
69
71
  interface Client {
70
72
  index: number;
@@ -1,4 +1,4 @@
1
- import { NetDriver, ServerCommand, PlayerState, UserCommand, BinaryStream } from '@quake2ts/shared';
1
+ import { NetDriver, ServerCommand, PlayerState, EntityState, UserCommand, BinaryStream } from '@quake2ts/shared';
2
2
  import WebSocket from 'ws';
3
3
  import { GameEngine, MulticastType, Entity } from '@quake2ts/game';
4
4
 
@@ -28,6 +28,7 @@ declare class DedicatedServer implements GameEngine {
28
28
  constructor(port?: number);
29
29
  start(mapName: string): Promise<void>;
30
30
  private populateBaselines;
31
+ private entityToState;
31
32
  stop(): void;
32
33
  private handleConnection;
33
34
  private onClientMessage;
@@ -65,6 +66,7 @@ interface ClientFrame {
65
66
  numEntities: number;
66
67
  firstEntity: number;
67
68
  sentTime: number;
69
+ entities: EntityState[];
68
70
  }
69
71
  interface Client {
70
72
  index: number;
@@ -134,7 +134,8 @@ function createClient(index, net) {
134
134
  playerState: createEmptyPlayerState(),
135
135
  numEntities: 0,
136
136
  firstEntity: 0,
137
- sentTime: 0
137
+ sentTime: 0,
138
+ entities: []
138
139
  });
139
140
  }
140
141
  return {
@@ -263,7 +264,7 @@ var ClientMessageParser = class {
263
264
  };
264
265
 
265
266
  // src/dedicated.ts
266
- import { BinaryWriter as BinaryWriter2, ServerCommand as ServerCommand2, BinaryStream as BinaryStream2, traceBox, MAX_CONFIGSTRINGS as MAX_CONFIGSTRINGS2, MAX_EDICTS, CollisionEntityIndex, inPVS, inPHS } from "@quake2ts/shared";
267
+ import { BinaryWriter as BinaryWriter2, ServerCommand as ServerCommand2, BinaryStream as BinaryStream2, traceBox, UPDATE_BACKUP as UPDATE_BACKUP2, MAX_CONFIGSTRINGS as MAX_CONFIGSTRINGS2, MAX_EDICTS, CollisionEntityIndex, inPVS, inPHS } from "@quake2ts/shared";
267
268
  import { parseBsp } from "@quake2ts/engine";
268
269
  import fs from "fs/promises";
269
270
  import { createPlayerInventory, createPlayerWeaponStates } from "@quake2ts/game";
@@ -785,23 +786,26 @@ var DedicatedServer = class {
785
786
  this.game.entities.forEachEntity((ent) => {
786
787
  if (ent.index >= MAX_EDICTS) return;
787
788
  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
- };
789
+ this.sv.baselines[ent.index] = this.entityToState(ent);
802
790
  }
803
791
  });
804
792
  }
793
+ entityToState(ent) {
794
+ return {
795
+ number: ent.index,
796
+ origin: { ...ent.origin },
797
+ angles: { ...ent.angles },
798
+ modelIndex: ent.modelindex,
799
+ frame: ent.frame,
800
+ skinNum: ent.skin,
801
+ effects: ent.effects,
802
+ renderfx: ent.renderfx,
803
+ solid: ent.solid,
804
+ sound: ent.sounds,
805
+ // Assuming ent.sounds maps to 'sound' field in EntityState
806
+ event: 0
807
+ };
808
+ }
805
809
  stop() {
806
810
  if (this.frameTimeout) clearTimeout(this.frameTimeout);
807
811
  if (this.wss) this.wss.close();
@@ -996,7 +1000,11 @@ var DedicatedServer = class {
996
1000
  const writer = new BinaryWriter2(MTU);
997
1001
  writer.writeByte(ServerCommand2.frame);
998
1002
  writer.writeLong(this.sv.frame);
999
- writer.writeLong(0);
1003
+ let deltaFrame = 0;
1004
+ if (client.lastFrame && client.lastFrame < this.sv.frame && client.lastFrame >= this.sv.frame - UPDATE_BACKUP2) {
1005
+ deltaFrame = client.lastFrame;
1006
+ }
1007
+ writer.writeLong(deltaFrame);
1000
1008
  writer.writeByte(0);
1001
1009
  writer.writeByte(0);
1002
1010
  writer.writeByte(ServerCommand2.playerinfo);
@@ -1030,13 +1038,26 @@ var DedicatedServer = class {
1030
1038
  writer.writeByte(ServerCommand2.packetentities);
1031
1039
  const entities = snapshot.packetEntities || [];
1032
1040
  const currentEntityIds = [];
1033
- for (const entity of entities) {
1041
+ const frameIdx = this.sv.frame % UPDATE_BACKUP2;
1042
+ const currentFrame = client.frames[frameIdx];
1043
+ currentFrame.entities = entities;
1044
+ let oldEntities = [];
1045
+ if (deltaFrame > 0) {
1046
+ const oldFrameIdx = deltaFrame % UPDATE_BACKUP2;
1047
+ oldEntities = client.frames[oldFrameIdx].entities;
1048
+ }
1049
+ for (const entityState of currentFrame.entities) {
1034
1050
  if (writer.getOffset() > MTU - 200) {
1035
1051
  console.warn("Packet MTU limit reached, dropping remaining entities");
1036
1052
  break;
1037
1053
  }
1038
- currentEntityIds.push(entity.number);
1039
- writeDeltaEntity({}, entity, writer, false, true);
1054
+ currentEntityIds.push(entityState.number);
1055
+ const oldState = oldEntities.find((e) => e.number === entityState.number);
1056
+ if (oldState) {
1057
+ writeDeltaEntity(oldState, entityState, writer, false, false);
1058
+ } else {
1059
+ writeDeltaEntity({}, entityState, writer, false, true);
1060
+ }
1040
1061
  }
1041
1062
  for (const oldId of client.lastPacketEntities) {
1042
1063
  if (writer.getOffset() > MTU - 10) {