@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.
- package/dist/fishnet/replay.d.ts +20 -0
- package/dist/fishnet/replay.d.ts.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +56 -0
- package/dist/text-format.d.ts +3 -0
- package/dist/text-format.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -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";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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,
|
package/dist/text-format.d.ts
CHANGED
|
@@ -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"}
|