quake2ts 0.0.308 → 0.0.309

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.
@@ -7056,9 +7056,31 @@ function spawnTrail(context) {
7056
7056
  // src/demo/demoReader.ts
7057
7057
  var DemoReader = class {
7058
7058
  constructor(buffer) {
7059
+ this.messageOffsets = [];
7059
7060
  this.buffer = buffer;
7060
7061
  this.view = new DataView(buffer);
7061
7062
  this.offset = 0;
7063
+ this.scan();
7064
+ }
7065
+ /**
7066
+ * Scans the buffer to build an index of message offsets.
7067
+ */
7068
+ scan() {
7069
+ let scanOffset = 0;
7070
+ this.messageOffsets = [];
7071
+ while (scanOffset + 4 <= this.buffer.byteLength) {
7072
+ const length = this.view.getInt32(scanOffset, true);
7073
+ if (length < 0 || length > 2097152) {
7074
+ console.warn(`DemoReader: Invalid block length ${length} at offset ${scanOffset} during scan`);
7075
+ break;
7076
+ }
7077
+ if (scanOffset + 4 + length > this.buffer.byteLength) {
7078
+ console.warn(`DemoReader: Incomplete block at offset ${scanOffset} during scan`);
7079
+ break;
7080
+ }
7081
+ this.messageOffsets.push(scanOffset);
7082
+ scanOffset += 4 + length;
7083
+ }
7062
7084
  }
7063
7085
  /**
7064
7086
  * Checks if there are more blocks to read.
@@ -7076,15 +7098,10 @@ var DemoReader = class {
7076
7098
  return null;
7077
7099
  }
7078
7100
  const length = this.view.getInt32(this.offset, true);
7079
- this.offset += 4;
7080
- if (length < 0 || length > 2097152) {
7081
- console.warn(`DemoReader: Invalid block length ${length} at offset ${this.offset - 4}`);
7082
- return null;
7083
- }
7084
- if (this.offset + length > this.buffer.byteLength) {
7085
- console.warn(`DemoReader: Incomplete block. Expected ${length} bytes, but only ${this.buffer.byteLength - this.offset} remain.`);
7101
+ if (length < 0 || this.offset + 4 + length > this.buffer.byteLength) {
7086
7102
  return null;
7087
7103
  }
7104
+ this.offset += 4;
7088
7105
  const blockData = this.buffer.slice(this.offset, this.offset + length);
7089
7106
  this.offset += length;
7090
7107
  return {
@@ -7098,6 +7115,23 @@ var DemoReader = class {
7098
7115
  reset() {
7099
7116
  this.offset = 0;
7100
7117
  }
7118
+ /**
7119
+ * Seeks to a specific message index.
7120
+ * Returns true if successful, false if index is out of bounds.
7121
+ */
7122
+ seekToMessage(index) {
7123
+ if (index < 0 || index >= this.messageOffsets.length) {
7124
+ return false;
7125
+ }
7126
+ this.offset = this.messageOffsets[index];
7127
+ return true;
7128
+ }
7129
+ /**
7130
+ * Returns the total number of messages in the demo.
7131
+ */
7132
+ getMessageCount() {
7133
+ return this.messageOffsets.length;
7134
+ }
7101
7135
  getOffset() {
7102
7136
  return this.offset;
7103
7137
  }
@@ -12255,6 +12289,7 @@ var DemoPlaybackController = class {
12255
12289
  this.state = 0 /* Stopped */;
12256
12290
  this.playbackSpeed = 1;
12257
12291
  this.currentProtocolVersion = 0;
12292
+ this.currentFrameIndex = 0;
12258
12293
  // Timing
12259
12294
  this.accumulatedTime = 0;
12260
12295
  this.frameDuration = 100;
@@ -12267,6 +12302,7 @@ var DemoPlaybackController = class {
12267
12302
  this.state = 0 /* Stopped */;
12268
12303
  this.accumulatedTime = 0;
12269
12304
  this.currentProtocolVersion = 0;
12305
+ this.currentFrameIndex = 0;
12270
12306
  }
12271
12307
  play() {
12272
12308
  if (this.reader) {
@@ -12285,6 +12321,7 @@ var DemoPlaybackController = class {
12285
12321
  }
12286
12322
  this.accumulatedTime = 0;
12287
12323
  this.currentProtocolVersion = 0;
12324
+ this.currentFrameIndex = 0;
12288
12325
  }
12289
12326
  setFrameDuration(ms) {
12290
12327
  this.frameDuration = ms;
@@ -12315,6 +12352,19 @@ var DemoPlaybackController = class {
12315
12352
  stepBackward() {
12316
12353
  console.warn("stepBackward not implemented");
12317
12354
  }
12355
+ /**
12356
+ * Seeks to a specific frame number.
12357
+ */
12358
+ seek(frameNumber) {
12359
+ if (!this.reader) return;
12360
+ const total = this.getTotalFrames();
12361
+ if (frameNumber < 0) frameNumber = 0;
12362
+ if (frameNumber >= total) frameNumber = total - 1;
12363
+ if (this.reader.seekToMessage(frameNumber)) {
12364
+ this.currentFrameIndex = frameNumber;
12365
+ this.accumulatedTime = 0;
12366
+ }
12367
+ }
12318
12368
  processNextFrame() {
12319
12369
  if (!this.reader || !this.reader.hasMore()) {
12320
12370
  this.state = 3 /* Finished */;
@@ -12325,6 +12375,7 @@ var DemoPlaybackController = class {
12325
12375
  this.state = 3 /* Finished */;
12326
12376
  return false;
12327
12377
  }
12378
+ this.currentFrameIndex++;
12328
12379
  const parser = new NetworkMessageParser(block.data, this.handler);
12329
12380
  parser.setProtocolVersion(this.currentProtocolVersion);
12330
12381
  parser.parseMessage();
@@ -12337,6 +12388,18 @@ var DemoPlaybackController = class {
12337
12388
  getCurrentTime() {
12338
12389
  return this.accumulatedTime;
12339
12390
  }
12391
+ getTotalFrames() {
12392
+ return this.reader ? this.reader.getMessageCount() : 0;
12393
+ }
12394
+ getCurrentFrame() {
12395
+ return this.currentFrameIndex;
12396
+ }
12397
+ /**
12398
+ * Returns estimated duration in seconds based on frame count and frame duration.
12399
+ */
12400
+ getDuration() {
12401
+ return this.getTotalFrames() * this.frameDuration / 1e3;
12402
+ }
12340
12403
  };
12341
12404
 
12342
12405
  // src/index.ts