mirror of
https://github.com/jwetzell/psn-js.git
synced 2026-08-17 13:23:43 +00:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c05e2447b0 | |||
| 4abc3968c1 | |||
| 06a974e557 | |||
| 7a5b027c68 | |||
| afebfe75b1 | |||
| 3e51737881 | |||
| 3a249ff52d | |||
| 9273f5a1a5 | |||
| 82d4e17ec9 | |||
| 8710e75a93 | |||
| 4eaedcdfaa | |||
| 90e1bd09a0 | |||
| 1358158333 | |||
| 521ef895d8 | |||
| d0645d4c93 | |||
| 8d99c0a647 | |||
| efc69c9345 |
Vendored
+2
-2
@@ -2,7 +2,7 @@
|
|||||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||||
"editor.formatOnSave": true,
|
"editor.formatOnSave": true,
|
||||||
"editor.codeActionsOnSave": {
|
"editor.codeActionsOnSave": {
|
||||||
"source.fixAll": true,
|
"source.fixAll": "explicit",
|
||||||
"source.organizeImports": true
|
"source.organizeImports": "explicit"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2024 Joel Wetzell
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@@ -13,8 +13,16 @@ typesecript implementation of the [PosiStageNet protocol](https://github.com/vyv
|
|||||||
const { Decoder } = require('@jwetzell/posistagenet')
|
const { Decoder } = require('@jwetzell/posistagenet')
|
||||||
const decoder = new Decoder()
|
const decoder = new Decoder()
|
||||||
|
|
||||||
const infoPacketBuffer = Buffer.from('5667348000000c0001000000000000000203010101000b00536572766572204e616d650200118001000d8000000900547261636b65722031','hex')
|
const infoPacketBuffer = new Uint8Array([
|
||||||
const dataPacketBuffer = Buffer.from('5567288000000c00010000000000000002030101010014800100108000000c000000803f0000803f0000803f','hex')
|
0x56, 0x67, 0x34, 0x80, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x01,
|
||||||
|
0x01, 0x01, 0x00, 0x0b, 0x00, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x4e, 0x61, 0x6d, 0x65, 0x02, 0x00, 0x11,
|
||||||
|
0x80, 0x01, 0x00, 0x0d, 0x80, 0x00, 0x00, 0x09, 0x00, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x72, 0x20, 0x31,
|
||||||
|
]);
|
||||||
|
const dataPacketBuffer = new Uint8Array([
|
||||||
|
0x55, 0x67, 0x28, 0x80, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x01,
|
||||||
|
0x01, 0x01, 0x00, 0x14, 0x80, 0x01, 0x00, 0x10, 0x80, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00,
|
||||||
|
0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f,
|
||||||
|
]);
|
||||||
|
|
||||||
decoder.decode(infoPacketBuffer)
|
decoder.decode(infoPacketBuffer)
|
||||||
decoder.decode(dataPacketBuffer)
|
decoder.decode(dataPacketBuffer)
|
||||||
@@ -49,12 +57,12 @@ const infoPackets = encoder.getInfoPackets(timestamp, trackers)
|
|||||||
|
|
||||||
dataPackets.forEach((dataPacket)=>{
|
dataPackets.forEach((dataPacket)=>{
|
||||||
console.log('send packet somehow')
|
console.log('send packet somehow')
|
||||||
console.log(dataPacket.toString('hex'))
|
console.log(dataPacket)
|
||||||
})
|
})
|
||||||
|
|
||||||
infoPackets.forEach((infoPacket)=>{
|
infoPackets.forEach((infoPacket)=>{
|
||||||
console.log('send packet somehow')
|
console.log('send packet somehow')
|
||||||
console.log(infoPacket.toString('hex'))
|
console.log(infoPacket)
|
||||||
})
|
})
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
const { Decoder } = require('../dist/cjs');
|
||||||
|
const decoder = new Decoder();
|
||||||
|
|
||||||
|
const infoPacketBuffer = new Uint8Array([
|
||||||
|
0x56, 0x67, 0x34, 0x80, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x01,
|
||||||
|
0x01, 0x01, 0x00, 0x0b, 0x00, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x4e, 0x61, 0x6d, 0x65, 0x02, 0x00, 0x11,
|
||||||
|
0x80, 0x01, 0x00, 0x0d, 0x80, 0x00, 0x00, 0x09, 0x00, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x72, 0x20, 0x31,
|
||||||
|
]);
|
||||||
|
const dataPacketBuffer = new Uint8Array([
|
||||||
|
0x55, 0x67, 0x28, 0x80, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x01,
|
||||||
|
0x01, 0x01, 0x00, 0x14, 0x80, 0x01, 0x00, 0x10, 0x80, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00,
|
||||||
|
0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f,
|
||||||
|
]);
|
||||||
|
|
||||||
|
decoder.decode(infoPacketBuffer);
|
||||||
|
decoder.decode(dataPacketBuffer);
|
||||||
|
|
||||||
|
// the system_name from info packets if available
|
||||||
|
console.log(decoder.system_name);
|
||||||
|
|
||||||
|
// map of trackers populated with any data that has been received
|
||||||
|
// this merges both info and data packet properties into one
|
||||||
|
console.log(decoder.trackers);
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
const { Encoder, Tracker } = require('../dist/cjs');
|
||||||
|
const encoder = new Encoder('Server Name', 2, 3); //server name, version high, version low
|
||||||
|
|
||||||
|
const trackers = [];
|
||||||
|
|
||||||
|
const tracker = new Tracker(1, 'Tracker 1'); // id, name
|
||||||
|
tracker.setPos(1.0, 1.0, 1.0); // x, y, z
|
||||||
|
|
||||||
|
trackers.push(tracker);
|
||||||
|
|
||||||
|
const timestamp = 1;
|
||||||
|
|
||||||
|
// these two calls return an array of Buffers due to potential splitting that might take place because of max UDP packet size
|
||||||
|
const dataPackets = encoder.getDataPackets(timestamp, trackers);
|
||||||
|
const infoPackets = encoder.getInfoPackets(timestamp, trackers);
|
||||||
|
|
||||||
|
dataPackets.forEach((dataPacket) => {
|
||||||
|
console.log('send packet somehow');
|
||||||
|
console.log(dataPacket);
|
||||||
|
});
|
||||||
|
|
||||||
|
infoPackets.forEach((infoPacket) => {
|
||||||
|
console.log('send packet somehow');
|
||||||
|
console.log(infoPacket);
|
||||||
|
});
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
// recreation of psn_client.cpp example from https://github.com/vyv/psn-cpp
|
// recreation of psn_client.cpp example from https://github.com/vyv/psn-cpp
|
||||||
const dgram = require('dgram');
|
const dgram = require('dgram');
|
||||||
const { Decoder } = require('../dist');
|
const { Decoder } = require('../dist/cjs');
|
||||||
|
|
||||||
const client = dgram.createSocket('udp4');
|
const client = dgram.createSocket('udp4');
|
||||||
const decoder = new Decoder();
|
const decoder = new Decoder();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// recreation of psn_server.cpp example from https://github.com/vyv/psn-cpp
|
// recreation of psn_server.cpp example from https://github.com/vyv/psn-cpp
|
||||||
const dgram = require('dgram');
|
const dgram = require('dgram');
|
||||||
const { Encoder, Tracker, Decoder } = require('../dist');
|
const { Encoder, Tracker, Decoder } = require('../dist/cjs');
|
||||||
|
|
||||||
const client = dgram.createSocket('udp4');
|
const client = dgram.createSocket('udp4');
|
||||||
const encoder = new Encoder('Test PSN Server', 2, 0);
|
const encoder = new Encoder('Test PSN Server', 2, 0);
|
||||||
|
|||||||
Generated
+11
-11
@@ -1,18 +1,18 @@
|
|||||||
{
|
{
|
||||||
"name": "@jwetzell/posistagenet",
|
"name": "@jwetzell/posistagenet",
|
||||||
"version": "0.4.7",
|
"version": "1.1.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@jwetzell/posistagenet",
|
"name": "@jwetzell/posistagenet",
|
||||||
"version": "0.4.7",
|
"version": "1.1.0",
|
||||||
"license": "ISC",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "22.7.4",
|
"@types/node": "22.7.7",
|
||||||
"prettier": "3.3.3",
|
"prettier": "3.3.3",
|
||||||
"rimraf": "6.0.1",
|
"rimraf": "6.0.1",
|
||||||
"typescript": "5.6.2"
|
"typescript": "5.6.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@isaacs/cliui": {
|
"node_modules/@isaacs/cliui": {
|
||||||
@@ -43,9 +43,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "22.7.4",
|
"version": "22.7.7",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.4.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.7.tgz",
|
||||||
"integrity": "sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg==",
|
"integrity": "sha512-SRxCrrg9CL/y54aiMCG3edPKdprgMVGDXjA3gB8UmmBW5TcXzRUYAh8EWzTnSJFAd1rgImPELza+A3bJ+qxz8Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~6.19.2"
|
"undici-types": "~6.19.2"
|
||||||
@@ -434,9 +434,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/typescript": {
|
"node_modules/typescript": {
|
||||||
"version": "5.6.2",
|
"version": "5.6.3",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz",
|
||||||
"integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==",
|
"integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsc": "bin/tsc",
|
"tsc": "bin/tsc",
|
||||||
|
|||||||
+18
-7
@@ -1,12 +1,23 @@
|
|||||||
{
|
{
|
||||||
"name": "@jwetzell/posistagenet",
|
"name": "@jwetzell/posistagenet",
|
||||||
"version": "0.4.7",
|
"version": "1.1.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "dist/index.js",
|
"main": "./dist/cjs/index.js",
|
||||||
"types": "dist/index.d.ts",
|
"module": "./dist/esm/index.js",
|
||||||
|
"types": "./dist/types/index.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"import": "./dist/esm/index.js",
|
||||||
|
"require": "./dist/cjs/index.js",
|
||||||
|
"types": "./dist/types/index.d.ts"
|
||||||
|
}
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prebuild": "rimraf dist",
|
"prebuild": "rimraf dist",
|
||||||
"build": "tsc",
|
"build": "npm run build:cjs && npm run build:esm && npm run build:types",
|
||||||
|
"build:cjs": "tsc -p tsconfig.cjs.json",
|
||||||
|
"build:esm": "tsc -p tsconfig.esm.json",
|
||||||
|
"build:types": "tsc -p tsconfig.types.json",
|
||||||
"example:client": "node examples/psn_client.js",
|
"example:client": "node examples/psn_client.js",
|
||||||
"example:server": "node examples/psn_server.js",
|
"example:server": "node examples/psn_server.js",
|
||||||
"prepublishOnly": "npm run build"
|
"prepublishOnly": "npm run build"
|
||||||
@@ -20,11 +31,11 @@
|
|||||||
"url": "https://jwetzell.com"
|
"url": "https://jwetzell.com"
|
||||||
},
|
},
|
||||||
"repository": "https://github.com/jwetzell/psn-js",
|
"repository": "https://github.com/jwetzell/psn-js",
|
||||||
"license": "ISC",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "22.7.4",
|
"@types/node": "22.7.7",
|
||||||
"prettier": "3.3.3",
|
"prettier": "3.3.3",
|
||||||
"rimraf": "6.0.1",
|
"rimraf": "6.0.1",
|
||||||
"typescript": "5.6.2"
|
"typescript": "5.6.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -47,7 +47,7 @@ export class Decoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO(jwetzell): add invalid frame id decoding. Scenario where a frame id is reused before one is complete
|
// TODO(jwetzell): add invalid frame id decoding. Scenario where a frame id is reused before one is complete
|
||||||
decode(packetBuf: Buffer): DataPacketChunk | InfoPacketChunk | undefined {
|
decode(packetBuf: Uint8Array): DataPacketChunk | InfoPacketChunk | undefined {
|
||||||
const packet = Decoders.Packet(packetBuf);
|
const packet = Decoders.Packet(packetBuf);
|
||||||
if (packet === undefined) {
|
if (packet === undefined) {
|
||||||
return packet;
|
return packet;
|
||||||
|
|||||||
@@ -1,17 +1,18 @@
|
|||||||
import { Chunk } from '../models/chunk';
|
import { Chunk } from '../models/chunk';
|
||||||
|
|
||||||
export default (buffer: Buffer, dataDecoder: Function): Chunk => {
|
export default (buffer: Uint8Array, dataDecoder: Function): Chunk => {
|
||||||
let offset = 0;
|
let offset = 0;
|
||||||
|
const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
||||||
const chunk: Chunk = {};
|
const chunk: Chunk = {};
|
||||||
chunk.id = buffer.readUInt16LE(offset);
|
chunk.id = view.getUint16(offset, true);
|
||||||
offset += 2;
|
offset += 2;
|
||||||
|
|
||||||
// NOTE(jwetzell): this data is split up as 1 bit for has_subchunks and 15 bits for the data_len
|
// NOTE(jwetzell): this data is split up as 1 bit for has_subchunks and 15 bits for the data_len
|
||||||
const combinedLengthAndFlag = buffer.readUInt16LE(offset);
|
const combinedLengthAndFlag = view.getUint16(offset, true);
|
||||||
chunk.has_subchunks = combinedLengthAndFlag > 32768;
|
chunk.has_subchunks = combinedLengthAndFlag > 32768;
|
||||||
chunk.data_len = chunk.has_subchunks ? combinedLengthAndFlag - 32768 : combinedLengthAndFlag;
|
chunk.data_len = chunk.has_subchunks ? combinedLengthAndFlag - 32768 : combinedLengthAndFlag;
|
||||||
offset += 2;
|
offset += 2;
|
||||||
chunk.chunk_data = buffer.subarray(offset, offset + chunk.data_len);
|
chunk.chunk_data = buffer.slice(offset, offset + chunk.data_len);
|
||||||
|
|
||||||
dataDecoder(chunk);
|
dataDecoder(chunk);
|
||||||
return chunk;
|
return chunk;
|
||||||
|
|||||||
@@ -6,17 +6,22 @@ function decodeDataPacketChunk(dataPacketChunk: DataPacketChunk) {
|
|||||||
if (dataPacketChunk.has_subchunks && dataPacketChunk.chunk_data && dataPacketChunk.data_len) {
|
if (dataPacketChunk.has_subchunks && dataPacketChunk.chunk_data && dataPacketChunk.data_len) {
|
||||||
let offset = 0;
|
let offset = 0;
|
||||||
while (offset < dataPacketChunk.data_len) {
|
while (offset < dataPacketChunk.data_len) {
|
||||||
const chunkId = dataPacketChunk.chunk_data.readUInt16LE(offset);
|
const view = new DataView(
|
||||||
|
dataPacketChunk.chunk_data.buffer,
|
||||||
|
dataPacketChunk.chunk_data.byteOffset,
|
||||||
|
dataPacketChunk.chunk_data.byteLength
|
||||||
|
);
|
||||||
|
const chunkId = view.getUint16(offset, true);
|
||||||
switch (chunkId) {
|
switch (chunkId) {
|
||||||
case 0x0000:
|
case 0x0000:
|
||||||
dataPacketChunk.packet_header = Decoders.PacketHeaderChunk(dataPacketChunk.chunk_data.subarray(offset));
|
dataPacketChunk.packet_header = Decoders.PacketHeaderChunk(dataPacketChunk.chunk_data.slice(offset));
|
||||||
offset += Constants.CHUNK_HEADER_SIZE;
|
offset += Constants.CHUNK_HEADER_SIZE;
|
||||||
if (dataPacketChunk.packet_header?.data_len) {
|
if (dataPacketChunk.packet_header?.data_len) {
|
||||||
offset += dataPacketChunk.packet_header.data_len;
|
offset += dataPacketChunk.packet_header.data_len;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x0001:
|
case 0x0001:
|
||||||
dataPacketChunk.tracker_list = Decoders.DataTrackerListChunk(dataPacketChunk.chunk_data.subarray(offset));
|
dataPacketChunk.tracker_list = Decoders.DataTrackerListChunk(dataPacketChunk.chunk_data.slice(offset));
|
||||||
offset += Constants.CHUNK_HEADER_SIZE;
|
offset += Constants.CHUNK_HEADER_SIZE;
|
||||||
if (dataPacketChunk.tracker_list.data_len) {
|
if (dataPacketChunk.tracker_list.data_len) {
|
||||||
offset += dataPacketChunk.tracker_list.data_len;
|
offset += dataPacketChunk.tracker_list.data_len;
|
||||||
@@ -29,4 +34,5 @@ function decodeDataPacketChunk(dataPacketChunk: DataPacketChunk) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default (buffer: Buffer): DataPacketChunk => Decoders.Chunk(buffer, decodeDataPacketChunk) as DataPacketChunk;
|
export default (buffer: Uint8Array): DataPacketChunk =>
|
||||||
|
Decoders.Chunk(buffer, decodeDataPacketChunk) as DataPacketChunk;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ function decodeTrackerChunk(trackerChunk: DataTrackerChunk) {
|
|||||||
if (trackerChunk.chunk_data && trackerChunk.data_len) {
|
if (trackerChunk.chunk_data && trackerChunk.data_len) {
|
||||||
let offset = 0;
|
let offset = 0;
|
||||||
while (offset < trackerChunk.data_len) {
|
while (offset < trackerChunk.data_len) {
|
||||||
const trackerFieldChunk = Decoders.DataTrackerFieldChunk(trackerChunk.chunk_data.subarray(offset));
|
const trackerFieldChunk = Decoders.DataTrackerFieldChunk(trackerChunk.chunk_data.slice(offset));
|
||||||
offset += Constants.CHUNK_HEADER_SIZE;
|
offset += Constants.CHUNK_HEADER_SIZE;
|
||||||
if (trackerFieldChunk.data_len) {
|
if (trackerFieldChunk.data_len) {
|
||||||
offset += trackerFieldChunk.data_len;
|
offset += trackerFieldChunk.data_len;
|
||||||
@@ -40,4 +40,4 @@ function decodeTrackerChunk(trackerChunk: DataTrackerChunk) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default (buffer: Buffer): DataTrackerChunk => Decoders.Chunk(buffer, decodeTrackerChunk) as DataTrackerChunk;
|
export default (buffer: Uint8Array): DataTrackerChunk => Decoders.Chunk(buffer, decodeTrackerChunk) as DataTrackerChunk;
|
||||||
|
|||||||
@@ -5,9 +5,14 @@ import { DataTrackerFieldChunk } from '../../models/data/data-tracker-field-chun
|
|||||||
|
|
||||||
function readXYZ(trackerFieldChunk: DataTrackerFieldChunk, prefix: string = '') {
|
function readXYZ(trackerFieldChunk: DataTrackerFieldChunk, prefix: string = '') {
|
||||||
if (trackerFieldChunk.chunk_data) {
|
if (trackerFieldChunk.chunk_data) {
|
||||||
trackerFieldChunk[`${prefix}x`] = trackerFieldChunk.chunk_data.readFloatLE(0);
|
const view = new DataView(
|
||||||
trackerFieldChunk[`${prefix}y`] = trackerFieldChunk.chunk_data.readFloatLE(4);
|
trackerFieldChunk.chunk_data.buffer,
|
||||||
trackerFieldChunk[`${prefix}z`] = trackerFieldChunk.chunk_data.readFloatLE(8);
|
trackerFieldChunk.chunk_data.byteOffset,
|
||||||
|
trackerFieldChunk.chunk_data.byteLength
|
||||||
|
);
|
||||||
|
trackerFieldChunk[`${prefix}x`] = view.getFloat32(0, true);
|
||||||
|
trackerFieldChunk[`${prefix}y`] = view.getFloat32(4, true);
|
||||||
|
trackerFieldChunk[`${prefix}z`] = view.getFloat32(8, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function decodeTrackerFieldChunk(trackerFieldChunk: DataTrackerFieldChunk) {
|
function decodeTrackerFieldChunk(trackerFieldChunk: DataTrackerFieldChunk) {
|
||||||
@@ -24,7 +29,12 @@ function decodeTrackerFieldChunk(trackerFieldChunk: DataTrackerFieldChunk) {
|
|||||||
break;
|
break;
|
||||||
case 0x0003:
|
case 0x0003:
|
||||||
if (trackerFieldChunk.chunk_data) {
|
if (trackerFieldChunk.chunk_data) {
|
||||||
trackerFieldChunk.validity = trackerFieldChunk.chunk_data.readFloatLE();
|
const view = new DataView(
|
||||||
|
trackerFieldChunk.chunk_data.buffer,
|
||||||
|
trackerFieldChunk.chunk_data.byteOffset,
|
||||||
|
trackerFieldChunk.chunk_data.byteLength
|
||||||
|
);
|
||||||
|
trackerFieldChunk.validity = view.getFloat32(0, true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x0004:
|
case 0x0004:
|
||||||
@@ -35,7 +45,12 @@ function decodeTrackerFieldChunk(trackerFieldChunk: DataTrackerFieldChunk) {
|
|||||||
break;
|
break;
|
||||||
case 0x0006:
|
case 0x0006:
|
||||||
if (trackerFieldChunk.chunk_data) {
|
if (trackerFieldChunk.chunk_data) {
|
||||||
trackerFieldChunk.tracker_timestamp = trackerFieldChunk.chunk_data.readBigUInt64LE();
|
const view = new DataView(
|
||||||
|
trackerFieldChunk.chunk_data.buffer,
|
||||||
|
trackerFieldChunk.chunk_data.byteOffset,
|
||||||
|
trackerFieldChunk.chunk_data.byteLength
|
||||||
|
);
|
||||||
|
trackerFieldChunk.tracker_timestamp = view.getBigUint64(0, true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -44,5 +59,5 @@ function decodeTrackerFieldChunk(trackerFieldChunk: DataTrackerFieldChunk) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default (buffer: Buffer): DataTrackerFieldChunk =>
|
export default (buffer: Uint8Array): DataTrackerFieldChunk =>
|
||||||
Decoders.Chunk(buffer, decodeTrackerFieldChunk) as DataTrackerFieldChunk;
|
Decoders.Chunk(buffer, decodeTrackerFieldChunk) as DataTrackerFieldChunk;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ function decodeDataTrackerListChunk(dataTrackerListChunk: DataTrackerListChunk)
|
|||||||
let offset = 0;
|
let offset = 0;
|
||||||
if (dataTrackerListChunk.chunk_data) {
|
if (dataTrackerListChunk.chunk_data) {
|
||||||
while (offset < dataTrackerListChunk.chunk_data.length) {
|
while (offset < dataTrackerListChunk.chunk_data.length) {
|
||||||
const trackerChunk = Decoders.DataTrackerChunk(dataTrackerListChunk.chunk_data.subarray(offset));
|
const trackerChunk = Decoders.DataTrackerChunk(dataTrackerListChunk.chunk_data.slice(offset));
|
||||||
offset += Constants.CHUNK_HEADER_SIZE;
|
offset += Constants.CHUNK_HEADER_SIZE;
|
||||||
if (trackerChunk.data_len) {
|
if (trackerChunk.data_len) {
|
||||||
offset += trackerChunk.data_len;
|
offset += trackerChunk.data_len;
|
||||||
@@ -20,5 +20,5 @@ function decodeDataTrackerListChunk(dataTrackerListChunk: DataTrackerListChunk)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export default (buffer: Buffer): DataTrackerListChunk =>
|
export default (buffer: Uint8Array): DataTrackerListChunk =>
|
||||||
Decoders.Chunk(buffer, decodeDataTrackerListChunk) as DataTrackerListChunk;
|
Decoders.Chunk(buffer, decodeDataTrackerListChunk) as DataTrackerListChunk;
|
||||||
|
|||||||
@@ -6,24 +6,29 @@ function decodeInfoPacketChunk(infoPacketChunk: InfoPacketChunk) {
|
|||||||
if (infoPacketChunk.has_subchunks && infoPacketChunk.chunk_data && infoPacketChunk.data_len) {
|
if (infoPacketChunk.has_subchunks && infoPacketChunk.chunk_data && infoPacketChunk.data_len) {
|
||||||
let offset = 0;
|
let offset = 0;
|
||||||
while (offset < infoPacketChunk.data_len) {
|
while (offset < infoPacketChunk.data_len) {
|
||||||
const chunkId = infoPacketChunk.chunk_data.readUInt16LE(offset);
|
const view = new DataView(
|
||||||
|
infoPacketChunk.chunk_data.buffer,
|
||||||
|
infoPacketChunk.chunk_data.byteOffset,
|
||||||
|
infoPacketChunk.chunk_data.byteLength
|
||||||
|
);
|
||||||
|
const chunkId = view.getUint16(offset, true);
|
||||||
switch (chunkId) {
|
switch (chunkId) {
|
||||||
case 0x0000:
|
case 0x0000:
|
||||||
infoPacketChunk.packet_header = Decoders.PacketHeaderChunk(infoPacketChunk.chunk_data.subarray(offset));
|
infoPacketChunk.packet_header = Decoders.PacketHeaderChunk(infoPacketChunk.chunk_data.slice(offset));
|
||||||
offset += Constants.CHUNK_HEADER_SIZE;
|
offset += Constants.CHUNK_HEADER_SIZE;
|
||||||
if (infoPacketChunk.packet_header?.data_len) {
|
if (infoPacketChunk.packet_header?.data_len) {
|
||||||
offset += infoPacketChunk.packet_header.data_len;
|
offset += infoPacketChunk.packet_header.data_len;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x0001:
|
case 0x0001:
|
||||||
infoPacketChunk.system_name = Decoders.InfoSystemNameChunk(infoPacketChunk.chunk_data.subarray(offset));
|
infoPacketChunk.system_name = Decoders.InfoSystemNameChunk(infoPacketChunk.chunk_data.slice(offset));
|
||||||
offset += Constants.CHUNK_HEADER_SIZE;
|
offset += Constants.CHUNK_HEADER_SIZE;
|
||||||
if (infoPacketChunk.system_name?.data_len) {
|
if (infoPacketChunk.system_name?.data_len) {
|
||||||
offset += infoPacketChunk.system_name.data_len;
|
offset += infoPacketChunk.system_name.data_len;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x0002:
|
case 0x0002:
|
||||||
infoPacketChunk.tracker_list = Decoders.InfoTrackerListChunk(infoPacketChunk.chunk_data.subarray(offset));
|
infoPacketChunk.tracker_list = Decoders.InfoTrackerListChunk(infoPacketChunk.chunk_data.slice(offset));
|
||||||
offset += Constants.CHUNK_HEADER_SIZE;
|
offset += Constants.CHUNK_HEADER_SIZE;
|
||||||
if (infoPacketChunk.tracker_list?.data_len) {
|
if (infoPacketChunk.tracker_list?.data_len) {
|
||||||
offset += infoPacketChunk.tracker_list.data_len;
|
offset += infoPacketChunk.tracker_list.data_len;
|
||||||
@@ -36,4 +41,5 @@ function decodeInfoPacketChunk(infoPacketChunk: InfoPacketChunk) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default (buffer: Buffer): InfoPacketChunk => Decoders.Chunk(buffer, decodeInfoPacketChunk) as InfoPacketChunk;
|
export default (buffer: Uint8Array): InfoPacketChunk =>
|
||||||
|
Decoders.Chunk(buffer, decodeInfoPacketChunk) as InfoPacketChunk;
|
||||||
|
|||||||
@@ -3,9 +3,11 @@ import { InfoSystemNameChunk } from '../../models/info/info-system-name-chunk';
|
|||||||
|
|
||||||
function decodeSystemNameChunk(systemNameChunk: InfoSystemNameChunk) {
|
function decodeSystemNameChunk(systemNameChunk: InfoSystemNameChunk) {
|
||||||
if (systemNameChunk.chunk_data !== undefined && systemNameChunk.data_len !== undefined) {
|
if (systemNameChunk.chunk_data !== undefined && systemNameChunk.data_len !== undefined) {
|
||||||
systemNameChunk.system_name = systemNameChunk.chunk_data.subarray(0, systemNameChunk.data_len).toString();
|
systemNameChunk.system_name = new TextDecoder().decode(
|
||||||
|
systemNameChunk.chunk_data.slice(0, systemNameChunk.data_len)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default (buffer: Buffer): InfoSystemNameChunk =>
|
export default (buffer: Uint8Array): InfoSystemNameChunk =>
|
||||||
Decoders.Chunk(buffer, decodeSystemNameChunk) as InfoSystemNameChunk;
|
Decoders.Chunk(buffer, decodeSystemNameChunk) as InfoSystemNameChunk;
|
||||||
|
|||||||
@@ -6,10 +6,15 @@ function decodeInfoTrackerChunk(infoTrackerChunk: InfoTrackerChunk) {
|
|||||||
if (infoTrackerChunk.has_subchunks && infoTrackerChunk.chunk_data && infoTrackerChunk.data_len) {
|
if (infoTrackerChunk.has_subchunks && infoTrackerChunk.chunk_data && infoTrackerChunk.data_len) {
|
||||||
let offset = 0;
|
let offset = 0;
|
||||||
while (offset < infoTrackerChunk.data_len) {
|
while (offset < infoTrackerChunk.data_len) {
|
||||||
const chunkId = infoTrackerChunk.chunk_data.readUInt16LE(offset);
|
const view = new DataView(
|
||||||
|
infoTrackerChunk.chunk_data.buffer,
|
||||||
|
infoTrackerChunk.chunk_data.byteOffset,
|
||||||
|
infoTrackerChunk.chunk_data.byteLength
|
||||||
|
);
|
||||||
|
const chunkId = view.getUint16(offset, true);
|
||||||
switch (chunkId) {
|
switch (chunkId) {
|
||||||
case 0x0000:
|
case 0x0000:
|
||||||
infoTrackerChunk.tracker_name = Decoders.InfoTrackerNameChunk(infoTrackerChunk.chunk_data.subarray(offset));
|
infoTrackerChunk.tracker_name = Decoders.InfoTrackerNameChunk(infoTrackerChunk.chunk_data.slice(offset));
|
||||||
offset += Constants.CHUNK_HEADER_SIZE;
|
offset += Constants.CHUNK_HEADER_SIZE;
|
||||||
if (infoTrackerChunk.tracker_name?.data_len) {
|
if (infoTrackerChunk.tracker_name?.data_len) {
|
||||||
offset += infoTrackerChunk?.tracker_name?.data_len;
|
offset += infoTrackerChunk?.tracker_name?.data_len;
|
||||||
@@ -23,4 +28,4 @@ function decodeInfoTrackerChunk(infoTrackerChunk: InfoTrackerChunk) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default (buffer: Buffer): InfoTrackerChunk => Decoders.Chunk(buffer, decodeInfoTrackerChunk);
|
export default (buffer: Uint8Array): InfoTrackerChunk => Decoders.Chunk(buffer, decodeInfoTrackerChunk);
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ function decodeInfoTrackerListChunk(infoTrackerListChunk: InfoTrackerListChunk)
|
|||||||
let offset = 0;
|
let offset = 0;
|
||||||
if (infoTrackerListChunk.data_len) {
|
if (infoTrackerListChunk.data_len) {
|
||||||
while (offset < infoTrackerListChunk.data_len) {
|
while (offset < infoTrackerListChunk.data_len) {
|
||||||
const trackerChunk = Decoders.InfoTrackerChunk(infoTrackerListChunk.chunk_data.subarray(offset));
|
const trackerChunk = Decoders.InfoTrackerChunk(infoTrackerListChunk.chunk_data.slice(offset));
|
||||||
offset += Constants.CHUNK_HEADER_SIZE;
|
offset += Constants.CHUNK_HEADER_SIZE;
|
||||||
if (trackerChunk.data_len) {
|
if (trackerChunk.data_len) {
|
||||||
offset += trackerChunk.data_len;
|
offset += trackerChunk.data_len;
|
||||||
@@ -20,5 +20,5 @@ function decodeInfoTrackerListChunk(infoTrackerListChunk: InfoTrackerListChunk)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export default (buffer: Buffer): InfoTrackerListChunk =>
|
export default (buffer: Uint8Array): InfoTrackerListChunk =>
|
||||||
Decoders.Chunk(buffer, decodeInfoTrackerListChunk) as InfoTrackerListChunk;
|
Decoders.Chunk(buffer, decodeInfoTrackerListChunk) as InfoTrackerListChunk;
|
||||||
|
|||||||
@@ -3,8 +3,10 @@ import { InfoTrackerNameChunk } from '../../models/info/info-tracker-name-chunk'
|
|||||||
|
|
||||||
function decodeTrackerNameChunk(trackerNameChunk: InfoTrackerNameChunk) {
|
function decodeTrackerNameChunk(trackerNameChunk: InfoTrackerNameChunk) {
|
||||||
if (trackerNameChunk.chunk_data !== undefined && trackerNameChunk.data_len !== undefined) {
|
if (trackerNameChunk.chunk_data !== undefined && trackerNameChunk.data_len !== undefined) {
|
||||||
trackerNameChunk.tracker_name = trackerNameChunk.chunk_data.subarray(0, trackerNameChunk.data_len).toString();
|
trackerNameChunk.tracker_name = new TextDecoder().decode(
|
||||||
|
trackerNameChunk.chunk_data.slice(0, trackerNameChunk.data_len)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export default (buffer: Buffer): InfoTrackerNameChunk =>
|
export default (buffer: Uint8Array): InfoTrackerNameChunk =>
|
||||||
Decoders.Chunk(buffer, decodeTrackerNameChunk) as InfoTrackerNameChunk;
|
Decoders.Chunk(buffer, decodeTrackerNameChunk) as InfoTrackerNameChunk;
|
||||||
|
|||||||
@@ -3,12 +3,19 @@ import { PacketHeaderChunk } from '../models/packet-header-chunk';
|
|||||||
|
|
||||||
function decodePacketHeaderChunk(packetHeaderChunk: PacketHeaderChunk) {
|
function decodePacketHeaderChunk(packetHeaderChunk: PacketHeaderChunk) {
|
||||||
if (packetHeaderChunk.chunk_data) {
|
if (packetHeaderChunk.chunk_data) {
|
||||||
packetHeaderChunk.packet_timestamp = packetHeaderChunk.chunk_data.readBigUInt64LE(0);
|
const view = new DataView(
|
||||||
packetHeaderChunk.version_high = packetHeaderChunk.chunk_data.readUInt8(8);
|
packetHeaderChunk.chunk_data.buffer,
|
||||||
packetHeaderChunk.version_low = packetHeaderChunk.chunk_data.readUInt8(9);
|
packetHeaderChunk.chunk_data.byteOffset,
|
||||||
packetHeaderChunk.frame_id = packetHeaderChunk.chunk_data.readUInt8(10);
|
packetHeaderChunk.chunk_data.byteLength
|
||||||
packetHeaderChunk.frame_packet_count = packetHeaderChunk.chunk_data.readUInt8(11);
|
);
|
||||||
|
packetHeaderChunk.packet_timestamp = view.getBigUint64(0, true);
|
||||||
|
packetHeaderChunk.version_high = view.getUint8(8);
|
||||||
|
packetHeaderChunk.version_low = view.getUint8(9);
|
||||||
|
packetHeaderChunk.frame_id = view.getUint8(10);
|
||||||
|
packetHeaderChunk.frame_packet_count = view.getUint8(11);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default (buffer: Buffer): PacketHeaderChunk => Decoders.Chunk(buffer, decodePacketHeaderChunk);
|
export default (buffer: Uint8Array): PacketHeaderChunk => {
|
||||||
|
return Decoders.Chunk(buffer, decodePacketHeaderChunk);
|
||||||
|
};
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ import { Decoders } from '.';
|
|||||||
import { DataPacketChunk } from '../models/data/data-packet-chunk';
|
import { DataPacketChunk } from '../models/data/data-packet-chunk';
|
||||||
import { InfoPacketChunk } from '../models/info/info-packet-chunk';
|
import { InfoPacketChunk } from '../models/info/info-packet-chunk';
|
||||||
|
|
||||||
export default (buffer: Buffer): InfoPacketChunk | DataPacketChunk | undefined => {
|
export default (buffer: Uint8Array): InfoPacketChunk | DataPacketChunk | undefined => {
|
||||||
const chunkId = buffer.readUInt16LE();
|
const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
||||||
|
const chunkId = view.getUint16(0, true);
|
||||||
|
|
||||||
switch (chunkId) {
|
switch (chunkId) {
|
||||||
case 0x6756:
|
case 0x6756:
|
||||||
return Decoders.InfoPacketChunk(buffer);
|
return Decoders.InfoPacketChunk(buffer);
|
||||||
|
|||||||
+7
-7
@@ -47,14 +47,14 @@ export class Encoder {
|
|||||||
|
|
||||||
const trackerChunks = trackers.map((tracker: Tracker) => tracker.getInfoChunk());
|
const trackerChunks = trackers.map((tracker: Tracker) => tracker.getInfoChunk());
|
||||||
|
|
||||||
const infoPackets: Buffer[] = [];
|
const infoPackets: Uint8Array[] = [];
|
||||||
|
|
||||||
const trackerChunksLists: Buffer[][] = [];
|
const trackerChunksLists: Uint8Array[][] = [];
|
||||||
let currentTrackerList: Buffer[] = [];
|
let currentTrackerList: Uint8Array[] = [];
|
||||||
|
|
||||||
let currentInfoPacketSize = Constants.PACKET_HEADER_SIZE + systemNameChunk.length + Constants.CHUNK_HEADER_SIZE;
|
let currentInfoPacketSize = Constants.PACKET_HEADER_SIZE + systemNameChunk.length + Constants.CHUNK_HEADER_SIZE;
|
||||||
|
|
||||||
trackerChunks.forEach((trackerChunk: Buffer) => {
|
trackerChunks.forEach((trackerChunk: Uint8Array) => {
|
||||||
if (currentInfoPacketSize + trackerChunk.length > Constants.MAX_UDP_PACKET_SIZE) {
|
if (currentInfoPacketSize + trackerChunk.length > Constants.MAX_UDP_PACKET_SIZE) {
|
||||||
trackerChunksLists.push(currentTrackerList);
|
trackerChunksLists.push(currentTrackerList);
|
||||||
currentTrackerList = [];
|
currentTrackerList = [];
|
||||||
@@ -95,10 +95,10 @@ export class Encoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const allTrackerChunks = trackers.map((tracker) => tracker.getDataChunk());
|
const allTrackerChunks = trackers.map((tracker) => tracker.getDataChunk());
|
||||||
const dataPackets: Buffer[] = [];
|
const dataPackets: Uint8Array[] = [];
|
||||||
|
|
||||||
const trackerChunksLists: Buffer[][] = [];
|
const trackerChunksLists: Uint8Array[][] = [];
|
||||||
let currentTrackerList: Buffer[] = [];
|
let currentTrackerList: Uint8Array[] = [];
|
||||||
|
|
||||||
let currentDataPacketSize = Constants.PACKET_HEADER_SIZE + Constants.CHUNK_HEADER_SIZE;
|
let currentDataPacketSize = Constants.PACKET_HEADER_SIZE + Constants.CHUNK_HEADER_SIZE;
|
||||||
|
|
||||||
|
|||||||
+10
-5
@@ -1,4 +1,4 @@
|
|||||||
export default (id: number, chunkData: Buffer, hasSubchunks: boolean): Buffer => {
|
export default (id: number, chunkData: Uint8Array, hasSubchunks: boolean): Uint8Array => {
|
||||||
if (!Number.isInteger(id)) {
|
if (!Number.isInteger(id)) {
|
||||||
throw new Error('chunk id must be an integer');
|
throw new Error('chunk id must be an integer');
|
||||||
}
|
}
|
||||||
@@ -11,10 +11,15 @@ export default (id: number, chunkData: Buffer, hasSubchunks: boolean): Buffer =>
|
|||||||
throw new Error('chunkData can not be greater than 32767 bytes');
|
throw new Error('chunkData can not be greater than 32767 bytes');
|
||||||
}
|
}
|
||||||
|
|
||||||
const header = Buffer.alloc(4);
|
const header = new DataView(new ArrayBuffer(4));
|
||||||
header.writeUInt16LE(id);
|
header.setUint16(0, id, true);
|
||||||
const hasSubChunksBit = (hasSubchunks ? 1 : 0) << 15;
|
const hasSubChunksBit = (hasSubchunks ? 1 : 0) << 15;
|
||||||
header.writeUInt16LE(hasSubChunksBit + chunkData.length, 2);
|
header.setUint16(2, hasSubChunksBit + chunkData.length, true);
|
||||||
|
|
||||||
return Buffer.concat([header, chunkData]);
|
const headerBytes = new Uint8Array(header.buffer);
|
||||||
|
|
||||||
|
const bytes = new Uint8Array(headerBytes.length + chunkData.length);
|
||||||
|
bytes.set(headerBytes);
|
||||||
|
bytes.set(chunkData, headerBytes.length);
|
||||||
|
return bytes;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
import chunk from '../chunk';
|
import chunk from '../chunk';
|
||||||
export default (packetHeaderChunk: Buffer, trackerListChunk: Buffer): Buffer =>
|
export default (packetHeaderChunk: Uint8Array, trackerListChunk: Uint8Array): Uint8Array => {
|
||||||
chunk(0x6755, Buffer.concat([packetHeaderChunk, trackerListChunk]), true);
|
const chunkData = new Uint8Array(packetHeaderChunk.length + trackerListChunk.length);
|
||||||
|
chunkData.set(packetHeaderChunk);
|
||||||
|
chunkData.set(trackerListChunk, packetHeaderChunk.length);
|
||||||
|
return chunk(0x6755, chunkData, true);
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import chunk from '../chunk';
|
import chunk from '../chunk';
|
||||||
|
|
||||||
export default (x: number, y: number, z: number): Buffer => {
|
export default (x: number, y: number, z: number): Uint8Array => {
|
||||||
const buf = Buffer.alloc(12);
|
const buf = new DataView(new ArrayBuffer(12));
|
||||||
buf.writeFloatLE(x);
|
buf.setFloat32(0, x, true);
|
||||||
buf.writeFloatLE(y, 4);
|
buf.setFloat32(4, y, true);
|
||||||
buf.writeFloatLE(z, 8);
|
buf.setFloat32(8, z, true);
|
||||||
return chunk(0x0004, buf, false);
|
return chunk(0x0004, new Uint8Array(buf.buffer), false);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,20 @@
|
|||||||
import chunk from '../chunk';
|
import chunk from '../chunk';
|
||||||
|
|
||||||
export default (trackerId: number, fieldChunks: Buffer[]): Buffer =>
|
export default (trackerId: number, fieldChunks: Uint8Array[]): Uint8Array => {
|
||||||
chunk(trackerId, Buffer.concat(fieldChunks), fieldChunks.length > 0);
|
let fieldChunksTotalLength = 0;
|
||||||
|
|
||||||
|
fieldChunks.forEach((fieldChunk) => {
|
||||||
|
fieldChunksTotalLength += fieldChunk.length;
|
||||||
|
});
|
||||||
|
|
||||||
|
const fieldChunksBytes = new Uint8Array(fieldChunksTotalLength);
|
||||||
|
|
||||||
|
let offset = 0;
|
||||||
|
|
||||||
|
fieldChunks.forEach((fieldChunk) => {
|
||||||
|
fieldChunksBytes.set(fieldChunk, offset);
|
||||||
|
offset += fieldChunk.length;
|
||||||
|
});
|
||||||
|
|
||||||
|
return chunk(trackerId, fieldChunksBytes, fieldChunks.length > 0);
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,3 +1,20 @@
|
|||||||
import chunk from '../chunk';
|
import chunk from '../chunk';
|
||||||
|
|
||||||
export default (trackerChunks: Buffer[]) => chunk(0x0001, Buffer.concat(trackerChunks), true);
|
export default (trackerChunks: Uint8Array[]) => {
|
||||||
|
let trackerChunksTotalLength = 0;
|
||||||
|
|
||||||
|
trackerChunks.forEach((trackerChunk) => {
|
||||||
|
trackerChunksTotalLength += trackerChunk.length;
|
||||||
|
});
|
||||||
|
|
||||||
|
const trackerChunksBytes = new Uint8Array(trackerChunksTotalLength);
|
||||||
|
|
||||||
|
let offset = 0;
|
||||||
|
|
||||||
|
trackerChunks.forEach((trackerChunk) => {
|
||||||
|
trackerChunksBytes.set(trackerChunk, offset);
|
||||||
|
offset += trackerChunk.length;
|
||||||
|
});
|
||||||
|
|
||||||
|
return chunk(0x0001, trackerChunksBytes, true);
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import chunk from '../chunk';
|
import chunk from '../chunk';
|
||||||
|
|
||||||
export default (x: number, y: number, z: number): Buffer => {
|
export default (x: number, y: number, z: number): Uint8Array => {
|
||||||
const buf = Buffer.alloc(12);
|
const buf = new DataView(new ArrayBuffer(12));
|
||||||
buf.writeFloatLE(x);
|
|
||||||
buf.writeFloatLE(y, 4);
|
buf.setFloat32(0, x, true);
|
||||||
buf.writeFloatLE(z, 8);
|
buf.setFloat32(4, y, true);
|
||||||
return chunk(0x0002, buf, false);
|
buf.setFloat32(8, z, true);
|
||||||
|
return chunk(0x0002, new Uint8Array(buf.buffer), false);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import chunk from '../chunk';
|
import chunk from '../chunk';
|
||||||
|
|
||||||
export default (x: number, y: number, z: number): Buffer => {
|
export default (x: number, y: number, z: number): Uint8Array => {
|
||||||
const buf = Buffer.alloc(12);
|
const buf = new DataView(new ArrayBuffer(12));
|
||||||
buf.writeFloatLE(x);
|
|
||||||
buf.writeFloatLE(y, 4);
|
buf.setFloat32(0, x, true);
|
||||||
buf.writeFloatLE(z, 8);
|
buf.setFloat32(4, y, true);
|
||||||
return chunk(0x0000, buf, false);
|
buf.setFloat32(8, z, true);
|
||||||
|
|
||||||
|
return chunk(0x0000, new Uint8Array(buf.buffer), false);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import chunk from '../chunk';
|
import chunk from '../chunk';
|
||||||
|
|
||||||
export default (x: number, y: number, z: number): Buffer => {
|
export default (x: number, y: number, z: number): Uint8Array => {
|
||||||
const buf = Buffer.alloc(12);
|
const buf = new DataView(new ArrayBuffer(12));
|
||||||
buf.writeFloatLE(x);
|
|
||||||
buf.writeFloatLE(y, 4);
|
buf.setFloat32(0, x, true);
|
||||||
buf.writeFloatLE(z, 8);
|
buf.setFloat32(4, y, true);
|
||||||
return chunk(0x0001, buf, false);
|
buf.setFloat32(8, z, true);
|
||||||
|
|
||||||
|
return chunk(0x0001, new Uint8Array(buf.buffer), false);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import chunk from '../chunk';
|
import chunk from '../chunk';
|
||||||
|
|
||||||
export default (validity: number): Buffer => {
|
export default (validity: number): Uint8Array => {
|
||||||
const buf = Buffer.alloc(4);
|
const buf = new DataView(new ArrayBuffer(4));
|
||||||
buf.writeFloatLE(validity);
|
buf.setFloat32(0, validity, true);
|
||||||
return chunk(0x0003, buf, false);
|
return chunk(0x0003, new Uint8Array(buf.buffer), false);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import chunk from '../chunk';
|
import chunk from '../chunk';
|
||||||
|
|
||||||
export default (timestamp: bigint): Buffer => {
|
export default (timestamp: bigint): Uint8Array => {
|
||||||
const buf = Buffer.alloc(8);
|
const buf = new DataView(new ArrayBuffer(8));
|
||||||
buf.writeBigUInt64LE(BigInt(timestamp));
|
buf.setBigUint64(0, BigInt(timestamp), true);
|
||||||
return chunk(0x0006, buf, false);
|
return chunk(0x0006, new Uint8Array(buf.buffer), false);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import chunk from '../chunk';
|
import chunk from '../chunk';
|
||||||
|
|
||||||
export default (x: number, y: number, z: number): Buffer => {
|
export default (x: number, y: number, z: number): Uint8Array => {
|
||||||
const buf = Buffer.alloc(12);
|
const buf = new DataView(new ArrayBuffer(12));
|
||||||
buf.writeFloatLE(x);
|
|
||||||
buf.writeFloatLE(y, 4);
|
buf.setFloat32(0, x, true);
|
||||||
buf.writeFloatLE(z, 8);
|
buf.setFloat32(4, y, true);
|
||||||
return chunk(0x0005, buf, false);
|
buf.setFloat32(8, z, true);
|
||||||
|
|
||||||
|
return chunk(0x0005, new Uint8Array(buf.buffer), false);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,14 @@
|
|||||||
import chunk from '../chunk';
|
import chunk from '../chunk';
|
||||||
|
|
||||||
export default (packetHeaderChunk: Buffer, systemNameChunk: Buffer, trackerListChunk: Buffer): Buffer =>
|
export default (
|
||||||
chunk(0x6756, Buffer.concat([packetHeaderChunk, systemNameChunk, trackerListChunk]), true);
|
packetHeaderChunk: Uint8Array,
|
||||||
|
systemNameChunk: Uint8Array,
|
||||||
|
trackerListChunk: Uint8Array
|
||||||
|
): Uint8Array => {
|
||||||
|
const chunkData = new Uint8Array(packetHeaderChunk.length + systemNameChunk.length + trackerListChunk.length);
|
||||||
|
|
||||||
|
chunkData.set(packetHeaderChunk);
|
||||||
|
chunkData.set(systemNameChunk, packetHeaderChunk.length);
|
||||||
|
chunkData.set(trackerListChunk, packetHeaderChunk.length + systemNameChunk.length);
|
||||||
|
return chunk(0x6756, chunkData, true);
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
import chunk from '../chunk';
|
import chunk from '../chunk';
|
||||||
|
|
||||||
export default (systemName: string): Buffer => chunk(0x0001, Buffer.from(systemName), false);
|
export default (systemName: string): Uint8Array => chunk(0x0001, new TextEncoder().encode(systemName), false);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
import chunk from '../chunk';
|
import chunk from '../chunk';
|
||||||
|
|
||||||
export default (trackerId: number, trackerNameChunk: Buffer): Buffer => chunk(trackerId, trackerNameChunk, true);
|
export default (trackerId: number, trackerNameChunk: Uint8Array): Uint8Array =>
|
||||||
|
chunk(trackerId, trackerNameChunk, true);
|
||||||
|
|||||||
@@ -1,3 +1,19 @@
|
|||||||
import chunk from '../chunk';
|
import chunk from '../chunk';
|
||||||
|
|
||||||
export default (trackerChunks: Buffer[]): Buffer => chunk(0x0002, Buffer.concat(trackerChunks), true);
|
export default (trackerChunks: Uint8Array[]): Uint8Array => {
|
||||||
|
let trackerChunksTotalLength = 0;
|
||||||
|
|
||||||
|
trackerChunks.forEach((trackerChunk) => {
|
||||||
|
trackerChunksTotalLength += trackerChunk.length;
|
||||||
|
});
|
||||||
|
|
||||||
|
const trackerChunksBytes = new Uint8Array(trackerChunksTotalLength);
|
||||||
|
|
||||||
|
let offset = 0;
|
||||||
|
|
||||||
|
trackerChunks.forEach((trackerChunk) => {
|
||||||
|
trackerChunksBytes.set(trackerChunk, offset);
|
||||||
|
offset += trackerChunk.length;
|
||||||
|
});
|
||||||
|
return chunk(0x0002, trackerChunksBytes, true);
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
import chunk from '../chunk';
|
import chunk from '../chunk';
|
||||||
|
|
||||||
export default (trackerName: string) => chunk(0x0000, Buffer.from(trackerName), false);
|
export default (trackerName: string) => chunk(0x0000, new TextEncoder().encode(trackerName), false);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ export default (
|
|||||||
versionLow: number,
|
versionLow: number,
|
||||||
frameId: number,
|
frameId: number,
|
||||||
framePacketCount: number
|
framePacketCount: number
|
||||||
): Buffer => {
|
): Uint8Array => {
|
||||||
if (!Number.isInteger(versionHigh)) {
|
if (!Number.isInteger(versionHigh)) {
|
||||||
throw new Error('version high must be an integer');
|
throw new Error('version high must be an integer');
|
||||||
}
|
}
|
||||||
@@ -33,12 +33,12 @@ export default (
|
|||||||
throw new Error('frame packet count must be >= 0 and <= 255');
|
throw new Error('frame packet count must be >= 0 and <= 255');
|
||||||
}
|
}
|
||||||
|
|
||||||
const packetHeader = Buffer.alloc(12);
|
const packetHeader = new DataView(new ArrayBuffer(12));
|
||||||
packetHeader.writeBigUInt64LE(BigInt(timestamp));
|
packetHeader.setBigUint64(0, BigInt(timestamp), true);
|
||||||
packetHeader.writeUint8(versionHigh, 8);
|
packetHeader.setUint8(8, versionHigh);
|
||||||
packetHeader.writeUint8(versionLow, 9);
|
packetHeader.setUint8(9, versionLow);
|
||||||
packetHeader.writeUint8(frameId, 10);
|
packetHeader.setUint8(10, frameId);
|
||||||
packetHeader.writeUint8(framePacketCount, 11);
|
packetHeader.setUint8(11, framePacketCount);
|
||||||
|
|
||||||
return chunk(0x0000, packetHeader, false);
|
return chunk(0x0000, new Uint8Array(packetHeader.buffer), false);
|
||||||
};
|
};
|
||||||
|
|||||||
+1
-1
@@ -2,5 +2,5 @@ export interface Chunk {
|
|||||||
id?: number;
|
id?: number;
|
||||||
has_subchunks?: boolean;
|
has_subchunks?: boolean;
|
||||||
data_len?: number;
|
data_len?: number;
|
||||||
chunk_data?: Buffer;
|
chunk_data?: Uint8Array;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Chunk } from '../chunk';
|
import { Chunk } from '../chunk';
|
||||||
|
|
||||||
export interface DataTrackerFieldChunk extends Chunk {
|
export interface DataTrackerFieldChunk extends Chunk {
|
||||||
[key: string]: number | bigint | number[] | Buffer | undefined | boolean;
|
[key: string]: number | bigint | number[] | Uint8Array | undefined | boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ export class Tracker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getDataChunk() {
|
getDataChunk() {
|
||||||
const fieldChunks: Buffer[] = [];
|
const fieldChunks: Uint8Array[] = [];
|
||||||
|
|
||||||
if (this.pos) {
|
if (this.pos) {
|
||||||
fieldChunks.push(dataTrackerPosChunk(...this.pos));
|
fieldChunks.push(dataTrackerPosChunk(...this.pos));
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "CommonJS",
|
||||||
|
"declaration": false,
|
||||||
|
"outDir": "./dist/cjs"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "ESNext",
|
||||||
|
"declaration": false,
|
||||||
|
"outDir": "./dist/esm"
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
-7
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
|
"moduleResolution": "Node",
|
||||||
|
"lib": ["ESNext"],
|
||||||
|
"target": "ESNext",
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"module": "commonjs",
|
"isolatedModules": true,
|
||||||
"target": "ES2020",
|
"rootDir": "src/",
|
||||||
"declaration": true,
|
"strict": true
|
||||||
"rootDir": "./src",
|
|
||||||
"strict": true,
|
|
||||||
"outDir": "dist"
|
|
||||||
},
|
},
|
||||||
"exclude": ["node_modules", "dist", "examples"]
|
"include": ["src/"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"emitDeclarationOnly": true,
|
||||||
|
"declaration": true,
|
||||||
|
"outDir": "./dist/types"
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user