@kar-mi/spirit-vale-tools-capture 2.6.0 → 3.0.0
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/capture/drop-diagnostics.d.ts +42 -0
- package/dist/capture/drop-diagnostics.d.ts.map +1 -0
- package/dist/capture/duplicate-filter.d.ts +39 -0
- package/dist/capture/duplicate-filter.d.ts.map +1 -0
- package/dist/capture/packet-capture.d.ts +11 -0
- package/dist/capture/packet-capture.d.ts.map +1 -1
- package/dist/capture.js +351 -130
- package/dist/fishnet/{decoder.d.ts → decoding/decoder.d.ts} +2 -2
- package/dist/fishnet/decoding/decoder.d.ts.map +1 -0
- package/dist/fishnet/{field-decoder.d.ts → decoding/fields.d.ts} +2 -2
- package/dist/fishnet/decoding/fields.d.ts.map +1 -0
- package/dist/fishnet/{message-parser.d.ts → decoding/messages.d.ts} +2 -2
- package/dist/fishnet/{message-parser.d.ts.map → decoding/messages.d.ts.map} +1 -1
- package/dist/fishnet/{network-transform-decoder.d.ts → decoding/network-transform.d.ts} +2 -2
- package/dist/fishnet/decoding/network-transform.d.ts.map +1 -0
- package/dist/fishnet/{protocol.d.ts → decoding/protocol.d.ts} +1 -1
- package/dist/fishnet/decoding/protocol.d.ts.map +1 -0
- package/dist/fishnet/{quaternion-compression.d.ts → decoding/quaternion.d.ts} +1 -1
- package/dist/fishnet/decoding/quaternion.d.ts.map +1 -0
- package/dist/fishnet/{session-decoder.d.ts → decoding/session.d.ts} +2 -2
- package/dist/fishnet/decoding/session.d.ts.map +1 -0
- package/dist/fishnet/{spawn-parser.d.ts → decoding/spawn.d.ts} +2 -2
- package/dist/fishnet/decoding/spawn.d.ts.map +1 -0
- package/dist/fishnet/decoding/wire-reader.d.ts.map +1 -0
- package/dist/fishnet/{wire-reader.js → decoding/wire-reader.js} +2 -2
- package/dist/fishnet/generated/map-names.current.d.ts +3 -0
- package/dist/fishnet/generated/map-names.current.d.ts.map +1 -0
- package/dist/fishnet/generated/rpc-map/base-unit-controller.d.ts.map +1 -0
- package/dist/fishnet/generated/rpc-map/boss-grave-stone.d.ts.map +1 -0
- package/dist/fishnet/generated/rpc-map/broadcasts.d.ts.map +1 -0
- package/dist/fishnet/generated/rpc-map/combat-component.d.ts.map +1 -0
- package/dist/fishnet/{rpc-definitions/generated/index.d.ts → generated/rpc-map/definitions.d.ts} +53 -1
- package/dist/fishnet/{rpc-definitions/generated/index.d.ts.map → generated/rpc-map/definitions.d.ts.map} +1 -1
- package/dist/fishnet/generated/rpc-map/engine/network-animator.d.ts.map +1 -0
- package/dist/fishnet/generated/rpc-map/engine/network-transform.d.ts.map +1 -0
- package/dist/fishnet/generated/rpc-map/engine/predicted-owner.d.ts.map +1 -0
- package/dist/fishnet/{rpc-definitions/generated → generated/rpc-map}/health-component.d.ts +17 -0
- package/dist/fishnet/generated/rpc-map/health-component.d.ts.map +1 -0
- package/dist/fishnet/{rpc-definitions → generated/rpc-map}/index.d.ts +52 -0
- package/dist/fishnet/{rpc-definitions → generated/rpc-map}/index.d.ts.map +1 -1
- package/dist/fishnet/generated/rpc-map/loot-drop.d.ts.map +1 -0
- package/dist/fishnet/{rpc-definitions/generated → generated/rpc-map}/manifest.d.ts +1 -1
- package/dist/fishnet/generated/rpc-map/manifest.d.ts.map +1 -0
- package/dist/fishnet/generated/rpc-map/monster-controller.d.ts.map +1 -0
- package/dist/fishnet/generated/rpc-map/move-component.d.ts.map +1 -0
- package/dist/fishnet/generated/rpc-map/player-controller.d.ts.map +1 -0
- package/dist/fishnet/generated/rpc-map/player-save.d.ts.map +1 -0
- package/dist/fishnet/generated/rpc-map/prefabs.d.ts.map +1 -0
- package/dist/fishnet/{rpc-definitions/generated → generated/rpc-map}/skills-component.d.ts +35 -0
- package/dist/fishnet/generated/rpc-map/skills-component.d.ts.map +1 -0
- package/dist/fishnet/generated/rpc-map/status-component.d.ts.map +1 -0
- package/dist/fishnet/generated/rpc-map/summoning-component.d.ts.map +1 -0
- package/dist/fishnet/inference/rpc-inference.d.ts +9 -0
- package/dist/fishnet/inference/rpc-inference.d.ts.map +1 -0
- package/dist/fishnet/{builtin-maps.d.ts → mapping/bundled-rpc-map.d.ts} +54 -2
- package/dist/fishnet/{builtin-maps.d.ts.map → mapping/bundled-rpc-map.d.ts.map} +1 -1
- package/dist/fishnet/{map-definitions/index.d.ts → mapping/map-names.d.ts} +1 -1
- package/dist/fishnet/mapping/map-names.d.ts.map +1 -0
- package/dist/fishnet/mapping/rpc-map.d.ts +15 -0
- package/dist/fishnet/mapping/rpc-map.d.ts.map +1 -0
- package/dist/fishnet/schema/character-data.d.ts +3 -0
- package/dist/fishnet/schema/character-data.d.ts.map +1 -0
- package/dist/fishnet/schema/codecs.d.ts.map +1 -0
- package/dist/fishnet/{definitions/protocol.d.ts → schema/packets.d.ts} +2 -2
- package/dist/fishnet/schema/packets.d.ts.map +1 -0
- package/dist/fishnet/{definitions → schema}/rpc-map.d.ts +1 -1
- package/dist/fishnet/schema/rpc-map.d.ts.map +1 -0
- package/dist/fishnet/{boss-gravestone.d.ts → tracking/boss-gravestone.d.ts} +1 -1
- package/dist/fishnet/tracking/boss-gravestone.d.ts.map +1 -0
- package/dist/fishnet/{eternal-tower-tracker.d.ts → tracking/eternal-tower.d.ts} +2 -2
- package/dist/fishnet/tracking/eternal-tower.d.ts.map +1 -0
- package/dist/fishnet/{monster-directory.d.ts → tracking/monsters.d.ts} +2 -2
- package/dist/fishnet/tracking/monsters.d.ts.map +1 -0
- package/dist/fishnet/types.d.ts +4 -4
- package/dist/fishnet/types.d.ts.map +1 -1
- package/dist/index.d.ts +16 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +197 -179
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +4 -4
- package/dist/fishnet/boss-gravestone.d.ts.map +0 -1
- package/dist/fishnet/character-data-schema.d.ts +0 -3
- package/dist/fishnet/character-data-schema.d.ts.map +0 -1
- package/dist/fishnet/decoder.d.ts.map +0 -1
- package/dist/fishnet/definitions/codecs.d.ts.map +0 -1
- package/dist/fishnet/definitions/protocol.d.ts.map +0 -1
- package/dist/fishnet/definitions/rpc-map.d.ts.map +0 -1
- package/dist/fishnet/eternal-tower-tracker.d.ts.map +0 -1
- package/dist/fishnet/field-decoder.d.ts.map +0 -1
- package/dist/fishnet/map-definitions/current-build.d.ts +0 -3
- package/dist/fishnet/map-definitions/current-build.d.ts.map +0 -1
- package/dist/fishnet/map-definitions/index.d.ts.map +0 -1
- package/dist/fishnet/monster-directory.d.ts.map +0 -1
- package/dist/fishnet/network-transform-decoder.d.ts.map +0 -1
- package/dist/fishnet/protocol.d.ts.map +0 -1
- package/dist/fishnet/quaternion-compression.d.ts.map +0 -1
- package/dist/fishnet/recovery-style.d.ts +0 -5
- package/dist/fishnet/recovery-style.d.ts.map +0 -1
- package/dist/fishnet/rpc-definitions/generated/base-unit-controller.d.ts.map +0 -1
- package/dist/fishnet/rpc-definitions/generated/boss-grave-stone.d.ts.map +0 -1
- package/dist/fishnet/rpc-definitions/generated/broadcasts.d.ts.map +0 -1
- package/dist/fishnet/rpc-definitions/generated/combat-component.d.ts.map +0 -1
- package/dist/fishnet/rpc-definitions/generated/engine/network-animator.d.ts.map +0 -1
- package/dist/fishnet/rpc-definitions/generated/engine/network-transform.d.ts.map +0 -1
- package/dist/fishnet/rpc-definitions/generated/engine/predicted-owner.d.ts.map +0 -1
- package/dist/fishnet/rpc-definitions/generated/health-component.d.ts.map +0 -1
- package/dist/fishnet/rpc-definitions/generated/loot-drop.d.ts.map +0 -1
- package/dist/fishnet/rpc-definitions/generated/manifest.d.ts.map +0 -1
- package/dist/fishnet/rpc-definitions/generated/monster-controller.d.ts.map +0 -1
- package/dist/fishnet/rpc-definitions/generated/move-component.d.ts.map +0 -1
- package/dist/fishnet/rpc-definitions/generated/player-controller.d.ts.map +0 -1
- package/dist/fishnet/rpc-definitions/generated/player-save.d.ts.map +0 -1
- package/dist/fishnet/rpc-definitions/generated/prefabs.d.ts.map +0 -1
- package/dist/fishnet/rpc-definitions/generated/skills-component.d.ts.map +0 -1
- package/dist/fishnet/rpc-definitions/generated/status-component.d.ts.map +0 -1
- package/dist/fishnet/rpc-definitions/generated/summoning-component.d.ts.map +0 -1
- package/dist/fishnet/rpc-resolution.d.ts +0 -65
- package/dist/fishnet/rpc-resolution.d.ts.map +0 -1
- package/dist/fishnet/semantic-definitions.d.ts +0 -40
- package/dist/fishnet/semantic-definitions.d.ts.map +0 -1
- package/dist/fishnet/semantic-map.d.ts +0 -23
- package/dist/fishnet/semantic-map.d.ts.map +0 -1
- package/dist/fishnet/session-decoder.d.ts.map +0 -1
- package/dist/fishnet/spawn-parser.d.ts.map +0 -1
- package/dist/fishnet/wire-reader.d.ts.map +0 -1
- /package/dist/fishnet/{wire-reader.d.ts → decoding/wire-reader.d.ts} +0 -0
- /package/dist/fishnet/{rpc-definitions/generated → generated/rpc-map}/base-unit-controller.d.ts +0 -0
- /package/dist/fishnet/{rpc-definitions/generated → generated/rpc-map}/boss-grave-stone.d.ts +0 -0
- /package/dist/fishnet/{rpc-definitions/generated → generated/rpc-map}/broadcasts.d.ts +0 -0
- /package/dist/fishnet/{rpc-definitions/generated → generated/rpc-map}/combat-component.d.ts +0 -0
- /package/dist/fishnet/{rpc-definitions/generated → generated/rpc-map}/engine/network-animator.d.ts +0 -0
- /package/dist/fishnet/{rpc-definitions/generated → generated/rpc-map}/engine/network-transform.d.ts +0 -0
- /package/dist/fishnet/{rpc-definitions/generated → generated/rpc-map}/engine/predicted-owner.d.ts +0 -0
- /package/dist/fishnet/{rpc-definitions/generated → generated/rpc-map}/loot-drop.d.ts +0 -0
- /package/dist/fishnet/{rpc-definitions/generated → generated/rpc-map}/monster-controller.d.ts +0 -0
- /package/dist/fishnet/{rpc-definitions/generated → generated/rpc-map}/move-component.d.ts +0 -0
- /package/dist/fishnet/{rpc-definitions/generated → generated/rpc-map}/player-controller.d.ts +0 -0
- /package/dist/fishnet/{rpc-definitions/generated → generated/rpc-map}/player-save.d.ts +0 -0
- /package/dist/fishnet/{rpc-definitions/generated → generated/rpc-map}/prefabs.d.ts +0 -0
- /package/dist/fishnet/{rpc-definitions/generated → generated/rpc-map}/status-component.d.ts +0 -0
- /package/dist/fishnet/{rpc-definitions/generated → generated/rpc-map}/summoning-component.d.ts +0 -0
- /package/dist/fishnet/{definitions → schema}/codecs.d.ts +0 -0
package/dist/capture.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
// src/fishnet/protocol.ts
|
|
2
|
+
// src/fishnet/decoding/protocol.ts
|
|
3
3
|
var PACKET_NAMES = new Map([
|
|
4
4
|
[0, "unset"],
|
|
5
5
|
[1, "authenticated"],
|
|
@@ -70,7 +70,7 @@ function unresolvedLinkPacket(buffer, start, tick, bundleIndex, packetId) {
|
|
|
70
70
|
return packet;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
// src/fishnet/wire-reader.ts
|
|
73
|
+
// src/fishnet/decoding/wire-reader.ts
|
|
74
74
|
function requireBytes(buffer, offset, count, description) {
|
|
75
75
|
if (buffer.length - offset < count) {
|
|
76
76
|
throw new FishNetProtocolError(`${description} needs ${count} bytes at byte ${offset}; ${buffer.length - offset} remain`);
|
|
@@ -277,7 +277,7 @@ function requireLength(bytes, offset, length, absoluteOffset, field) {
|
|
|
277
277
|
}
|
|
278
278
|
}
|
|
279
279
|
|
|
280
|
-
// src/fishnet/rpc-
|
|
280
|
+
// src/fishnet/generated/rpc-map/base-unit-controller.ts
|
|
281
281
|
var baseUnitControllerRpcs = [
|
|
282
282
|
{
|
|
283
283
|
wireHash: 0,
|
|
@@ -379,7 +379,7 @@ var baseUnitControllerRpcs = [
|
|
|
379
379
|
}
|
|
380
380
|
];
|
|
381
381
|
|
|
382
|
-
// src/fishnet/rpc-
|
|
382
|
+
// src/fishnet/generated/rpc-map/boss-grave-stone.ts
|
|
383
383
|
var bossGraveStoneRpcs = [];
|
|
384
384
|
var bossGraveStoneSyncTypes = [
|
|
385
385
|
{
|
|
@@ -411,7 +411,7 @@ var bossGraveStoneSyncTypes = [
|
|
|
411
411
|
}
|
|
412
412
|
];
|
|
413
413
|
|
|
414
|
-
// src/fishnet/rpc-
|
|
414
|
+
// src/fishnet/generated/rpc-map/combat-component.ts
|
|
415
415
|
var combatComponentRpcs = [
|
|
416
416
|
{
|
|
417
417
|
wireHash: 0,
|
|
@@ -516,7 +516,7 @@ var combatComponentSyncTypes = [
|
|
|
516
516
|
}
|
|
517
517
|
];
|
|
518
518
|
|
|
519
|
-
// src/fishnet/rpc-
|
|
519
|
+
// src/fishnet/generated/rpc-map/engine/network-animator.ts
|
|
520
520
|
var networkAnimatorRpcs = [
|
|
521
521
|
{
|
|
522
522
|
wireHash: 0,
|
|
@@ -542,7 +542,7 @@ var networkAnimatorRpcs = [
|
|
|
542
542
|
}
|
|
543
543
|
];
|
|
544
544
|
|
|
545
|
-
// src/fishnet/rpc-
|
|
545
|
+
// src/fishnet/generated/rpc-map/engine/predicted-owner.ts
|
|
546
546
|
var predictedOwnerRpcs = [
|
|
547
547
|
{
|
|
548
548
|
wireHash: 0,
|
|
@@ -558,7 +558,7 @@ var predictedOwnerRpcs = [
|
|
|
558
558
|
}
|
|
559
559
|
];
|
|
560
560
|
|
|
561
|
-
// src/fishnet/rpc-
|
|
561
|
+
// src/fishnet/generated/rpc-map/engine/network-transform.ts
|
|
562
562
|
var networkTransformRpcs = [
|
|
563
563
|
{
|
|
564
564
|
wireHash: 0,
|
|
@@ -651,7 +651,7 @@ var networkTransformRpcs = [
|
|
|
651
651
|
}
|
|
652
652
|
];
|
|
653
653
|
|
|
654
|
-
// src/fishnet/rpc-
|
|
654
|
+
// src/fishnet/generated/rpc-map/health-component.ts
|
|
655
655
|
var healthComponentRpcs = [
|
|
656
656
|
{
|
|
657
657
|
wireHash: 0,
|
|
@@ -748,7 +748,29 @@ var healthComponentRpcs = [
|
|
|
748
748
|
},
|
|
749
749
|
{
|
|
750
750
|
name: "settings",
|
|
751
|
-
typeName: "FloaterSettings"
|
|
751
|
+
typeName: "FloaterSettings",
|
|
752
|
+
fields: [
|
|
753
|
+
{
|
|
754
|
+
name: "DisableFloater",
|
|
755
|
+
typeName: "System.Boolean",
|
|
756
|
+
codec: "boolean"
|
|
757
|
+
},
|
|
758
|
+
{
|
|
759
|
+
name: "DisableSfx",
|
|
760
|
+
typeName: "System.Boolean",
|
|
761
|
+
codec: "boolean"
|
|
762
|
+
},
|
|
763
|
+
{
|
|
764
|
+
name: "Offset",
|
|
765
|
+
typeName: "System.Int32",
|
|
766
|
+
codec: "packedInt32"
|
|
767
|
+
},
|
|
768
|
+
{
|
|
769
|
+
name: "Scale",
|
|
770
|
+
typeName: "System.Single",
|
|
771
|
+
codec: "float32"
|
|
772
|
+
}
|
|
773
|
+
]
|
|
752
774
|
}
|
|
753
775
|
]
|
|
754
776
|
},
|
|
@@ -853,7 +875,7 @@ var healthComponentSyncTypes = [
|
|
|
853
875
|
}
|
|
854
876
|
];
|
|
855
877
|
|
|
856
|
-
// src/fishnet/rpc-
|
|
878
|
+
// src/fishnet/generated/rpc-map/loot-drop.ts
|
|
857
879
|
var lootDropRpcs = [];
|
|
858
880
|
var lootDropSyncTypes = [
|
|
859
881
|
{
|
|
@@ -917,7 +939,7 @@ var lootDropSyncTypes = [
|
|
|
917
939
|
}
|
|
918
940
|
];
|
|
919
941
|
|
|
920
|
-
// src/fishnet/rpc-
|
|
942
|
+
// src/fishnet/generated/rpc-map/monster-controller.ts
|
|
921
943
|
var monsterControllerRpcs = [
|
|
922
944
|
{
|
|
923
945
|
wireHash: 7,
|
|
@@ -1065,7 +1087,7 @@ var monsterControllerSyncTypes = [
|
|
|
1065
1087
|
}
|
|
1066
1088
|
];
|
|
1067
1089
|
|
|
1068
|
-
// src/fishnet/rpc-
|
|
1090
|
+
// src/fishnet/generated/rpc-map/move-component.ts
|
|
1069
1091
|
var moveComponentRpcs = [
|
|
1070
1092
|
{
|
|
1071
1093
|
wireHash: 0,
|
|
@@ -1129,7 +1151,7 @@ var moveComponentSyncTypes = [
|
|
|
1129
1151
|
}
|
|
1130
1152
|
];
|
|
1131
1153
|
|
|
1132
|
-
// src/fishnet/rpc-
|
|
1154
|
+
// src/fishnet/generated/rpc-map/player-controller.ts
|
|
1133
1155
|
var playerControllerRpcs = [
|
|
1134
1156
|
{
|
|
1135
1157
|
wireHash: 7,
|
|
@@ -5354,7 +5376,7 @@ var playerControllerSyncTypes = [
|
|
|
5354
5376
|
}
|
|
5355
5377
|
];
|
|
5356
5378
|
|
|
5357
|
-
// src/fishnet/rpc-
|
|
5379
|
+
// src/fishnet/generated/rpc-map/player-save.ts
|
|
5358
5380
|
var playerSaveRpcs = [
|
|
5359
5381
|
{
|
|
5360
5382
|
wireHash: 0,
|
|
@@ -13024,7 +13046,7 @@ var playerSaveSyncTypes = [
|
|
|
13024
13046
|
}
|
|
13025
13047
|
];
|
|
13026
13048
|
|
|
13027
|
-
// src/fishnet/rpc-
|
|
13049
|
+
// src/fishnet/generated/rpc-map/skills-component.ts
|
|
13028
13050
|
var skillsComponentRpcs = [
|
|
13029
13051
|
{
|
|
13030
13052
|
wireHash: 0,
|
|
@@ -13050,7 +13072,29 @@ var skillsComponentRpcs = [
|
|
|
13050
13072
|
},
|
|
13051
13073
|
{
|
|
13052
13074
|
name: "settings",
|
|
13053
|
-
typeName: "FloaterSettings"
|
|
13075
|
+
typeName: "FloaterSettings",
|
|
13076
|
+
fields: [
|
|
13077
|
+
{
|
|
13078
|
+
name: "DisableFloater",
|
|
13079
|
+
typeName: "System.Boolean",
|
|
13080
|
+
codec: "boolean"
|
|
13081
|
+
},
|
|
13082
|
+
{
|
|
13083
|
+
name: "DisableSfx",
|
|
13084
|
+
typeName: "System.Boolean",
|
|
13085
|
+
codec: "boolean"
|
|
13086
|
+
},
|
|
13087
|
+
{
|
|
13088
|
+
name: "Offset",
|
|
13089
|
+
typeName: "System.Int32",
|
|
13090
|
+
codec: "packedInt32"
|
|
13091
|
+
},
|
|
13092
|
+
{
|
|
13093
|
+
name: "Scale",
|
|
13094
|
+
typeName: "System.Single",
|
|
13095
|
+
codec: "float32"
|
|
13096
|
+
}
|
|
13097
|
+
]
|
|
13054
13098
|
}
|
|
13055
13099
|
]
|
|
13056
13100
|
},
|
|
@@ -13318,11 +13362,35 @@ var skillsComponentSyncTypes = [
|
|
|
13318
13362
|
{
|
|
13319
13363
|
index: 2,
|
|
13320
13364
|
name: "BondSync",
|
|
13321
|
-
typeName: "BondDto"
|
|
13365
|
+
typeName: "BondDto",
|
|
13366
|
+
fields: [
|
|
13367
|
+
{
|
|
13368
|
+
name: "Entries",
|
|
13369
|
+
typeName: "System.Collections.Generic.List`1[[SkillsComponent+BondEntry, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]",
|
|
13370
|
+
repeated: true,
|
|
13371
|
+
fields: [
|
|
13372
|
+
{
|
|
13373
|
+
name: "Other",
|
|
13374
|
+
typeName: "FishNet.Object.NetworkObject",
|
|
13375
|
+
codec: "networkObject"
|
|
13376
|
+
},
|
|
13377
|
+
{
|
|
13378
|
+
name: "SkillId",
|
|
13379
|
+
typeName: "System.String",
|
|
13380
|
+
codec: "stringUtf8Packed"
|
|
13381
|
+
},
|
|
13382
|
+
{
|
|
13383
|
+
name: "Caster",
|
|
13384
|
+
typeName: "System.Boolean",
|
|
13385
|
+
codec: "boolean"
|
|
13386
|
+
}
|
|
13387
|
+
]
|
|
13388
|
+
}
|
|
13389
|
+
]
|
|
13322
13390
|
}
|
|
13323
13391
|
];
|
|
13324
13392
|
|
|
13325
|
-
// src/fishnet/rpc-
|
|
13393
|
+
// src/fishnet/generated/rpc-map/status-component.ts
|
|
13326
13394
|
var statusComponentRpcs = [
|
|
13327
13395
|
{
|
|
13328
13396
|
wireHash: 0,
|
|
@@ -13469,7 +13537,7 @@ var statusComponentSyncTypes = [
|
|
|
13469
13537
|
}
|
|
13470
13538
|
];
|
|
13471
13539
|
|
|
13472
|
-
// src/fishnet/rpc-
|
|
13540
|
+
// src/fishnet/generated/rpc-map/summoning-component.ts
|
|
13473
13541
|
var summoningComponentRpcs = [
|
|
13474
13542
|
{
|
|
13475
13543
|
wireHash: 0,
|
|
@@ -13584,7 +13652,7 @@ var summoningComponentSyncTypes = [
|
|
|
13584
13652
|
}
|
|
13585
13653
|
];
|
|
13586
13654
|
|
|
13587
|
-
// src/fishnet/rpc-
|
|
13655
|
+
// src/fishnet/generated/rpc-map/broadcasts.ts
|
|
13588
13656
|
var GENERATED_BROADCASTS = [
|
|
13589
13657
|
{
|
|
13590
13658
|
wireHash: 40743,
|
|
@@ -13611,7 +13679,7 @@ var GENERATED_BROADCASTS = [
|
|
|
13611
13679
|
typeName: "FishNet.Managing.Server.ConnectedClientsBroadcast"
|
|
13612
13680
|
}
|
|
13613
13681
|
];
|
|
13614
|
-
// src/fishnet/rpc-
|
|
13682
|
+
// src/fishnet/generated/rpc-map/prefabs.ts
|
|
13615
13683
|
var GENERATED_PREFAB_DEFINITIONS = [
|
|
13616
13684
|
{
|
|
13617
13685
|
collectionId: 0,
|
|
@@ -13772,11 +13840,11 @@ var GENERATED_PREFAB_DEFINITIONS = [
|
|
|
13772
13840
|
]
|
|
13773
13841
|
}
|
|
13774
13842
|
];
|
|
13775
|
-
// src/fishnet/rpc-
|
|
13843
|
+
// src/fishnet/generated/rpc-map/manifest.ts
|
|
13776
13844
|
var GENERATED_BUILD_FINGERPRINT = "53305f369c4176d4b7644d06ad7f0cdc5c9bda6563144d0ce8cff3d12c520158";
|
|
13777
13845
|
var GENERATED_METADATA_VERSION = 31;
|
|
13778
13846
|
|
|
13779
|
-
// src/fishnet/rpc-definitions
|
|
13847
|
+
// src/fishnet/generated/rpc-map/definitions.ts
|
|
13780
13848
|
var GENERATED_BEHAVIOURS = [
|
|
13781
13849
|
{ typeName: "BaseUnitController", rpcs: baseUnitControllerRpcs },
|
|
13782
13850
|
{ typeName: "BossGraveStone", rpcs: bossGraveStoneRpcs, syncTypes: bossGraveStoneSyncTypes },
|
|
@@ -13795,7 +13863,7 @@ var GENERATED_BEHAVIOURS = [
|
|
|
13795
13863
|
{ typeName: "SummoningComponent", rpcs: summoningComponentRpcs, syncTypes: summoningComponentSyncTypes }
|
|
13796
13864
|
];
|
|
13797
13865
|
|
|
13798
|
-
// src/fishnet/rpc-
|
|
13866
|
+
// src/fishnet/generated/rpc-map/index.ts
|
|
13799
13867
|
var FISHNET_RPC_MAP = {
|
|
13800
13868
|
buildFingerprint: GENERATED_BUILD_FINGERPRINT,
|
|
13801
13869
|
metadataVersion: GENERATED_METADATA_VERSION,
|
|
@@ -13810,7 +13878,7 @@ var BUNDLED_GAME_BUILD_FINGERPRINTS = [
|
|
|
13810
13878
|
CURRENT_GAME_BUILD_FINGERPRINT
|
|
13811
13879
|
];
|
|
13812
13880
|
|
|
13813
|
-
// src/fishnet/
|
|
13881
|
+
// src/fishnet/mapping/bundled-rpc-map.ts
|
|
13814
13882
|
var MAPS = {
|
|
13815
13883
|
[CURRENT_GAME_BUILD_FINGERPRINT]: FISHNET_RPC_MAP
|
|
13816
13884
|
};
|
|
@@ -13824,7 +13892,7 @@ function isBundledFingerprint(value) {
|
|
|
13824
13892
|
return Object.hasOwn(MAPS, value);
|
|
13825
13893
|
}
|
|
13826
13894
|
|
|
13827
|
-
// src/fishnet/map-
|
|
13895
|
+
// src/fishnet/generated/map-names.current.ts
|
|
13828
13896
|
var CURRENT_BUILD_MAP_NAMES = {
|
|
13829
13897
|
1: "Nevaris",
|
|
13830
13898
|
2: "Sunny Meadows 1",
|
|
@@ -13884,7 +13952,7 @@ var CURRENT_BUILD_MAP_NAMES = {
|
|
|
13884
13952
|
56: "Jail"
|
|
13885
13953
|
};
|
|
13886
13954
|
|
|
13887
|
-
// src/fishnet/map-
|
|
13955
|
+
// src/fishnet/mapping/map-names.ts
|
|
13888
13956
|
var MAPS2 = {
|
|
13889
13957
|
[CURRENT_GAME_BUILD_FINGERPRINT]: CURRENT_BUILD_MAP_NAMES
|
|
13890
13958
|
};
|
|
@@ -13892,7 +13960,7 @@ function resolveBundledMapName(mapId, buildFingerprint = CURRENT_GAME_BUILD_FING
|
|
|
13892
13960
|
return MAPS2[buildFingerprint]?.[mapId];
|
|
13893
13961
|
}
|
|
13894
13962
|
|
|
13895
|
-
// src/fishnet/
|
|
13963
|
+
// src/fishnet/decoding/fields.ts
|
|
13896
13964
|
function applyDecodedFields(packet, parameters, startOffset = 0) {
|
|
13897
13965
|
if (!parameters || parameters.length === 0)
|
|
13898
13966
|
return;
|
|
@@ -14128,7 +14196,7 @@ function decodeField(buffer, offset, codec) {
|
|
|
14128
14196
|
}
|
|
14129
14197
|
}
|
|
14130
14198
|
|
|
14131
|
-
// src/fishnet/quaternion
|
|
14199
|
+
// src/fishnet/decoding/quaternion.ts
|
|
14132
14200
|
var MAXIMUM = 1 / 1.414214;
|
|
14133
14201
|
var SCALE_10_BIT = (1 << 9) - 1;
|
|
14134
14202
|
var SCALE_21_BIT = (1 << 20) - 1;
|
|
@@ -14182,7 +14250,7 @@ function quaternionYaw(quaternion) {
|
|
|
14182
14250
|
return Math.atan2(2 * (w * y + x * z), 1 - 2 * (y * y + x * x));
|
|
14183
14251
|
}
|
|
14184
14252
|
|
|
14185
|
-
// src/fishnet/network-transform
|
|
14253
|
+
// src/fishnet/decoding/network-transform.ts
|
|
14186
14254
|
var COMPRESSED_SCALE = 100;
|
|
14187
14255
|
var ROTATION_WIDTHS = [16, 8, 4];
|
|
14188
14256
|
var AXIS_FLAGS = [
|
|
@@ -14303,7 +14371,94 @@ var NETWORK_TRANSFORM_RPC_NAMES = new Set([
|
|
|
14303
14371
|
"ServerUpdateTransform"
|
|
14304
14372
|
]);
|
|
14305
14373
|
|
|
14306
|
-
// src/fishnet/rpc-
|
|
14374
|
+
// src/fishnet/mapping/rpc-map.ts
|
|
14375
|
+
function lookupRpc(map, networkBehaviourType, packetName, hash8, hash16) {
|
|
14376
|
+
if (!map)
|
|
14377
|
+
return { resolution: "unresolved" };
|
|
14378
|
+
const hashes = new Set([hash8, ...hash16 === undefined ? [] : [hash16]]);
|
|
14379
|
+
const behaviours = networkBehaviourType ? map.behaviours.filter(({ typeName }) => typeName === networkBehaviourType) : map.behaviours;
|
|
14380
|
+
const matches = behaviours.flatMap(({ typeName, rpcs }) => rpcs.filter((rpc) => rpc.packetKind === packetName && hashes.has(rpc.wireHash)).map((rpc) => ({ ...rpc, typeName })));
|
|
14381
|
+
return definitionLookup(matches);
|
|
14382
|
+
}
|
|
14383
|
+
function signatureAdmitsPayload(lookup, payload) {
|
|
14384
|
+
const fit = tryDecodeFields(payload, lookup.parameters);
|
|
14385
|
+
return fit.undecodable || fit.complete && (fit.consumed === payload.length || admitsVerifiedPrefix(lookup.parameters));
|
|
14386
|
+
}
|
|
14387
|
+
function admitsVerifiedPrefix(parameters) {
|
|
14388
|
+
return parameters?.at(-1)?.prefix === true;
|
|
14389
|
+
}
|
|
14390
|
+
function rejectedByPayload(packet, lookup) {
|
|
14391
|
+
return lookup.resolution === "verified" && !signatureAdmitsPayload(lookup, packet.payload);
|
|
14392
|
+
}
|
|
14393
|
+
function applyRpcLookup(packet, lookup) {
|
|
14394
|
+
if (rejectedByPayload(packet, lookup)) {
|
|
14395
|
+
packet.rpcResolution = "unresolved";
|
|
14396
|
+
return;
|
|
14397
|
+
}
|
|
14398
|
+
packet.rpcResolution = lookup.resolution;
|
|
14399
|
+
if (lookup.resolution !== "verified")
|
|
14400
|
+
return;
|
|
14401
|
+
packet.rpcName = lookup.methodName;
|
|
14402
|
+
applyDecodedFields(packet, lookup.parameters);
|
|
14403
|
+
applyNetworkTransform(packet);
|
|
14404
|
+
}
|
|
14405
|
+
function applyNetworkTransform(packet) {
|
|
14406
|
+
if (packet.rpcName === undefined || !NETWORK_TRANSFORM_RPC_NAMES.has(packet.rpcName))
|
|
14407
|
+
return;
|
|
14408
|
+
const update = decodeNetworkTransformData(packet.payload);
|
|
14409
|
+
if (!update)
|
|
14410
|
+
return;
|
|
14411
|
+
packet.networkTransform = update;
|
|
14412
|
+
const fields = [];
|
|
14413
|
+
for (const [axis, value] of Object.entries(update.position)) {
|
|
14414
|
+
if (value !== undefined)
|
|
14415
|
+
fields.push({ name: `position.${axis}`, typeName: "System.Single", codec: "float32", value });
|
|
14416
|
+
}
|
|
14417
|
+
for (const [axis, value] of Object.entries(update.scale ?? {})) {
|
|
14418
|
+
if (value !== undefined)
|
|
14419
|
+
fields.push({ name: `scale.${axis}`, typeName: "System.Single", codec: "float32", value });
|
|
14420
|
+
}
|
|
14421
|
+
if (fields.length > 0)
|
|
14422
|
+
packet.decodedFields = [...packet.decodedFields ?? [], ...fields];
|
|
14423
|
+
packet.undecodedPayload = update.consumed < packet.payload.length ? packet.payload.subarray(update.consumed) : undefined;
|
|
14424
|
+
}
|
|
14425
|
+
function findBroadcast(map, wireHash) {
|
|
14426
|
+
if (!map)
|
|
14427
|
+
return;
|
|
14428
|
+
const matches = (map.broadcasts ?? []).filter((broadcast) => broadcast.wireHash === wireHash);
|
|
14429
|
+
return matches.length === 1 ? matches[0] : undefined;
|
|
14430
|
+
}
|
|
14431
|
+
function findSyncType(map, typeName, index) {
|
|
14432
|
+
if (!map || !typeName)
|
|
14433
|
+
return;
|
|
14434
|
+
const matches = map.behaviours.filter((behaviour) => behaviour.typeName === typeName).flatMap((behaviour) => behaviour.syncTypes ?? []).filter((sync) => sync.index === index);
|
|
14435
|
+
return matches.length === 1 ? matches[0] : undefined;
|
|
14436
|
+
}
|
|
14437
|
+
function findPrefab(map, collectionId, prefabId) {
|
|
14438
|
+
if (!map?.prefabs)
|
|
14439
|
+
return;
|
|
14440
|
+
const matches = map.prefabs.filter((layout) => layout.collectionId === collectionId && layout.prefabId === prefabId);
|
|
14441
|
+
return matches.length === 1 ? matches[0] : undefined;
|
|
14442
|
+
}
|
|
14443
|
+
function definitionLookup(matches) {
|
|
14444
|
+
const wireHashes = new Set(matches.map(({ wireHash }) => wireHash));
|
|
14445
|
+
if (matches.length === 1 && matches[0]) {
|
|
14446
|
+
return {
|
|
14447
|
+
resolution: "verified",
|
|
14448
|
+
wireHash: matches[0].wireHash,
|
|
14449
|
+
methodName: matches[0].methodName,
|
|
14450
|
+
parameters: matches[0].parameters
|
|
14451
|
+
};
|
|
14452
|
+
}
|
|
14453
|
+
const ambiguousBehaviourTypes = matches.length > 1 ? [...new Set(matches.map(({ typeName }) => typeName).filter((typeName) => typeName !== undefined))] : undefined;
|
|
14454
|
+
return {
|
|
14455
|
+
resolution: matches.length > 1 ? "ambiguous" : "unresolved",
|
|
14456
|
+
ambiguousBehaviourTypes: ambiguousBehaviourTypes?.length ? ambiguousBehaviourTypes : undefined,
|
|
14457
|
+
wireHash: wireHashes.size === 1 ? wireHashes.values().next().value : undefined
|
|
14458
|
+
};
|
|
14459
|
+
}
|
|
14460
|
+
|
|
14461
|
+
// src/fishnet/inference/rpc-inference.ts
|
|
14307
14462
|
function bindBehaviourTypes(registrations, map) {
|
|
14308
14463
|
if (!map)
|
|
14309
14464
|
return [];
|
|
@@ -14365,19 +14520,9 @@ function inferBehaviourType(map, packetName, hash8, hash16) {
|
|
|
14365
14520
|
if (!map)
|
|
14366
14521
|
return;
|
|
14367
14522
|
const hashes = new Set([hash8, ...hash16 === undefined ? [] : [hash16]]);
|
|
14368
|
-
const matches = map.behaviours.filter(({ rpcs }) =>
|
|
14369
|
-
return rpcs.some((rpc) => rpc.packetKind === packetName && hashes.has(rpc.wireHash));
|
|
14370
|
-
});
|
|
14523
|
+
const matches = map.behaviours.filter(({ rpcs }) => rpcs.some((rpc) => rpc.packetKind === packetName && hashes.has(rpc.wireHash)));
|
|
14371
14524
|
return matches.length === 1 ? matches[0]?.typeName : undefined;
|
|
14372
14525
|
}
|
|
14373
|
-
function lookupRpc(map, networkBehaviourType, packetName, hash8, hash16) {
|
|
14374
|
-
if (!map)
|
|
14375
|
-
return { resolution: "unresolved" };
|
|
14376
|
-
const hashes = new Set([hash8, ...hash16 === undefined ? [] : [hash16]]);
|
|
14377
|
-
const behaviours = networkBehaviourType ? map.behaviours.filter(({ typeName }) => typeName === networkBehaviourType) : map.behaviours;
|
|
14378
|
-
const matches = behaviours.flatMap(({ typeName, rpcs }) => rpcs.filter((rpc) => rpc.packetKind === packetName && hashes.has(rpc.wireHash)).map((rpc) => ({ ...rpc, typeName })));
|
|
14379
|
-
return definitionLookup(matches);
|
|
14380
|
-
}
|
|
14381
14526
|
function eliminateBoundBehaviourTypes(components, objectId, componentIndex, candidates) {
|
|
14382
14527
|
const selfKey = componentKey(objectId, componentIndex);
|
|
14383
14528
|
const prefix = `${objectId}:`;
|
|
@@ -14438,94 +14583,17 @@ function eliminateByPayloadShape(map, candidates, packetName, hash8, hash16, pay
|
|
|
14438
14583
|
const fit = tryDecodeFields(payload, rpc.parameters);
|
|
14439
14584
|
if (fit.undecodable)
|
|
14440
14585
|
return;
|
|
14441
|
-
if (fit.complete && (fit.consumed === payload.length ||
|
|
14586
|
+
if (fit.complete && (fit.consumed === payload.length || rpc.parameters?.at(-1)?.prefix === true))
|
|
14442
14587
|
fitting.add(typeName);
|
|
14443
14588
|
}
|
|
14444
14589
|
}
|
|
14445
14590
|
return fitting.size === 1 ? [...fitting][0] : undefined;
|
|
14446
14591
|
}
|
|
14447
|
-
function signatureAdmitsPayload(lookup, payload) {
|
|
14448
|
-
const fit = tryDecodeFields(payload, lookup.parameters);
|
|
14449
|
-
return fit.undecodable || fit.complete && (fit.consumed === payload.length || admitsVerifiedPrefix(lookup.parameters));
|
|
14450
|
-
}
|
|
14451
|
-
function admitsVerifiedPrefix(parameters) {
|
|
14452
|
-
return parameters?.at(-1)?.prefix === true;
|
|
14453
|
-
}
|
|
14454
|
-
function rejectedByPayload(packet, lookup) {
|
|
14455
|
-
return lookup.resolution === "verified" && !signatureAdmitsPayload(lookup, packet.payload);
|
|
14456
|
-
}
|
|
14457
|
-
function applyRpcLookup(packet, lookup) {
|
|
14458
|
-
if (rejectedByPayload(packet, lookup)) {
|
|
14459
|
-
packet.rpcResolution = "unresolved";
|
|
14460
|
-
return;
|
|
14461
|
-
}
|
|
14462
|
-
packet.rpcResolution = lookup.resolution;
|
|
14463
|
-
if (lookup.resolution !== "verified")
|
|
14464
|
-
return;
|
|
14465
|
-
packet.rpcName = lookup.methodName;
|
|
14466
|
-
applyDecodedFields(packet, lookup.parameters);
|
|
14467
|
-
applyNetworkTransform(packet);
|
|
14468
|
-
}
|
|
14469
|
-
function applyNetworkTransform(packet) {
|
|
14470
|
-
if (packet.rpcName === undefined || !NETWORK_TRANSFORM_RPC_NAMES.has(packet.rpcName))
|
|
14471
|
-
return;
|
|
14472
|
-
const update = decodeNetworkTransformData(packet.payload);
|
|
14473
|
-
if (!update)
|
|
14474
|
-
return;
|
|
14475
|
-
packet.networkTransform = update;
|
|
14476
|
-
const fields = [];
|
|
14477
|
-
for (const [axis, value] of Object.entries(update.position)) {
|
|
14478
|
-
if (value !== undefined)
|
|
14479
|
-
fields.push({ name: `position.${axis}`, typeName: "System.Single", codec: "float32", value });
|
|
14480
|
-
}
|
|
14481
|
-
for (const [axis, value] of Object.entries(update.scale ?? {})) {
|
|
14482
|
-
if (value !== undefined)
|
|
14483
|
-
fields.push({ name: `scale.${axis}`, typeName: "System.Single", codec: "float32", value });
|
|
14484
|
-
}
|
|
14485
|
-
if (fields.length > 0)
|
|
14486
|
-
packet.decodedFields = [...packet.decodedFields ?? [], ...fields];
|
|
14487
|
-
packet.undecodedPayload = update.consumed < packet.payload.length ? packet.payload.subarray(update.consumed) : undefined;
|
|
14488
|
-
}
|
|
14489
|
-
function findBroadcast(map, wireHash) {
|
|
14490
|
-
if (!map)
|
|
14491
|
-
return;
|
|
14492
|
-
const matches = (map.broadcasts ?? []).filter((broadcast) => broadcast.wireHash === wireHash);
|
|
14493
|
-
return matches.length === 1 ? matches[0] : undefined;
|
|
14494
|
-
}
|
|
14495
|
-
function findSyncType(map, typeName, index) {
|
|
14496
|
-
if (!map || !typeName)
|
|
14497
|
-
return;
|
|
14498
|
-
const matches = map.behaviours.filter((behaviour) => behaviour.typeName === typeName).flatMap((behaviour) => behaviour.syncTypes ?? []).filter((sync) => sync.index === index);
|
|
14499
|
-
return matches.length === 1 ? matches[0] : undefined;
|
|
14500
|
-
}
|
|
14501
14592
|
function rpcFingerprint(values) {
|
|
14502
14593
|
return values.map(({ wireHash, packetKind }) => `${wireHash}:${packetKind}`).sort().join(",");
|
|
14503
14594
|
}
|
|
14504
|
-
function definitionLookup(matches) {
|
|
14505
|
-
const wireHashes = new Set(matches.map(({ wireHash }) => wireHash));
|
|
14506
|
-
if (matches.length === 1 && matches[0]) {
|
|
14507
|
-
return {
|
|
14508
|
-
resolution: "verified",
|
|
14509
|
-
wireHash: matches[0].wireHash,
|
|
14510
|
-
methodName: matches[0].methodName,
|
|
14511
|
-
parameters: matches[0].parameters
|
|
14512
|
-
};
|
|
14513
|
-
}
|
|
14514
|
-
const ambiguousBehaviourTypes = matches.length > 1 ? [...new Set(matches.map(({ typeName }) => typeName).filter((typeName) => typeName !== undefined))] : undefined;
|
|
14515
|
-
return {
|
|
14516
|
-
resolution: matches.length > 1 ? "ambiguous" : "unresolved",
|
|
14517
|
-
ambiguousBehaviourTypes: ambiguousBehaviourTypes?.length ? ambiguousBehaviourTypes : undefined,
|
|
14518
|
-
wireHash: wireHashes.size === 1 ? wireHashes.values().next().value : undefined
|
|
14519
|
-
};
|
|
14520
|
-
}
|
|
14521
|
-
function findPrefab(map, collectionId, prefabId) {
|
|
14522
|
-
if (!map?.prefabs)
|
|
14523
|
-
return;
|
|
14524
|
-
const matches = map.prefabs.filter((layout) => layout.collectionId === collectionId && layout.prefabId === prefabId);
|
|
14525
|
-
return matches.length === 1 ? matches[0] : undefined;
|
|
14526
|
-
}
|
|
14527
14595
|
|
|
14528
|
-
// src/fishnet/spawn
|
|
14596
|
+
// src/fishnet/decoding/spawn.ts
|
|
14529
14597
|
function parseObjectSpawn(buffer, start, map) {
|
|
14530
14598
|
try {
|
|
14531
14599
|
requireBytes(buffer, start, 1, "spawn flags");
|
|
@@ -14676,7 +14744,7 @@ function parseLinkRegistrations(buffer, start, end, objectId) {
|
|
|
14676
14744
|
return offset === end ? registrations : undefined;
|
|
14677
14745
|
}
|
|
14678
14746
|
|
|
14679
|
-
// src/fishnet/
|
|
14747
|
+
// src/fishnet/decoding/messages.ts
|
|
14680
14748
|
function parseMessage(buffer, start, tick, bundleIndex, state, options) {
|
|
14681
14749
|
const packetId = buffer.readUInt16LE(start);
|
|
14682
14750
|
const packetName = classifyPacket(packetId);
|
|
@@ -15005,7 +15073,7 @@ function finish(entries) {
|
|
|
15005
15073
|
return entries.length > 0 ? entries : undefined;
|
|
15006
15074
|
}
|
|
15007
15075
|
|
|
15008
|
-
// src/fishnet/session
|
|
15076
|
+
// src/fishnet/decoding/session.ts
|
|
15009
15077
|
var MAX_SPLIT_CHUNKS = 1024;
|
|
15010
15078
|
var MAX_SPLIT_BYTES = 1024 * 1024;
|
|
15011
15079
|
var MAX_CONCURRENT_SPLITS_PER_CONNECTION = 32;
|
|
@@ -15181,7 +15249,7 @@ function removeObjectComponents(state, objectId) {
|
|
|
15181
15249
|
}
|
|
15182
15250
|
}
|
|
15183
15251
|
|
|
15184
|
-
// src/fishnet/decoder.ts
|
|
15252
|
+
// src/fishnet/decoding/decoder.ts
|
|
15185
15253
|
function decodeFishNetPayload(payload, options = { reliable: false }) {
|
|
15186
15254
|
if (payload.length < 6) {
|
|
15187
15255
|
throw new FishNetProtocolError(`FishNet payload needs a 4-byte tick and 2-byte packet id; received ${payload.length} bytes`);
|
|
@@ -15452,6 +15520,120 @@ function isUsable(device) {
|
|
|
15452
15520
|
return !device.loopback && device.addresses.length > 0 && !["bluetooth", "wan miniport", "vmware", "hyper-v", "zerotier"].some((value) => label.includes(value));
|
|
15453
15521
|
}
|
|
15454
15522
|
|
|
15523
|
+
// src/capture/duplicate-filter.ts
|
|
15524
|
+
var DUPLICATE_WINDOW_MS = 5;
|
|
15525
|
+
var DUPLICATE_ENTRY_LIMIT = 16384;
|
|
15526
|
+
|
|
15527
|
+
class DuplicateFilter {
|
|
15528
|
+
windowMs;
|
|
15529
|
+
entryLimit;
|
|
15530
|
+
seen = new Map;
|
|
15531
|
+
suppressed = 0;
|
|
15532
|
+
constructor(options = {}) {
|
|
15533
|
+
this.windowMs = options.windowMs ?? DUPLICATE_WINDOW_MS;
|
|
15534
|
+
this.entryLimit = options.entryLimit ?? DUPLICATE_ENTRY_LIMIT;
|
|
15535
|
+
}
|
|
15536
|
+
get suppressedCount() {
|
|
15537
|
+
return this.suppressed;
|
|
15538
|
+
}
|
|
15539
|
+
admit(packet, nowMs = Date.now()) {
|
|
15540
|
+
if (packet.payload.length === 0)
|
|
15541
|
+
return true;
|
|
15542
|
+
const key = digest(packet.protocol, packet.direction, localPortOf(packet), packet.payload);
|
|
15543
|
+
const previous = this.seen.get(key);
|
|
15544
|
+
if (previous !== undefined && nowMs - previous < this.windowMs) {
|
|
15545
|
+
this.suppressed += 1;
|
|
15546
|
+
return false;
|
|
15547
|
+
}
|
|
15548
|
+
this.seen.delete(key);
|
|
15549
|
+
this.seen.set(key, nowMs);
|
|
15550
|
+
this.evict(nowMs);
|
|
15551
|
+
return true;
|
|
15552
|
+
}
|
|
15553
|
+
takeSuppressedCount() {
|
|
15554
|
+
const total = this.suppressed;
|
|
15555
|
+
this.suppressed = 0;
|
|
15556
|
+
return total;
|
|
15557
|
+
}
|
|
15558
|
+
reset() {
|
|
15559
|
+
this.seen.clear();
|
|
15560
|
+
this.suppressed = 0;
|
|
15561
|
+
}
|
|
15562
|
+
evict(nowMs) {
|
|
15563
|
+
const cutoff = nowMs - this.windowMs;
|
|
15564
|
+
for (const [key, observedAt] of this.seen) {
|
|
15565
|
+
if (observedAt >= cutoff && this.seen.size <= this.entryLimit)
|
|
15566
|
+
break;
|
|
15567
|
+
this.seen.delete(key);
|
|
15568
|
+
}
|
|
15569
|
+
}
|
|
15570
|
+
}
|
|
15571
|
+
function digest(protocol, direction, localPort, payload) {
|
|
15572
|
+
return `${protocol}:${direction}:${localPort}:${payload.toString("latin1")}`;
|
|
15573
|
+
}
|
|
15574
|
+
function localPortOf(packet) {
|
|
15575
|
+
return packet.direction === "outbound" ? packet.sourcePort : packet.destinationPort;
|
|
15576
|
+
}
|
|
15577
|
+
|
|
15578
|
+
// src/capture/drop-diagnostics.ts
|
|
15579
|
+
var DROP_FLOW_LIMIT = 64;
|
|
15580
|
+
var DROP_FLOW_REPORT_COUNT = 5;
|
|
15581
|
+
var DROP_VERDICT_MIN_SAMPLES = 20;
|
|
15582
|
+
var DROP_VERDICT_THRESHOLD = 0.25;
|
|
15583
|
+
|
|
15584
|
+
class DropDiagnostics {
|
|
15585
|
+
flows = new Map;
|
|
15586
|
+
record(packet) {
|
|
15587
|
+
const flow = flowName(packet);
|
|
15588
|
+
let stats = this.flows.get(flow);
|
|
15589
|
+
if (!stats) {
|
|
15590
|
+
if (this.flows.size >= DROP_FLOW_LIMIT)
|
|
15591
|
+
return;
|
|
15592
|
+
stats = { packets: 0, sequenced: 0, consecutive: 0 };
|
|
15593
|
+
this.flows.set(flow, stats);
|
|
15594
|
+
}
|
|
15595
|
+
stats.packets += 1;
|
|
15596
|
+
this.countSequence(stats, packet);
|
|
15597
|
+
}
|
|
15598
|
+
topFlows(limit = DROP_FLOW_REPORT_COUNT) {
|
|
15599
|
+
return [...this.flows].sort(([, a], [, b]) => b.packets - a.packets).slice(0, limit).map(([flow, stats]) => ({ flow, packets: stats.packets, verdict: verdictFor(stats) }));
|
|
15600
|
+
}
|
|
15601
|
+
get hasGameTraffic() {
|
|
15602
|
+
return [...this.flows.values()].some((stats) => verdictFor(stats) === "game traffic");
|
|
15603
|
+
}
|
|
15604
|
+
reset() {
|
|
15605
|
+
this.flows.clear();
|
|
15606
|
+
}
|
|
15607
|
+
countSequence(stats, packet) {
|
|
15608
|
+
if (packet.protocol !== "udp" || packet.payload.length === 0)
|
|
15609
|
+
return;
|
|
15610
|
+
let decoded;
|
|
15611
|
+
try {
|
|
15612
|
+
decoded = decodeLiteNetLibDatagram(packet.payload);
|
|
15613
|
+
} catch {
|
|
15614
|
+
return;
|
|
15615
|
+
}
|
|
15616
|
+
for (const { packet: inner } of decoded) {
|
|
15617
|
+
const sequence = "sequence" in inner ? inner.sequence : undefined;
|
|
15618
|
+
if (sequence === undefined)
|
|
15619
|
+
continue;
|
|
15620
|
+
stats.sequenced += 1;
|
|
15621
|
+
if (stats.previous !== undefined && sequence === (stats.previous + 1) % 32768) {
|
|
15622
|
+
stats.consecutive += 1;
|
|
15623
|
+
}
|
|
15624
|
+
stats.previous = sequence;
|
|
15625
|
+
}
|
|
15626
|
+
}
|
|
15627
|
+
}
|
|
15628
|
+
function verdictFor(stats) {
|
|
15629
|
+
if (stats.sequenced < DROP_VERDICT_MIN_SAMPLES)
|
|
15630
|
+
return "unknown";
|
|
15631
|
+
return stats.consecutive / stats.sequenced >= DROP_VERDICT_THRESHOLD ? "game traffic" : "unrelated";
|
|
15632
|
+
}
|
|
15633
|
+
function flowName(packet) {
|
|
15634
|
+
return `${packet.protocol} ${packet.sourceIP}:${packet.sourcePort} -> ${packet.destinationIP}:${packet.destinationPort}`;
|
|
15635
|
+
}
|
|
15636
|
+
|
|
15455
15637
|
// src/capture/link-layer.ts
|
|
15456
15638
|
var DATA_LINK = {
|
|
15457
15639
|
NULL: 0,
|
|
@@ -15928,6 +16110,7 @@ var MAX_POLL_BATCH = 128;
|
|
|
15928
16110
|
var PENDING_PACKET_LIMIT = 16384;
|
|
15929
16111
|
var PENDING_PACKET_MAX_AGE_MS = TARGET_REFRESH_INTERVAL_MS * 5;
|
|
15930
16112
|
var PENDING_DROP_REPORT_MS = 1e4;
|
|
16113
|
+
var DUPLICATE_REPORT_MS = 1e4;
|
|
15931
16114
|
var systemRuntime = new SystemNpcapRuntime;
|
|
15932
16115
|
async function getNpcapStatus() {
|
|
15933
16116
|
return systemRuntime.status();
|
|
@@ -15952,6 +16135,11 @@ class PacketCapture extends EventEmitter {
|
|
|
15952
16135
|
currentConnectionId;
|
|
15953
16136
|
droppedPending = 0;
|
|
15954
16137
|
droppedReportedAtMs = 0;
|
|
16138
|
+
duplicateFilter = null;
|
|
16139
|
+
duplicateReportedAtMs = 0;
|
|
16140
|
+
relayObserved = false;
|
|
16141
|
+
dropDiagnostics = new DropDiagnostics;
|
|
16142
|
+
deviceLabel = "";
|
|
15955
16143
|
_state = "stopped";
|
|
15956
16144
|
constructor(dependencies = {}) {
|
|
15957
16145
|
super();
|
|
@@ -15987,10 +16175,12 @@ class PacketCapture extends EventEmitter {
|
|
|
15987
16175
|
this.decodeLiteNetLib = (config.decodeLiteNetLib ?? false) || decodeFishNet;
|
|
15988
16176
|
this.fishNetRpcMap = decodeFishNet ? config.fishNetRpcMap ?? loadBundledFishNetRpcMap(config.fishNetBuildFingerprint) : undefined;
|
|
15989
16177
|
this.fishNetSessionDecoder = decodeFishNet ? new FishNetSessionDecoder(this.fishNetRpcMap) : null;
|
|
16178
|
+
this.duplicateFilter = config.suppressDuplicates ?? true ? new DuplicateFilter : null;
|
|
15990
16179
|
const devices = await this.runtime.listDevices();
|
|
15991
16180
|
const resolved = await resolveCaptureDevice(devices, config.deviceName);
|
|
15992
16181
|
if (!resolved.device)
|
|
15993
16182
|
throw new Error("Npcap did not report a usable network adapter");
|
|
16183
|
+
this.deviceLabel = resolved.device.description || resolved.device.name;
|
|
15994
16184
|
const filter = config.filter ?? Array.from(new Set(protocols)).join(" or ");
|
|
15995
16185
|
this.session = await this.runtime.open(resolved.device, filter);
|
|
15996
16186
|
if (!supportsDataLink(this.session.dataLink)) {
|
|
@@ -16027,6 +16217,7 @@ class PacketCapture extends EventEmitter {
|
|
|
16027
16217
|
this.polling = true;
|
|
16028
16218
|
try {
|
|
16029
16219
|
this.flushPending();
|
|
16220
|
+
this.reportSuppressedDuplicates();
|
|
16030
16221
|
for (let index = 0;index < MAX_POLL_BATCH; index += 1) {
|
|
16031
16222
|
const captured = this.session.nextPacket();
|
|
16032
16223
|
if (!captured)
|
|
@@ -16054,7 +16245,7 @@ class PacketCapture extends EventEmitter {
|
|
|
16054
16245
|
this.emitTransportPacket(packet);
|
|
16055
16246
|
} else {
|
|
16056
16247
|
if (this.pending.length >= PENDING_PACKET_LIMIT)
|
|
16057
|
-
this.
|
|
16248
|
+
this.recordDropped(packet);
|
|
16058
16249
|
else
|
|
16059
16250
|
this.pending.push({ packet, observedAt: Date.now() });
|
|
16060
16251
|
}
|
|
@@ -16071,6 +16262,10 @@ class PacketCapture extends EventEmitter {
|
|
|
16071
16262
|
this.polling = false;
|
|
16072
16263
|
}
|
|
16073
16264
|
}
|
|
16265
|
+
recordDropped(packet) {
|
|
16266
|
+
this.droppedPending += 1;
|
|
16267
|
+
this.dropDiagnostics.record(packet);
|
|
16268
|
+
}
|
|
16074
16269
|
flushPending() {
|
|
16075
16270
|
if (!this.target)
|
|
16076
16271
|
return;
|
|
@@ -16082,7 +16277,7 @@ class PacketCapture extends EventEmitter {
|
|
|
16082
16277
|
const remaining = [];
|
|
16083
16278
|
for (const candidate of this.pending) {
|
|
16084
16279
|
if (candidate.observedAt < cutoff) {
|
|
16085
|
-
this.
|
|
16280
|
+
this.recordDropped(candidate.packet);
|
|
16086
16281
|
continue;
|
|
16087
16282
|
}
|
|
16088
16283
|
const direction = this.target.classify(candidate.packet);
|
|
@@ -16096,6 +16291,17 @@ class PacketCapture extends EventEmitter {
|
|
|
16096
16291
|
this.pending = remaining;
|
|
16097
16292
|
this.reportDroppedPending();
|
|
16098
16293
|
}
|
|
16294
|
+
reportSuppressedDuplicates() {
|
|
16295
|
+
if (!this.duplicateFilter || this.duplicateFilter.suppressedCount === 0)
|
|
16296
|
+
return;
|
|
16297
|
+
const now = Date.now();
|
|
16298
|
+
this.duplicateReportedAtMs ||= now;
|
|
16299
|
+
if (now - this.duplicateReportedAtMs < DUPLICATE_REPORT_MS)
|
|
16300
|
+
return;
|
|
16301
|
+
const total = this.duplicateFilter.takeSuppressedCount();
|
|
16302
|
+
this.emitSafely("warning", `suppressed ${total} duplicate packets on ${this.deviceLabel}; a VPN or proxy is relaying this traffic` + ", so select the adapter carrying it directly if decoding looks incomplete");
|
|
16303
|
+
this.duplicateReportedAtMs = now;
|
|
16304
|
+
}
|
|
16099
16305
|
reportDroppedPending() {
|
|
16100
16306
|
if (this.droppedPending === 0)
|
|
16101
16307
|
return;
|
|
@@ -16103,11 +16309,20 @@ class PacketCapture extends EventEmitter {
|
|
|
16103
16309
|
this.droppedReportedAtMs ||= now;
|
|
16104
16310
|
if (now - this.droppedReportedAtMs < PENDING_DROP_REPORT_MS)
|
|
16105
16311
|
return;
|
|
16106
|
-
this.
|
|
16312
|
+
const relay = this.relayObserved ? "; a VPN or proxy is also relaying traffic on this adapter" : "";
|
|
16313
|
+
this.emitSafely("warning", `gave up on ${this.droppedPending} packets that could not be attributed to the target process${relay}`);
|
|
16314
|
+
this.emitSafely("droppedFlows", this.dropDiagnostics.topFlows());
|
|
16315
|
+
if (this.dropDiagnostics.hasGameTraffic) {
|
|
16316
|
+
this.emitSafely("warning", "some discarded traffic carries sequenced game packets, so the target process does not own" + " every socket its traffic uses; capture that adapter directly or report these flows");
|
|
16317
|
+
}
|
|
16107
16318
|
this.droppedPending = 0;
|
|
16108
16319
|
this.droppedReportedAtMs = now;
|
|
16109
16320
|
}
|
|
16110
16321
|
emitTransportPacket(packet) {
|
|
16322
|
+
if (this.duplicateFilter && !this.duplicateFilter.admit(packet)) {
|
|
16323
|
+
this.relayObserved = true;
|
|
16324
|
+
return;
|
|
16325
|
+
}
|
|
16111
16326
|
if (packet.protocol === "tcp")
|
|
16112
16327
|
this.emitSafely("packet", packet);
|
|
16113
16328
|
else
|
|
@@ -16207,12 +16422,18 @@ class PacketCapture extends EventEmitter {
|
|
|
16207
16422
|
this.currentConnectionId = undefined;
|
|
16208
16423
|
this.droppedPending = 0;
|
|
16209
16424
|
this.droppedReportedAtMs = 0;
|
|
16425
|
+
this.duplicateFilter?.reset();
|
|
16426
|
+
this.duplicateFilter = null;
|
|
16427
|
+
this.duplicateReportedAtMs = 0;
|
|
16428
|
+
this.relayObserved = false;
|
|
16429
|
+
this.dropDiagnostics.reset();
|
|
16430
|
+
this.deviceLabel = "";
|
|
16210
16431
|
}
|
|
16211
16432
|
}
|
|
16212
16433
|
function connectionIdFor(packet) {
|
|
16213
16434
|
const udp = packet.udpPacket;
|
|
16214
|
-
const
|
|
16215
|
-
return
|
|
16435
|
+
const localPort = udp.direction === "outbound" ? udp.sourcePort : udp.destinationPort;
|
|
16436
|
+
return `local:${localPort}#${packet.packet.connectionNumber}`;
|
|
16216
16437
|
}
|
|
16217
16438
|
function inferDirection(ipPacket, device) {
|
|
16218
16439
|
if (ipPacket[0] >> 4 === 4 && ipPacket.length >= 20) {
|