@kar-mi/spirit-vale-tools-combat 3.3.5 → 3.3.6

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.
@@ -37,7 +37,7 @@ export interface FishNetCombatTrackerOptions {
37
37
  actorIdentityResolver?: (actorId: number) => FishNetCombatActorIdentity | undefined;
38
38
  /** Resolves healing mechanics for actors whose local character build is visible. */
39
39
  healingTraitsResolver?: (actorId: number) => FishNetHealingTraits | undefined;
40
- /** The local player's network object id, when known. */
40
+ /** @deprecated Summon packets now require a verified object id; retained as an unused compatibility option. */
41
41
  localActorIdResolver?: () => number | undefined;
42
42
  /** Names monsters seen spawning, emitting identity lifecycle events keyed by network object id. */
43
43
  monsterCatalog?: FishNetMonsterCatalog;
@@ -143,7 +143,8 @@ export interface FishNetCombatDeathEvent {
143
143
  }
144
144
  export interface FishNetCombatStatusEvent {
145
145
  kind: "status";
146
- rpc: "ApplyEffect_T" | "RemoveEffect_T" | "ApplyEffectDisplays_O" | "ApplySkillDisplay_O" | "RemoveSkillDisplay_O";
146
+ /** `LoadCharacter_T` is a login-restore fallback: an effect already active when the client connects, from the character save's own snapshot rather than a live apply. */
147
+ rpc: "ApplyEffect_T" | "RemoveEffect_T" | "ApplyEffectDisplays_O" | "ApplySkillDisplay_O" | "RemoveSkillDisplay_O" | "LoadCharacter_T";
147
148
  tick: number;
148
149
  payloadBytes: number;
149
150
  fields: Record<string, FishNetDecodedValue>;
@@ -152,22 +153,21 @@ export interface FishNetCombatStatusEvent {
152
153
  /** Absent on `ApplyEffectDisplays_O`, which carries no level; consumers keep the last known one. */
153
154
  level?: number;
154
155
  action: "applied" | "removed";
155
- /** Server-reported time left, from `ApplyEffectDisplays_O` only. */
156
+ /** Server-reported time left, from `ApplyEffectDisplays_O`/`LoadCharacter_T` only. */
156
157
  remainingSeconds?: number;
157
158
  stacks?: number;
158
159
  actorIdentity?: FishNetCombatActorIdentity;
159
160
  }
160
161
  export interface FishNetCombatSummonEvent {
161
162
  kind: "summon";
162
- rpc: "CalibrateSummons_T";
163
+ /** `SummonSkillSync` is a login-restore fallback: one active summon reported via SyncType rather than the batch RPC. */
164
+ rpc: "CalibrateSummons_T" | "SummonSkillSync";
163
165
  tick: number;
164
166
  payloadBytes: number;
165
167
  fields: Record<string, FishNetDecodedValue>;
166
168
  actorId: number;
167
169
  skillId: string;
168
170
  stacks: number;
169
- /** True when the packet arrived unnamed and was recovered heuristically. See `recoverSummons`. */
170
- recovered?: boolean;
171
171
  actorIdentity?: FishNetCombatActorIdentity;
172
172
  }
173
173
  /** A `PlayerController.FullHeal_C`, which restores an actor outright. */
@@ -213,7 +213,6 @@ export declare class FishNetCombatTracker {
213
213
  private readonly skillLabels;
214
214
  private readonly actorIdentityResolver?;
215
215
  private readonly healingTraitsResolver?;
216
- private readonly localActorIdResolver?;
217
216
  private readonly monsterCatalog?;
218
217
  private readonly bossCatalog?;
219
218
  private readonly monsters?;
@@ -223,6 +222,10 @@ export declare class FishNetCombatTracker {
223
222
  private readonly bossIdentities;
224
223
  private readonly activeRegenSources;
225
224
  private readonly summonStacks;
225
+ /** Pending `SummonSkillSync`/`SummonerSync` state per summoned object's own network id, until both are known. */
226
+ private readonly summonSkillSyncState;
227
+ /** Actors for whom a `CalibrateSummons_T` snapshot has been seen; the `SummonSkillSync` fallback stops touching their stacks from then on, since the batch RPC now fully owns them. */
228
+ private readonly authoritativeSummonActors;
226
229
  private readonly recentDamageSignatures;
227
230
  private recentDamageTick;
228
231
  private nextActivation;
@@ -261,21 +264,37 @@ export declare class FishNetCombatTracker {
261
264
  */
262
265
  private consumeSkillDisplay;
263
266
  /**
264
- * Last-resort recovery for a `CalibrateSummons_T` the capture layer could not name. Two paths lose
265
- * it. An rpcLink whose registration never arrived carries no object id, no hash and no name at all
266
- * - links are only ever learned from an `objectSpawn`, so if the player object's spawn is missed on
267
- * a connection, every link on that object is dead for the connection's whole life. A plain
268
- * targetRpc on an object with no bound components fares little better: wire hash 0 is shared by
269
- * several behaviours, and with nothing bound there is nothing to eliminate against. Either way the
270
- * summon tile stays blank until a map change respawns the player object and re-registers its links.
267
+ * Login restores whichever effects were active at save time through `PlayerSave.LoadCharacter_T`'s
268
+ * own `State.Effects` snapshot - no other packet reports them. Unlike `ApplyEffectDisplays_O`
269
+ * (which repeats and self-heals), this fires once per login, so a status it lists that never gets
270
+ * an explicit apply afterward would otherwise never appear at all.
271
+ */
272
+ private consumeLoginEffects;
273
+ /**
274
+ * Login restores an existing summon through `SummonSkillSync` (a `SummoningComponent` SyncType),
275
+ * not `CalibrateSummons_T` - that RPC only fires on a later change, so without this the overlay
276
+ * shows nothing for a summon that was already active when the client connected.
271
277
  *
272
- * This is a heuristic and deliberately narrow. `decodeSummonCalibration` must consume the payload
273
- * exactly, at least one entry must decode, every skill id must be one the catalog knows, and the
274
- * result is attributed to the local player because `CalibrateSummons_T` is a targetRpc no other
275
- * client receives. An empty calibration - the "all summons gone" snapshot - is *not* recovered: it
276
- * encodes as a single 0x01 byte, which carries no signature worth trusting.
278
+ * `SummonSkillSync` lives on the summoned object's own `SummoningComponent`, not the owner's - the
279
+ * packet's `objectId` names the summon (e.g. one skeleton), not the actor to credit. `SummonerSync`,
280
+ * a sibling SyncType on that same component, is the owner reference. FishNet sends every dirty
281
+ * SyncType on login together, so both usually arrive in the same packet, but not always in the same
282
+ * order, and only a change re-sends a SyncType afterward - so `summonSkillSyncState` accumulates
283
+ * whichever field arrives first, per summon object, until both are known. Each summon object
284
+ * contributes its own +1 once (never more), so two objects reporting the same skill both count -
285
+ * this is per-object state, not a "have I seen this skill" flag.
286
+ */
287
+ private consumeSummonSkillSync;
288
+ /**
289
+ * Clears a summon object's `SummonSkillSync` bookkeeping on despawn (or a respawn reusing the same
290
+ * network object id), so a later reused id starts fresh rather than inheriting a stale owner/skill.
291
+ * Also corrects the stack count for an object this tracker itself counted in, unless a
292
+ * `CalibrateSummons_T` snapshot has since taken over that actor's stacks (which will correct the
293
+ * count on its own).
277
294
  */
278
- private recoverSummons;
295
+ private consumeSummonObjectLifecycle;
296
+ /** Adjusts one actor's stack count for one skill by `delta` and reports the resulting total. */
297
+ private applySummonDelta;
279
298
  private consumeSummonCalibration;
280
299
  /** Diffs one summon snapshot against the actor's last known stacks and emits only the changes. */
281
300
  private applySummonSnapshot;
@@ -1 +1 @@
1
- {"version":3,"file":"combat-tracker.d.ts","sourceRoot":"","sources":["../src/combat-tracker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"combat-tracker.d.ts","sourceRoot":"","sources":["../src/combat-tracker.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  FishNetMonsterDirectory,
7
7
  loadBundledFishNetSemanticMap
8
8
  } from "@kar-mi/spirit-vale-tools-capture";
9
- import { readSignedPackedWhole as readSignedPackedWhole3 } from "@kar-mi/spirit-vale-tools-capture/wire-reader";
9
+ import { readSignedPackedWhole as readSignedPackedWhole2 } from "@kar-mi/spirit-vale-tools-capture/wire-reader";
10
10
  import { loadBundledSkillCatalog } from "@kar-mi/spirit-vale-tools-skills";
11
11
 
12
12
  // src/effect-display.ts
@@ -69,51 +69,6 @@ function readBoolean(buffer, offset, description) {
69
69
  return { value: value === 1, nextOffset: offset + 1 };
70
70
  }
71
71
 
72
- // src/summon-calibration.ts
73
- import { FishNetProtocolError as FishNetProtocolError2 } from "@kar-mi/spirit-vale-tools-capture";
74
- import { checkedEnd as checkedEnd2, readSignedPackedWhole as readSignedPackedWhole2, requireBytes as requireBytes2 } from "@kar-mi/spirit-vale-tools-capture/wire-reader";
75
- function decodeSummonCalibration(payload) {
76
- const count = readSignedPackedWhole2(payload, 0);
77
- if (count.value === -1) {
78
- requireComplete(payload, count.nextOffset);
79
- return [];
80
- }
81
- if (count.value < 0)
82
- throw new FishNetProtocolError2("invalid summon calibration array length");
83
- const entries = [];
84
- let offset = count.nextOffset;
85
- for (let index = 0;index < count.value; index += 1) {
86
- const skill = readString2(payload, offset);
87
- offset = skill.nextOffset;
88
- const primary = readBoolean2(payload, offset, "summon primary flag");
89
- offset = primary.nextOffset;
90
- const mounted = readBoolean2(payload, offset, "summon mounted flag");
91
- offset = mounted.nextOffset;
92
- entries.push({ skillId: skill.value, isPrimary: primary.value, isMountedSummon: mounted.value });
93
- }
94
- requireComplete(payload, offset);
95
- return entries;
96
- }
97
- function readString2(buffer, offset) {
98
- const length = readSignedPackedWhole2(buffer, offset);
99
- if (length.value < 0)
100
- throw new FishNetProtocolError2("summon skill id must not be null");
101
- const nextOffset = checkedEnd2(buffer, length.nextOffset, length.value);
102
- return { value: buffer.toString("utf8", length.nextOffset, nextOffset), nextOffset };
103
- }
104
- function readBoolean2(buffer, offset, description) {
105
- requireBytes2(buffer, offset, 1, description);
106
- const value = buffer[offset];
107
- if (value !== 0 && value !== 1)
108
- throw new FishNetProtocolError2(`invalid ${description}`);
109
- return { value: value === 1, nextOffset: offset + 1 };
110
- }
111
- function requireComplete(buffer, offset) {
112
- if (offset !== buffer.length) {
113
- throw new FishNetProtocolError2(`summon calibration left ${buffer.length - offset} undecoded bytes`);
114
- }
115
- }
116
-
117
72
  // src/combat-tracker.ts
118
73
  var HIT_RESULTS = {
119
74
  0: "normal",
@@ -125,7 +80,6 @@ var HIT_RESULTS = {
125
80
  var SKILL_RPC_NAMES = new Set(["CastBegin_C", "AutoCast_C", "ToggleBegin_C", "CastComplete_C", "CastInterrupt_C", "CastCancel_C"]);
126
81
  var CURRENT_STATUS_COMPONENT_INDICES = new Set([5, 6]);
127
82
  var CURRENT_HEALTH_COMPONENT_INDICES = new Set([2, 3]);
128
- var MAX_RECOVERED_SUMMON_BYTES = 256;
129
83
  var HEALING_SKILL_IDS = new Set(["Heal", "HighHeal", "FieldHealing"]);
130
84
  var REGEN_SKILL_IDS = new Set(["HealAll", "Sanctuary", "GuardianBond", "SanctuaryField"]);
131
85
  var REGEN_STATUS_ID = "Regeneration";
@@ -136,7 +90,6 @@ class FishNetCombatTracker {
136
90
  skillLabels;
137
91
  actorIdentityResolver;
138
92
  healingTraitsResolver;
139
- localActorIdResolver;
140
93
  monsterCatalog;
141
94
  bossCatalog;
142
95
  monsters;
@@ -145,6 +98,8 @@ class FishNetCombatTracker {
145
98
  bossIdentities = new Map;
146
99
  activeRegenSources = new Map;
147
100
  summonStacks = new Map;
101
+ summonSkillSyncState = new Map;
102
+ authoritativeSummonActors = new Set;
148
103
  recentDamageSignatures = new Set;
149
104
  recentDamageTick;
150
105
  nextActivation = 1;
@@ -168,7 +123,6 @@ class FishNetCombatTracker {
168
123
  this.skillLabels.set(value, label);
169
124
  this.actorIdentityResolver = options.actorIdentityResolver;
170
125
  this.healingTraitsResolver = options.healingTraitsResolver;
171
- this.localActorIdResolver = options.localActorIdResolver;
172
126
  this.monsterCatalog = options.monsterCatalog;
173
127
  if (options.monsterCatalog)
174
128
  this.monsters = new FishNetMonsterDirectory(options.monsterCatalog);
@@ -177,6 +131,7 @@ class FishNetCombatTracker {
177
131
  consume(packet) {
178
132
  const monsterIdentity = this.monsterIdentity(packet.tick, this.monsters?.consume(packet));
179
133
  const bossLifecycle = this.bossIdentityLifecycle(packet);
134
+ const summonLifecycle = this.consumeSummonObjectLifecycle(packet);
180
135
  if (packet.packetName === "authenticated" || packet.packetName === "disconnect") {
181
136
  this.reset();
182
137
  return uniqueMonsterIdentityEvents([
@@ -191,11 +146,15 @@ class FishNetCombatTracker {
191
146
  }
192
147
  const events = [
193
148
  ...monsterIdentity ? [monsterIdentity] : [],
194
- ...bossLifecycle ? [bossLifecycle] : []
149
+ ...bossLifecycle ? [bossLifecycle] : [],
150
+ ...summonLifecycle ? [summonLifecycle] : []
195
151
  ];
152
+ if (packet.packetName === "syncType" && matchesBehaviour(packet, "SummoningComponent")) {
153
+ events.push(...this.consumeSummonSkillSync(packet));
154
+ return events;
155
+ }
196
156
  if (packet.objectId === undefined || !packet.rpcName) {
197
157
  events.push(...this.recoverAmbiguousCombat(packet));
198
- events.push(...this.recoverSummons(packet));
199
158
  return events;
200
159
  }
201
160
  if (SKILL_RPC_NAMES.has(packet.rpcName) && matchesBehaviour(packet, "SkillsComponent")) {
@@ -255,10 +214,14 @@ class FishNetCombatTracker {
255
214
  }
256
215
  return events;
257
216
  }
258
- if (packet.rpcName === "CalibrateSummons_T" && matchesBehaviour(packet, "SummoningComponent")) {
217
+ if (packet.rpcName === "CalibrateSummons_T" && packet.rpcResolution === "verified" && packet.networkBehaviourType === "SummoningComponent") {
259
218
  events.push(...this.consumeSummonCalibration(packet));
260
219
  return events;
261
220
  }
221
+ if (packet.rpcName === "LoadCharacter_T" && packet.rpcResolution === "verified" && packet.networkBehaviourType === "PlayerSave") {
222
+ events.push(...this.consumeLoginEffects(packet));
223
+ return events;
224
+ }
262
225
  return events;
263
226
  }
264
227
  reset() {
@@ -266,6 +229,8 @@ class FishNetCombatTracker {
266
229
  this.bossIdentities.clear();
267
230
  this.activeRegenSources.clear();
268
231
  this.summonStacks.clear();
232
+ this.summonSkillSyncState.clear();
233
+ this.authoritativeSummonActors.clear();
269
234
  this.recentDamageSignatures.clear();
270
235
  this.recentDamageTick = undefined;
271
236
  this.monsters?.reset();
@@ -359,7 +324,7 @@ class FishNetCombatTracker {
359
324
  return [];
360
325
  let amount;
361
326
  try {
362
- amount = readSignedPackedWhole3(packet.payload, 0);
327
+ amount = readSignedPackedWhole2(packet.payload, 0);
363
328
  } catch {
364
329
  return [];
365
330
  }
@@ -397,35 +362,92 @@ class FishNetCombatTracker {
397
362
  actorIdentity: this.actorIdentityResolver?.(actorId)
398
363
  };
399
364
  }
400
- recoverSummons(packet) {
401
- if (packet.rpcName || packet.rpcResolution === "verified" || packet.rpcResolution === "recovered")
365
+ consumeLoginEffects(packet) {
366
+ const entries = decodedLoginEffects(packet);
367
+ if (!entries)
402
368
  return [];
403
- if (packet.payload.length < 2 || packet.payload.length > MAX_RECOVERED_SUMMON_BYTES)
404
- return [];
405
- if (this.skillLabels.size === 0)
369
+ const actorId = packet.objectId;
370
+ return entries.map((entry) => ({
371
+ kind: "status",
372
+ rpc: "LoadCharacter_T",
373
+ tick: packet.tick,
374
+ payloadBytes: packet.payload.length,
375
+ fields: {
376
+ Id: entry.statusId,
377
+ Level: entry.level,
378
+ Duration: entry.remainingSeconds ?? null,
379
+ Stacks: entry.stacks
380
+ },
381
+ actorId,
382
+ statusId: entry.statusId,
383
+ level: entry.level,
384
+ action: "applied",
385
+ ...entry.remainingSeconds === undefined ? {} : { remainingSeconds: entry.remainingSeconds },
386
+ stacks: entry.stacks,
387
+ actorIdentity: this.actorIdentityResolver?.(actorId)
388
+ }));
389
+ }
390
+ consumeSummonSkillSync(packet) {
391
+ const summonObjectId = packet.objectId;
392
+ const summonerSync = packet.syncEntries?.find((candidate) => candidate.name === "SummonerSync")?.fields.find((entryField) => entryField.name === "SummonerSync")?.value;
393
+ const skillId = packet.syncEntries?.find((candidate) => candidate.name === "SummonSkillSync")?.fields.find((entryField) => entryField.name === "SkillId")?.value;
394
+ if (typeof summonerSync !== "number" && typeof skillId !== "string")
406
395
  return [];
407
- const actorId = packet.objectId ?? this.localActorIdResolver?.();
408
- if (actorId === undefined)
396
+ const state = this.summonSkillSyncState.get(summonObjectId) ?? { counted: false };
397
+ if (typeof summonerSync === "number")
398
+ state.ownerActorId = summonerSync;
399
+ if (typeof skillId === "string")
400
+ state.skillId = skillId;
401
+ this.summonSkillSyncState.set(summonObjectId, state);
402
+ if (state.counted || state.ownerActorId === undefined || state.skillId === undefined)
409
403
  return [];
410
- let entries;
411
- try {
412
- entries = decodeSummonCalibration(packet.payload);
413
- } catch {
404
+ if (this.authoritativeSummonActors.has(state.ownerActorId))
414
405
  return [];
406
+ state.counted = true;
407
+ return [this.applySummonDelta(state.ownerActorId, state.skillId, 1, packet, "SummonSkillSync")];
408
+ }
409
+ consumeSummonObjectLifecycle(packet) {
410
+ if (packet.packetName !== "objectDespawn" && packet.packetName !== "objectSpawn" || packet.objectId === undefined) {
411
+ return;
415
412
  }
416
- if (entries.length === 0)
417
- return [];
418
- if (!entries.every(({ skillId }) => this.skillLabels.has(skillId)))
419
- return [];
420
- return this.applySummonSnapshot(actorId, packet, entries).map((event) => ({ ...event, recovered: true }));
413
+ const state = this.summonSkillSyncState.get(packet.objectId);
414
+ if (!state)
415
+ return;
416
+ this.summonSkillSyncState.delete(packet.objectId);
417
+ if (!state.counted || state.ownerActorId === undefined || state.skillId === undefined)
418
+ return;
419
+ if (this.authoritativeSummonActors.has(state.ownerActorId))
420
+ return;
421
+ return this.applySummonDelta(state.ownerActorId, state.skillId, -1, packet, "SummonSkillSync");
422
+ }
423
+ applySummonDelta(actorId, skillId, delta, packet, rpc) {
424
+ const stacks = new Map(this.summonStacks.get(actorId));
425
+ const nextCount = Math.max(0, (stacks.get(skillId) ?? 0) + delta);
426
+ if (nextCount === 0)
427
+ stacks.delete(skillId);
428
+ else
429
+ stacks.set(skillId, nextCount);
430
+ if (stacks.size === 0)
431
+ this.summonStacks.delete(actorId);
432
+ else
433
+ this.summonStacks.set(actorId, stacks);
434
+ return {
435
+ kind: "summon",
436
+ rpc,
437
+ tick: packet.tick,
438
+ payloadBytes: packet.payload.length,
439
+ fields: decodedFieldRecord(packet),
440
+ actorId,
441
+ skillId,
442
+ stacks: nextCount,
443
+ actorIdentity: this.actorIdentityResolver?.(actorId)
444
+ };
421
445
  }
422
446
  consumeSummonCalibration(packet) {
423
- let entries;
424
- try {
425
- entries = decodeSummonCalibration(packet.payload);
426
- } catch {
447
+ const entries = decodedSummonCalibration(packet);
448
+ if (!entries)
427
449
  return [];
428
- }
450
+ this.authoritativeSummonActors.add(packet.objectId);
429
451
  return this.applySummonSnapshot(packet.objectId, packet, entries);
430
452
  }
431
453
  applySummonSnapshot(actorId, packet, entries) {
@@ -446,7 +468,7 @@ class FishNetCombatTracker {
446
468
  rpc: "CalibrateSummons_T",
447
469
  tick: packet.tick,
448
470
  payloadBytes: packet.payload.length,
449
- fields: {},
471
+ fields: decodedFieldRecord(packet),
450
472
  actorId,
451
473
  skillId,
452
474
  stacks: current.get(skillId) ?? 0,
@@ -811,6 +833,45 @@ function field(packet, name) {
811
833
  function decodedFieldRecord(packet) {
812
834
  return Object.fromEntries(packet.decodedFields?.map(({ name, value }) => [name, value]) ?? []);
813
835
  }
836
+ function decodedSummonCalibration(packet) {
837
+ if (packet.undecodedPayload && packet.undecodedPayload.length > 0)
838
+ return;
839
+ const length = numberField(packet, "data.length");
840
+ if (length === undefined || !Number.isInteger(length) || length < 0)
841
+ return;
842
+ const entries = [];
843
+ for (let index = 0;index < length; index += 1) {
844
+ const skillId = stringField(packet, `data[${index}].SkillId`);
845
+ const level = numberField(packet, `data[${index}].Level`);
846
+ if (skillId === undefined || level === undefined || !Number.isInteger(level) || level < 0)
847
+ return;
848
+ entries.push({ skillId, level });
849
+ }
850
+ return entries;
851
+ }
852
+ function decodedLoginEffects(packet) {
853
+ if (packet.undecodedPayload && packet.undecodedPayload.length > 0)
854
+ return;
855
+ const length = numberField(packet, "data.State.Effects.length");
856
+ if (length === undefined || !Number.isInteger(length) || length < 0)
857
+ return;
858
+ const entries = [];
859
+ for (let index = 0;index < length; index += 1) {
860
+ const statusId = stringField(packet, `data.State.Effects[${index}].Id`);
861
+ const level = numberField(packet, `data.State.Effects[${index}].Level`);
862
+ const duration = numberField(packet, `data.State.Effects[${index}].Duration`);
863
+ const stacks = numberField(packet, `data.State.Effects[${index}].Stacks`);
864
+ if (statusId === undefined || level === undefined || !Number.isInteger(level) || level < 0 || duration === undefined || stacks === undefined || !Number.isInteger(stacks) || stacks < 0)
865
+ return;
866
+ entries.push({
867
+ statusId,
868
+ level,
869
+ ...duration < 0 || !Number.isFinite(duration) ? {} : { remainingSeconds: duration },
870
+ stacks
871
+ });
872
+ }
873
+ return entries;
874
+ }
814
875
  function matchesBehaviour(packet, expected) {
815
876
  return packet.networkBehaviourType === undefined || packet.networkBehaviourType === expected;
816
877
  }
@@ -909,7 +970,7 @@ function createBossCatalog(entries) {
909
970
  var CURRENT_BOSS_SKILL_NAMES = createBossCatalog({});
910
971
  // src/actor-directory.ts
911
972
  import { characterDataParameter, decodeFieldRun, loadBundledFishNetRpcMap } from "@kar-mi/spirit-vale-tools-capture";
912
- import { readSignedPackedWhole as readSignedPackedWhole4 } from "@kar-mi/spirit-vale-tools-capture/wire-reader";
973
+ import { readSignedPackedWhole as readSignedPackedWhole3 } from "@kar-mi/spirit-vale-tools-capture/wire-reader";
913
974
 
914
975
  class FishNetActorDirectory {
915
976
  options;
@@ -1313,7 +1374,7 @@ function decodeCharacterDataName(payload) {
1313
1374
  try {
1314
1375
  let offset = 0;
1315
1376
  if (skipEnum)
1316
- offset = readSignedPackedWhole4(payload, offset).nextOffset;
1377
+ offset = readSignedPackedWhole3(payload, offset).nextOffset;
1317
1378
  const run = decodeFieldRun(payload, [characterNameParameter()], offset);
1318
1379
  const values = new Map(run.fields.map((field2) => [field2.name, field2.value]));
1319
1380
  const uid = values.get("data.UID");
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@kar-mi/spirit-vale-tools-combat",
3
- "version": "3.3.5",
4
- "description": "Spirit Vale combat event tracking and replay utilities.",
5
- "license": "AGPL-3.0-only",
6
- "repository": {
7
- "type": "git",
8
- "url": "git+https://github.com/kar-mi/spirit-vale-tools.git",
9
- "directory": "packages/combat"
10
- },
3
+ "version": "3.3.6",
4
+ "description": "Spirit Vale combat event tracking and replay utilities.",
5
+ "license": "AGPL-3.0-only",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/kar-mi/spirit-vale-tools.git",
9
+ "directory": "packages/combat"
10
+ },
11
11
  "type": "module",
12
12
  "files": [
13
13
  "dist",
@@ -23,7 +23,7 @@
23
23
  }
24
24
  },
25
25
  "dependencies": {
26
- "@kar-mi/spirit-vale-tools-capture": "^2.3.0",
26
+ "@kar-mi/spirit-vale-tools-capture": "^2.4.2",
27
27
  "@kar-mi/spirit-vale-tools-logging": "^0.9.0",
28
28
  "@kar-mi/spirit-vale-tools-metrics": "^0.2.0",
29
29
  "@kar-mi/spirit-vale-tools-skills": "^0.2.1",
@@ -1,115 +0,0 @@
1
- import type { FishNetActorIdentityEvent } from "./actor-directory.ts";
2
- import type { FishNetCombatEvent } from "./combat-tracker.ts";
3
- export interface FishNetDpsMeterOptions {
4
- /** Milliseconds without positive player damage before a new encounter. Defaults to 30 seconds. */
5
- idleGapMs?: number;
6
- /** Minimum duration used as the DPS divisor. Defaults to one second. */
7
- minimumDurationMs?: number;
8
- /** Decay constant for current DPS. Defaults to 2.5 seconds, which matches a 5-second window's smoothing. */
9
- currentTauSeconds?: number;
10
- /** Milliseconds to wait for a late identity before showing unidentified damage. Defaults to ten seconds. */
11
- anonymousIdentityGraceMs?: number;
12
- /** FishNet ticks per second used for replay records without wall-clock timestamps. Defaults to 30. */
13
- replayTicksPerSecond?: number;
14
- personalName?: string;
15
- personalActorId?: number;
16
- }
17
- export interface FishNetDpsSkillRow {
18
- sourceId: string;
19
- sourceLabel: string;
20
- damage: number;
21
- dps: number;
22
- contribution: number;
23
- hits: number;
24
- criticalHits: number;
25
- /** Critical hits as a fraction of total hits, when the skill has hit. */
26
- critRate?: number;
27
- }
28
- export interface FishNetDpsTimelinePoint {
29
- /** Milliseconds elapsed since the encounter began. */
30
- elapsedMs: number;
31
- /** Damage dealt during this time bucket. */
32
- damage: number;
33
- /** Damage dealt from encounter start through this time bucket. */
34
- cumulativeDamage: number;
35
- /** Damage per second for this time bucket. */
36
- dps: number;
37
- }
38
- export interface FishNetDpsActorRow {
39
- actorIds: number[];
40
- displayName: string;
41
- archetype?: number;
42
- /** Milliseconds used as the DPS divisor and timeline span for this row. */
43
- durationMs?: number;
44
- /** Timestamp of this actor's most recent positive damage in the encounter. */
45
- lastDamageAtMs?: number;
46
- damage: number;
47
- dps: number;
48
- /**
49
- * Recent damage per second: an exponentially-weighted rate, not a flat window of the last few
50
- * seconds. It rises the instant a hit lands and then fades, so it never steps discontinuously as
51
- * a hit ages out and never reads exactly zero after one.
52
- */
53
- currentDps: number;
54
- contribution: number;
55
- hits: number;
56
- criticalHits: number;
57
- /** Critical hits as a fraction of total hits, when the actor has hit. */
58
- critRate?: number;
59
- kills: number;
60
- /** Number of distinct enemy object IDs damaged by this actor during the encounter. */
61
- mobsHit: number;
62
- skills: FishNetDpsSkillRow[];
63
- timeline: FishNetDpsTimelinePoint[];
64
- /** True when the row contains damage that has not been verified to a player identity. */
65
- isUnidentified?: boolean;
66
- }
67
- export type FishNetPersonalMatch = "unconfigured" | "missing" | "matched" | "ambiguous";
68
- export interface FishNetDpsEncounterSnapshot {
69
- id: string;
70
- startedAtMs: number;
71
- lastDamageAtMs: number;
72
- endedAtMs?: number;
73
- durationMs: number;
74
- totalDamage: number;
75
- partyDps: number;
76
- partyCurrentDps: number;
77
- actors: FishNetDpsActorRow[];
78
- personalName: string;
79
- personalMatch: FishNetPersonalMatch;
80
- personal?: FishNetDpsActorRow;
81
- }
82
- /** Aggregates structured FishNet identity and combat events into encounter DPS summaries. */
83
- export declare class FishNetDpsMeter {
84
- private readonly idleGapMs;
85
- private readonly minimumDurationMs;
86
- private readonly currentTauSeconds;
87
- private readonly anonymousIdentityGraceMs;
88
- private readonly replayTicksPerSecond;
89
- private readonly finished;
90
- private readonly identities;
91
- private current?;
92
- private nextEncounter;
93
- private personalName;
94
- private personalActorId?;
95
- constructor(options?: FishNetDpsMeterOptions);
96
- consumeIdentity(event: FishNetActorIdentityEvent, observedAtMs: number): void;
97
- consumeCombat(event: FishNetCombatEvent, observedAtMs: number): void;
98
- /** Finalizes an idle encounter. Calling this regularly keeps live status current. */
99
- advance(observedAtMs: number): void;
100
- /** Finalizes the current encounter; the next qualifying hit starts a new one. */
101
- reset(observedAtMs?: number): void;
102
- /** Discards all encounter statistics while retaining actor and personal configuration. */
103
- clearEncounters(): void;
104
- setPersonalName(name: string): void;
105
- getPersonalName(): string;
106
- setPersonalActorId(actorId: number | undefined): void;
107
- getPersonalActorId(): number | undefined;
108
- getSnapshots(nowMs?: number): FishNetDpsEncounterSnapshot[];
109
- getLatestSnapshot(nowMs?: number): FishNetDpsEncounterSnapshot | undefined;
110
- /** Maps a FishNet tick onto replay time relative to a caller-selected origin. */
111
- replayTimeMs(tick: number, originTick: number, originTimeMs?: number): number;
112
- private finishCurrent;
113
- private snapshot;
114
- }
115
- //# sourceMappingURL=dps-meter.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dps-meter.d.ts","sourceRoot":"","sources":["../src/dps-meter.ts"],"names":[],"mappings":"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"}
@@ -1,8 +0,0 @@
1
- export interface FishNetSummonCalibrationEntry {
2
- skillId: string;
3
- isPrimary: boolean;
4
- isMountedSummon: boolean;
5
- }
6
- /** Decodes the complete summon snapshot carried by CalibrateSummons_T. */
7
- export declare function decodeSummonCalibration(payload: Buffer): FishNetSummonCalibrationEntry[];
8
- //# sourceMappingURL=summon-calibration.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"summon-calibration.d.ts","sourceRoot":"","sources":["../src/summon-calibration.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,6BAA6B;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,0EAA0E;AAC1E,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,6BAA6B,EAAE,CAqBxF"}