@kar-mi/spirit-vale-tools-capture 3.0.0 → 3.0.1

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.
@@ -0,0 +1,20 @@
1
+ import type { DecodedFishNetPacket } from "./types.ts";
2
+ export interface FishNetReplayLogRecord {
3
+ readonly type: string;
4
+ readonly recordedAt: string;
5
+ readonly data: Record<string, unknown>;
6
+ }
7
+ export type FishNetReplayRecordResult = "ignored" | "invalid" | "decoded";
8
+ export interface FishNetTransportReplayStats {
9
+ datagrams: number;
10
+ decodeWarnings: number;
11
+ }
12
+ /** Replays structured UDP transport records through one connection-aware FishNet decoder. */
13
+ export declare class FishNetTransportReplay {
14
+ private readonly session;
15
+ private datagrams;
16
+ private decodeWarnings;
17
+ consumeRecord(record: FishNetReplayLogRecord, consume: (packet: DecodedFishNetPacket, observedAtMs: number | undefined) => void): FishNetReplayRecordResult;
18
+ stats(): FishNetTransportReplayStats;
19
+ }
20
+ //# sourceMappingURL=replay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replay.d.ts","sourceRoot":"","sources":["../../src/fishnet/replay.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAIvD,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACxC;AAED,MAAM,MAAM,yBAAyB,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAE1E,MAAM,WAAW,2BAA2B;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,6FAA6F;AAC7F,qBAAa,sBAAsB;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyD;IACjF,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,cAAc,CAAK;IAE3B,aAAa,CACX,MAAM,EAAE,sBAAsB,EAC9B,OAAO,EAAE,CAAC,MAAM,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,GAChF,yBAAyB,CAmC3B;IAED,KAAK,IAAI,2BAA2B,CAEnC;CACF"}
package/dist/index.d.ts CHANGED
@@ -9,6 +9,8 @@ export type { FieldDecodeRun } from "./fishnet/decoding/fields.ts";
9
9
  export { characterDataParameter } from "./fishnet/schema/character-data.ts";
10
10
  export { decodeNetworkTransformData, NETWORK_TRANSFORM_RPC_NAMES } from "./fishnet/decoding/network-transform.ts";
11
11
  export { resolveBundledMapName } from "./fishnet/mapping/map-names.ts";
12
+ export { FishNetTransportReplay } from "./fishnet/replay.ts";
13
+ export type { FishNetReplayLogRecord, FishNetReplayRecordResult, FishNetTransportReplayStats, } from "./fishnet/replay.ts";
12
14
  export { compact, count, warnings } from "./text-format.ts";
13
15
  export type { BundledFishNetBuildFingerprint } from "./fishnet/mapping/bundled-rpc-map.ts";
14
16
  export { FishNetEternalTowerTracker } from "./fishnet/tracking/eternal-tower.ts";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,+BAA+B,EAC/B,8BAA8B,GAC/B,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAC5F,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAC;AAChF,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,YAAY,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAC5E,OAAO,EAAE,0BAA0B,EAAE,2BAA2B,EAAE,MAAM,yCAAyC,CAAC;AAClH,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5D,YAAY,EAAE,8BAA8B,EAAE,MAAM,sCAAsC,CAAC;AAC3F,OAAO,EAAE,0BAA0B,EAAE,MAAM,qCAAqC,CAAC;AACjF,YAAY,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AACvF,OAAO,EACL,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,gCAAgC,CAAC;AACxC,YAAY,EACV,6BAA6B,EAC7B,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC7E,YAAY,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,YAAY,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACjE,YAAY,EACV,aAAa,EACb,sBAAsB,EACtB,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,iBAAiB,EACjB,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,wBAAwB,EACxB,uBAAuB,EACvB,mBAAmB,EACnB,yBAAyB,EACzB,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,wBAAwB,EACxB,oBAAoB,EACpB,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,0BAA0B,EAC1B,0BAA0B,EAC1B,gCAAgC,EAChC,uBAAuB,EACvB,iBAAiB,EACjB,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACpB,0BAA0B,EAC1B,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,EACrB,gBAAgB,EAChB,yBAAyB,EACzB,gBAAgB,EAChB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,+BAA+B,EAC/B,8BAA8B,GAC/B,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAC5F,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAC;AAChF,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,YAAY,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAC5E,OAAO,EAAE,0BAA0B,EAAE,2BAA2B,EAAE,MAAM,yCAAyC,CAAC;AAClH,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,YAAY,EACV,sBAAsB,EACtB,yBAAyB,EACzB,2BAA2B,GAC5B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5D,YAAY,EAAE,8BAA8B,EAAE,MAAM,sCAAsC,CAAC;AAC3F,OAAO,EAAE,0BAA0B,EAAE,MAAM,qCAAqC,CAAC;AACjF,YAAY,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AACvF,OAAO,EACL,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,gCAAgC,CAAC;AACxC,YAAY,EACV,6BAA6B,EAC7B,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC7E,YAAY,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,YAAY,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACjE,YAAY,EACV,aAAa,EACb,sBAAsB,EACtB,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,iBAAiB,EACjB,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,wBAAwB,EACxB,uBAAuB,EACvB,mBAAmB,EACnB,yBAAyB,EACzB,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,wBAAwB,EACxB,oBAAoB,EACpB,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,0BAA0B,EAC1B,0BAA0B,EAC1B,gCAAgC,EAChC,uBAAuB,EACvB,iBAAiB,EACjB,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACpB,0BAA0B,EAC1B,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,EACrB,gBAAgB,EAChB,yBAAyB,EACzB,gBAAgB,EAChB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -15307,6 +15307,61 @@ function characterDataParameter() {
15307
15307
  cached = parameter;
15308
15308
  return parameter;
15309
15309
  }
15310
+ // src/fishnet/replay.ts
15311
+ class FishNetTransportReplay {
15312
+ session = new FishNetSessionDecoder(loadBundledFishNetRpcMap());
15313
+ datagrams = 0;
15314
+ decodeWarnings = 0;
15315
+ consumeRecord(record, consume) {
15316
+ if (record.type !== "transport.packet")
15317
+ return "ignored";
15318
+ const transport = parseUdpRecord(record.data);
15319
+ if (!transport)
15320
+ return "invalid";
15321
+ this.datagrams += 1;
15322
+ const source = `${transport.sourceIP}:${transport.sourcePort}`;
15323
+ const destination = `${transport.destinationIP}:${transport.destinationPort}`;
15324
+ const endpoints = [source, destination].sort();
15325
+ const connectionBase = `${endpoints[0]}<->${endpoints[1]}`;
15326
+ const direction = source === endpoints[0] ? "a-to-b" : "b-to-a";
15327
+ const parsedAtMs = Date.parse(record.recordedAt);
15328
+ const observedAtMs = Number.isFinite(parsedAtMs) ? parsedAtMs : undefined;
15329
+ try {
15330
+ for (const decoded of decodeLiteNetLibDatagram(Buffer.from(transport.payloadHex, "hex"))) {
15331
+ const packet = decoded.packet;
15332
+ const connectionId = `${connectionBase}#${packet.connectionNumber}`;
15333
+ if (packet.property === "connectRequest" || packet.property === "connectAccept" || packet.property === "disconnect") {
15334
+ this.session.reset(connectionId);
15335
+ continue;
15336
+ }
15337
+ if (packet.property !== "unreliable" && packet.property !== "channeled" || packet.payload.length < 6)
15338
+ continue;
15339
+ for (const fishNetPacket of this.session.decode(packet.payload, {
15340
+ reliable: packet.property === "channeled",
15341
+ connectionId,
15342
+ direction,
15343
+ channel: packet.property === "channeled" ? packet.channel : 1,
15344
+ sequence: packet.property === "channeled" ? packet.sequence : undefined
15345
+ }))
15346
+ consume(fishNetPacket, observedAtMs);
15347
+ }
15348
+ } catch {
15349
+ this.decodeWarnings += 1;
15350
+ }
15351
+ return "decoded";
15352
+ }
15353
+ stats() {
15354
+ return { datagrams: this.datagrams, decodeWarnings: this.decodeWarnings };
15355
+ }
15356
+ }
15357
+ function parseUdpRecord(data) {
15358
+ if (data["protocol"] !== "udp" || typeof data["sourceIP"] !== "string" || typeof data["destinationIP"] !== "string" || !isPort(data["sourcePort"]) || !isPort(data["destinationPort"]) || typeof data["payloadHex"] !== "string" || !/^(?:[0-9a-fA-F]{2})*$/.test(data["payloadHex"]))
15359
+ return;
15360
+ return data;
15361
+ }
15362
+ function isPort(value) {
15363
+ return Number.isInteger(value) && value >= 0 && value <= 65535;
15364
+ }
15310
15365
  // src/text-format.ts
15311
15366
  function count(value, label) {
15312
15367
  return `${value} ${label}${value === 1 ? "" : "s"}`;
@@ -15494,6 +15549,7 @@ export {
15494
15549
  FishNetMonsterDirectory,
15495
15550
  FishNetProtocolError,
15496
15551
  FishNetSessionDecoder,
15552
+ FishNetTransportReplay,
15497
15553
  LiteNetLibProtocolError,
15498
15554
  NETWORK_TRANSFORM_RPC_NAMES,
15499
15555
  characterDataParameter,
@@ -1,4 +1,7 @@
1
+ /** @deprecated Import this application-facing helper from spirit-vale-tools-logging. */
1
2
  export declare function count(value: number, label: string): string;
3
+ /** @deprecated Import this application-facing helper from spirit-vale-tools-logging. */
2
4
  export declare function compact(value: number | bigint): string;
5
+ /** @deprecated Import this application-facing helper from spirit-vale-tools-logging. */
3
6
  export declare function warnings(value: number): string;
4
7
  //# sourceMappingURL=text-format.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"text-format.d.ts","sourceRoot":"","sources":["../src/text-format.ts"],"names":[],"mappings":"AAAA,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAEtD;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE9C"}
1
+ {"version":3,"file":"text-format.d.ts","sourceRoot":"","sources":["../src/text-format.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wFAAwF;AACxF,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAEtD;AAED,wFAAwF;AACxF,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE9C"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kar-mi/spirit-vale-tools-capture",
3
- "version": "3.0.0",
3
+ "version": "3.0.1",
4
4
  "description": "Passive Windows packet capture and Spirit Vale protocol decoding for Bun.",
5
5
  "license": "AGPL-3.0-only",
6
6
  "repository": {